API Reference#
The Live Video Alert Agent exposes REST and SSE endpoints for management, data consumption, and operational monitoring.
Observability#
GET /health#
Liveness probe. Always returns 200 if the application process is alive.
Response:
{ "status": "healthy", "streams_active": 2, "alerts_enabled": 3, "vlm_reachable": true, "uptime_seconds": 342.1, "timestamp": "2026-03-12T10:00:00Z" }
GET /ready#
Readiness probe. Returns 200 only when the manager is running and at least
one alert is enabled. Returns 503 otherwise.
Response (ready):
{ "status": "ready", "streams": 1, "alerts": 2 }
GET /metrics#
System and per-stream inference counters.
Response:
{ "cpu_percent": 18.4, "memory_percent": 42.1, "streams": [ { "stream_id": "cam1", "analysis_count": 120, "alert_count": 5, "last_inference_ms": 850.3 } ] }
Streaming#
GET /events (SSE)#
Server-Sent Events stream for real-time updates.
Response Type:
text/event-streamEvents:
Event |
When |
Data fields |
|---|---|---|
|
On connect |
|
|
Each VLM cycle |
|
|
Alert fired + tools invoked |
|
|
Every 15 s |
|
alert_actionexample:{ "event": "alert_action", "data": { "stream_id": "cam1", "alert_name": "Fire Detection", "severity": "critical", "answer": "YES", "reason": "Flames visible in lower-left quadrant", "actions_taken": ["log_alert", "capture_snapshot"], "escalated": false, "snapshot_path": "/app/snapshots/cam1/Fire_Detection_critical_20260312T100512.jpg" } }
GET /video_feed#
MJPEG stream for live frame preview.
Query Parameters:
stream_id(string, default:default)Response Type:
multipart/x-mixed-replace; boundary=frame
GET /data#
Polling endpoint returning latest VLM results enriched with runtime alert state. Prefer /events for new integrations.
Response:
{ "cam1": { "stream_name": "Lobby Camera", "alerts": { "Fire Detection": { "answer": "NO", "reason": "No fire or smoke visible", "consecutive_yes": 0, "consecutive_no": 3, "last_answer": "NO" } } } }
Stream Management#
GET /streams#
List all active streams with health status.
Response:
{ "streams": [ { "stream_id": "cam1", "name": "Lobby Camera", "url": "rtsp://192.168.1.10:554/stream", "connected": true, "fps": 1.0, "resolution": "1920x1080", "buffer_fill": 1, "tools": [], "alerts": [] } ] }
POST /streams#
Register a new video stream.
Request Body:
{ "stream_id": "cam1", "name": "Lobby Camera", "url": "rtsp://192.168.1.10:554/stream", "tools": [], "alerts": [] }
Response:
{"status": "added", "stream_id": "cam1"}Status Codes:
200added |409already exists |422validation error
PATCH /streams/{stream_id}#
Update per-stream settings.
Request Body:
{ "alerts": ["Fire Detection", "Person Detection"] }
alerts— list of alert names to evaluate for this stream
Response:
{ "id": "cam1", "alerts": ["Fire Detection", "Person Detection"] }
Status Codes:
200updated |404not found
DELETE /streams/{stream_id}#
Remove an active stream.
Response:
{"status": "removed", "stream_id": "cam1"}Status Codes:
200removed |404not found
Alert Configuration#
GET /config/alerts#
Return the current alert configurations.
Response: array of
AlertConfigobjects (see schema below).
POST /config/alerts#
Replace the full alert configuration.
Request Body: array of alert config objects:
[ { "name": "Fire Detection", "prompt": "Is there fire or smoke visible?", "enabled": true, "tools": ["log_alert", "capture_snapshot"], "escalation": { "threshold_consecutive": 3, "additional_tools": ["trigger_webhook", "publish_mqtt"] } }, { "name": "Person Detection", "prompt": "Is there a person in the frame?", "enabled": true, "tools": ["log_alert"] } ]
Alert Config Fields:
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
yes |
Alert identifier (letters, digits, spaces, hyphens, dots, underscores) |
|
string |
yes |
Natural-language yes/no question sent to the VLM |
|
bool |
no (default |
Whether this alert is active |
|
list of tool names |
no (default |
Tools to invoke when alert fires |
|
object |
no |
Per-tool argument overrides; supports |
|
int (≥ 2) |
no |
Consecutive YES count before escalation |
|
list of tool names |
no |
Extra tools added on escalation |
Valid built-in tool names:
log_alert,capture_snapshot,trigger_webhook,publish_mqttMCP tool names (when
MCP_ENABLED=true): prefixed withmcp_{server_name}_(see MCP section)Response:
{"status": "saved", "count": 2}Status Codes:
200saved |422schema validation failed
Action Tools#
GET /tools#
List all registered action tools and whether they are currently enabled (based on environment variable configuration).
Response:
{ "tools": [ { "name": "log_alert", "description": "...", "enabled": true, "parameters": {} } ] }
POST /tools/{tool_name}/invoke#
Manually invoke a registered tool for testing.
Path Parameters:
tool_name— one oflog_alert,trigger_webhook,capture_snapshot,publish_mqttRequest Body:
{ "parameters": { "stream_id": "cam1", "alert_name": "Test" } }
Response:
{ "tool": "log_alert", "status": "success", "result": { "status": "logged" }, "duration_ms": 1.2 }
Status Codes:
200(success or error both return 200 withstatusfield) |404tool not found
POST /tools/reload#
Reload tool definitions from resources/tools.json without restarting the application.
Response:
{"status": "ok", "tools_loaded": 4}Status Codes:
200ok
MCP#
Model Context Protocol (MCP) endpoints allow the agent to discover and invoke tools from
external MCP servers. Enabled when MCP_ENABLED=true (default). Server connections can be
configured an added in resources/mcp_servers.json.
GET /mcp/status#
Get connection status and available tools per configured MCP server.
Response:
{ "enabled": true, "servers": [ { "name": "prometheus", "connected": true, "transport": "http", "url": "http://10.0.0.1:8080/mcp", "tool_count": 6 } ], "total_tools": 6 }
When
MCP_ENABLED=false:{"enabled": false, "servers": [], "total_tools": 0}
GET /mcp/tools#
List all tools available from connected MCP servers.
Response:
{ "tools": [ { "name": "mcp_prometheus_execute_query", "description": "[MCP:prometheus] Execute a PromQL query", "server": "prometheus", "input_schema": { "type": "object", "properties": { "query": { "type": "string" } } } } ], "count": 6 }
Tool names are prefixed with
mcp_{server_name}_to avoid conflicts with built-in tools.
POST /mcp/reload#
Reload MCP server configuration from resources/mcp_servers.json and reconnect to all servers.
Response:
{"status": "ok", "tools_loaded": 6}When
MCP_ENABLED=false:{"status": "skipped", "reason": "MCP is disabled", "tools_loaded": 0}Status Codes:
200ok |500reload failed
POST /mcp/tools/{tool_name}/invoke#
Manually invoke an MCP tool for testing.
Path Parameters:
tool_name— full prefixed name (e.g.mcp_prometheus_execute_query)Request Body:
{ "parameters": { "query": "up" } }
Response:
{ "tool": "mcp_prometheus_execute_query", "status": "success", "result": {...}, "duration_ms": 45.3 }Note: The
resultfield contains the raw response returned by the MCP tool; its structure varies per tool.Status Codes:
200|404tool not found |503MCP disabled or server not connected
Dashboard UI#
GET /#
Serves the monitoring dashboard HTML.
Response:
text/html