0025-mcp-spec-features.md 2.9 KB

ADR-0025 按 MCP 规范补齐工具以外的能力

  • 状态:Accepted · 日期:2026-10-29 · 补充 ADR-0021 · 设计见 16-mcp-support,接入指南见 mcp-guide

背景

网关(ADR-0021)只用到了 MCP 的工具部分:工具提示只认只读,结构化结果在有文本时被丢弃,没有长任务、询问用户、OAuth、资源与提示模板。业务方的 MCP 工具有运行一小时以上的作业,原来的做法是拆成"触发"和"查询"两个工具让模型轮询,既花 token 又不可靠;后台调用(docs/design/15)保持连接等待,服务重启或断线就失败。

决策

  • 只实现规范中定义的机制,不自定义协议字段。 曾考虑在工具结果里约定 async_job 字段由平台代为轮询,放弃:MCP 2025-11-25 已有 Tasks,自定义字段只在本平台有效。
  • 长任务用 MCP Tasks,与后台调用合并为同一套记录、唤醒、取消与界面,只多一个"等待方式"。服务不支持 Tasks 时仍按原来的方式保持连接等待。Tasks 在规范中是实验性的,相关代码集中在 mcp-gateway/tasks.ts。
  • 破坏性提示只认明确声明的 true:规范中非只读工具的 destructiveHint 默认为 true,若据此强制审批,所有没写提示的工具在自动模式下都要审批。明确声明的工具默认"总是审批";管理员可以逐个工具覆盖提示。
  • 询问用户(Elicitation)必须能确定属于哪个会话:规范的询问请求不带发起调用的信息,因此 HTTP 服务按"服务 × 会话"建立连接;本地进程只在连接上的调用都属于同一个会话时才接受询问,否则拒绝。长任务中的询问按任务 id 找发起方。
  • OAuth 按服务共享:管理员授权一次,所有会话共用这个账号,与请求头令牌一致;不引入"终端使用者"概念(01-requirements 中明确不做)。
  • 资源由模型按需读取,或由用户附加;不做 Profile 固定附加与资源订阅。提示模板展开后放进输入框,由用户修改后发送。
  • 不做 Sampling(服务借用平台的模型):花平台的 token,外部服务可以借此驱动模型,安全与费用难以控制。

后果

  • interactions 增加 form 类交互,runId 可以为空;Agent API / Bot API 的回复增加 { action, content },<InteractionCard> 增加表单与网址卡片。
  • 后台调用增加 mode、任务 id 等字段;长任务在服务重启后继续查询(前提是服务按认证身份而不是 MCP 会话归属任务)。
  • HTTP 服务的连接数从"每个服务一个"变为"每个服务 × 会话一个"(空闲 10 分钟关闭);长任务进行中占用的连接不关闭。
  • 新增《MCP 接入指南》与参考服务 examples/mcp-reference-server,测试 mcp-reference.test.ts 保证两者与平台一致。