跳到正文
工程约 3 分钟

扩展协议

L0 探测与 L1 MCP 会话:线格式、状态机、不变量与限制。

更新于 2025年11月6日约 3 分钟编辑此页
本页目录

这是 MCP 宿主(Lumo)与任何提供工具的 Chrome 扩展之间的契约。它只有两层:一条回答「提供方是否可用」的自定义消息,以及其余全部走标准 MCP。

两层结构#

MCP 的 initialize 无法在不失败握手的情况下表达「已安装但关闭」或「未授权」,宿主也就无法告诉用户该修什么。L0 用来表达这些状态;L1 保持完全标准。

L0 请求(chrome.runtime.sendMessage)json
{  "channel": "lumo:probe",  "version": 1,  "id": "probe-42",  "client": { "id": "<lumo extension id>", "name": "Lumo", "version": "1.0.19" }}
L0 响应——策略失败时 ok 仍为 truejson
{  "ok": true,  "service": { "namespace": "userscripts", "name": "Lumo Userscripts", "version": "1.0.1" },  "status": {    "enabled": true,    "authorized": false,    "ready": true,    "pendingApproval": true  }}

第 1 层:运行端口上的 MCP#

  • 端口名固定为 lumo:mcp,探测频道固定为 lumo:probe。
  • JSON-RPC、initialize、能力协商、tools/list 与 tools/call 都由双方官方 MCP SDK 处理。
  • 端口关闭不等于服务消失:MV3 可能回收 service worker。宿主保留逻辑会话与工具缓存,下一次调用时懒重连。
  • 重连会重新执行 initialize。提供方为每个端口新建 McpServer,不能复用旧的初始化结果。

状态机#

探测结果宿主状态用户可见结果
sendMessage 拒绝error扩展未安装,或没有智能体端点。
1500ms 超时error原始错误信息。
ok: falseerror协议错误信息。
缺少 service 或 statuserror探测响应不完整。
enabled: falseerror提供方中的智能体访问已关闭。
authorized: false + 待审批error正在提供方中等待你的批准。
authorized: falseerror调用方不在允许列表。
ready: falseerror提供方自己的原因说明。
全部通过connected工具出现,并显示数量。

不变量#

  1. 名称与版本固定:lumo:probe、lumo:mcp、探测版本 1。
  2. isExtensionId() 是唯一的 ID 判据:/^[a-p]{32}$/。所有输入路径都必须经过它。
  3. 策略失败时探测仍返回 ok: true;只有协议失败才返回 ok: false。
  4. 授权比较 sender.id。client.name 与 service.name 只用于展示。
  5. L1 需要同时满足 enabled && authorized。ready 描述能力,不是权限。
  6. 提供方在每次工具调用时重新校验策略,因此开关立即生效。
  7. 端口关闭不代表服务被删除;重连必须重新初始化。
  8. L0 只携带元数据,工具与业务数据在授权后只走 L1。

工具命名空间与限制#

规则值原因
单提供方工具上限64保持模型可见目录有界。
命名空间长度≤ 16给工具名留出空间。
工具名长度≤ 40提供方侧约束。
合计长度≤ 57低于 OpenAI function name 的 64 字符上限。
保留命名空间browser、page、file、network、devtools、webmcp、ext避免与内置工具冲突。
重名处理先到先得绝不静默覆盖其他服务的工具。

审计与限流#

  • 每次写入记录工具名、发送方 ID、结果、目标 UUID 与参数哈希。
  • 脚本源码永远不会进入审计日志。
  • 写入按调用方使用滑动窗口:每 60 秒 30 次。
  • 业务失败以 isError: true 的成功 MCP 调用返回,让模型读到原因,而不是丢掉整轮。

不要随意放宽这些限制

57 字符合计来自硬性的提供方上限。未经核对所有模型集成就提高命名空间或工具预算,会让工具调用以「模型失败」的形态坏掉。

实现一个提供方#

  1. 1

    声明边界

    在 manifest 中添加 externally_connectable。宿主未打包时 ID 每次安装都会变,因此需要 ids: ['*']。

  2. 2

    同步注册两个监听器

    在 background 顶层调用 chrome.runtime.onMessageExternal 与 onConnectExternal,不要放进异步回调。

  3. 3

    写一个带缓冲的 Transport

    在端口上实现 MCP Transport 接口,并在授权完成前缓冲入站消息。

  4. 4

    每个端口一个服务

    用官方 SDK 注册工具,并按当前策略生成 instructions。

  5. 5

    持久化并复核策略

    保存端点、允许列表、写入与复核开关;每次工具调用开始时重新解析。

Lumo Userscripts 是参考实现:lib/agent/protocol.ts、probe.ts、transport.ts、mcp-server.ts、tools.ts、policy.ts 与 audit.ts。宿主侧位于 lib/mcp/extension-*.ts。