Complete enumeration of every endpoint. REST is JSON unless noted; the only SSE endpoint is
/api/events.
All non-API routes return static files (server.js → serveStatic /
serveIndex).
- Base URL:
http://127.0.0.1:8080(or LAN IP if enabled) - Path prefix:
/api/ - Content-Type:
application/json; charset=utf-8for both request and response - Auth header: if
TOKENenv is set, every request must include either- query:
?token=… - header:
Authorization: Bearer … - 401 if missing or wrong
- query:
- CID: every request must include
?cid=<uuid>to identify the webui tab. The webui injects this automatically; the API is unusable without it. - Errors: every error response is
{ok: false, error: 'human-readable message'}with an appropriate 4xx/5xx status. Some legacy endpoints still return{ok: true, …}even on soft failures — those are called out below.
Returns server status. No auth required, no CID required.
Response 200
{
"ok": true,
"port": 8080,
"defaultModel": "minimax_api/MiniMax-M3",
"defaultWorkspace": "C:\\Users\\you\\.minimax-code\\webui",
"mcodeCmd": "C:\\Users\\you\\.minimax-code\\mcode.cmd",
"mcodeVersion": "0.1.2",
"maxConcurrent": 3
}Returns the current state object for this CID. See
ARCHITECTURE.md §4 for the full shape.
Response 200
{ "ok": true, "version": "0.1.3", "running": {"active": false}, … }Server-Sent Events stream for this CID. The connection stays open indefinitely. Events are listed in ARCHITECTURE.md §5.
Response 200 (Content-Type: text/event-stream)
event: state
data: {"version":"0.1.3","running":{"active":false},…}
event: delta
data: {"text":"hello","isPartial":true}
event: exec
data: {"status":"ok","durationMs":12345}
The connection is held open until the client closes it (EventSource.close())
or the server shuts down. No automatic reconnect from the server side;
the webui handles reconnection with exponential backoff.
Send a user message. Spawns (or reuses) the mcode subprocess for this CID and streams the result via SSE.
Request
{
"content": "refactor the workspace picker to use a tree",
"attachments": ["@C:\\path\\to\\file.py"],
"isAskAnswer": false
}content(string, required) — the user message. May include@pathreferences to attachments; the webui injects these automatically.attachments(string[], optional) — list of@pathstrings to prepend to the content. The webui populates this from the attachment UI; you usually don't pass it directly.isAskAnswer(bool, optional) — whentrue, the content is the answer to an activeask_userquestion. Set by the ask modal automatically.
Response 200 {ok: true} immediately. The actual response is
streamed via /api/events.
Errors
- 409 if
state.running.active === true(already running) - 400 if
contentis empty
Cancel the current run. Best-effort: tries session/cancel via acp
(unimplemented in 0.1.5), then SIGTERM, then SIGKILL after 2s.
Request {}
Response 200 {ok: true}
Send a raw slash command (e.g. /compact, /clear). The server sends
the command to mcode and streams the result.
Request
{ "cmd": "/compact" }Response 200 {ok: true}
List webui sessions + mcode sessions (merged, deduplicated).
Response 200
{
"ok": true,
"count": 12,
"sessions": [
{ "id": "uuid", "title": "…", "workspace": "C:\\…", "mcodeSessionId": "mvs_…", "updatedAt": 1234567890 }
]
}Create a new webui session. Optionally tied to a workspace.
Request
{ "workspace": "C:\\path\\to\\project" }Response 200 {ok: true, id: "uuid"}
Switch to an existing session. Loads its chat history and (if linked) re-attaches to the mcode session.
Request
{ "id": "uuid" }Response 200 {ok: true}
Delete mcode sessions that no webui session references. Two scopes:
scope: "orphans"(default) — only delete mcode sessions with no webui reference. The currently-active session is always preserved.scope: "all"— delete every mcode session, then re-link webui sessions that had amcodeSessionId(which now points to a deleted session — they become "webui-only" again).
Request
{ "scope": "orphans" }Response 200
{
"ok": true,
"scope": "orphans",
"total": 37,
"targets": 18,
"deleted": 18,
"failed": 0,
"log": ["deleted mvs_5103ca…", "deleted mvs_88c796…", …]
}Delete a webui session AND its linked mcode session (if any). The mcode deletion is a transaction across 8 sqlite tables.
Response 200 {ok: true}
Raw mcode session list (from sqlite). No webui merge.
Response 200 {ok: true, sessions: [...]}
Get the title of an mcode session.
Response 200 {ok: true, title: "…"}
Change the workspace for the current CID.
Request
{
"dir": "C:\\path\\to\\project",
"syncTui": true
}dir(string, required) — absolute pathsyncTui(bool, optional) — also write the path tocwd.jsonso the mcode TUI sees itaction: "detect"— instead of changing, return the current TUI cwdaction: "useTui"— copy the TUI's cwd to webuiaction: "reset"— restore webui's default workspace
Response 200 {ok: true, dir: "…", branch: "main", treeState: "clean"}
List a directory for the tree browser.
Request query: ?path=C:\\Users (omit for drive roots on Windows
or / for Linux)
Response 200
{
"ok": true,
"path": "C:\\Users",
"children": [
{ "name": "Public", "path": "C:\\Users\\Public", "isDir": true }
]
}When path is omitted:
- Windows:
roots: ["C:", "D:", …] - Linux:
children: [{name: "/", path: "/", isDir: true}]
Returns the full settings snapshot. This endpoint is exempt from the LAN guard — it's how a remote user toggles LAN back on after locking themselves out.
Response 200
{
"ok": true,
"lanBroadcast": true,
"port": 8080,
"host": "0.0.0.0",
"lanIp": "192.168.1.50",
"lanUrl": "http://192.168.1.50:8080",
"localUrl": "http://127.0.0.1:8080",
"mcodeCmd": "C:\\…\\mcode.cmd",
"mcodeVersion": "0.1.2",
"defaultWorkspace": "C:\\…",
"defaultModel": "minimax_api/MiniMax-M3"
}Update one or more settings. Only lanBroadcast is currently settable.
Request
{ "lanBroadcast": false }Response 200 {ok: true, lanBroadcast: false, …}
Multipart file upload. Saves to MCODE_WEBUI_UPLOAD_DIR and returns
the absolute path.
Request multipart/form-data with a file field.
Response 200
{
"ok": true,
"filename": "screenshot.png",
"path": "C:\\…\\.webui-uploads\\screenshot.png",
"size": 12345,
"mime": "image/png"
}Returns the builtin + currently-configured model list.
Response 200
{
"ok": true,
"current": "minimax_api/MiniMax-M3",
"models": [
{ "id": "minimax_api/MiniMax-M3", "label": "MiniMax-M3", "provider": "minimax_api" }
]
}If the list is empty, the response includes a hint field pointing
the user at the mcode TUI for model configuration.
Change the model for the current CID.
Request
{ "model": "minimax_api/MiniMax-M3" }Response 200 {ok: true, model: "…"}
Change the session-level permission mode.
Request
{ "permissions": "ask" }permissions(string) — one ofask,auto,full,plan
Response 200 {ok: true, permissions: "ask"}
Note: mcode 0.1.5 acp does not implement
session/set_mode. The webui's UI shows the mode the user selected, but the underlying mcode session does not change. This is logged in the server console as[mcode-rpc] UNSUPPORTED session/set_mode. Will start working when mcode implements the method.
List the available permission modes.
Response 200 {ok: true, modes: ["default", "bypassPermissions", "auto", "off", "read", "full"]}
Respond to an active permission / plan / ask_user prompt.
Request
{ "type": "permission", "option": "ask" }type(string) —permission|plan|planmode|askoption(string) — depends on type:permission:ask|auto|fullplan:agree|skip|addplanmode:continue|denyask:esc(skip) |<index>(option) |<text>(free-form)
Response 200 {ok: true}
Fetch the current mmx quota show snapshot. POST /api/usage-trigger
also triggers a fresh fetch from the CLI. GET /api/usage and
POST /api/usage return the cached value if recent.
Response 200
{
"ok": true,
"remaining": 91,
"resetAt": 1234567890,
"weeklyResetAt": 1234567890,
"fetchedAt": 1234567890,
"source": "mmx"
}Fetch per-turn context usage from the mavis runtime db. This is the
source of truth for "已用 N / 占比 N%" in the right panel.
Response 200
{
"ok": true,
"lastTurnContextTokens": 12345,
"lastInputTokens": 1000,
"lastCacheReadTokens": 500,
"lastCacheWriteTokens": 200,
"lastOutputTokens": 800,
"contextLimit": 524288,
"model": "MiniMax-M3",
"ts": 1234567890
}Re-fetch quota + per-turn context. The webui calls this when the user clicks the "刷新" button in the usage popover.
Response 200 {ok: true}
These endpoints wrap the acp protocol methods that the webui can
call. Methods that mcode 0.1.5 doesn't implement return 501 with
{code: 'unsupported'}.
Calls session/set_mode. Currently returns 501 (mcode 0.1.5).
Calls session/set_config_option. Currently returns 501.
Calls session/cancel. Currently returns 501 (falls back to
SIGTERM on the subprocess).
Calls session/load. Works in 0.1.5.
Request {sessionId: "mvs_…", cwd: "C:\\…"}
Calls session/activate. Currently returns 501.
Calls session/list. Works in 0.1.5.
Returns the list of acp methods the webui knows about and their support status. Used by the webui to decide which UI controls to enable.
Response 200
{
"ok": true,
"agentInfo": { "name": "mcode", "title": "mcode", "version": "0.1.5" },
"supported": ["session/new", "session/list", "session/load", "session/prompt", "session/close"],
"unsupported": ["session/set_mode", "session/set_config_option", "session/cancel", …]
}Inject a fake event into the SSE channel for a CID. Used for testing the UI without a real mcode subprocess.
Request
{ "cid": "uuid", "type": "delta", "text": "hello" }Response 200 {ok: true}
Gating: this endpoint only works if DEBUG_INJECT=1 is set in the
server's environment. The server logs a warning every time it's
called. Production deployments should leave the env unset.
Returns the full per-cid state including internal flags. Same
DEBUG_INJECT gating.
Returns public/index.html.
Returns the file from public/ if it exists. Served by serveStatic.
Cache headers: public, max-age=3600. The HTML/JS/CSS paths
embed a ?v=N cache-bust query string; bump it in index.html when
you want clients to refetch.
All errors follow one of these shapes:
{ "ok": false, "error": "human-readable message" }{ "ok": false, "code": "unsupported", "error": "mcode 0.1.5 acp does not implement session/set_mode" }{ "ok": false, "error": "LAN 访问已关闭。在本机打开设置开启。" }The HTTP status is appropriate to the cause (400 / 401 / 403 / 404 / 409 / 500 / 501).