Skip to content

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.

Terminal window
TOKEN=... # from the startup URL
curl -s -H "x-moka-token: $TOKEN" localhost:4000/api/bootstrap | jq .config.llms

POST /api/chat streams NDJSON — one JSON object per line.

Terminal window
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
messagesAI SDK ModelMessage[] — the full history
workspaceIdOptional; defaults to the active workspace
llmIdOptional; override the workspace’s model
agentIdOptional; talk to this remote agent instead
Chunk typeFields
startrunId, model, profileId, tools (count)
text / reasoningtext (delta)
tool-callid, name, tool, source, input
tool-resultid, output, isError, durationMs, ui?, raw?
stepusage, finishReason
finishusage, durationMs, messages — append these to your history for the next turn
errormessage

ui is one of {kind:"mcp-app", serverId, resourceUri}, {kind:"mcp-ui", …} or {kind:"a2ui", messages}.

Method & pathDescription
GET /api/health{ ok, version }
GET /api/bootstrapConfig, provider presets, detected env keys, MCP states, skills
PUT /api/configReplace the whole config (validated; 400 with details if invalid)
GET /api/config/export?redact=1Config 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/mcpAll server states
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/signoutForget OAuth tokens and reconnect
GET /oauth/callbackOAuth 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/catalogsThe 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/interactionsPending 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/eventsNDJSON stream: buffered history, then live events (15 s heartbeats)
POST /api/events/uiReport ui.rpc / ui.action events
DELETE /api/eventsClear the buffer
GET /api/sessions · GET/PUT/DELETE /api/sessions/:idChat history