HTTP API
The UI talks to the Moka server over a small JSON API. You can use it too — for scripted demos, CI smoke tests or your own front end.
Auth: send the token printed at startup as x-moka-token: <token> (or ?token=). GET /api/health needs no token.
TOKEN=... # from the startup URLcurl -s -H "x-moka-token: $TOKEN" localhost:4000/api/bootstrap | jq .config.llmsPOST /api/chat streams NDJSON — one JSON object per line.
curl -N -H "x-moka-token: $TOKEN" -H 'content-type: application/json' \ -d '{"messages":[{"role":"user","content":"What time is it in Tokyo?"}]}' \ localhost:4000/api/chat| Body field | |
|---|---|
messages | AI SDK ModelMessage[] — the full history |
workspaceId | Optional; defaults to the active workspace |
llmId | Optional; override the workspace’s model |
agentId | Optional; talk to this remote agent instead |
File parts the model can’t take (a PDF for an OpenAI-compatible model, a Word file for any model) are replaced by text before the request: the part’s providerOptions.moka.text if it has one, otherwise a note that the model can’t read the file. The web UI puts the text it read from PDFs and Word files there.
Chunk type | Fields |
|---|---|
start | runId, model, profileId, tools (count) |
text / reasoning | text (delta) |
tool-call | id, name, tool, source, serverId (MCP tools), input |
tool-result | id, output, isError, durationMs, ui?, raw? |
step | usage, finishReason |
finish | usage, durationMs, messages — append these to your history for the next turn |
error | message |
ui is one of {kind:"mcp-app", serverId, resourceUri}, {kind:"mcp-ui", …} or {kind:"a2ui", messages}.
Endpoints
Section titled “Endpoints”| Method & path | Description |
|---|---|
GET /api/health | { ok, version } |
GET /api/bootstrap | Config, provider presets, detected env keys, MCP states, skills |
PUT /api/config | Replace the whole config (validated; 400 with details if invalid) |
GET /api/config/export?redact=1 | Config with secrets redacted |
POST /api/export | {target: "ai-sdk"|"langgraph"|"mcp-json"|"moka", workspaceId} → {code} |
POST /api/llm/test | {profile} → {ok, latencyMs, text?, error?} |
POST /api/llm/models | {profile} → {models, error?} |
GET /api/mcp | All server states. HTTP/SSE servers include http: the last request with masked headers |
POST /api/mcp/test | {server} → connect a draft config and report capabilities |
POST /api/mcp/import | {json} → parsed servers from Claude/Cursor/VS Code JSON |
POST /api/mcp/:id/connect | {force?} → connect or reconnect |
POST /api/mcp/:id/disconnect | |
POST /api/mcp/:id/call | {tool, args} → {result, durationMs} |
POST /api/mcp/:id/resource | {uri} → resources/read result |
POST /api/mcp/:id/subscribe | {uri, subscribe?: false} → {subscriptions}: subscribe to (or unsubscribe from) resource updates |
POST /api/mcp/:id/signout | Forget OAuth tokens and reconnect |
GET /oauth/callback | OAuth redirect target (no token needed) |
POST /api/agents/test | {agent} → {ok, latencyMs, card?, events?, text?, error?} |
POST /api/mcp/:id/prompt | {name, args} → prompts/get result |
POST /api/skills/preview | {skill} → loaded skill (body, files, errors) |
POST /api/skills/discover | {path} → skill folders under a path |
GET /api/catalogs | The standard catalog plus every configured catalog (loaded) |
POST /api/catalogs/preview | {catalog} → load a draft catalog config and report errors |
GET /api/ui/tool?workspaceId= | The render tool a workspace sends: name, description, inputSchema, components |
POST /api/ui/preview | {input, workspaceId} → {messages, problems} (validated and expanded A2UI), or {component: {catalogId, name}} for a component preview |
POST /api/ui/generate | {prompt, workspaceId?, llmId?} → ask a model for UI with only the render tool |
GET /api/interactions | Pending approvals / elicitation / sampling requests |
POST /api/interactions/:id | {response}: {approved, remember?: "session"|"always"} for approvals and sampling, {action: "accept"|"decline"|"cancel", content?} for elicitation |
GET /api/events | NDJSON stream: buffered history, then live events (15 s heartbeats) |
POST /api/events/ui | Report ui.rpc / ui.action events |
DELETE /api/events | Clear the buffer |
GET /api/sessions · GET/PUT/DELETE /api/sessions/:id | Chat history |
GET /api/budget?workspaceId= | {total, items, notConnected}: estimated tokens the model reads before every message (system prompt, skills, instructions, each tool) |
GET /api/security?workspaceId= | {servers}: the security check of each connected server: findings and changes |
POST /api/security/:id/trust | Trust a server’s tools as they are now |
POST /api/tests/run | {llmIds, workspaceId?, runs?, toolMode?: "run"|"read-only"|"none", testIds?} → NDJSON stream of test results |
POST /api/tests/suggest | {workspaceId?, count?} → {tests} proposed by the workspace’s model |
GET /api/local-models | {ollama, lmstudio}: models of local servers running now |