kimi-code/docs/zh/reference/server-api.md
liruifengv 2bf7ed22d7
feat(auth): split model readiness from sign-in state in /api/v1/auth (#3293)
* feat(auth): split model readiness from sign-in state in /api/v1/auth

GET /api/v1/auth now reports models_ready (the default model resolves
against the configured catalog, providerless and env-injected models
included) instead of the compound ready flag, and no longer carries
default_model — config values are served by /config alone. The v1
summary schema follows.

OAuth managed-model refreshes now heal a lost default model: the
refresh snapshot includes defaultModel, so an unchanged catalog with
a missing default still lands the write-back branch and re-selects
one. The refresh also rebases onto a fresh config read after the
remote fetch, so a model or thinking change made during the fetch is
no longer overwritten. The shared discovery refresh path (scheduler,
POST /providers/{id}:refresh) heals the default the same way.

Config changes are now published to WS clients on every write path:
a debounced+trailing publisher bridges IConfigService section changes
to ConfigChanged with camelCase changedFields and a full config
projection, and the broadcaster forwards event.config.changed and
event.model_catalog.changed (both previously published but never
delivered). All three event types are registered in the event unions,
so session_event parsing and AsyncAPI describe them.

BREAKING CHANGE: GET /api/v1/auth drops the ready and default_model
fields in favor of models_ready; event.config.changed's changedFields
is now camelCase domain names instead of the raw snake_case request
keys (v1 summary schema follows).

* fix(kap-server): expose the session model in session list projections

GET /api/v1/sessions hardcoded agent_config.model to '' and the v2
projection had no model field at all, so clients could only learn a
session's model via the post-select /status read — which races the WS
replay and often never lands. SessionFacts now carries the live
session's model (same source as the snapshot route), toWireSession
emits it, and the v2 activity domain gains a nullable model field.

* fix(kap-server): gate prompt submission on the effective session model

The submit gate called ensureReady() with no override, so it only ever
validated config.default_model: a session with a bound model (or a
prompt carrying one) was rejected with 40113 whenever default_model was
missing or dangling. Pass the effective model (request model, then the
agent profile's bound model, falling back to default_model inside
ensureReady) on both the prompt submit and btw routes.

* fix(agent-core-v2): honor defaultProvider in model readiness resolution

resolveModelForReady stopped at the flat baseUrl fallback, so a model
that omits provider/providerId and relies on the configured
defaultProvider resolved at runtime (ModelCatalog.resolveProviderContext
falls back to it) while /api/v1/auth reported models_ready:false and the
send gate rejected the prompt. Mirror the runtime order (providerId ->
provider -> defaultProvider -> flat baseUrl) and pass the configured
default provider from both readiness callers.

* fix(kap-server): redact inline model credentials from config responses

toConfigResponse only redacted the providers section, so a model's
inline apiKey/oauth rode GET /config verbatim and, via the new
event.config.changed publisher, every WS connection plus the persistent
event journal. Project the models section the same way: strip
credential fields and report has_api_key.

* fix(agent-core-v2): honor defaultProvider in ensureReady credential checks

The readiness phase learned the defaultProvider fallback, but the
credential phase right after still derived the provider only from the
model's explicit fields: a model omitting provider/providerId passed
readiness yet missed the default provider's apiKey/OAuth material and
prompts failed with auth.token_missing. Mirror the same provider chain
(providerId -> provider -> defaultProvider) when resolving credentials.

* fix(kap-server): validate the model a profile bind will select at the prompt gate

The gate validated the session's current model even for a prompt that
switches profile without a model — but bind falls back to defaultModel
in that case, so a stale session model drew a misleading 40113 before
bind could run. Gate on bind's selection order instead: the request's
explicit model, then the default on a profile switch, then the session's
bound model.

* fix(kap-server): redact inline service credentials from config responses

The earlier redaction covered providers and models, but toConfigResponse
still passed the services section through verbatim: inline or
env-injected apiKey, oauth references, and credential-bearing
customHeaders rode GET /config and, via the event.config.changed
publisher, every WS connection plus the persistent event journal.
Project services the same way: strip apiKey/oauth into has_api_key and
report only the header names as custom_header_keys (the MCP
envKeys/headerKeys convention).

* fix(kap-server): keep unlisted config domains through event validation

The config.changed broadcaster returned the zod-parsed config, which
strips domains absent from configResponseSchema (mcp, identity,
model_catalog, image, tools, token_counting): changedFields named them
while the advertised full snapshot no longer matched GET /api/v1/config.
Make the response projection passthrough (defineRoute validates only
requests, so REST responses are unaffected).

* fix(agent-core-v2): use the exact configured key for model readiness lookups

resolveModelForReady trimmed the model id before the models-table lookup
while ModelCatalog and ensureReady use the configured string as an exact
record key: a whitespace-padded default_model was reported ready and then
crashed the submit gate with an internal error instead of 40113, and a
legitimate key containing spaces was reported dangling. Trim only rejects
blank values now; the lookup always uses the raw key.

* fix(protocol): keep unlisted config domains in the shared event projection

The shared configResponseSchema stripped domains it does not enumerate
(mcp, identity, model_catalog, image, tools, token_counting, subagent,
secondary_model), so event.config.changed parsed through agentEventSchema
named them in changedFields while omitting their values. Make the shared
projection passthrough like the kap-server-local one.

* fix(agent-core-v2): use the exact default_provider key in readiness checks

The defaultProvider fallback trimmed the configured value before the
providers-table lookup while ProviderService and ModelCatalog use the
configured string verbatim: a whitespace-padded default_provider could
build successfully yet report not-ready (40113), or report ready for a
provider runtime resolution cannot find. Trim only rejects blank values;
the lookup uses the raw key.

* chore: sync web dist from code-app

Rebuild the bundled web UI against this branch's /auth contract (models_ready, no ready/default_model): the previous bundle still read the old fields and stayed in the not-ready flow against this server.

code-app: 000d2594ff3e95b553be326126bab3f939b62944

* Revert "chore: sync web dist from code-app"

This reverts commit 9400a24a03863b3e8b780dda251540f824f02f3a.

* fix(oauth): rebase the default selection after the refresh fetch

A provider refresh snapshots the config before the remote catalog fetch;
when the user selects a default model while the fetch is in flight, the
stale snapshot's empty default made an otherwise unchanged catalog enter
the write path and the self-heal persisted the generated default over the
user's newer selection. Each branch now re-reads and rebases the
default/thinking selection after its fetch, before cloning, comparing,
or writing.

* style(kap-server): pass optional custom_header_keys without conditional spread
2026-08-28 15:53:56 +08:00

136 KiB
Raw Blame History

服务 API

kimi web 启动的本地服务暴露两组程序化接口REST API/api/v1,另有 /api/v2/sessions/api/v2/mcp)和 WebSocket 事件流(/api/v1/ws)。本页是这两组接口的协议参考。如何启动服务及其命令行选项见 kimi 命令 参考;端到端的上手流程见下文「用 API 驱动一个会话」。

本页是一份经过整理、面向人阅读的参考:下文逐一记录每个端点的参数、请求体与响应结构。每个端点精确的机器可读 schema 以服务的在线规范文档为准:GET /openapi.jsonOpenAPIGET /asyncapi.jsonAsyncAPI两者都由服务运行时实际执行的校验 schema 生成。两者都需要鉴权;当本页与在线规范不一致时,以在线规范为准。

::: warning 注意 本页描述的 REST 与 WebSocket API 为实验性特性:不保证接口稳定性,端点、字段与事件类型可能随任何版本更改。集成时请以你所用版本服务的 /openapi.json/asyncapi.json 文档为准。 :::

基础约定

地址

默认地址为 http://127.0.0.1:58627。端口被占用时,服务会用下一个端口重试(至多 100 次);可用 --port / --host 修改绑定。同一 home 目录下可并存多个实例,运行中的实例登记在 ~/.kimi-code/server/instances/

鉴权

除以下例外,所有 /api/* 路径(含 /openapi.json/asyncapi.json)都要求 bearer token

  • OPTIONS 预检请求
  • GET /api/v1/healthz(探活)
  • 静态 web 资源(非 /api/ 路径)

携带方式REST 用 Authorization: Bearer <token> 请求头WebSocket 升级请求接受同一请求头,或子协议 kimi-code.bearer.<token>。token 的生成与轮换见 在网页中使用:开始使用

鉴权失败返回 HTTP 401信封 code40101。在非 loopback 绑定上,同一来源 60 秒内鉴权失败 10 次会被封禁 60 秒,期间每个请求都返回 HTTP 429code42901)。

响应信封

所有 JSON 响应统一包在信封里:

{
  "code": 0,
  "msg": "success",
  "data": {},
  "request_id": "01JZX4A6E7M8V0R3Q0N2K2M5Q9"
}
  • code:业务结果,0 表示成功;错误码分段见下文。
  • data:成功时的业务数据。注意部分「错误」信封也携带非空 data——例如重复解决审批返回 40902data.resolvedfalse——客户端应先判 code 再看 data
  • request_id:本次请求的 ULID客户端可用 X-Request-Id 请求头指定,非法值会被服务端重新生成。

HTTP 状态码几乎总是 200业务结果以 code 为准。例外情况:

场景 HTTP 状态
鉴权失败 / 触发限流 401 / 429
创建供应商、导入供应商目录成功 201
删除供应商成功 204
二进制与流式端点 支持时返回 206Range 分段)/ 304ETag 未变),各端点能力不同,详见「二进制与流式端点
GET /api/v1/files/{file_id} 下载错误 真实 404 / 500响应体仍为信封

其中 201 的响应体仍是标准信封(code0),只是状态行遵循 REST 的资源创建惯例204 按定义没有响应体,删除成功以状态码本身为准。

错误码

错误码按段位分组:

段位 含义 示例
0 成功
400xx 请求参数错误 40001 校验失败(details 逐字段说明)、40003 供应商由 OAuth 托管
401xx 鉴权与就绪状态 40101 未授权、40110 未配置供应商、40113 模型未解析
404xx 资源不存在 40401 会话、40408 MCP 服务、40409 文件路径
409xx 状态冲突 40901 会话忙、40902 审批已解决、40922 分页条件与 page_token 不符
410xx 资源已过期 41001 审批超时、41002 提问超时、41003 临时文件过期
413xx 体积或边界超限 41302 读取文件超 10 MB、41304 路径越出会话目录
429xx 限流 42901 鉴权失败封禁、42902 文件监听数超限
500xx 服务端内部错误 50001 未捕获异常、50003 持久化失败
6xxxx / 7xxxx / 8xxxx 工具运行时 / LLM 供应商 / MCP 透传错误,msg 保留上游原文

分页

列表端点有两种分页风格:

  • 游标式before_id / after_id(互斥)加 page_size1100响应为 { items, has_more }。用于会话列表、消息列表、转录等。
  • page_token:不透明令牌(绑定了查询条件的指纹),用于 POST /api/v1/searchGET /api/v2/sessions。翻页途中改变任何查询条件会使令牌失效v2 返回 40922search 返回 40001GET /api/v2/sessions 另提供无状态的 page 页码模式作为替代。

用 API 驱动一个会话

下面用 curl 走一遍最小流程:确认服务状态 → 创建会话 → 订阅事件 → 提交提示词 → 回读历史。示例假设服务跑在默认地址token 已存入 shell 变量 TOKEN

  1. 确认服务状态:
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:58627/api/v1/meta

所有 JSON 响应都包在统一信封里——{ "code": 0, "msg": "success", "data": ..., "request_id": "..." },业务结果以 code 为准(0 表示成功HTTP 状态码只表达传输层结果。

  1. 创建会话,metadata.cwd 指定工作目录:
curl -s -X POST http://127.0.0.1:58627/api/v1/sessions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"metadata": {"cwd": "/path/to/project"}}'

返回的 data.id(形如 session_...)就是后续所有请求要用的会话 id。

  1. 连接 WebSocket 并订阅会话事件。任何 WebSocket 客户端都可以;下面是一个零依赖的 Node.js 脚本Node.js 22+ 内置 WebSocket 客户端):
// subscribe.mjs —— 用法TOKEN=... node subscribe.mjs session_...
const ws = new WebSocket('ws://127.0.0.1:58627/api/v1/ws', [
  `kimi-code.bearer.${process.env.TOKEN}`,
]);
ws.onmessage = (e) => console.log(e.data);
ws.onopen = () =>
  ws.send(
    JSON.stringify({
      type: 'subscribe',
      id: '1',
      payload: { session_ids: [process.argv[2]] },
    }),
  );
  1. 提交提示词:
curl -s -X POST http://127.0.0.1:58627/api/v1/sessions/<session_id>/prompts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": [{"type": "text", "text": "用一句话介绍这个仓库"}]}'

订阅端会依次看到 turn.started(轮次开始)→ assistant.delta(流式文本增量)→ 发生工具调用时的 tool.call.started / tool.resultturn.ended(轮次结束)。

  1. 随时可以用 REST 回读历史消息:
curl -s -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:58627/api/v1/sessions/<session_id>/messages?page_size=20"

REST 端点

下文按资源分组列出端点。路径里的 :{action} 后缀是动作约定——对单个资源 POST 到 路径:动作 执行非 CRUD 操作(如会话的 :fork:archive)。

服务与元信息

方法与路径 说明
GET /api/v1/healthz 探活,免鉴权
GET /api/v1/meta 服务版本、能力集、server_id、实验开关
POST /api/v1/shutdown 优雅退出(先回 200 再关闭);仅 loopback 绑定时挂载

GET /api/v1/healthz

供脚本与进程管理器使用的探活端点。它是唯一豁免 bearer token 的 /api 端点(见 鉴权),应答时不触碰配置与引擎。

成功时 data{ "ok": true }

GET /api/v1/meta

返回本实例的身份信息与能力集。大多数字段在启动时即固定;experimental_flagsfeatures 按请求实时解析,因此开关翻转或某个 feature 失败会体现在下一次响应中。

成功时 data 携带:

字段 类型 说明
server_version string 服务版本
capabilities object 能力集——websocketfile_uploadfs_querymcptasksterminal,均恒为 true
server_id string 本服务实例的唯一 id
started_at string 启动时间ISO 8601 格式
open_in_apps array 可作为 open-in 目标的宿主应用(finder / cursor / vscode / iterm / terminal);目前恒为空
dangerous_bypass_auth boolean 服务是否以 --dangerous-bypass-auth 启动(客户端可跳过 token 提示)
backend string 引擎后端,v1v2;本服务恒为 v2
web_title string 来自 --web-title 的自定义浏览器标签页标题;未设置时省略
experimental_flags object 实验开关 id → 是否启用,按请求时解析
features array 引擎 feature形如 { name, state, meta }statePending / Activating / Active / Unloading / Failed

POST /api/v1/shutdown

请求服务优雅退出。响应先发出,随后立即执行关闭,因此调用方可以信任收到的响应。该路由仅在 loopback 绑定时挂载——非 loopback 绑定时它根本不会被注册(请求得到 404除非服务以 --allow-remote-shutdown 启动。

成功时 data{ "ok": true }

登录与用量

这组端点驱动托管 Kimi OAuth 登录的生命周期,并暴露账号级信息。托管供应商名为 managed:kimi-code;下面每个端点上可选的 provider 参数都默认取它。

方法与路径 说明
GET /api/v1/auth 鉴权状态快照
POST /api/v1/oauth/login 发起 OAuth device-code 登录流程
GET /api/v1/oauth/login 轮询登录流程状态
DELETE /api/v1/oauth/login 取消进行中的登录流程
POST /api/v1/oauth/logout 登出托管供应商
GET /api/v1/oauth/usage 套餐用量与限额
GET /api/v1/oauth/userinfo 账号资料
GET /api/v1/oauth/region 解析客户端所属区域(mainland-cn / global

GET /api/v1/auth

鉴权状态快照:默认模型能否解析到可用的供应商配置,以及托管供应商的登录状态。当全局 default_model 别名存在于模型表中且能解析到已配置的供应商时,models_readytrue——包括自带 base_url 的平铺providerless模型以及通过 KIMI_MODEL_* 环境变量注入的模型。它不做凭据校验,因此此后的对话请求仍可能以 40111 / 40112 失败。

成功时 data 携带 models_ready(布尔值)、providers_count(已配置供应商数量)与 managed_providernull,或 { name, status },其中 statusauthenticated / expired / revoked / unauthenticated 之一)。全局默认模型别名本身改从 GET /api/v1/configdefault_model 读取,本端点不再携带。

POST /api/v1/oauth/login

为托管供应商发起 OAuth device-code 登录流程;发起新流程会中止同一供应商进行中的流程。账号已登录时无需用户交互,响应会立即报告 authenticated

参数 位置 类型 说明
provider body string 托管供应商名称。默认 managed:kimi-code
region body string mainland-cnglobal;覆盖 GET /api/v1/oauth/region 一节描述的区域解析结果,仅对本次流程生效

成功时 data 有两种形态。进行中的流程——{ flow_id, provider, status: "pending", verification_uri, verification_uri_complete, user_code, expires_in, interval, expires_at }:打开 verification_uri_complete(或打开 verification_uri 并输入 user_code),然后每隔 interval 秒轮询 GET /api/v1/oauth/login,直到流程完结或超过 expires_atexpires_in 是以秒表示的同一时限)。已登录的快速路径——{ flow_id, provider, status: "authenticated" }

GET /api/v1/oauth/login

轮询某供应商的登录流程状态。尚未发起过流程时返回 null

参数 位置 类型 说明
provider query string 托管供应商名称。默认 managed:kimi-code

成功时 datanull 或流程快照:{ flow_id, provider, status, verification_uri, verification_uri_complete, user_code, expires_in, expires_at, interval },其中 statuspending / authenticated / denied / expired / cancelled。流程离开 pending 后,resolved_at 记录其到达终态的时间,error_message 描述失败的流程。

DELETE /api/v1/oauth/login

取消某供应商进行中的登录流程。没有进行中的流程时,该调用为空操作,返回最近一次已知状态。

参数 位置 类型 说明
provider query string 托管供应商名称。默认 managed:kimi-code

成功时 data{ cancelled, status }:只有确实中止了一个 pending 流程时 cancelled 才为 truestatus 为调用后的流程状态。

POST /api/v1/oauth/logout

登出托管供应商:丢弃已存储的 OAuth 凭据、中止进行中的登录流程并把托管供应商从配置中移除。OAuth 托管的供应商拒绝手动编辑与删除(见下文 PUT / DELETE /api/v1/providers/{provider_id}),因此要移除它需先登出。

参数 位置 类型 说明
provider body string 托管供应商名称。默认 managed:kimi-code

成功时 data{ logged_out: true, provider }

GET /api/v1/oauth/usage

托管账号的套餐用量与限额,实时取自账号服务。上游失败不会让信封失败——它以 kind: "error" 的形式带内返回。

参数 位置 类型 说明
provider query string 托管供应商名称。默认 managed:kimi-code

成功时 data{ kind: "ok", summary, limits, extra_usage }{ kind: "error", message, status? },其中 status 为上游 HTTP 状态码(如存在)。在 ok 形态中,summary(可空)是主配额行,limits 列出每个配额窗口;一行的结构为 { name?, window?, used, limit, reset_at? },其中 window{ duration, unit }unitminute / hour / day / week 之一。extra_usage(可空)是按量付费钱包:{ balance_cents, total_cents, monthly_charge_limit_enabled, monthly_charge_limit_cents, monthly_used_cents, currency }

GET /api/v1/oauth/userinfo

托管账号的资料,带内 kind: "error" 约定与 GET /api/v1/oauth/usage 相同。

参数 位置 类型 说明
provider query string 托管供应商名称。默认 managed:kimi-code

成功时 data{ kind: "ok", userInfo }{ kind: "error", message, status? }userInfo 始终携带 userIdnicknamestatusregionuserLeveluserLevelNamedomaindomainName,并可能附加 globalIdbioavatarusernameemailphone{ countryCode, number })、createdTimelastLoginTime

GET /api/v1/oauth/region

解析该客户端所属的 Kimi 区域。结果在本地推导,不经网络探测:优先取环境变量或配置固定的 OAuth host其次是已配置的 OAuth key再次是 home 目录中的区域标记文件;默认为 mainland-cn

成功时 data{ region }regionmainland-cn / global 之一。

配置

方法与路径 说明
GET /api/v1/config 读取全局配置(密钥字段脱敏)
POST /api/v1/config 合并式更新配置,并广播 event.config.changed

GET /api/v1/config

返回解析后的全局配置——config.toml 叠加覆盖层后的生效结果。密钥已脱敏:每个供应商只报告 has_api_key,绝不返回存储的密钥。

成功时 data 为配置对象;其字段与 顶层字段 记录的顶层域一一对应:

字段 类型 说明
providers object 供应商 id → { type, base_url?, default_model?, has_api_key } 的映射
default_provider string 全局默认供应商 id
default_model string 全局默认模型别名
models object 模型别名 → 模型记录的映射
thinking object Thinking 模式的默认参数
plan_mode boolean Plan 模式开关
yolo boolean 派生值:default_permission_modeyolo 时为 true
default_permission_mode string 新会话的默认权限模式
default_plan_mode boolean 新会话是否以 Plan 模式启动
permission object 初始权限规则
hooks array 生命周期钩子
services object 内置外部服务配置
merge_all_available_skills boolean 是否合并所有可用目录中的 Agent Skills
extra_skill_dirs array 额外的 Skill 搜索目录
loop_control object Agent 循环控制参数
background object 后台任务运行参数
subagent object subagent 配置
secondary_model object subagent 的次级模型池
experimental object 实验开关 id → 是否启用
telemetry boolean 是否启用匿名遥测
raw object 原始解析的 config.toml 内容,包含未建模字段

POST /api/v1/config

合并式更新全局配置:请求体中的每个顶层域被深合并进对应域,未出现在请求体中的域保持不动。把 yolo 设为 truedefault_permission_mode: "yolo" 的简写;被拒绝的补丁(值非法或持久化失败)返回 40001 与底层错误信息。

每一次配置变更——经本端点成功更新、在进程外编辑 config.toml,或服务端内部写入(如 OAuth 登录刷新)——都会广播全局 event.config.changed 事件。短时间窗内的多次变更会合并为一个事件,其 changedFields 携带受影响的域名camelCase 配置域,例如 defaultModelconfig 携带当前完整的配置投影(与 GET /api/v1/config 响应同形状)。

请求体是部分配置对象——上述响应域中除 raw 外的任意子集,均为可选:

参数 位置 类型 说明
providers body object 供应商 id → 供应商表的映射
default_provider body string 全局默认供应商 id
default_model body string 全局默认模型别名
models body object 模型别名 → 模型记录的映射
thinking body object Thinking 模式的默认参数
plan_mode body boolean Plan 模式开关
yolo body boolean true 映射为 default_permission_mode: "yolo"false 被忽略
default_permission_mode body string manual / yolo / auto
default_plan_mode body boolean 新会话是否以 Plan 模式启动
permission body object 初始权限规则
hooks body array 生命周期钩子
services body object 内置外部服务配置
merge_all_available_skills body boolean 是否合并所有可用目录中的 Agent Skills
extra_skill_dirs body array 额外的 Skill 搜索目录
loop_control body object Agent 循环控制参数
background body object 后台任务运行参数
subagent body object subagent 配置
secondary_model body object subagent 的次级模型池
experimental body object 实验开关 id → 是否启用
telemetry body boolean 是否启用匿名遥测

成功时 data 为完整的更新后配置,形态与 GET /api/v1/config 相同。

模型与供应商

这组端点管理模型配置的两半——config.toml供应商 表与模型别名表——外加一个由服务端代理的 models.dev 目录,用于一次性导入。模型别名 id 就是配置中的别名键:通过供应商管理端点创建的别名形如 provider_id/model(例如 my-provider/kimi-for-coding),而模型别名表中的裸键(如 turbo原样使用API 中任何接收 model_id 的地方(包括全局 default_model)指的都是这个别名 id。:{action} 路由上不支持的动作返回 40001

方法与路径 说明
GET /api/v1/models 列出已配置的模型别名
POST /api/v1/models/{model_id}:set_default 设置全局默认模型
GET /api/v1/providers 列出供应商
POST /api/v1/providers 创建供应商201
GET /api/v1/providers/{provider_id} 读取供应商(含已存密钥)
PUT /api/v1/providers/{provider_id} 整体替换供应商配置
DELETE /api/v1/providers/{provider_id} 删除供应商204
POST /api/v1/providers/{provider_id}:refresh 刷新该供应商的模型元数据
POST /api/v1/providers:{action} 集合级动作:refresh / refresh_oauth / import_catalog / import_registry
GET /api/v1/catalog/providers 浏览 models.dev 目录(服务端代理)
GET /api/v1/catalog/providers/{catalog_id} 读取目录中单个条目

GET /api/v1/models

列出所有供应商下已配置的模型别名。

成功时 data.items{ provider, model, display_name?, max_context_size, capabilities?, support_efforts?, default_effort? } 数组:model 是别名 id供应商管理的别名为 provider_id/model,否则为裸键),provider 是所属供应商 idmax_context_size 是以 token 计的上下文窗口,capabilities / support_efforts / default_effort 描述能力标志与 Thinking 模式的 effort 支持。

POST /api/v1/models/{model_id}:set_default

把全局 default_model 设为一个已存在的别名。model_id 是配置中的别名键原样——裸键如 POST /api/v1/models/turbo:set_default;当 id 含 / 时需做 URL 编码,如 POST /api/v1/models/my-provider%2Fkimi-for-coding:set_default

参数 位置 类型 说明
model_id path string 必填。 配置中的模型别名键原样;含 / 时需 URL 编码

成功时 data{ default_model, model }——当前生效的别名及其目录项(形态与 GET /api/v1/models 的单项相同)。

  • 40001:路径中的动作后缀非法或不支持
  • 40413:不存在该 id 的模型别名

GET /api/v1/providers

列出每个已配置供应商及其凭据与模型发现状态,不泄露任何密钥。这也是其他供应商端点引用的供应商条目形态。

成功时 data.items 为如下结构的数组:

字段 类型 说明
id string 供应商 id
type string 通信协议:kimi / openai / openai_responses / anthropic / google-genai / vertexai
base_url string API 基础 URL如已设置
default_model string 该供应商的默认模型别名,如已设置
has_api_key boolean 是否已存储凭据
status string 存在 API 密钥或缓存的 OAuth token 时为 connected,否则为 unconfigurederror 在 schema 中保留)
models array 该供应商的模型别名 id

POST /api/v1/providers

一次保存创建供应商及其模型别名;响应为 HTTP 201 加标准信封。当全局 default_model 完全未配置时(全新安装),会以新供应商的 default_model(或第一个模型)播种;已有默认值绝不被修改。

参数 位置 类型 说明
id body string 必填。 供应商 id——字母、数字、-_ 与空格;必须以字母或数字开头
type body string 必填。 通信协议:kimi / openai / openai_responses / anthropic / google-genai / vertexai
api_key body string API 密钥,存储于 config.toml
base_url body string API 基础 URL不得包含环境变量占位符${...}
default_model body string 该供应商的默认模型;必须是 models[].model 之一
models body array 必填。 至少一条,不允许重复的 model 值;条目结构见下文

每个 models[] 条目声明一个别名,其 id 为 id/model

字段 类型 说明
model string 必填。 上游模型名
max_context_size integer 必填。 以 token 计的上下文窗口,≥ 1
display_name string 显示名
capabilities array 能力标志,如 thinkingimage_in
max_output_size integer 最大输出 token 数,≥ 1
support_efforts array 支持的 Thinking 模式 effort 档位
adaptive_thinking boolean 自适应 thinking 开关

成功时 data 为创建好的供应商条目(形态与 GET /api/v1/providers 的单项相同)。

  • 40921:已存在该 id 的供应商

GET /api/v1/providers/{provider_id}

读取单个供应商。与列表路由不同,设置了密钥时响应会暴露存储的 api_key,以便本地编辑表单预填——暴露端口时请牢记这一点。

参数 位置 类型 说明
provider_id path string 必填。 供应商 id

成功时 data 为供应商条目,存有密钥时附带 api_key

  • 40412:供应商不存在

PUT /api/v1/providers/{provider_id}

一次保存整体替换供应商:typebase_url 与模型列表被重写,该供应商的别名按 models 重建——不再列出的别名从 config.toml 中消失,其他供应商的别名不受影响。api_key 是三态的:省略表示保留已存密钥,"" 表示清除,其他值表示替换。除 new_id 重命名迁移外,全局默认指针绝不被修改。

参数 位置 类型 说明
provider_id path string 必填。 当前供应商 id
new_id body string 重命名供应商providers 键、模型别名、default_provider、指向旧别名的 default_model 以及 subagent 次级模型池都会随之迁移。id 规则与 POST /api/v1/providers 相同
type body string 必填。 通信协议:kimi / openai / openai_responses / anthropic / google-genai / vertexai
api_key body string 三态,见上文
base_url body string API 基础 URL不得包含环境变量占位符${...}
default_model body string 该供应商的默认模型;必须是 models[].model 之一
models body array 必填。 至少一条,不允许重复的 model 值;条目结构与 POST /api/v1/providers 相同

成功时 data{ provider },即保存后的供应商条目。

  • 40001:重命名后的别名 id 会与其他供应商的别名冲突
  • 40003:供应商由 OAuth 托管——请改用 POST /api/v1/oauth/logout 登出
  • 40412:供应商不存在
  • 40921new_id 已被占用

DELETE /api/v1/providers/{provider_id}

删除供应商及其全部模型别名subagent 次级模型池会级联清理。全局 default_provider / default_model 指针保持不动,即使它们指向被删的供应商——那是用户的设置,不由本端点代为回收。

参数 位置 类型 说明
provider_id path string 必填。 供应商 id

成功时服务应答 204 且无响应体——状态行本身即表示删除成功(见 响应信封)。

  • 40003:供应商由 OAuth 托管——请改用 POST /api/v1/oauth/logout 登出
  • 40412:供应商不存在

POST /api/v1/providers/{provider_id}:refresh

从上游来源重新发现单个供应商的模型元数据,并重写该供应商的别名。模型来源为静态的供应商不经任何网络调用直接报告 unchanged。至少一个供应商的别名发生变化时,服务会广播全局 event.model_catalog.changed 事件。

参数 位置 类型 说明
provider_id path string 必填。 供应商 id

成功时 data 为刷新报告:changed{ provider_id, provider_name, added, removed }(新增 / 移除的别名数)的数组,unchanged 是无差异的供应商 id 数组,failed{ provider, reason } 的数组。

  • 40001:路径中的动作后缀非法或不支持
  • 40412:供应商不存在

POST /api/v1/providers:refresh

刷新每个供应商的模型元数据。请求体可选且被忽略。

成功时 data 为与 POST /api/v1/providers/{provider_id}:refresh 相同的刷新报告(changed / unchanged / failed)。

POST /api/v1/providers:refresh_oauth

POST /api/v1/providers:refresh 相同的刷新,仅限 OAuth 凭据的供应商。请求体可选且被忽略。

成功时 data 为刷新报告(changed / unchanged / failed)。

POST /api/v1/providers:import_catalog

把一个 models.dev 目录条目导入为已配置供应商;响应为 HTTP 201 加标准信封。通信协议与端点来自目录解析,目录中的每个模型都写为一个别名。导入已存在的 id 等同于刷新——供应商条目及其别名按目录重写,省略 api_key 表示保留已存密钥。全局默认指针绝不被修改,仅在完全未配置默认模型时,以第一个导入的模型播种 default_model

参数 位置 类型 说明
catalog_id body string 必填。 来自 GET /api/v1/catalog/providers 的目录条目 id
id body string 覆盖目录 id 作为本地供应商 id。id 规则与 POST /api/v1/providers 相同
api_key body string 导入供应商的 API 密钥
base_url body string 覆盖目录解析出的端点;条目的 needs_base_urltrue 时必填

成功时 data{ provider, models_imported }——供应商条目与写入的别名数量。

  • 40001:缺少 catalog_id 或其他请求体校验失败
  • 40003:目标供应商已存在且由 OAuth 托管
  • 40004:条目无法导入(被拒绝、要求 base_url、没有可导入的模型,或其 id 不能用作供应商 id
  • 40417:不存在该 catalog_id 的目录条目
  • 50004models.dev 目录不可用

POST /api/v1/providers:import_registry

把一个 models.dev 形态的私有注册表——一个 api.json URL 加可选的 Bearer key——导入为已配置供应商响应为 HTTP 201 加标准信封。每个列出的供应商都带 source 记录写入,以便定时刷新重新发现。重复导入同一 URL 会移除上游已消失的供应商——URL 是注册表的稳定身份,因此轮换 key 是安全的。全局默认指针遵循与 :import_catalog 相同的规则。

参数 位置 类型 说明
url body string 必填。 注册表 api.json 的 URL
api_key body string 注册表的 Bearer key省略时复用上一次导入同一 URL 所用的 key

成功时 data{ providers, models_imported }——供应商条目数组与写入的别名总数。

  • 40001:缺少 url 或其他请求体校验失败
  • 40003:某个列出的供应商已存在且由 OAuth 托管
  • 40005:注册表无法获取或解析,或未列出可导入的供应商

GET /api/v1/catalog/providers

浏览 models.dev 目录,由服务端代理,带 10 分钟内存缓存与内置快照兜底。条目保持上游目录顺序。服务无法导入的条目携带 rejected: true 与机器可读的 reject_reasonneeds_base_url: true 的条目在导入时要求提供 base URL。

成功时 data.items{ id, name, wire_type, guessed, needs_base_url, rejected, reject_reason, env_key, models } 数组:wire_type 是解析出的协议(可空,枚举与供应商 type 相同),guessed 标记启发式解析,env_key 是上游约定的 API 密钥环境变量(可空),models{ id, name?, max_context_size, capabilities?, reasoning } 的数组。

  • 50004:目录不可用(在线拉取与内置快照均失败)

GET /api/v1/catalog/providers/{catalog_id}

按 catalog id 读取单个 models.dev 目录条目——条目形态与 GET /api/v1/catalog/providers 相同。

参数 位置 类型 说明
catalog_id path string 必填。 目录条目 id

成功时 data 为该目录条目(形态与 GET /api/v1/catalog/providers 的单项相同)。

  • 40417:不存在该 catalog_id 的目录条目
  • 50004:目录不可用

会话

这些端点用于创建、列出和查看会话执行会话级动作fork、compact、undo 等),并读取会话级汇总。其中大多数返回的会话采用 session 对象 中统一说明的线上格式;非 CRUD 操作使用上文介绍的 :{action} 约定。

方法与路径 说明
POST /api/v1/sessions 创建会话(需 workspace_idmetadata.cwd
GET /api/v1/sessions 列出会话,游标分页,支持 busy / archived_only 等过滤
GET /api/v1/sessions/{session_id} 读取单个会话
GET /api/v1/sessions/{session_id}/profile 读取会话档案
POST /api/v1/sessions/{session_id}/profile 更新标题、元数据、Agent 配置
POST /api/v1/sessions/{session_id}/title/generate 通过托管的 chat_title 工具生成标题
POST /api/v1/sessions/{session_id}:{action} 会话动作:fork / compact / undo / abort / btw / archive / restore
GET /api/v1/sessions/{session_id}/children 列出子会话
POST /api/v1/sessions/{session_id}/children 创建子会话fork 并打标)
GET /api/v1/sessions/{session_id}/status 实时状态汇总
GET /api/v1/sessions/{session_id}/goal 当前目标快照(无则 null
GET /api/v1/sessions/{session_id}/warnings 会话级告警
GET /api/v1/sessions/{session_id}/runtime 读取 main agent 的运行时绑定
POST /api/v1/sessions/{session_id}/runtime 切换 main agent 的运行时绑定
POST /api/v1/sessions/{session_id}/export 导出会话与诊断信息zip 流,不走信封)
GET /api/v1/sessions/{session_id}/snapshot 客户端重建用全量快照(含 as_of_seqepoch
GET /api/v1/sessions/{session_id}/media/{file_id} 按文件 id 下载提示词媒体(二进制)

session 对象

每个返回会话的端点都使用这种线上格式。实时状态字段(busymain_turn_activepending_interactionlast_turn_reason)由会话的活动聚合解析得出:未加载到本服务进程中的会话(冷会话)始终上报为不忙碌且无待处理交互。少数字段在当前投影中是占位值——已逐字段注明。

字段 类型 说明
id string 会话 idsession_...
workspace_id string 所属工作区 id
title string 会话标题;无标题时为 ""
created_at / updated_at string 创建时间与最后更新时间ISO 8601
archived boolean 会话是否已归档(归档后从默认会话列表中隐藏)
archived_at string 归档时间ISO 8601仅在已归档时存在
busy boolean 是否有任一 Agent 存在进行中的轮次或后台任务
main_turn_active boolean main agent 是否有进行中的轮次
pending_interaction string none / approval / question——有未答复的交互在等待
last_turn_reason string main agent 最近一次轮次的结果:completed / cancelled / failed
last_prompt string 最近一条用户提示词文本(如有)
metadata object 自定义元数据;始终携带 cwd(会话的工作目录)
agent_config object 投影为 { model }model 在大多数响应中为 "",仅由 GET /api/v1/sessions/{session_id}/snapshot 填入实时模型
usage object token 汇总 { input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, context_tokens, context_limit?, total_cost_usd?, turn_count? };在 snapshot 端点之外全为零
permission_rules array 会话权限规则;当前始终为 []
message_count integer 消息数;当前始终为 0
last_seq integer 最后的事件序列号;当前始终为 0

POST /api/v1/sessions

创建会话并返回。目标目录来自 workspace_id(已注册的工作区)或 metadata.cwd(首次使用时注册该工作区);两者同时提供时必须一致。创建时会广播全局 event.session.created 事件。

参数 位置 类型 说明
workspace_id body string 未提供 metadata.cwd必填。已注册的工作区 id会话创建于该工作区的根目录
metadata body object 自定义元数据。metadata.cwd 为工作目录,未提供 workspace_id必填;两者同时提供时必须等于工作区根目录
title body string 初始标题(至少 1 个字符);否则会话无标题
agent_config body object schema 接受该字段但当前不会应用——模型与各模式请通过 POST /api/v1/sessions/{session_id}/profile 设置

成功时,data 为新会话的 session 对象

  • 40001workspace_idmetadata.cwd 都未提供,或 metadata.cwd 与工作区根目录不一致(details 会列出该字段)
  • 40409:工作目录不存在或不是目录
  • 40410:没有以该 workspace_id 注册的工作区

GET /api/v1/sessions

跨工作区列出会话,按 updated_at 最新在前。游标分页遵循 分页,但有一个特例:不提供 page_size(且不提供 archived_only)时,响应是单个不分页的窗口,其 has_more 恒为 false,因此要真正翻页请传入 page_size

参数 位置 类型 说明
before_id query string 只保留早于该 id 的会话;与 after_id 互斥
after_id query string 只保留晚于该 id 的会话;与 before_id 互斥
page_size query integer 1100。分页生效时默认为 20;不分页的默认行为见上文说明
busy query boolean 只保留忙碌(或只保留空闲)的会话
include_archive query boolean 在活跃会话之外同时包含已归档会话。默认 false
archived_only query boolean 只保留已归档会话;与 include_archive 互斥;即使不提供 page_size 也会启用游标分页
exclude_empty query boolean 去掉没有任何用户提示词的会话
workspace_id query string 限定到单个工作区(别名会被解析)

成功时,data{ items, has_more },其中每个元素为 session 对象

  • 40001:校验失败——例如 before_idafter_id 同用,或 archived_onlyinclude_archive 同用
  • 40410:未知的 workspace_id

GET /api/v1/sessions/{session_id}

从索引中读取单个会话。会话已加载到本进程时会包含实时状态字段;冷会话上报为不忙碌,并携带其最后持久化的轮次结果。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,datasession 对象

  • 40401:会话不存在,或其工作区已无法解析

GET /api/v1/sessions/{session_id}/profile

读取会话档案——与 GET /api/v1/sessions/{session_id} 相同的线上载荷。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,datasession 对象

  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/profile

更新会话档案:标题、自定义元数据以及 main agent 的配置。在这里设置的标题会成为自定义标题,优先级高于生成的标题;设置标题会广播全局 session.meta.updated 事件。

参数 位置 类型 说明
session_id path string 必填。 会话 id
title body string 新标题(至少 1 个字符);会成为自定义标题
metadata body object 合并进会话自定义元数据的键
agent_config body object main agent 的部分配置;字段如下,均为可选

每个 agent_config 字段都会立即应用到 main agent

字段 类型 说明
model string 模型别名 id空字符串会被忽略
thinking string Thinking 强度等级
permission_mode string manual / yolo / auto
plan_mode boolean 进入或退出 Plan 模式
swarm_mode boolean 进入或退出 swarm 模式
goal_objective string 以该文本为内容创建一个目标
goal_control string pause / resume / cancel 当前目标

schema 还接受 agent_config 内的 system_prompttoolsmcp_servers,以及顶层的 permission_rules 数组,但更新路由当前不会应用它们。

成功时,data 为更新后的 session 对象

  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/title/generate

通过托管供应商的 chat_title 工具根据会话的提示词生成标题并应用,同时广播 session.meta.updated。生成需要托管 OAuth 登录和 auto_session_title 实验开关;未提供 force 时,已有自定义标题或已生成标题的会话会上报为不可用,而不会被覆盖。

参数 位置 类型 说明
session_id path string 必填。 会话 id
force body boolean 即使已有自定义或生成的标题也重新生成。默认 false
source body string 标题输入:user_prompts(默认)/ first_turn / digest

成功时,data{ title }——当前应用到会话的标题。

  • 40401:会话不存在
  • 40923:生成不可用——开关未开启、没有托管 OAuth 登录或尚无任何提示词内容、已有标题但未提供 force,或后端请求失败

POST /api/v1/sessions/{session_id}:{action}

会话动作通过同一条路由分发:路径尾部解析为 {session_id}:{action},请求体按该动作的 schema 校验,动作缺失或未知时返回 40001unsupported action: ...)。每个动作都会先解析会话,因此会话未知时都可能返回 40401。支持的动作在下面逐一说明。

POST /api/v1/sessions/{session_id}:fork

将会话——其转录、Agent 状态与文件——复制到同一工作区中的新会话,并广播 event.session.created。当会话中任一 Agent 有进行中的轮次时fork 会被拒绝。

参数 位置 类型 说明
title body string fork 的标题(至少 1 个字符)。默认 Fork: <source title>
metadata body object fork 的自定义元数据

成功时,data 为新会话的 session 对象

  • 40901:会话有进行中的轮次,无法 fork

POST /api/v1/sessions/{session_id}:compact

对 main agent 的上下文发起一次手动全量压缩。调用立即返回;进度与完成通过 compaction.* WebSocket 事件投递。

参数 位置 类型 说明
instruction body string 给压缩摘要的额外指引;空值会被忽略

成功时,data 为空对象。

  • 40910:有轮次或其他上下文变更正在进行,或历史中没有可压缩的内容

POST /api/v1/sessions/{session_id}:undo

将 main agent 的对话回退 count 个轮次,并同步修正派生的会话状态(包括会话的 last_prompt)。

参数 位置 类型 说明
count body integer 要撤销的轮次数;正整数。默认 1
page_size body integer 返回的历史窗口大小1100。默认 50

成功时,data{ messages, status }messages 是剩余上下文消息按最新在前的 { items, has_more } 分页,statusGET /api/v1/sessions/{session_id}/status 的汇总相同。

  • 40901:有轮次正在进行或压缩正在运行——等其结束后重试
  • 40911:无法撤销那么多轮次(遇到压缩边界或检查点丢失);data 携带 { reason, requestedCount, undoableCount }

POST /api/v1/sessions/{session_id}:abort

取消 main agent 正在运行的轮次——等同于用户在 TUI 中中止轮次的程序化版本。

成功时,data{ aborted: true }

POST /api/v1/sessions/{session_id}:btw

开启一个 "by the way" 旁路对话:把 main agent fork 成一个禁用工具调用的子 Agent让快速的临时问题在隔离环境中运行不触碰工作上下文。需要可用的模型配置。

成功时,data{ agent_id }——新子 Agent 的 id。

POST /api/v1/sessions/{session_id}:archive

将会话标记为已归档:它从默认会话列表中消失(使用 include_archivearchived_only 时仍会列出),并且服务端广播全局 event.session.archived 事件。

成功时,data{ archived: true }

POST /api/v1/sessions/{session_id}:restore

取消会话的归档状态并恢复它。

成功时,dataarchived: falsesession 对象

GET /api/v1/sessions/{session_id}/children

列出会话的子会话——即通过 POST /api/v1/sessions/{session_id}/children 创建的会话。游标分页遵循 分页

参数 位置 类型 说明
session_id path string 必填。 会话 id
before_id query string 只保留早于该 id 的子会话;与 after_id 互斥
after_id query string 只保留晚于该 id 的子会话;与 before_id 互斥
page_size query integer 1100。默认 100
busy query boolean 只保留忙碌(或只保留空闲)的子会话

成功时,data{ items, has_more },其中每个元素为 session 对象

  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/children

创建子会话fork 当前会话并记录为其子会话,因此会出现在 GET /api/v1/sessions/{session_id}/children 下。适用与 :fork 相同的进行中轮次限制。

参数 位置 类型 说明
session_id path string 必填。 会话 id
title body string 子会话的标题(至少 1 个字符)。默认 Child: <source title>
metadata body object 子会话的自定义元数据

成功时,data 为新会话的 session 对象,并且服务端广播 event.session.created

  • 40901:会话有进行中的轮次,无法 fork

GET /api/v1/sessions/{session_id}/status

main agent 的实时状态汇总;读取它会在会话为冷态时将其恢复。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,data{ busy, model?, thinking_level, permission, plan_mode, swarm_mode, context_tokens, max_context_tokens?, context_usage? }busy 表示是否有进行中的轮次,model / thinking_level / permission 为当前生效的 Agent 设置,plan_mode / swarm_mode 为模式标志,context_tokensmax_context_tokenscontext_usage01描述上下文窗口的占用情况。

  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/goal

读取会话当前的目标快照;没有活跃目标时为 null。注意,与本 API 的大多数载荷不同,该载荷使用 camelCase 键。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,datanull{ goalId, objective, completionCriterion?, status, turnsUsed, tokensUsed, wallClockMs, budget, terminalReason? },其中 statusactive / paused / blocked / completebudget 报告 token、轮次与 wall-clock 三项预算,以及各自的剩余量与每项预算的 reached 标志(未设置对应预算时各项为 null

  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/warnings

读取会话级告警。目前的产生者只有 AGENTS.md 过大检查(agents-md-oversized),因此大多数会话的列表为空。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,data{ warnings },每个条目为 { code, message, severity },其中 severityinfo / warning / error 之一。

  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/runtime

读取 main agent 的运行时绑定——即该会话的 Agent 循环运行在哪个运行时上。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,data{ workspace_id, runtime_id }

  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/runtime

切换 main agent 的运行时绑定。

参数 位置 类型 说明
session_id path string 必填。 会话 id
runtime_id body string 必填。 目标运行时 id

成功时,data 为新的绑定 { workspace_id, runtime_id }

  • 40420:不存在该 runtime_id 的运行时
  • 40926:运行时存在但不可用

POST /api/v1/sessions/{session_id}/export

将会话连同诊断日志一起导出为 zip 附件(kimi-session-<id>.zip)。响应是二进制流,不是 JSON 信封——能力与失败语义见 二进制与流式端点

参数 位置 类型 说明
session_id path string 必填。 会话 id
web_log body string 要包含在归档中的客户端日志文本,最多 256 KB UTF-8
desktop body boolean 同时包含桌面宿主的日志。默认 false

GET /api/v1/sessions/{session_id}/snapshot

为重新同步后重建客户端组装一份原子快照:会话、最近的消息、进行中的轮次、存活的 subagent 以及待处理交互,全部盖上 as_of_seq 水位与用于重新订阅的 epoch——见 断线恢复。与普通的会话端点不同,内嵌的会话携带实时的 agent_config.model 与真实的 usage 总计。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,data{ as_of_seq, epoch, session, messages, in_flight_turn, subagents?, pending_approvals, pending_questions }sessionsession 对象messages 为最新 100 条消息的 { items, has_more }in_flight_turn 为已部分流式输出的轮次(空闲时为 null,已知时带 current_prompt_idsubagents 列出存活的 subagent 任务,pending_approvals / pending_questions 承载未答复的交互。

  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/media/{file_id}

按文件 id 下载提示词媒体文件(会话提示词引用的图片或其他附件);尚未提交到会话的 id 会回退到暂存的上传中查找。响应为二进制并支持 Range(范围请求返回 206——共享约定见 二进制与流式端点;与那里走信封的端点不同,会话或文件不存在时会返回真正的 404 状态码并携带信封体。

参数 位置 类型 说明
session_id path string 必填。 会话 id
file_id path string 必填。 媒体文件 id

消息与转录

messages 端点分页返回 main agent 的扁平化消息历史,transcript 端点则提供按 Agent 组织的结构化转录——轮次、任务、交互、附件——即 WebSocket 转录协议 实时流式推送的内容。历史分页与补漏用这些端点,实时尾部用 WebSocket 订阅。

方法与路径 说明
GET /api/v1/sessions/{session_id}/messages 消息分页(before_id / after_id / role
GET /api/v1/sessions/{session_id}/messages/{message_id} 读取单条消息
GET /api/v1/sessions/{session_id}/transcript 按轮次分页的转录(需 agent_id);全局状态不分页随响应返回
GET /api/v1/sessions/{session_id}/transcript/ops op 批次补漏(since_seqcomplete: false 表示需要全量刷新
GET /api/v1/sessions/{session_id}/transcript/user-messages 各轮次起始的用户输入,不分页
GET /api/v1/sessions/{session_id}/transcript/plan ExitPlanMode 计划内容、路径与审阅结果

GET /api/v1/sessions/{session_id}/messages

分页返回 main agent 的消息历史——与会话快照共享的扁平化上下文转录——最新在前。游标分页遵循 分页;读取历史会在会话为冷态时将其恢复。

参数 位置 类型 说明
session_id path string 必填。 会话 id
before_id query string 只保留早于该消息 id 的消息;与 after_id 互斥
after_id query string 只保留晚于该消息 id 的消息;与 before_id 互斥
page_size query integer 1100。默认 50
role query string 只保留单一角色:user / assistant / tool / system。过滤在分页切片之后应用,因此过滤后的一页可能少于 page_size 条而 has_more 仍为 true——持续翻页直到 has_morefalse

成功时,data{ items, has_more },其中每个元素是消息对象 { id, session_id, role, content, created_at, prompt_id?, parent_message_id?, metadata? }content 是按 提示词 中说明的线上格式组成的内容块数组(texttool_usetool_resultimagevideofilethinking)。

  • 40001:校验失败——例如 before_idafter_id 同用
  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/messages/{message_id}

按 id 从同一历史中读取单条消息。

参数 位置 类型 说明
session_id path string 必填。 会话 id
message_id path string 必填。 消息 id

成功时,data 为上文 GET /api/v1/sessions/{session_id}/messages 中说明的元素形态的消息对象。

  • 40401:会话不存在
  • 40403:该会话中不存在此 id 的消息

GET /api/v1/sessions/{session_id}/transcript

返回某个 Agent 的结构化转录中的一页:轮次(含其步骤与帧)以及轮次之间的标记与任务引用。活跃会话从内存存储应答(先回填所请求 Agent 的持久化历史);冷会话则从持久化的线上记录重建 Agent。这是转录能力的历史半边——实时流式半边是 转录协议 订阅。

参数 位置 类型 说明
session_id path string 必填。 会话 id
agent_id query string 必填。 要读取其转录的 Agent必须是纯文本形式的 agent id字母、数字、._-——不含路径分隔符)
before_turn query string 只保留早于该轮次 id 的轮次;与 after_turn 互斥
after_turn query string 只保留晚于该轮次 id 的轮次;与 before_turn 互斥
page_size query integer 1100 个轮次。默认 20

分页单位是轮次:不带游标时返回最新的一页,has_more 表示还有更早的轮次。成功时,data{ agent_id, items, has_more, tasks, interactions, attachments, todos, meta, agents, pending_interactions, seq? }——items 是本次分页的轮次切片,tasks / interactions / attachments / todos / meta / agents / pending_interactions 是不分页、随每次响应一起返回的全局 Agent 状态,seq 是该 Agent 用于恢复流的 op 批次水位(仅活跃会话)。

  • 40001:校验失败——before_turnafter_turn 同用,或 agent_id 不是纯文本形式
  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/transcript/ops

从服务端的 op 日志提供点对点的补漏:某个 Agent 的 seq > since_seq 的已记录 op 批次,最旧在前。它是 转录协议transcript_since 恢复游标的 REST 对应物,共享同一份有界日志,因此适用相同的回退规则。

参数 位置 类型 说明
session_id path string 必填。 会话 id
agent_id query string 必填。 Agent id纯文本形式约束与转录端点相同
since_seq query integer 必填。 调用方已应用的最后一个 op 批次 seq最小为 0;返回其之后的批次

成功时,data{ agent_id, batches, latest_seq, complete },每个批次为 { seq, ops }complete: true 表示直到 latest_seq 的每个批次都在;complete: false 表示日志已不再覆盖到 since_seq(或会话根本不是活跃状态),调用方必须回退为一次完整的 GET .../transcript 刷新。

  • 40001:校验失败
  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/transcript/user-messages

列出会话中每个开启轮次的输入,按 Agent 分组且不分页:真实用户文本、以斜杠命令形式使用的 Skill 与插件命令、以及 cron 提示词——可通过 origin 区分——另有仅含附件的提示词,其 prompt 投影为空。所列消息引用的附件实体会随响应一起返回(仅元数据,绝不包含字节内容)。

参数 位置 类型 说明
session_id path string 必填。 会话 id
agent_id query string 只读取一个 Agent纯文本 id。默认读取所有在册 Agent

成功时,data{ agents },每个条目为 { agent_id, messages, attachments };消息为 { turn_id, ordinal, state, origin, prompt, attachment_ids?, started_at? },其中 state 为轮次状态(queued / running / completed / failed / cancelled)。

  • 40001:校验失败——agent_id 不是纯文本形式
  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/transcript/plan

按时间线顺序读取某个 Agent 的 ExitPlanMode 工具调用的计划信息——计划内容、计划文件路径、提供的选项以及审阅结果。内容投影自第一个可用的事实来源关联的审批交互交互式审阅、实时工具帧的展示auto 模式),或工具结果的输出文本;每个条目在 source 中记录了具体来源。

参数 位置 类型 说明
session_id path string 必填。 会话 id
agent_id query string 必填。 Agent id纯文本形式
tool_call_id query string 将读取范围限定到单次 ExitPlanMode 调用;不提供时列出所有可恢复计划内容的调用

成功时,data{ agent_id, plans },每个计划为 { tool_call_id, turn_id, source, plan, path?, options?, review? }sourceinteraction / display / outputoptions 是审阅选项,形如 { label, description? }review(仅交互式审阅时存在)为 { state, selected_option?, feedback? },其中 statepending / approved / rejected / cancelled 之一。

  • 40001:校验失败
  • 40401:会话不存在
  • 40416:提供了 tool_call_id,但不存在该 id 的 ExitPlanMode 调用

提示词

提示词是一次用户输入的单位:提交一条提示词会把它排入会话的 main agent或指定 Agent的队列排队中的提示词可以插入进行中的轮次运行中的提示词可以中止。轮次进度本身通过 WebSocket 事件 流式推送,不经过这些端点。

方法与路径 说明
GET /api/v1/sessions/{session_id}/prompts 进行中与排队中的提示词
POST /api/v1/sessions/{session_id}/prompts 提交提示词(内容块数组,可带模型 / 权限模式覆盖)
POST /api/v1/sessions/{session_id}/prompts:steer 把排队的提示词插入进行中的轮次
POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:abort 中止运行中的提示词
POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:steer 插入单条排队的提示词

GET /api/v1/sessions/{session_id}/prompts

读取 main agent 的提示词队列快照。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时,data{ active, queued }active 是运行中的提示词(空闲时为 nullqueued 按顺序列出等待中的提示词。提示词为 { prompt_id, user_message_id, status, content, created_at },其中 statusrunning / queued / blocked 之一,content 采用 POST /api/v1/sessions/{session_id}/prompts 接受的内容块格式。

  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/prompts

向会话提交一条用户提示词。先校验媒体引用,然后把可选的覆盖项应用到目标 Agent——profile(与 model / thinking 一起绑定),接着是 modelthinkingpermission_modedisabled_tools——随后提示词入队;响应在提示词被接受后立即返回,不等待轮次执行。提供 skills 时,提示词以打包的 Skill 激活方式运行,而不是普通用户提示词。

参数 位置 类型 说明
session_id path string 必填。 会话 id
content body array 必填。 非空的内容块数组;变体见下
agent_id body string 目标 Agent。默认为 main agent
prompt_id body string 客户端选定的提示词 id用于幂等提交已被进行中提示词占用的 id 返回 40927,已完成的返回 40903。不能与 skills 同用
skills body array 打包的 Skill 激活,至少 1 个 { name, args? } 条目;每个 Skill 必须存在且可由用户激活
profile body string 提交前要绑定的 Agent 档案
model body string 要切换到的模型别名
thinking body string Thinking 强度等级
permission_mode body string manual / yolo / auto
disabled_tools body array 要为会话禁用的工具名

schema 还接受 metadataplan_modeswarm_modegoal_objectivegoal_control,但提交路由当前不会应用它们。每个 content 内容块是按 type 区分的对象:

内容块 字段 说明
text text 纯文本
image / video source 媒体输入;source{ kind: "url", url, id? }{ kind: "base64", media_type, data }{ kind: "file", file_id }(来自 POST /api/v1/files 的上传)或 { kind: "session_media", file_id }(已提交到本会话的媒体)之一
file file_idnamemedia_typesize 通过 POST /api/v1/files 上传的文件附件

schema 还接受共享消息格式中的 tool_usetool_resultthinking 内容块,但它们在用户提示词中没有意义。未知或 kind 不匹配的 file_id 引用会在提示词创建之前、任何覆盖项应用之前被拒绝。

成功时,data 为被接受的提示词 { prompt_id, user_message_id, status, content, created_at }

  • 40001:校验失败——例如 prompt_idskills 同用,或未知的 profile
  • 40110:尚未配置供应商——请先完成登录
  • 40111:解析出的供应商没有凭据(details.provider_id
  • 40112:供应商的凭据被拒绝(details.provider_id
  • 40113:模型无法解析(已知时带 details.model_id / details.provider_id
  • 40401:会话不存在
  • 40407:引用的 file_id 不存在(或与内容块的媒体 kind 不匹配)
  • 40415:某个 skills 条目指向未知的 Skill
  • 40903prompt_id 属于已完成的提示词;data 携带 { aborted: false }
  • 40912Skill 存在但无法由用户激活
  • 40927prompt_id 已被进行中的提示词占用

POST /api/v1/sessions/{session_id}/prompts:steer

把排队的提示词插入进行中的轮次,让运行中的轮次立即消费它们,而不是先运行结束。

参数 位置 类型 说明
session_id path string 必填。 会话 id
prompt_ids body array 必填。 非空的排队提示词 id 数组

成功时,data{ steered: true, prompt_ids }

  • 40001:校验失败
  • 40401:会话不存在
  • 40402:所列提示词 id 不在队列中

POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:abort

中止运行中的提示词。本端点与下面的 :steer 通过同一条路由 POST /api/v1/sessions/{session_id}/prompts/{tail} 分发:尾部解析为 {prompt_id}:{action},动作缺失或未知时返回 40001unsupported action: ...)。

参数 位置 类型 说明
session_id path string 必填。 会话 id
prompt_id path string 必填。 提示词 id

成功时,data{ aborted: true }

  • 40401:会话不存在
  • 40402:不存在该 id 的提示词
  • 40903:提示词已完成;data 携带 { aborted: false }

POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:steer

把单条排队的提示词插入进行中的轮次——是 POST /api/v1/sessions/{session_id}/prompts:steer 的单提示词形式。

参数 位置 类型 说明
session_id path string 必填。 会话 id
prompt_id path string 必填。 排队中的提示词 id

成功时,data{ steered: true, prompt_ids: [prompt_id] }

  • 40401:会话不存在
  • 40402:没有该 id 的排队提示词

审批与提问

审批与提问是会话的两类待处理交互:审批是为工具调用请求许可,提问是请求带标签选项的结构化输入。这些端点用于列出和答复它们;新的请求通过 WebSocket 以 event.approval.requestedevent.question.requested 到达。

方法与路径 说明
GET /api/v1/sessions/{session_id}/approvals 列出待处理的审批请求(必须 status=pending
POST /api/v1/sessions/{session_id}/approvals/{approval_id} 答复审批
GET /api/v1/sessions/{session_id}/questions 列出待处理的提问(必须 status=pending
POST /api/v1/sessions/{session_id}/questions/{question_id} 回答提问
POST /api/v1/sessions/{session_id}/questions/{question_id}:dismiss 忽略提问

GET /api/v1/sessions/{session_id}/approvals

列出会话待处理的审批请求——即工具调用发起的权限提示。读取列表会在会话为冷态时将其恢复。

参数 位置 类型 说明
session_id path string 必填。 会话 id
status query string 必填。 必须为 pending

成功时,data{ items },每个元素为 { approval_id, session_id, turn_id?, tool_call_id, tool_name, action, tool_input_display, created_at, expires_at }tool_name / action / tool_input_display 描述等待许可的调用,expires_atcreated_at 之后 24 小时。

  • 40001status 缺失或不是 pending
  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/approvals/{approval_id}

答复一个待处理的审批请求,让等待中的工具调用继续执行(或不执行)。

参数 位置 类型 说明
session_id path string 必填。 会话 id
approval_id path string 必填。 审批请求 id
decision body string 必填。 approved / rejected / cancelled
scope body string 配合 approved 使用,session(唯一取值)还会让该审批规则在会话的剩余时间内被记住
feedback body string 回传给 Agent 的自由文本反馈
selected_label body string 当请求提供了带标签的选项时(例如计划审阅),所选选项的标签

成功时,data{ resolved: true, resolved_at }

  • 40001:校验失败
  • 40401:会话不存在
  • 40404:没有该 id 的待处理审批
  • 40902:审批已被答复;data 携带 { resolved: false }

GET /api/v1/sessions/{session_id}/questions

列出会话待处理的提问。

参数 位置 类型 说明
session_id path string 必填。 会话 id
status query string 必填。 必须为 pending

成功时,data{ items },每个元素为 { question_id, session_id, turn_id?, tool_call_id?, questions, created_at }questions 包含 14 个 { id, question, header?, body?, options, multi_select?, allow_other?, other_label?, other_description? } 条目,每个条目带 24 个 { id, label, description? } 形式的 optionsmulti_select 允许选择多个选项,allow_other 允许自由文本回答。

  • 40001status 缺失或不是 pending
  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/questions/{question_id}

回答一个待处理的提问。两个提问端点通过同一条路由 POST /api/v1/sessions/{session_id}/questions/{tail} 分发:单独的提问 id 表示回答问题,{question_id}:dismiss 尾部表示忽略问题,其他情况返回 40001

参数 位置 类型 说明
session_id path string 必填。 会话 id
question_id path string 必填。 提问 id
answers body object 必填。 提问条目 idq_0……)到答案对象的映射;变体见下
method body string 答案的产生方式:enter / space / number_key / click
note body string 附在回答上的自由文本备注

每个答案是按 kind 区分的对象:

kind 值 字段 说明
single option_id 选中的单个选项
multi option_ids 选中的多个选项(至少 1 个)
other text 自由文本回答
multi_with_other option_idsother_text 选项加自由文本
skipped 跳过了该条目

成功时,data{ resolved: true, resolved_at }

  • 40001:校验失败(details 列出每个字段)
  • 40401:会话不存在
  • 40405:没有该 id 的待处理提问
  • 40902:提问已被答复;data 携带 { resolved: false }

POST /api/v1/sessions/{session_id}/questions/{question_id}:dismiss

忽略一个待处理的提问,不作回答。

参数 位置 类型 说明
session_id path string 必填。 会话 id
question_id path string 必填。 提问 id

成功时信封的 code40909question dismissed)而不是 0data{ dismissed: true, dismissed_at }——客户端必须特殊处理该端点的成功码。

  • 40401:会话不存在
  • 40405:没有该 id 的待处理提问
  • 40902:提问已被答复;data 携带 { resolved: false }

后台任务

后台任务是会话的异步单元——后台 Shell、subagent 与长时间运行的工具任务。注册表仅包含实时数据:未加载到本服务进程中的会话会返回空列表。

方法与路径 说明
GET /api/v1/sessions/{session_id}/tasks 列出后台任务
GET /api/v1/sessions/{session_id}/tasks/{task_id} 读取任务(可选输出预览)
POST /api/v1/sessions/{session_id}/tasks/{task_id}:cancel 取消任务
POST /api/v1/sessions/{session_id}/tasks/{task_id}:detach 将前台任务转入后台

GET /api/v1/sessions/{session_id}/tasks

列出会话的后台任务。

参数 位置 类型 说明
session_id path string 必填。 会话 id
status query string 只保留单一状态:running / completed / failed / cancelled

成功时,data{ items },每个元素是任务对象 { id, session_id, kind, description, status, created_at, started_at?, completed_at?, command?, model?, thinking_effort?, agent_id?, subagent_type?, parent_tool_call_id?, output_preview?, output_bytes? }kindbash / subagent / toolcommand 仅在 bash 任务时设置,模型与 Agent 字段仅在 subagent 任务时设置,输出字段仅在以 with_output 读取任务时设置。超时与丢失的任务上报为 failed;被杀死的任务上报为 cancelled

  • 40001:校验失败——未知的 status
  • 40401:会话不存在

GET /api/v1/sessions/{session_id}/tasks/{task_id}

读取单个后台任务,可选携带输出的末尾片段。

参数 位置 类型 说明
session_id path string 必填。 会话 id
task_id path string 必填。 任务 id
with_output query boolean 在响应中包含输出末尾片段。默认 false
output_bytes query integer 请求的输出末尾片段的字节大小,最小 0。默认 32768

成功时,data 为上文 GET /api/v1/sessions/{session_id}/tasks 中说明的任务对象;当 with_output=true 且输出非空时,output_preview 携带末尾片段文本,output_bytes 为其字节长度。

  • 40001:校验失败
  • 40401:会话不存在
  • 40406:没有该 id 的任务(冷会话完全没有实时任务)

POST /api/v1/sessions/{session_id}/tasks/{task_id}:cancel

取消运行中的任务。它通过 POST /api/v1/sessions/{session_id}/tasks/{tail} 分发,支持 cancel / detach 两个动作——单独的任务 id 或未知动作返回 40001

参数 位置 类型 说明
session_id path string 必填。 会话 id
task_id path string 必填。 任务 id

成功时,data{ cancelled: true }

  • 40001:动作后缀缺失或未知
  • 40401:会话不存在
  • 40406:没有该 id 的任务
  • 40904:任务已结束;data 携带 { cancelled: false }details.current_status 为最终状态

POST /api/v1/sessions/{session_id}/tasks/{task_id}:detach

将运行中的前台任务转入后台而不终止它:等待该任务的工具调用会立即以后台任务结果返回,轮次继续推进,任务则在后台任务注册表下继续运行(输出持久化,完成时以任务通知投递)。已在后台或已结束的任务为幂等空操作。它通过 POST /api/v1/sessions/{session_id}/tasks/{tail} 分发,支持 cancel / detach 两个动作——单独的任务 id 或未知动作返回 40001

参数 位置 类型 说明
session_id path string 必填。 会话 id
task_id path string 必填。 任务 id

成功时,data{ detached, status }:本次调用确实将运行中的前台任务转入后台时 detachedtrue,幂等空操作时为 falsestatus 为调用后的任务状态。

  • 40001:动作后缀缺失或未知
  • 40401:会话不存在
  • 40406:没有该 id 的任务

技能、工具与 MCP

这组端点暴露会话或工作区可见的技能目录、当前生效 agent 的工具列表及其 MCP 服务。技能激活与 MCP 重启使用 :{action} 约定;激活即斜杠命令 /<skill> 的 REST 等价形式。

方法与路径 说明
GET /api/v1/sessions/{session_id}/skills 会话级技能目录
GET /api/v1/workspaces/{workspace_id}/skills 无会话的工作区技能目录
POST /api/v1/sessions/{session_id}/skills/{skill_name}:activate 激活技能(开启一个轮次)
GET /api/v1/tools 列出当前生效 agent 的工具
GET /api/v1/mcp/servers 列出 MCP 服务
POST /api/v1/mcp/servers/{mcp_server_id}:restart 重启 MCP 服务

GET /api/v1/sessions/{session_id}/skills

列出单个会话可用的技能按会话的优先级合并所有来源内置、插件、extra、用户、项目。会话处于冷态时读取目录会恢复该会话。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时 data{ skills },每项是一个技能描述符 { name, description, path, source, type?, disable_model_invocation? }sourceproject / user / extra / builtintype 标识技能类别(只有用户可激活的类型才能被激活);disable_model_invocation 会让技能对模型不可见。

  • 40401:会话不存在(或未激活)

GET /api/v1/workspaces/{workspace_id}/skills

列出该工作区中的会话将看到的技能目录但不创建或恢复会话——即针对工作区根目录计算出的同一套内置、插件、extra、用户、项目来源合并结果。

参数 位置 类型 说明
workspace_id path string 必填。 已注册工作区 id

成功时 data{ skills },技能描述符见上文 GET /api/v1/sessions/{session_id}/skills 的说明。

  • 40410:工作区不存在

POST /api/v1/sessions/{session_id}/skills/{skill_name}:activate

在会话中激活技能——即斜杠命令 /<skill> 的 REST 等价形式——以技能内容加上 args 与附件在 main agent 上开启一个轮次。该端点经单一路由 POST /api/v1/sessions/{session_id}/skills/{tail} 分发:尾部按 {skill_name}:{action} 解析,activate 是唯一动作;只给名称或动作未知时返回 40001unsupported action: ...)。

参数 位置 类型 说明
session_id path string 必填。 会话 id
skill_name path string 必填。 要激活的技能名
args body string 传给技能的自由文本参数,相当于斜杠命令后的文本
attachments body array 随激活携带的媒体块。image / video 块带 source 对象(kindurl / base64 / file / session_media,与提示词内容块同形);file 块带顶层 file_idnamemedia_typesize

成功时 data{ activated: true, skill_name }

  • 40001:校验失败或动作后缀不支持
  • 40401:会话不存在(或未激活)
  • 40407:引用的附件文件不存在
  • 40415:没有该名称的技能
  • 40912:技能存在,但其类型不允许用户激活

GET /api/v1/tools

列出当前生效 agent 的工具——即 session_id 指定会话的 main agent省略参数时取最近创建的会话。若该会话不在本服务进程中存活列表为空。

参数 位置 类型 说明
session_id query string 要查看其 main agent 的会话。默认最近创建的会话

成功时 data{ tools },每项为 { name, description, input_schema, source, mcp_server_id?, active? }sourcebuiltin / skill / mcpmcp_server_id 仅 MCP 工具携带(从 mcp__<server>__<tool> 名称解析);active 报告工具策略的判定结果。input_schema 目前恒为 null

GET /api/v1/mcp/servers

列出当前生效 agent 配置的 MCP 服务(与 GET /api/v1/tools 相同,取最近创建的存活会话的 main agent。没有存活会话时列表为空。

成功时 data{ servers },每项为 { id, name, transport, status, last_error?, tool_count }transportstdio / http / ssestatusconnected / connecting / disconnected / error;服务处于 errorlast_error 携带失败信息。

POST /api/v1/mcp/servers/{mcp_server_id}:restart

重新连接当前生效 agent 的某个 MCP 服务。该端点经 POST /api/v1/mcp/servers/{tail} 分发,restart 是唯一动作——只给服务 id 或动作未知时返回 40001

参数 位置 类型 说明
mcp_server_id path string 必填。 MCP 服务 id即其配置名称

成功时 data{ restarting: true }

  • 40001:缺少动作后缀或动作未知
  • 40408:没有该 id 的 MCP 服务(无存活会话时同样返回此错误)

能力与插件

能力是带有分层就绪状态的内置特性——由检测步骤加后台安装组成;当前版本注册了 kimi-cuKimi Computer Usekimi-webbridgeKimi WebBridge。插件是已安装的技能、MCP 服务、hook 与命令的打包集合。这组端点报告能力状态、驱动能力安装,并管理插件从市场列表到移除的整个生命周期。

方法与路径 说明
GET /api/v1/capabilities 列出内置能力及其就绪状态
GET /api/v1/capabilities/{capability_id} 读取单个能力的状态
POST /api/v1/capabilities/{capability_id}:install 开始安装能力(后台进行,轮询 GET 查看进度)
GET /api/v1/plugins 列出已安装插件
POST /api/v1/plugins 从本地路径、zip URL 或 GitHub 仓库安装插件
GET /api/v1/plugins/marketplace 插件市场目录,合并实时安装状态
POST /api/v1/plugins/{plugin_id}:{action} 插件动作:enable / disable / remove

GET /api/v1/capabilities

列出所有已注册能力及其就绪状态。

成功时 data{ capabilities },每项是一个能力状态对象 { id, pluginId?, displayName, description, supported, state, version?, steps, install }stateready(所有必需检测步骤均为 ok/ partial(部分步骤 ok/ not_installed / unsupported(当前平台/架构不可用);steps{ id, state, detail?, optional? } 列出各检测步骤,其 stateok / missing / failed 之一;install 为安装进度 { running, step?, percent?, error?, note? },其中 percent 取值 0 到 100。

GET /api/v1/capabilities/{capability_id}

读取单个能力的就绪状态——即 :install 动作的轮询对应端点。

参数 位置 类型 说明
capability_id path string 必填。 能力 id

成功时 data 为上文 GET /api/v1/capabilities 说明的能力状态对象。

  • 40418:没有该 id 的能力

POST /api/v1/capabilities/{capability_id}:install

在后台开始安装能力并立即返回当前状态(install.runningtrue);轮询 GET /api/v1/capabilities/{capability_id} 查看进度。该端点经 POST /api/v1/capabilities/{tail} 分发,install 是唯一动作——只给 id 或动作未知时返回 40001

参数 位置 类型 说明
capability_id path string 必填。 能力 id

成功时 data 为上文 GET /api/v1/capabilities 说明的能力状态对象。

  • 40001:缺少动作后缀或动作未知
  • 40418:没有该 id 的能力
  • 40924:该能力的安装已在进行中
  • 40925:当前平台/架构不支持该能力

GET /api/v1/plugins

列出已安装插件。

成功时 data{ plugins },每项为 { id, displayName, version?, enabled, state, skillCount, mcpServerCount, enabledMcpServerCount, hookCount, commandCount, hasErrors, source, originalSource?, github? }stateok / error(加载失败也会置 hasErrorssourcelocal-path / zip-url / githubGitHub 来源的插件由 github 携带来源信息 { owner, repo, ref, installedSha? },其中 ref{ kind: branch|tag|sha, value }

POST /api/v1/plugins

安装插件并返回其摘要。

参数 位置 类型 说明
source body string 必填。 安装来源:本地绝对路径、指向 zip 压缩包的 http(s) URL或 GitHub URL——https://github.com/<owner>/<repo>,可选地用 /tree/<branch-or-sha>/releases/tag/<tag>/commit/<sha> 锁定版本

成功时 data 为上文 GET /api/v1/plugins 说明的插件摘要。

  • 40001:校验失败——例如 source 既不是 URL 也不是绝对路径,或插件加载失败
  • 40409:本地路径不存在

GET /api/v1/plugins/marketplace

列出插件市场目录并合并实时安装状态。目录按请求从配置的市场 URL 拉取(超时 10 秒);使用默认目录时,目录中缺少的内置能力会作为条目合并进来(带 capabilityId),而当前平台不支持的能力对应条目会被剔除。

成功时 data{ entries },每项为 { id, tier, displayName, description?, homepage?, keywords?, version?, source, installed?, updateAvailable?, capabilityId? }tierofficial / curated / third-party;插件已安装时 installed{ version?, enabled }updateAvailable 标记目录版本新于已安装版本的条目。条目的 sourcePOST /api/v1/pluginssource 字段取值。

  • 50001:市场不可达或返回了非法目录

POST /api/v1/plugins/{plugin_id}:enable

启用一个已安装插件。插件动作经单一路由 POST /api/v1/plugins/{tail} 分发:尾部按 {plugin_id}:{action} 解析,动作为 enable / disable / remove;只给 id 或动作未知时返回 40001unsupported action: ...)。

参数 位置 类型 说明
plugin_id path string 必填。 已安装插件 id

成功时 data{ ok: true }

  • 40001:缺少动作后缀或动作未知
  • 40419:没有该 id 的已安装插件

POST /api/v1/plugins/{plugin_id}:disable

停用一个已安装插件但不移除它;分发约定同上文 :enable

参数 位置 类型 说明
plugin_id path string 必填。 已安装插件 id

成功时 data{ ok: true }

  • 40001:缺少动作后缀或动作未知
  • 40419:没有该 id 的已安装插件

POST /api/v1/plugins/{plugin_id}:remove

移除一个已安装插件;分发约定同上文 :enable

参数 位置 类型 说明
plugin_id path string 必填。 已安装插件 id

成功时 data{ ok: true }

  • 40001:缺少动作后缀或动作未知
  • 40419:没有该 id 的已安装插件

终端

PTY 终端接口;仅在 loopback 绑定时挂载(非 loopback 绑定会跳过它们,除非传入 --allow-remote-terminals)。终端的输入、输出与尺寸调整经 WebSocket 的 terminal_* 帧传输——REST 侧只管理终端生命周期。

方法与路径 说明
GET /api/v1/sessions/{session_id}/terminals 列出终端
POST /api/v1/sessions/{session_id}/terminals 创建终端
GET /api/v1/sessions/{session_id}/terminals/{terminal_id} 读取终端
POST /api/v1/sessions/{session_id}/terminals/{terminal_id}:close 关闭终端

GET /api/v1/sessions/{session_id}/terminals

列出会话的终端。会话处于冷态时,读取列表会恢复该会话。

参数 位置 类型 说明
session_id path string 必填。 会话 id

成功时 data{ items },每项是一个终端对象 { id, session_id, cwd, shell, cols, rows, status, created_at, exited_at?, exit_code? }statusrunning / exited;已退出的终端携带 exited_atexit_code(进程未报告退出码时为 null,例如因信号终止)。回滚缓冲不属于该对象——输出经 WebSocket 回放与流式推送。

  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/terminals

为会话创建一个 PTY 终端。

参数 位置 类型 说明
session_id path string 必填。 会话 id
runtime_id body string 生成终端进程的运行时。默认 local
cwd body string 工作目录,相对于会话工作区(传绝对路径会校验失败)。默认工作区根目录
shell body string Shell 可执行文件。默认该运行时的 shell
cols body integer 终端宽度,正数。默认 80
rows body integer 终端高度,正数。默认 24

成功时 data 为上文 GET /api/v1/sessions/{session_id}/terminals 说明的终端对象。

  • 40001:校验失败(details 逐字段说明)
  • 40401:会话不存在
  • 41304cwd 解析后越出会话工作区

GET /api/v1/sessions/{session_id}/terminals/{terminal_id}

读取单个终端。

参数 位置 类型 说明
session_id path string 必填。 会话 id
terminal_id path string 必填。 终端 id

成功时 data 为上文 GET /api/v1/sessions/{session_id}/terminals 说明的终端对象。

  • 40401:会话不存在
  • 40414:没有该 id 的终端

POST /api/v1/sessions/{session_id}/terminals/{terminal_id}:close

关闭终端并结束其进程。该端点经 POST /api/v1/sessions/{session_id}/terminals/{tail} 分发,close 是唯一动作——只给 id 或动作未知时返回 40001

参数 位置 类型 说明
session_id path string 必填。 会话 id
terminal_id path string 必填。 终端 id

成功时 data{ closed: true }

  • 40001:缺少动作后缀或动作未知
  • 40401:会话不存在
  • 40414:没有该 id 的终端

工作区

工作区是已注册的项目目录,会话都落在其中。这组端点管理注册表——列出、注册、重命名、注销——以及控制项目级 MCP 配置是否加载的每工作区信任状态。所有返回工作区的端点都使用 workspace 对象 中统一说明的传输结构。

方法与路径 说明
GET /api/v1/workspaces 列出已注册工作区
POST /api/v1/workspaces 注册工作区(按根路径幂等)
PATCH /api/v1/workspaces/{workspace_id} 重命名
DELETE /api/v1/workspaces/{workspace_id} 注销(保留磁盘内容)
GET /api/v1/workspaces/{workspace_id}/trust 读取信任状态
POST /api/v1/workspaces/{workspace_id}/trust 授予信任
POST /api/v1/workspaces/{workspace_id}/untrust 撤销信任

workspace 对象

所有返回工作区的端点都使用此传输结构。注册与重命名会广播全局事件 event.workspace.created / event.workspace.updated

字段 类型 说明
id string 工作区 id由根路径派生的 wd_<slug>_<hash12> 字符串
root string 项目目录的绝对路径
name string 显示名1100 个字符;默认取根目录的基名
created_at string 注册时间ISO 8601
last_opened_at string 最近一次打开或重新注册工作区的时间ISO 8601
session_count integer 工作区内的会话数

GET /api/v1/workspaces

列出所有已注册工作区。

成功时 data{ items },每项是一个 workspace 对象

POST /api/v1/workspaces

注册工作区并返回它。注册按根路径幂等:重复注册同一根路径会返回已存在的工作区,仅刷新 last_opened_at(保留已存名称),并广播 event.workspace.updated 而非 event.workspace.created

参数 位置 类型 说明
root body string 必填。 已存在目录的绝对路径
name body string 显示名1100 个字符。默认根目录的基名

成功时 dataworkspace 对象

  • 40001root 缺失或不是绝对路径(details 会列出该字段)
  • 40409root 不存在或不是目录

PATCH /api/v1/workspaces/{workspace_id}

重命名工作区——仅修改显示名,根路径不变。

参数 位置 类型 说明
workspace_id path string 必填。 工作区 id
name body string 必填。 新的显示名1100 个字符

成功时 dataworkspace 对象

  • 40001:校验失败(details 逐字段说明)
  • 40410:工作区不存在

DELETE /api/v1/workspaces/{workspace_id}

注销工作区。只移除注册表条目——磁盘上的目录不受影响。

参数 位置 类型 说明
workspace_id path string 必填。 工作区 id

成功时 data{ deleted: true }

  • 40410:工作区不存在

GET /api/v1/workspaces/{workspace_id}/trust

读取工作区信任状态。信任状态决定是否为该工作区加载项目级 MCP 配置。

参数 位置 类型 说明
workspace_id path string 必填。 工作区 id

成功时 data{ trusted }

  • 40410:工作区不存在

POST /api/v1/workspaces/{workspace_id}/trust

将工作区标记为信任,并加载其项目级 MCP 配置。

参数 位置 类型 说明
workspace_id path string 必填。 工作区 id

成功时 data{ trusted: true }

  • 40410:工作区不存在

POST /api/v1/workspaces/{workspace_id}/untrust

撤销工作区信任,并卸载其项目级 MCP 配置。

参数 位置 类型 说明
workspace_id path string 必填。 工作区 id

成功时 data{ trusted: false }

  • 40410:工作区不存在

文件系统

会话内文件操作走 POST /api/v1/sessions/{session_id}/fs:{action},请求体为 JSON动作包括 list / read / list_many / stat / stat_many / mkdir / search / grep / git_status / diff / open / open-in / reveal。每个动作的请求体还接受可选的 runtime_idstring默认 local),用于选择执行操作的运行时;openopen-inreveal 仅在 local 运行时上可用。另有:

方法与路径 说明
POST /api/v1/workspace/fs:search 无会话的工作区搜索body 携带工作区引用)
POST /api/v1/workspace/fs:suggest 无会话的文件补全候选(用于 @ 文件提及)
GET /api/v1/sessions/{session_id}/fs/{path}:download 下载会话文件(二进制,见下文)
GET /api/v1/fs:browse 列出本机目录(文件夹选择器用)
GET /api/v1/fs:home 用户主目录与最近工作区
GET /api/v1/fs:content 读取本机任意文件原始字节(仅受 token 保护,谨慎暴露端口)
POST /api/v1/fs:mkdir 按绝对路径创建目录

POST /api/v1/sessions/{session_id}/fs:list

列出会话工作区目录下的条目,可选递归子目录。

参数 位置 类型 说明
session_id path string 必填。 会话 id
path body string 要列出的目录,相对于会话工作目录。默认 .
depth body integer 递归深度110。默认 1
limit body integer 最大条目数11000。默认 200
show_hidden body boolean 包含点文件。默认 false
follow_gitignore body boolean 跳过 gitignore 的路径。默认 true
exclude_globs body string[] 额外要跳过的 glob
sort body string type_first(默认)/ name_asc / name_desc / mtime_desc / size_desc
include_git_status body boolean 附带每个条目的 git 状态。默认 false

成功时 data{ items, truncated }——depth 大于 1 时另附 children_by_path(路径 → 条目的映射)。每项是一个条目对象 { path, name, kind, size?, modified_at, etag?, mime?, language_id?, is_binary?, is_symlink_to?, git_status?, child_count? },其中 kindfile / directory / symlinkgit_status(仅 include_git_status: true 时存在)为 clean / modified / added / deleted / renamed / untracked / ignored / conflicted 之一;truncated 表示 limit 截断了列表。

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40409:路径不存在(包括 path 不是目录的情况)
  • 41304:路径越出会话工作区

POST /api/v1/sessions/{session_id}/fs:read

以文本或 base64 读取会话文件的一段内容。

参数 位置 类型 说明
session_id path string 必填。 会话 id
path body string 必填。 文件路径,相对于会话工作目录
offset body integer 起始字节偏移。默认 0
length body integer 读取字节数11048576010 MiB。默认 10485761 MiB
encoding body string auto(默认)/ utf-8 / base64

成功时 data{ path, content, encoding, size, truncated, etag, mime, language_id?, line_count?, is_binary },其中 encoding 报告实际使用的编码(utf-8base64size 为文件完整大小。encoding: "auto" 时文本以 utf-8 返回(非 UTF-8 文本会被转码),二进制内容以 base64 返回;encoding: "utf-8" 强制按文本读取并拒绝二进制文件。

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40409:路径不存在
  • 40906:路径是目录
  • 40907:二进制文件却指定了 encoding: "utf-8"
  • 41302:文件超过 10 MiB 读取上限
  • 41304:路径越出会话工作区

POST /api/v1/sessions/{session_id}/fs:list_many

一次调用列出多个会话目录;失败的路径会折进响应里,而不是让整个请求失败。

参数 位置 类型 说明
session_id path string 必填。 会话 id
paths body string[] 必填。 要列出的目录1100 条

其余请求体字段(depthlimitshow_hiddenfollow_gitignoreexclude_globssortinclude_git_status)的类型、取值范围与默认值同 fs:list。成功时 data{ results }——每个请求路径到其条目数组(条目对象见 fs:list 的说明)的映射,另附 truncated_paths(达到 limit 的路径)与 partial_errors(失败路径到其 { code, msg } 错误的映射)。

  • 40001:请求体校验失败
  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/fs:stat

查询会话工作区内单个路径的元信息。

参数 位置 类型 说明
session_id path string 必填。 会话 id
path body string 必填。 要查询的路径,相对于会话工作目录

成功时 datafs:list 中说明的条目对象。

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40409:路径不存在
  • 41304:路径越出会话工作区

POST /api/v1/sessions/{session_id}/fs:stat_many

一次调用查询多个会话路径的元信息;不存在的路径返回 null,不会让整个请求失败。

参数 位置 类型 说明
session_id path string 必填。 会话 id
paths body string[] 必填。 要查询的路径11000 条

成功时 data{ entries }——每个请求路径到其条目对象(见 fs:list 的说明)的映射,路径不存在时为 null

  • 40001:请求体校验失败
  • 40401:会话不存在

POST /api/v1/sessions/{session_id}/fs:mkdir

在会话工作区内创建目录。

参数 位置 类型 说明
session_id path string 必填。 会话 id
path body string 必填。 要创建的目录,相对于会话工作目录
recursive body boolean 创建缺失的父目录。默认 false

成功时 data 为所建目录的条目对象(见 fs:list 的说明)。

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40409:父目录不存在(非递归创建)
  • 40919:路径已存在(非递归创建)
  • 41304:路径越出会话工作区

POST /api/v1/sessions/{session_id}/fs:search

在会话工作区内模糊搜索文件与目录名。query 为空时改为列出顶层条目。当 {session_id} 位置携带的是工作区引用(已注册工作区 id 或绝对根路径)而非会话 id 时,搜索针对该工作区执行——这是为尚未创建的草稿会话准备的无会话形式;正式的无会话端点是 POST /api/v1/workspace/fs:search

参数 位置 类型 说明
session_id path string 必填。 会话 id或工作区引用
query body string 必填。 搜索文本;"" 表示列出顶层
limit body integer 最大命中数1200。默认 50
include_globs body string[] 只保留匹配这些 glob 之一的路径
exclude_globs body string[] 跳过匹配这些 glob 的路径
follow_gitignore body boolean 跳过 gitignore 的路径。默认 true

成功时 data{ items, truncated },每项为 { path, name, kind, score, match_positions }——kindfile / directory / symlinkscore 为 0 到 1 之间的模糊匹配得分,match_positions 列出匹配到的字符偏移。命中按得分排序(同分按路径),truncated 表示超出 limit 的命中被丢弃。

  • 40001:请求体校验失败
  • 40401:该引用既不是会话,也不是可解析的工作区

POST /api/v1/sessions/{session_id}/fs:grep

在会话工作区内搜索文件内容——默认按字面字符串,regex: true 时按正则表达式。

参数 位置 类型 说明
session_id path string 必填。 会话 id
pattern body string 必填。 要搜索的文本或正则
regex body boolean pattern 视为正则表达式。默认 false
case_sensitive body boolean 默认 true
include_globs body string[] 只保留匹配这些 glob 之一的文件
exclude_globs body string[] 跳过匹配这些 glob 的文件
follow_gitignore body boolean 跳过 gitignore 的路径。默认 true
max_files body integer 最多扫描的文件数110000。默认 200
max_matches_per_file body integer 每个文件保留的匹配数110000。默认 50
max_total_matches body integer 总共保留的匹配数1100000。默认 5000
context_lines body integer 每个匹配携带的上下文行数010。默认 2

成功时 data{ files, files_scanned, truncated, elapsed_ms },其中 files 的每项为 { path, matches },每个匹配为 { line, col, text, before, after }before / after 最多携带 context_lines 行上下文);truncated 表示某个匹配配额截断了结果。

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 41305:搜索超时

POST /api/v1/sessions/{session_id}/fs:git_status

读取会话工作区的 git 状态,可选限定在一组路径内。

参数 位置 类型 说明
session_id path string 必填。 会话 id
paths body string[] 将状态限定在这些路径;省略表示整个工作区

成功时 data{ branch, ahead, behind, entries, additions, deletions, pullRequest },其中 entries 把每个变更路径映射到其状态(clean / modified / added / deleted / renamed / untracked / ignored / conflictedpullRequest{ number, state, url }stateopen / merged / closed / draft)或 null

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40908git 不可用(不是仓库,或没有 git 可执行文件)

POST /api/v1/sessions/{session_id}/fs:diff

返回会话工作区内单个文件的 unified git diff。

参数 位置 类型 说明
session_id path string 必填。 会话 id
path body string 必填。 要 diff 的文件,相对于会话工作目录

成功时 data{ path, diff, truncated },其中 diff 为 unified diff 文本,truncated 表示过长的 diff 被截断。

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40908git 不可用(不是仓库,或没有 git 可执行文件)
  • 41304:路径越出会话工作区

POST /api/v1/sessions/{session_id}/fs:open

用宿主操作系统的默认程序打开会话文件。仅限 local 运行时。

参数 位置 类型 说明
session_id path string 必填。 会话 id
path body string 必填。 要打开的文件,相对于会话工作目录
line body integer 在处理程序支持时跳转到的行号(正整数)

成功时 data{ opened: true }

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40409:路径不存在
  • 41304:路径越出会话工作区

POST /api/v1/sessions/{session_id}/fs:open-in

在指定的宿主应用程序中打开会话文件或目录。仅限 local 运行时。

参数 位置 类型 说明
session_id path string 必填。 会话 id
app_id body string 必填。 目标应用:finder / cursor / vscode / iterm / terminal
path body string 必填。 要打开的文件或目录,相对于会话工作目录
line body integer 在应用支持时跳转到的行号(正整数)

成功时 data{ opened: true }

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40409:路径不存在
  • 41304:路径越出会话工作区
  • 50001:应用启动失败

POST /api/v1/sessions/{session_id}/fs:reveal

在宿主操作系统的文件管理器中显示会话文件。仅限 local 运行时。

参数 位置 类型 说明
session_id path string 必填。 会话 id
path body string 必填。 要显示的文件,相对于会话工作目录

成功时 data{ revealed: true }

  • 40001:请求体校验失败
  • 40401:会话不存在
  • 40409:路径不存在
  • 41304:路径越出会话工作区

GET /api/v1/sessions/{session_id}/fs/{path}:download

从会话工作区下载文件;{path} 是相对于工作区的文件路径,并带字面量 :download 后缀。响应为支持 Range 与 ETag 的二进制流——见 二进制与流式端点

参数 位置 类型 说明
session_id path string 必填。 会话 id
path path string 必填。 相对于工作区的文件路径,加 :download 后缀
runtime_id query string 从哪个运行时读取。默认 local
  • 40001:路径缺失或为空
  • 40401:会话不存在
  • 40409:路径不存在
  • 41304:路径越出会话工作区

POST /api/v1/workspace/fs:search

fs:search 的无会话形式:工作区改由请求体而非 URL 携带。

参数 位置 类型 说明
workspace body string 必填。 已注册工作区 id 或绝对根路径(当场注册)
query body string 必填。 搜索文本;"" 表示列出顶层
limit body integer 最大命中数1200。默认 50
include_globs body string[] 只保留匹配这些 glob 之一的路径
exclude_globs body string[] 跳过匹配这些 glob 的路径
follow_gitignore body boolean 跳过 gitignore 的路径。默认 true
runtime_id body string 在哪个运行时上搜索。默认 local

成功时 data{ items, truncated },命中结构与排序同 fs:search

  • 40001:请求体校验失败
  • 40410:工作区不存在,且不是可用的绝对路径

POST /api/v1/workspace/fs:suggest

在无会话的情况下给出工作区内的文件与目录补全候选——即输入框中 @ 文件提及的后端。

参数 位置 类型 说明
workspace body string 必填。 已注册工作区 id 或绝对根路径(当场注册)
query body string 必填。 要补全的部分路径文本
limit body integer 最大候选数1200。默认 50
follow_gitignore body boolean 跳过 gitignore 的路径。默认 true
show_hidden body boolean 包含点文件。默认 false
include_globs body string[] 只保留匹配这些 glob 之一的路径
exclude_globs body string[] 跳过匹配这些 glob 的路径
runtime_id body string 在哪个运行时上补全。默认 local

成功时 data{ items, truncated },每项为 { path, name, kind, score, match_positions },命中结构同 fs:search

  • 40001:请求体校验失败
  • 40410:工作区不存在,且不是可用的绝对路径

GET /api/v1/fs:browse

列出某个本机目录的子目录——文件夹选择器的后端。

参数 位置 类型 说明
path query string 绝对目录路径。默认用户主目录

成功时 data{ path, parent, entries },其中 path 为解析后的目录,parent 为其父目录(文件系统根处为 null),每条目为 { name, path, is_dir: true }

  • 40001path 不是绝对路径
  • 40409:路径不存在
  • 40411:权限不足

GET /api/v1/fs:home

返回文件夹选择器的落地数据。无参数。

成功时 data{ home, recent_roots },其中 home 为用户主目录,recent_roots 列出已注册工作区的根目录。

GET /api/v1/fs:content

以流式返回本机文件系统上任意文件的原始字节——仅受 API token 保护,暴露端口时务必谨慎。支持 Range 请求与 ETag 缓存;见 二进制与流式端点

参数 位置 类型 说明
path query string 必填。 绝对文件路径
  • 40001path 不是绝对路径,或不是普通文件
  • 40409:路径不存在
  • 40411:权限不足
  • 40906:路径是目录

POST /api/v1/fs:mkdir

按绝对路径在本机文件系统上创建一个目录——文件夹选择器「新建文件夹」的后端。非递归:父目录必须已存在。

参数 位置 类型 说明
path body string 必填。 绝对目录路径

成功时 data{ path }

  • 40001path 不是绝对路径
  • 40409:父路径不存在
  • 40411:权限不足
  • 40919:路径已存在

文件上传

方法与路径 说明
POST /api/v1/files multipart 上传(字段 file,可选 nameexpires_in_sec),返回文件元信息
GET /api/v1/files/{file_id} 下载(二进制,错误用真实 HTTP 状态码)
DELETE /api/v1/files/{file_id} 删除

POST /api/v1/files

multipart/form-data 上传文件,供后续引用(例如作为提示词附件)。

参数 位置 类型 说明
file body binary 必填。 multipart 的文件部分
name body string 存储的显示名。默认上传文件名
expires_in_sec body number 文件过期前的秒数(非负)。默认永不过期

成功时 data 为文件元信息 { id, name, media_type, size, created_at, expires_at? },其中 media_type 取自上传的内容类型。

  • 40001multipart 请求体缺少 file 字段

GET /api/v1/files/{file_id}

下载已上传的文件。响应为二进制流,支持 Range 请求但不处理 If-None-Match;失败使用真实 HTTP 状态码——见 二进制与流式端点

参数 位置 类型 说明
file_id path string 必填。 上传响应返回的文件 id
  • 40407HTTP 404没有该 id 的文件(包括已过期的文件)

DELETE /api/v1/files/{file_id}

删除已上传的文件。

参数 位置 类型 说明
file_id path string 必填。 上传响应返回的文件 id

成功时 data{ deleted: true }

  • 40407HTTP 404没有该 id 的文件

GUI 存储

由服务端支撑的键值存储,接口对齐浏览器的 localStorage,持久化在服务的 home 目录下web UI 用它保存跨客户端的 UI 状态。值是不透明字符串——序列化由调用方负责。

方法与路径 说明
GET /api/v1/gui/store/length 已存键的数量
GET /api/v1/gui/store/getItem 按键读取值
POST /api/v1/gui/store/setItem 按键写入值
POST /api/v1/gui/store/removeItem 按键删除值
POST /api/v1/gui/store/clear 删除所有值

GET /api/v1/gui/store/length

返回已存键的数量(对齐 localStorage.length)。无参数。

成功时 data{ length }

GET /api/v1/gui/store/getItem

读取一个值(对齐 localStorage.getItem)。

参数 位置 类型 说明
key query string 必填。 要读取的键1256 个字符

成功时 data{ value }——已存字符串,键不存在时为 null

POST /api/v1/gui/store/setItem

写入一个值(对齐 localStorage.setItem)。

参数 位置 类型 说明
key body string 必填。 要写入的键1256 个字符
value body string 必填。 要存储的值

成功时 datanull

POST /api/v1/gui/store/removeItem

删除一个值(对齐 localStorage.removeItem)。

参数 位置 类型 说明
key body string 必填。 要删除的键1256 个字符

成功时 datanull

POST /api/v1/gui/store/clear

删除所有已存值(对齐 localStorage.clear)。无参数。

成功时 datanull

全局搜索与其他

方法与路径 说明
POST /api/v1/search 跨会话全文搜索,modeterms(默认)或 literal(精确子串),page_token 分页
GET /api/v1/connections 列出当前在线的 WebSocket 连接
GET /api/v2/sessions 新一代会话列表,见下文
POST /api/v2/sessions:archive 批量归档会话,见下文
POST /api/v2/sessions:restore 批量恢复已归档会话,见下文
/api/v2/mcp/* 统一的 MCP 管理面,见下文
/api/v1/debug/* 反射式调试 RPC--debug-endpoints 且 loopback 时挂载,不属于稳定协议

POST /api/v1/search

跨会话全文搜索,覆盖 User 消息、Assistant 回复与会话标题,由服务端的持久搜索索引支撑。当 container.session_id 指向本服务进程中存活的会话时,搜索改为直接扫描该会话的内存转录,响应的 source 字段(indexlive)会报告本页结果由哪条路径提供。

参数 位置 类型 说明
query body string 必填。 搜索文本
mode body string terms(默认)/ literal
op body string terms 模式下的词项组合符:AND(默认)/ OR
container body object 将搜索限定在 { session_id?, agent_id? }
role body string 限定 user / assistant / title 命中
start_time body integer 只看不早于该时间的命中epoch 毫秒)
end_time body integer 只看不晚于该时间的命中epoch 毫秒)
sort body string score(默认)/ time_desc / time_ascliteral 模式忽略此参数,始终最新在前
page_size body integer 每页命中数150。默认 20
page_token body string 上一页响应返回的令牌

terms 模式下查询会被分词ASCII 词加 CJK n-gram、去重并以至多 32 个词项匹配倒排索引;literal 模式是零误报的精确子串搜索。成功时 data{ items, has_more, page_token?, index_state, source },每项为 { session_id, workspace_id, session_title, agent_id, role, snippet, time, turn?, step_id?, score }index_state{ state, indexed_sessions, total_sessions, documents, stale?, degraded? },其中 statebuilding / ready / readonly 之一;stale 标记仍在追赶的落后视图,degraded 携带最近一次刷新失败的信息。超出预算的页会额外携带 incomplete,取值为 candidate_cap / postings_budget / deadline 之一。分页令牌锁定索引代际与查询条件——索引重建或查询变更会使其失效。

  • 40001:请求体校验失败、查询不可用(为空或超过 32 个词项),或分页令牌非法

GET /api/v1/connections

列出当前连接到本服务的 WebSocket 客户端,按连接时间最早在前。无参数。

成功时 data{ connections },每项为 { id, connected_at, remote_address, user_agent, has_client_hello, subscriptions }connected_at 为 ISO 8601 时间戳;remote_addressuser_agent 未知时为 nullhas_client_hello 报告客户端是否已发送握手帧;subscriptions 列出该连接订阅的会话 id。

GET /api/v2/sessions

面向列表页的新一代会话查询,筛选、排序、字段组都在查询参数里:

参数 说明
workspace.id 按工作区过滤,可重复
activity.status 按活动状态过滤:running / approval / question / failed / idle,可重复
meta.updated_after 只看该时间epoch 毫秒)之后更新过的会话
meta.updated_before 只看该时间epoch 毫秒)之前更新过的会话
meta.archived true / false(默认)/ all
meta.has_prompt true 只保留有用户 prompt 的会话,false 只保留空会话(等价 GET /api/v1/sessionsexclude_empty
view flat(默认)/ by_workspace,见下文
group.page_size view=by_workspace 时每个工作区返回的会话数1100默认 5使用 id,archived 投影时上限 10000未开分组视图时传入返回 40001
sort meta.updated_at_desc(默认)/ meta.updated_at_asc / meta.created_at_desc
include 逗号分隔的附加字段组;目前支持 git(分支与 PR 信息,按目录去重并缓存 60 秒)
fields 逗号分隔的字段投影;目前仅支持 id,archived,每项裁剪为 { id, archived }(用于全选匹配场景)。不可与 include=git 同传(40001
page_size 1100默认 50使用 id,archived 投影时上限放宽至 10000。view=by_workspace 时按组计数
page_token 上一页返回的翻页令牌
page 无状态的 1 起始页码;与 page_token 互斥(同传返回 40001

响应每项固定包含 workspacemetaactivity 三组,include=git 时附加 git 组;fields=id,archived 时仅返回 { id, archived }activity 组还会带上 model:会话仍加载在当前进程时为其绑定的模型别名,冷会话(未加载)为 null。每页额外携带 total,即过滤后的集合大小。翻页令牌绑定首页查询条件(含投影),中途改条件返回 40922page 模式是跳页用的无状态替代:每次请求都是独立快照,不签发令牌,next_page_token 恒为 null

view=by_workspace 时,同一份过滤、排序后的集合会重新投影为按工作区分组的形态,概览页因此可以用一次请求替代「每个工作区各一轮询」:

{
  "code": 0,
  "msg": "success",
  "data": {
    "groups": [
      {
        "workspace": { "id": "wd_my-app_a1b2c3d4e5f6", "cwd": "/Users/dev/my-app" },
        "sessions": [ { "id": "session_...", "workspace": { "id": "wd_my-app_a1b2c3d4e5f6", "cwd": "/Users/dev/my-app" }, "meta": { "title": "Fix the login page", "last_prompt": "adjust the button spacing", "created_at": 1787000000000, "updated_at": 1787000100000, "archived": false, "archived_at": null }, "activity": { "status": "idle", "model": "kimi-for-coding" } } ],
        "total": 42
      }
    ],
    "total": 7,
    "has_more": true,
    "next_page_token": "eyJ2IjoxLCJmIjoi..."
  },
  "request_id": "req_..."
}

每组携带该工作区按请求 sort 排序的前 group.page_size 条会话,以及该工作区匹配过滤条件的会话总数 total(用作「查看全部」入口)。只有至少有一条匹配会话的工作区才会出现;组间按组内首条会话的 sort key 排序,相同则按工作区 id。pagepage_token 按组翻页(外层 total 为组数),指纹绑定规则相同:令牌同时覆盖 view 与分组参数,翻页途中变更同样返回 40922

POST /api/v2/sessions:archivePOST /api/v2/sessions:restore

面向会话管理页的批量归档/恢复。请求体为 { "ids": ["session_..."] }——非空、去重后不超过 5000 条。仍在线的会话走完整生命周期;未加载的冷会话直接改写磁盘上的元数据,不会被加载。

只有请求体校验失败才会让整个请求失败(40001);其余情况按条返回:data.results 保持输入顺序,每项为 { id, ok }{ id, ok: false, error }(不存在的 id 在自身条目里报 40401),并附 succeeded / failed 计数。

{
  "code": 0,
  "msg": "success",
  "data": {
    "results": [
      { "id": "session_a", "ok": true },
      { "id": "session_b", "ok": false, "error": { "code": 40401, "message": "session session_b does not exist" } }
    ],
    "succeeded": 1,
    "failed": 1
  },
  "request_id": "req_..."
}

MCP 管理(/api/v2/mcp

/api/v2/mcp/* 路由是服务的统一 MCP 管理面:独立于任何会话,直接管理 MCP server 注册表本身——全局用户级CRUD 与逐条校验、连接测试探测、locator 寻址的检查目录、按 server 的授权状态列表,以及完整的 OAuth 流程生命周期。

方法与路径 说明
GET /api/v2/mcp/servers 列出所有已知 MCP server
GET /api/v2/mcp/servers/{name} 按运行时名称获取单个 server
POST /api/v2/mcp/servers 向用户级 mcp.json 添加 server
PUT /api/v2/mcp/servers/{name} 替换一个用户级条目
DELETE /api/v2/mcp/servers/{name} 删除一个用户级条目
POST /api/v2/mcp/servers:test 对单个 server 发起真实连接探测
POST /api/v2/mcp/servers:inspect locator 寻址的目录及批量连接探测
GET /api/v2/mcp/auth-statuses 目录中各 server 的 OAuth 状态
POST /api/v2/mcp/auth:begin 开始一次交互式 OAuth 流程
POST /api/v2/mcp/auth:complete 等待浏览器回调并完成 code 交换
POST /api/v2/mcp/auth:cancel 终止已开始的 OAuth 流程
POST /api/v2/mcp/auth:reset 清除某个 server 已存储的凭据

该管理面有两种寻址方式。CRUD 路由与 servers:test 使用普通的运行时 name;检查与 OAuth 路由使用 locator——文件层条目用 { "source": "global", "name" },插件清单条目用 { "source": "plugin", "pluginId", "serverName" }——因为插件条目和文件条目可能共用同一个运行时名称。检查条目还带有一个稳定的 serverId 线上标识:global:<name>plugin:<pluginId>:<serverName>URL 编码)。

大多数路由接受可选的 cwd(查询参数,:-action 路由则为请求体字段)。不传时目录只覆盖用户级文件与插件清单;传入后,该目录的项目根层与项目本地层会并入——但仅当工作区受信任时,否则项目层会被跳过。对 stdio server 执行 servers:test 时,cwd 同时是子进程的工作目录。连接探测与 OAuth 调用会等待服务配置加载完成后再执行。

GET /api/v2/mcp/serversGET /api/v2/mcp/servers/{name}

列出管理面已知的全部 MCP server第二个路由返回该运行时名称对应的单个条目。

参数 位置 类型 说明
name path string 必填(仅 get server 的运行时名称
cwd query string 并入该(受信任)目录的项目层

成功时 data 是受管 server 数组get 路由为单个对象),每项为 { name, config, source, origin, mutable, plugin? }

  • sourceglobal(配置文件层)或 plugin(插件清单)

  • origin:条目的定义位置——文件路径或插件 id

  • mutable:只有用户级条目可变;插件与项目层条目均为只读

  • config:可变条目携带完整配置,便于编辑界面预填;只读条目被脱敏为排序后的键名列表(envKeys / headerKeys),绝不泄露密钥值

  • plugin{ id, name },仅插件条目携带

  • 40001:校验失败

  • 40408:不存在该名称的 server

POST / PUT / DELETE /api/v2/mcp/servers

针对用户级 mcp.json 的全局 CRUD。新增请求体是包含 name 的完整 server 配置——transportstdio / http / sse)决定配置形状,每条配置写入前都会校验。更新请求体携带同样的配置但不含 name(由路径指定条目);删除无请求体。三者都在 data 中返回刷新后的 server 列表。若写入与项目层的同名条目冲突,会因只读被拒绝——请改为编辑定义它的文件;与同名的插件条目冲突并不阻止写入,新的文件条目会将其遮蔽。

  • 40001:校验失败,或目标条目为只读
  • 40408:(更新/删除)不存在该名称的 server

POST /api/v2/mcp/servers:test

对单个 server 发起真实连接探测,不持久化任何内容。传 name 探测注册表条目(含插件与受信任的项目层),或传 server(包含 name 的完整内联配置)按原样探测;两者都传或都不传会报 40001

参数 位置 类型 说明
name body string 注册表条目的运行时名称
server body object 按原样探测的内联 server 配置
cwd body string 项目层并入解析;同时是 stdio 的工作目录

成功时 data{ success, output }:连接成功时 output 列出该 server 的可用工具,否则携带失败信息。

  • 40001:两种目标形式都传或都不传、内联配置无效,或运行时名称被多个启用的 server 共用
  • 40408:不存在该名称的 server

POST /api/v2/mcp/servers:inspect

locator 寻址的目录(脱敏配置),外加对每个 OAuth 候选的批量真实连接探测。

参数 位置 类型 说明
targets body array 缩小目录范围的 locator 数组;不传则检查全部 server
cwd body string 并入该(受信任)目录的项目层

成功时 data 是检查结果数组,每项为 { serverId, locator, runtimeName, canonicalUrl?, origin, config, enabled, editable, authStatus, checkedAt?, error? }canonicalUrl 是远程 server 的凭据 URLconfig 为脱敏视图,authStatus 取值为 not-applicable / bearer-token / oauth-required / oauth-authorized / oauth-expired / unavailable 之一。运行时名称被多个启用的 server 共用时无法无歧义地探测,会报告 unavailable 并在 error 中给出说明。探测遇到过期授权时,可能刷新或作废已存储的凭据。

  • 40001:校验失败
  • 40408targets 中有 locator 未匹配到任何条目

GET /api/v2/mcp/auth-statuses

注册表目录中各 server 的 OAuth 状态——只需要授权维度时,这是比 servers:inspect 更轻量的选择。

参数 位置 类型 说明
cwd query string 并入该(受信任)目录的项目层
verify query string true 对每个 OAuth 候选发起真实连接验证;false 完全离线(仅凭配置与已存储 token 分类);缺省保留隐式 OAuth 探测,只探测未固定且没有已存储凭据的远程 server

成功时 data{ name, authStatus } 数组,authStatus 取值与 servers:inspect 相同。验证探测可能刷新或作废已存储的凭据。

POST /api/v2/mcp/auth:begin / :complete / :cancel / :reset

远程 server 的 OAuth 流程生命周期。auth:begin 接受 locator 请求体(外加可选的 cwd 查询参数),返回 data{ status: "authorization-required", flowId, authorizationUrl }——在浏览器中打开该 URL 完成授权——或当授权已存在时返回 { status: "already-authorized" }。目标 server 必须使用远程传输(http / sse)且不含静态 bearer token静态请求头仅当配置显式设置 auth: "oauth" 时允许。

auth:complete 等待已开始流程的浏览器回调并完成 code 交换。请求体为 { flowId, timeoutMs? }:等待默认 15 分钟(timeoutMs 可覆盖),空闲流程无论如何都会在 15 分钟后过期,关闭 HTTP 连接会中止等待。成功时 datanull

auth:cancel 在未完成的情况下终止已开始的流程({ flowId });未知流程会被忽略。auth:reset 接受 locator 请求体,清除该 server 已存储的凭据——失效事件会送达存活的会话。

  • 40001:校验失败——包括 :completeflowId 未知,或 :begin 的 server 无法使用 OAuthstdio 传输、静态 bearer token或未设置 auth: "oauth" 的静态请求头)
  • 40408:begin / :resetlocator 未匹配到任何条目
  • 40929OAuth 流程本身失败

WebSocket 协议

建立连接

唯一端点是 ws://<host>:<port>/api/v1/ws;鉴权在升级请求时完成(见上文 鉴权)。连接建立后服务端立即发送 server_hello

{
  "type": "server_hello",
  "timestamp": "2026-01-01T00:00:00.000Z",
  "payload": {
    "ws_connection_id": "conn_01JZX4...",
    "protocol_version": 2,
    "max_event_buffer_size": 1000,
    "capabilities": { "event_batching": false, "compression": false }
  }
}

注意服务端不发送心跳,也不会主动断开空闲连接——保活与重连由客户端自己负责。

控制帧

客户端发送 JSON 帧 { "type", "id"?, "payload" };每个请求帧都会收到应答 { "type": "ack", "id", "code", "msg", "payload" }code0 表示成功。

payload 说明
subscribe { session_ids, cursors?, agent_filter? } 订阅会话事件;带 cursors(每会话 {seq, epoch})时回放错过的持久事件
unsubscribe { session_ids } 取消会话订阅
subscribe_v2 { session_id, transcript, transcript_since? } 订阅转录流(唯一的转录订阅通道),transcript 按 agent 指定粒度
unsubscribe_v2 { session_id, agent_ids? } 退订转录流;省略 agent_ids 表示整个会话
watch_fs_add / watch_fs_remove { session_id, paths, recursive? } 订阅 / 取消文件变更通知(event.fs.changed
client_hello { client_id } 握手帧,其余字段为遗留兼容

事件

事件帧形状为 { "type", "seq", "epoch"?, "volatile"?, "offset"?, "session_id"?, "timestamp", "payload" }type 即事件类型。按投递范围分两类:

  • 全局事件:发送到每个已建立连接,无需订阅——session.meta.updatedevent.session.createdevent.session.archivedevent.session.work_changedevent.session.status_changedevent.workspace.*event.config.*event.model_catalog.*
  • 会话事件:只发给订阅了该会话的连接,受 agent_filter 过滤。主要事件族:
事件族 主要事件
轮次 turn.startedturn.endedturn.step.started / completed / interrupted / retrying
流式文本 assistant.deltathinking.delta(带 offset 用于对齐)
工具调用 tool.call.startedtool.call.deltatool.progresstool.result
交互 event.approval.requested / resolvedevent.question.requested / answered / dismissed
subagent subagent.spawned / started / suspended / completed / failed
后台 task.started / terminatedshell.started / output / completed
其他 compaction.*skill.activatedgoal.updatedprompt.*errorwarning

有三个全局生命周期事件可以让跨工作区概览免掉逐工作区轮询。event.session.archived 在在线归档与冷归档两条路径上都会发出;其事件帧 session_id 是全局水位 __global__,真实会话 id 在 payload 里:{ "type": "event.session.archived", "workspace_id": "wd_...", "sessionId": "session_..." }payload 字段为 workspace_id / sessionId)。event.workspace.created / updated 携带完整工作区对象({ id, root, name, created_at, last_opened_at, session_count }——会话创建触碰工作区时也会发 updatedevent.workspace.deleted 携带 { "workspace_id", "root" }。这些事件只覆盖本服务进程内的变更;其他进程(例如写同一 home 目录的 CLI的变更要等索引 reconcile约一分钟才可见因此概览客户端应保留低频兜底轮询。目前没有会话删除事件。

事件另分持久与易失两种:持久事件带严格递增的 seq,落盘并可回放;易失事件(各 *.deltatool.progressshell.* 等)标 volatile: true,不回放。消费易失文本流时用 offset(该轮次内的累计字符偏移)与本地已累积文本比对:小于本地长度说明是重复帧,大于说明有缺漏、需走快照恢复。

断线恢复

重连后在 subscribecursors 里带上每个会话最后应用事件的 {seq, epoch}服务端会回放缺口落后超过缓冲1000 条)或游标失效时改为收到 resync_required。此时调用 GET /api/v1/sessions/{session_id}/snapshot 拿全量快照(含 as_of_seqepoch),再以新游标重新订阅。

转录协议

subscribe_v2transcript 按 agent 指定粒度:off / turn / block / delta(键 "*" 表示默认粒度),粒度越高推送越细。粒度非 off 的 agent 走两帧推送:transcript.reset(基线快照,历史经 REST 分页回读)和 transcript.ops(增量批次,带每个 agent 连续递增的 seq);该 agent 的旧式事件在同一连接上被抑制,改由转录帧承载。断线时用 transcript_since 续传服务端批次日志无法覆盖缺口时REST 补漏返回 complete: false需全量刷新。REST 侧对应 GET .../transcript(按轮次分页)与 GET .../transcript/ops?since_seq=(批次补漏)。

二进制与流式端点

以下端点返回二进制流而非 JSON 载荷,各端点的 HTTP 能力并不相同:

方法与路径 说明 Range 分段206 ETag / 304
GET /api/v1/files/{file_id} 下载已上传文件 支持 不支持(会发送 etag 头,但不处理 If-None-Match
GET /api/v1/sessions/{session_id}/fs/{path}:download 下载会话工作区文件 支持 支持
GET /api/v1/fs:content 读取本机任意文件(仅受 token 保护,谨慎暴露端口) 支持 支持
POST /api/v1/sessions/{session_id}/export 导出会话与诊断信息zip 流) 不支持 不支持

错误语义也不相同:GET /api/v1/files/{file_id} 对查找和存储失败返回真实 404 / 500 状态码(参数校验失败仍走 HTTP 200 信封),其余三个端点的所有失败都走标准 响应信封——客户端在这三个端点上仍需检查信封中的 code

下一步