接口参考(字段级)
两部分:MCP 协议端(你的服务器要实现的)与市场动作面(app 侧 market.* 工具,了解用户侧发生什么)。本文与 McpClient.kt / McpExtDiscovery.kt / McpMarket.kt 实现一致。
要点(30 秒)
- MCP 协议端(你的服务器要实现):tools/list、tools/call、鉴权、超时。
- 市场动作面(app 内 market.* 工具)。
- 错误码表(MARKET_*)。
- 安全约束(不可协商)。
展开全文(完整表格 / 代码 / 细节)
一、MCP 协议端(你的服务器要实现的)
传输
- 仅 HTTP POST;
Content-Type: application/json;建议同时带Accept: application/json, text/event-stream; - body 为 JSON-RPC 2.0;响应可以是纯 JSON,也可以是 SSE(
data: {...}行),两种都收; - 超时预算:连接 5s、读取 30s(
McpClient.kt常量);长任务请先应答再异步执行。
健康检查(安装 / 启用时必调)
POST <你的URL> body: {}
返回 200 或 405 即视为存活;其它状态码 / 超时 = 不可达,安装报 MARKET_SERVER_UNREACHABLE(配置保留,可重试)。
tools/list(发现)
→ {"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
← {"jsonrpc":"2.0","id":1,"result":{"tools":[ { ... } ]}}
| tools[] 字段 | 必填 | 说明 |
|---|---|---|
name | ✅ | 工具名,建议 领域.动作。命中保留黑名单(sms.read 等 7 个)不会被挂出。 |
description | ✅ 必须 | 给 AI 的工具说明。禁止占位——空/占位描述上架审核即打回。 |
inputSchema | ✅ 必须 | 参数 JSON Schema(类型/必填/描述),给 AI 的。空 Schema 上架审核即打回;MOV 内置面自 2026-08-29 起全量携带。 |
level | — | "readonly"(缺省)或 "write"。当前版本 write 不挂出(只读先行)。 |
tools/call(调用)
→ {"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"weather.now","arguments":{"city":"北京"}}}
← {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"..."}],"isError":false}}
建议返回 result.content(MCP 标准内容数组);result 内结构化数据会原样转给 AI。失败可返回 "isError": true + 文本说明。
鉴权(可选)
需要鉴权的服务:用户安装后在 app 内填 token,之后每个请求带 Authorization: Bearer <token>。目录登记 server.token 留空,不要把真实 token 写进目录。
二、市场动作面(app 内 market.* 工具)
全部经 app 工具面 tools/call 调用(调试:adb forward tcp:8389 tcp:8389 + Bearer token)。返回统一 {"ok": Boolean, ...},失败带 {"ok": false, "error": "<CODE>: <message>"}。
| 动作 | 入参 | 返回 / 行为 |
|---|---|---|
market.refresh | {"force": false} | 拉取/刷新目录;距上次成功拉取 <1h 直接回缓存(force 绕过)。→ {"ok":true,"packageCount":12,"fromCache":false,"updatedAt":"..."} |
market.list | {"cat": "可选筛选"} | 目录列表(含安装状态 installed/enabled 与 ui 值)。 |
market.install | {"id": "weather-demo"} | 健康检查 + 发现 + 热挂 ext.* 工具(同步调用,发现可能数秒)。→ {"ok":true,"serverId":"...","tools":["ext.xxx.a"]};不可达 → ok:false + MARKET_SERVER_UNREACHABLE(配置已写入,可重试)。 |
market.uninstall | {"id": "..."} | 仅 origin="market" 条目可卸(手动添加的拒绝)→ 删除 + 热摘除该服务器全部工具。→ {"ok":true,"removed":3} |
market.enable / market.disable | {"id": "..."} | 启停 = 重新发现热挂 / 热摘除。→ {"ok":true,"enabled":true,"tools":[...]} |
market.status | {"id": "可选"} | 健康状态(可达性 / 工具数 / 最近错误 / 检查时间)。 |
market.submit | 条目字段 + confirm:true | 提交上架(确认前不会提交)。网页提交见上架流程。 |
market.submitStatus | {"id": "..."} | → pending / rejected(附理由)/ approved。 |
命名细节:外部工具前缀 ext.<tag>.<name> 的 tag = 目录 name(空则用 id),非 [A-Za-z0-9_-] 字符转下划线。
三、错误码表(MARKET_*)
| code | 含义 / 触发 |
|---|---|
MARKET_REGISTRY_UNAVAILABLE | 目录拉取失败且无本地缓存 |
MARKET_PACKAGE_NOT_FOUND | install 的 id 不在目录里(declarative 缺剧本同码) |
MARKET_ID_CONFLICT | 与既有服务器 id 冲突(含手动添加的) |
MARKET_SERVER_UNREACHABLE | 健康检查失败或发现失败(配置保留,enable/重试可恢复) |
MARKET_NOT_MARKET_ORIGIN | uninstall 目标是手动添加的服务器 |
MARKET_NOT_INSTALLED | enable/disable/status 的 id 未安装 |
工具执行层通用错误(16 类单源表)见开发规范 · 四。
四、安全约束(不可协商)
- 目录与你的服务必须 https(app 全局禁明文,仅放行回环供调试);
- 外部工具继承权限分级:readonly 默认放行;write 需用户显式开启(当前版本 write 不挂出);
- 保留黑名单工具外部服务器永远不可达;
- token 仅存用户本地,
market.list/status等任何响应不含 token。