HTTP API and MCP¶
vidx serve exposes every index under a directory. Base path /v1; JSON in, JSON or
Server-Sent Events out; the OpenAPI document is at /v1/openapi.json.
| Method | Path | Purpose |
|---|---|---|
| GET | /healthz |
liveness, version, known indexes |
| GET | /metrics |
Prometheus text |
| GET, POST | /v1/indexes |
list, create ({"id": "name"}) |
| GET | /v1/indexes/{id} |
status: videos, counts, sizes |
| GET, POST | /v1/indexes/{id}/videos |
list; add sources ({"sources": [...], "policy": "..."}) → 202 job |
| GET | /v1/indexes/{id}/videos/{vid}/timeline?level=chapter\|scene\|shot |
segments |
| GET | /v1/indexes/{id}/videos/{vid}/transcript?t0&t1&kind=transcript\|ocr\|description |
spans |
| POST | /v1/indexes/{id}/search |
hybrid search |
| POST | /v1/indexes/{id}/ask |
agentic answer; SSE with Accept: text/event-stream |
| POST | /v1/indexes/{id}/view |
labelled frame grid (PNG) |
| GET | /v1/indexes/{id}/blobs/{key} |
thumbnails, grids |
| GET, DELETE | /v1/jobs/{job} |
job status (SSE with Accept: text/event-stream); cancel |
| POST | /v1/mcp, /v1/indexes/{id}/mcp |
MCP (streamable HTTP, JSON-RPC 2.0) |
Authentication is Authorization: Bearer <key> (or X-API-Key) when server.api_keys
is set; server.daily_cost_cap_usd caps each key's provider spend per day (429 past it).
Streaming an answer¶
curl -N -H 'Accept: text/event-stream' -H 'Content-Type: application/json' \
-d '{"question": "what is regret matching?", "budget": {"max_tool_calls": 6}}' \
http://127.0.0.1:8080/v1/indexes/dataset/ask
Events (event: names the type): status, tool_call, tool_result, token,
citation (video_id, t0, t1, kind), done (partial, reason, usage).
MCP¶
Point an MCP client at POST /v1/mcp. Tools: search, list_videos, timeline,
get_transcript, get_ocr, get_descriptions, view (returns an image),
describe (when a VLM role is bound), index_state, and ask (VideoIndex's own agent).
{"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": "search", "arguments": {"query": "strawberry", "k": 5}}}