第 10 章 第三部分:多代理与协作

MCP 协议集成

6 种传输方式、工具注册与调用、MCP Server 配置管理、错误处理与重连——Claude Code 的外部扩展接口

Claude Code MCP Model Context Protocol 传输层 工具扩展

10.1 MCP 的角色

MCP(Model Context Protocol)是 Anthropic 推出的开放协议,定义了 AI 模型与外部工具之间的通信标准。在 Claude Code 中,MCP 承担两个角色:

  1. 作为客户端:Claude Code 连接外部 MCP Server,获取它们提供的工具
  2. 作为服务器:Claude Code 自身可以作为 MCP Server 运行,将 42+ 内置工具暴露给其他客户端

这种双重角色使 Claude Code 既是一个强大的终端工具,也是一个可被其他 AI 系统调用的”工具服务器”——比如让 GPT-4 通过 MCP 调用 Claude Code 的文件编辑和代码搜索工具。

10.2 六种传输方式

Claude Code 的 MCP 客户端支持 6 种传输方式,覆盖了几乎所有的进程间通信场景:

传输方式适用场景实现特点
stdio本地进程间通信StdioClientTransport最常用,零网络开销
SSE服务器推送事件SSEClientTransport单向推送,兼容性好
HTTPREST API 风格StreamableHTTPClientTransport无状态,易于部署
WebSocket双向实时通信WebSocketTransport全双工,低延迟
Streamable HTTP流式 HTTP + 无状态操作内置支持长连接流式传输,支持水平扩展
直连进程内通信SDK 内部使用零序列化开销

配置存储在 settings.json 中:

{
  "mcpServers": {
    "server-name": {
      "command": "path/to/server",
      "args": ["--arg"],
      "env": { "KEY": "value" }
    }
  }
}

源码引用:MCP 客户端核心位于 src/services/mcp/client.ts,WebSocket 传输参见 WebSocketTransport.ts。

Streamable HTTP 的 2026 演进。MCP 2026 路线图将 Streamable HTTP 定位为从本地子进程到远程云服务的关键转变。核心演进方向:

  • 无状态操作:支持负载均衡器和反向代理后的水平扩展,每次请求可路由到不同后端实例
  • SEP-2243 HTTP Header 标准化:新增 Mcp-Method 和 Mcp-Name 标准 HTTP 头,让网络中间件(WAF、代理、负载均衡器)无需深度包检测即可路由 MCP 流量
  • 会话管理标准化:会话创建、恢复、迁移的标准化协议,支持有状态操作在无状态基础设施上运行
  • 连接复用优化(2026 年新增):HTTP/2 多路复用支持,单个 TCP 连接承载多个 MCP 请求/响应,减少连接建立开销;与 STDIO 的零网络开销相比,Streamable HTTP 通过连接复用将延迟差距缩小到毫秒级

MCP 协议已达 10,000+ 公共 Server,9700 万安装量,Streamable HTTP 的无状态化是企业级部署的基础前提。

📌 生态规模更新(截至 2026-07-28 官方发布日):上面两组数字是更早时点的快照,与当前量级已不在一个数量级。官方发布博文原文为:“Across our Tier 1 SDKs, we’re seeing close to half-a-billion downloads a month, with both TypeScript and Python SDKs crossing the 1 billion total downloads threshold.”

  • Tier 1 SDK(TypeScript / Python / Go / C#)月下载量接近 5 亿次
  • TypeScript 与 Python SDK 各自累计下载量突破 10 亿
  • 四个 Tier 1 SDK 在发布当天即支持 2026-07-28;Tier 1 之外的 Rust SDK 以 beta 支持
  • AWS、Google Cloud、Microsoft Foundry、Cloudflare(Agents SDK day-zero)为发布背书;Claude 与 Claude Desktop 已是支持渲染 MCP Apps 的宿主之一

从”9700 万安装量”到”月下载 5 亿”的跨度说明:用绝对安装量衡量 MCP 的规模会持续低估。更稳定的观察指标是下载速率(每月多少次)而非累计量。

2026-10 中旬再补两个数字——但重点在于它们对不上。 上面两组(10,000+、9,700 万)应明确标为过时快照。本轮回源到的两个第三方口径:

来源枚举日数字口径
forkast 报道2026-10-1342,753官方 MCP Registry 的服务器数
RepoGates 枚举2026-10-05 / 0639,653官方 Registry 134,056 条版本记录去重后的服务器数

⚠️ 两者都指向官方 Registry,却在相隔约一周的两次枚举中差 7.8%。 这不一定是某一方出错,而是说明”服务器数”这个量本身就依赖枚举口径(按版本记录还是按命名空间、是否剔除归档、是否合并近似拼写)。因此本章的方法论要从一句扩成两句:① 用下载速率而非累计量(上面已有);② 用同一份目录的同一口径做纵向比较——跨来源、甚至跨日期的数字不能相减、不能平均,更不能当作增长率的分母。

比总数更有用的是同一份枚举里的结构性数字(RepoGates):27.0%(10,694 个)未声明任何代码仓库;57.7% 只提供远程 URL、没有可检视的代码;声明了 GitHub 仓库的 28,911 个(72.9%)实际只解析到 23,309 个不同的仓库——多个服务器共用同一个仓库。合起来一句话:“有仓库可审”这件事最多只能覆盖到 72.9%,其中还有相当一部分是共享的 monorepo。这比”生态有多大”更能支撑本章后面关于 MCP 安全的论述。⚠️ 官方 Registry 自身的 census 本轮仍未回源,上述两项均为第三方数字,不得当作官方口径引用。

10.2.1 无状态迁移:MCP 协议的最大架构变更

MCP 2026-07-28 规范(2026-05-21 发布 Release Candidate,2026-07-28 正式发布并 GA)确定了无状态迁移方向,这是 MCP 协议自发布以来最大的架构变更。官方发布博文的原话是 “Today, we’re officially pushing the release button on the next version of the MCP specification, 2026-07-28”——本书此前把若干结论挂在「RC 尚未定稿」的前提下,定稿后这些结论应改写为陈述句。核心变更:

1. 消除 Mcp-Session-Id:服务器不再维护会话状态,每次请求必须自包含所有必要信息。这意味着:

  • 不再有”连接→初始化→会话→断开”的有状态生命周期
  • 每次请求携带完整的调用上下文,服务器无需记住前序交互

2. 新增必选 HTTP 头:

必选头作用示例
Mcp-Method声明调用方法tools/call, resources/read
Mcp-Name标识工具/资源/提示的完整名称mcp__github__create_issue

这两个头让网络中间件(WAF、代理、负载均衡器)无需深度包检测即可路由 MCP 流量,是实现水平扩展的前提。

3. 缓存控制:ttlMs + cacheScope 控制 list 结果的缓存策略:

  • ttlMs:缓存 TTL(毫秒),减少重复 list 调用
  • cacheScope:缓存作用域(client/server),控制缓存共享范围

4. Tasks 移至扩展:异步长时任务不再是核心协议,移至扩展 io.modelcontextprotocol/tasks。这简化了核心协议的复杂度,使无状态模型更一致。正式的扩展框架一并收编了 MCP Apps 与 Enterprise Managed Authorization(EMA)——扩展而非核心,是 2026-07-28 之后 MCP 新增能力的主要落点。

在正式版中,Tasks 的 API 形态也做了重构:客户端侧改为轮询式的 tasks/get 与新增的 tasks/update(SEP-2663);变更通知也从旧的 HTTP GET 端点改为单一的 subscriptions/listen 流,客户端按通知类型逐个订阅。官方随 SDK 提供了 “breaking bits” 的迁移说明——换言之,按 2025-11-25 实验版实现过 Tasks 的读者,不要沿用实验期的 API 假设,应直接回官方 migration notes 核对方法集。

迁移路径:有状态→无状态的过渡期,Claude Code v2.1.152 已支持无状态模式。现有代码中 McpSessionExpiredError(HTTP 404 + JSON-RPC -32001)的处理逻辑将逐步被新的无状态重试机制替代。

“已支持”已经在主要通道上变成”默认协商”(v2.1.292 → 2.1.295 → 2.1.299)。 上面那句停留在”有能力”与”过渡期”,2026 年 10 月的三条把它推进到事实默认,而且是按通道分三批完成的:

通道版本变更
本地(stdio) MCP 服务器连接(含 Bedrock / Vertex / Foundry)v2.1.292(2026-10-06)在所有安装上默认协商协议版本 2026-07-28
claude.ai connectorsv2.1.295(2026-10-08)默认协商 2026-07-28(限不拉取 feature flag 的安装)
云端会话与 Remote Control 的 MCP connectorsv2.1.299(2026-10-14)默认协商 2026-07-28

三点必须写准。其一,三批按通道分先后,不是一次性切换:按”v2.1.292 起全部默认”去理解,会在 claude.ai connectors 与云端会话上判断错——它们分别晚了 2 天和 8 天。其二,三处共用同一个退出开关 MCP_PROTOCOL_NEGOTIATION=legacy,这是本节唯一需要的实操信息。其三,因此”已支持”应改写为”在主要通道上已成为默认”,“逐步”只用于描述尚未覆盖的通道——以及 v2.1.295 那条明确限定的”不拉 flag 的安装”这一例外。

社区迁移操作指南(ContextStudios 2026-06 整理)。从有状态到无状态的迁移不仅是协议层面的变化,更涉及基础设施配置的隐藏假设。建议按以下顺序操作:

  1. 库存盘点——grep 代码库和基础设施中所有 session_id / SSE endpoint / sticky routing 引用。关键警告:大多数有状态假设隐藏在负载均衡器/网关配置中(如 AWS ALB 的 sticky session、Cloudflare 的 session affinity),而非应用代码——这些配置如果不显式禁用,会让无状态 Server 仍然按有状态路由,造成”无状态但实际有状态”的诡异 bug。
  2. 分支原型——使用 mcp==2.0.0b1(Python)或 @modelcontextprotocol/server(TypeScript beta 包)搭建原型,不触及生产流量。验证清单:每个 tools/call 是否都包含完整 _meta?server/discover 返回的能力集是否与会话建立时一致?per-request 授权检查是否覆盖了所有工具?
  3. 负载均衡测试——验证请求在多实例间真正存活(不只是”看起来能路由”),监控每个实例的内存/CPU 分布(无状态后应均匀分布)。
  4. per-request 授权迁移——将授权从连接建立时移至每次请求路径。这是最大的代码改动点:从”会话级 RBAC 缓存”改为”请求级 JWT 验证 + 上下文对象重建”。

v1 回退方案保留至稳定 SDK 发布。ContextStudios 建议的兼容策略:保持 v1 server 端代码并行运行 12 个月(与 SEP-2596 弃用窗口一致),v1 客户端流量通过翻译层(translation proxy)桥接到 v2 server。这样即使客户端还没升级,服务端可以独立完成无状态改造。

MRTR:无状态交互的核心机制。会话概念消失后,Server 如何向 Client 发起交互(如弹窗请求用户输入)?答案是 Multi Round-Trip Requests(MRTR / SEP-2322)。

MRTR 的运作方式:

  1. Server 在处理请求时发现需要用户输入,返回 InputRequiredResult——包含 inputRequests(描述需要哪些输入)和 Base64 编码的 requestState(加密的状态快照)
  2. Client 收到后,收集用户回复(如弹窗表单)
  3. Client 重新发起原始请求,这次附带用户输入——requestState 让任何实例都能恢复上下文后继续处理

核心设计思想:请求-响应-重试循环替代了有状态模型下的 SSE 流保持。关键对比:

维度有状态模型(旧)MRTR 无状态模型(新)
交互方式SSE 流保持连接,Server 在流中推送请求→响应(InputRequired)→重新请求
状态存储Server 内存中维护上下文requestState 自包含在响应中
负载均衡必须路由到同一实例任何实例都能处理重试请求
弹性实例崩溃→交互中断真正的无状态弹性

与 Tasks(10.7 节)的关系:MRTR 是请求内弹窗(elicitation),Tasks 是跨请求的后台工作。MRTR 发生在一次用户请求的处理过程中,Tasks 则独立于用户请求生命周期运行。

向后兼容那一侧:老协议的 URL prompt 也支持,但要一个显式开关(v2.1.287,2026-10-01)。 MRTR 是新协议(2026-07-28)的机制;老协议(2025-11-25)上的 elicitation 走的是另一条路,官方把它也补上了:新增来自 2025-11-25 协议 MCP 服务器的 URL prompts(例如用于登录)。官方 changelog 逐字:

Added URL prompts from MCP servers on the 2025-11-25 protocol, for example to sign in. If a server no longer connects after this update, add "bareElicitationCapability": true to its MCP config entry

后半句是本条最实用的部分:升级后某个服务器连不上了,第一检查项是在它的 MCP 配置条目里加 "bareElicitationCapability": true。这是一条”协议能力探测失败 → 连接失败”的故障链,症状看起来像网络或认证问题,实际是客户端对该服务器 elicitation 能力的假设变了。

服务器能问了,客户端怎么拦。 MRTR 解决的是”无状态服务器上 elicitation 还能不能用”,是协议侧的能力;与之配套的还有客户端侧的拦截面,此前本章完全没写。官方 hooks 为此给了两个事件:Elicitation(MCP 服务器在工具调用过程中请求用户输入时触发)与 ElicitationResult(用户响应后、回传给服务器之前)。两者的 matcher 都是 MCP 服务器名;hookSpecificOutput 支持 action(accept / decline / cancel)与 content(表单字段值,后者可用于改写)。v2.1.284 之前,{"decision":"block"} 在这两个事件上会被静默忽略——现在它会拒绝该次 elicitation,效果等同退出码 2;ElicitationResult 上的 block 则把 action 变成 decline。还有一处 33 个事件里的唯一例外值得记住:这两个事件在退出码 2 时 hookSpecificOutput 会被忽略,其余 31 个事件都不会这样。配套的 Notification 事件新增了四个 type:elicitation_dialog、elicitation_url_dialog、elicitation_complete、elicitation_response。完整事件表见 Ch11。

协议级 Breaking Changes 完整清单。MCP 2026-07-28 规范(已 GA)的变更量看似庞大,但绝大多数是向后兼容的。严格 breaking 的仅两项:

变更影响SEP
① 资源错误码 -32002 → -32602(标准 JSON-RPC)任何硬编码 -32002 的客户端/服务端需更新SEP-2164
② inputSchema/outputSchema 全面支持 JSON Schema 2020-12使用了自定义 schema 验证逻辑的服务端需验证SEP-2106

此外,3 项原语被标记为 deprecation(12 个月窗口至 2027-07-28):

  • roots/*(Resources roots)
  • sampling/*(LLM Sampling)
  • logging/*(Logging)

其余变更——包括无状态迁移、MRTR、Tasks 移至扩展——均为向后兼容或通过 _meta/server/discover 平滑过渡。一个经常被忽略的关键事实:对大多数 Server 作者而言,迁移工作量远比头条标题暗示的要小。如果你的 Server 只是简单地注册工具、返回结构化输出,很可能零改动即可兼容新协议。

📌 口径补充:上面「仅两项严格 breaking」是对核心协议而言,且隐含一个基线前提。若你的实现此前已按 2025-11-25 版做过 Tasks 实验性支持,那么 Tasks 的方法集改写对你同样是破坏性的。判断「是否 breaking」要先问基线版本是哪个——从 2025-06-18 直接跳到 2026-07-28,与从 2025-11-25 跳过来,答案并不相同。这也是官方把「正式弃用政策」写进本版的原因:弃用不再是随口宣布,而是带至少 12 个月的最短窗口,让实现方可以计划升级而不是被动应对。

对传输方式的影响:

传输方式无状态兼容性协议生命周期说明
stdio✅现行本地进程,无状态影响最小
SSE⚠️⚠️ 2025-03-26 起已弃用单向推送模式与无状态有冲突;legacy HTTP+SSE 传输已正式弃用(见下方时间线订正)
HTTP✅现行天然无状态,最易适配
WebSocket❌现行全双工有状态连接,迁移复杂度最高
Streamable HTTP✅✅ 首选设计目标即为无状态,首选方案
直连✅现行进程内通信,无状态影响最小

新增的「协议生命周期」一列是本表原先缺失的维度:兼容性回答的是能不能迁移,生命周期回答的是还值不值得投入。官方在 2026-07-28 的弃用清单中写得很明确——“The legacy HTTP+SSE transport is also considered to be officially deprecated, with a year-long offramp.” 它和 Roots/Sampling/Logging 是两条并列的弃用条目,共同受「至少 12 个月最短窗口」的正式弃用政策约束;但二者性质不同:前者是传输层,后者是原语。(⚠️ 此句已被下方订正段推翻:回官方弃用特性登记表核验,SSE 与三项原语不在同一条时间线上,不得按本句单独引用。)把 SSE 标注为「兼容性好」而不标注「已弃用」,会让读者在新建集成时选错方向。

⚠️ 但”共同受至少 12 个月窗口约束”这句要订正:SSE 与 Roots/Sampling/Logging 不是同一条时间线。 回官方弃用特性登记表(modelcontextprotocol.io/specification/2026-07-28/deprecated)逐条核对:

弃用项弃用 SEP弃用于迁移路径最早移除
Roots / Sampling / LoggingSEP-25772026-07-28见 10.7 节2027-07-28 或之后发布的修订版
includeContext: "thisServer" / "allServers"SEP-25962025-11-25省略该字段或用 "none"跟随 Sampling(SEP-2577)
HTTP+SSE 传输SEP-25962025-03-26Streamable HTTPSEP-2596 达 Final 后三个月

三处差别必须写准。其一,SSE 的弃用时间是 2025-03-26,比另外三项原语早了一年多——2026-07-28 只是把它重新归类进正式生命周期。登记表原文逐字:“The HTTP+SSE transport and the includeContext values were already described as deprecated before the lifecycle policy existed; SEP-2596 reclassifies them as Deprecated under its transition provisions”。其二,SSE 的最早移除条件是”SEP-2596 达 Final 后三个月”,与 2027-07-28 那条不是一回事。其三,两条官方口径并不一致——发布博文写的是 “with a year-long offramp”,登记表写的是三个月;本章并列记录,不做换算。

工程含义很直接:规划一个新的远程集成时,SSE 的可用余量要与另外三项原语分开评估,不能共用一张时间表。相比之下 10.2 表格里”HTTP 与 SSE 存在协商回退”那条因此更值得警惕——回退的目标是一个弃用时间更早、移除条件独立的传输。

HTTP 与 SSE 并非纯并列,而是存在协商回退。Claude Code v2.1.265(2026-09-08)修复了一个长期存在的问题:配置为 http 但只支持 legacy HTTP+SSE 传输的 MCP 服务器此前永远连不上,现在 Claude Code 按 MCP 规范描述回退到 SSE。这条修复揭示了一个容易被表格掩盖的事实——传输方式的选择在运行时是可降级的。当你在 .mcp.json 里写 "type": "http" 时,实际建立的不一定是 Streamable HTTP 会话;服务端能力不足时会自动降级到 SSE。这也意味着:如果日志里出现 SSE 行为而你明明配的是 HTTP,那不是配置没生效,而是回退发生了。

10.3 MCP 工具与内置工具的统一

MCP 工具在 assembleToolPool 中与内置工具合并(第 5 章已介绍工具池装配)。合并规则:

  1. 内置优先:如果 MCP Server 提供了一个与内置工具同名的工具,内置版本被保留
  2. 排序稳定:内置工具和 MCP 工具各自按名称排序,确保工具列表在 System Prompt 中的顺序稳定(利于 Prompt Caching)
  3. 权限统一:MCP 工具沿用内置工具的权限系统

⚠️ “排序稳定”是版本内稳定,不是跨版本稳定(v2.1.293,2026-10-07)。 官方 changelog 逐字:“Changed the order of agent lists and of MCP servers announced to the model: names with non-ASCII characters now sort after ASCII names”。排序规则本身是可变的:这次变更之后,所有含非 ASCII 名的 agent 与 MCP 服务器在升级后会整体重排,进而打掉提示缓存。写法上要把第 2 条理解为”同一版本内顺序确定”,而不是”顺序永远不变”。

这一条还把排序从”利于缓存的正面因素”翻出了一面:它同时是一个前缀扰动源。凡工具名或服务器名含非 ASCII 字符的环境,升级 v2.1.293 之后第一次 /cost 的缓存命中率下降,都可以先怀疑这里(与 6.2.1 的前缀扰动表同源:工具列表顺序变化属于”公告/上下文被重发或移出前缀”一类)。

MCP 工具的权限可以在三个粒度上配置:

mcp__server1            → 控制 server1 的所有工具
mcp__server1__tool1     → 控制 server1 的特定工具
mcp__*                  → 控制所有 MCP 工具

这种层次化的权限配置让企业管理员可以对 MCP 工具施加和内置工具同等严格的安全控制。

服务器名是怎么被匹配的:从前缀匹配收紧为完整名称匹配(v2.1.299)。 上面三种写法没有说明匹配语义,官方把它收紧了。changelog 逐字:

Changed MCP allow rules to reach only the server they name: mcp__a no longer allows a server named a__b or a_; write mcp__<server>__* with the server’s whole normalized name

Changed agent tools: lists to take only the named MCP server’s tools; list a server whose name contains __ as mcp__<whole name>__*

两条是同一次收紧的两个落点:allow 规则与 agent 的 tools: 列表都只作用于其命名的那个服务器,不再向前缀延伸。名字里含 __ 的服务器要写 mcp__<完整名称>__*。

⚠️ 症状方向要写准:这是收紧,表现不是”防护消失了”,而是”原本能用的工具突然开始要授权”。命名有嵌套或近似前缀(a / a__b / a_)的环境升级后最容易踩到。(与第 7 章同批的 MCP 规则收紧同源。)

第三个配置层级:组织级托管服务器。上面的讨论隐含一个前提——MCP 服务器是用户自己在 settings.json 或 .mcp.json 里添加的。v2.1.259(2026-09-02)引入的 managedMcpServers 打破了这个前提:组织可以向每个用户提供 HTTP/SSE 类型的 MCP 服务器,条目格式与 .mcp.json 相同,但来源是组织而非用户。注意一个硬约束:声明了 command 的条目会被跳过——托管通道只下发远程服务器,本地子进程的启动权仍然留给用户自己。

于是 MCP 服务器的来源从两层变成三层:用户级 mcpServers → 项目级 .mcp.json → 组织级 managedMcpServers。权限配置的粒度没有变,但“谁能往工具池里塞东西”这个问题的答案变了。

⚠️ 一次静默的权限放宽:同一个 v2.1.259 把 allowedMcpServers 的语义收窄为只管用户自己添加的服务器。此前被 allowlist 过滤掉的 managed-mcp.json 服务器,在升级后会被加载。如果组织原本依赖 allowlist 屏蔽某些托管服务器,升级后这道防线消失了——必须改用 deniedMcpServers 才能继续屏蔽。

这类变更的危险之处在于它不产生任何错误、不改动任何配置文件,只是让原本不加载的东西开始加载。从 allowlist(默认拒绝)到 denylist(默认允许)的切换,在安全工程里是方向性的倒退,而它藏在一个小版本号里。升级到 v2.1.259 及之后的所有管理员都应复核这份名单。

该改用什么:三个确切的托管开关名。 上面只用 allowedMcpServers / deniedMcpServers 两个泛名,实际官方在 v2.1.273 一次性给出了三个具体字段名:allowManagedMcpServersOnly(只允许托管服务器,比 allowlist 更强的语义——它把默认态从”允许”翻回”拒绝”)、deniedMcpServers、disableClaudeAiConnectors。同版本还修了一个会让这三者整体失效的问题:经 MDM 或 managed-settings.json 设置的这三个开关,在同时存在 server-managed settings 时会被忽略——也就是说,你已经配好了屏蔽,却因为多了一份服务端下发设置而静默不生效,症状与上面那次放宽完全一样。

另有两条与独占控制相关:v2.1.271 起,企业 managed-mcp.json 不可读或不可解析时不再被忽略——它保持独占的 MCP 控制(用户、项目与插件服务器都不加载)并在启动时告警,而不是退回”读不到就当没有”;v2.1.282 新增 allowClaudeInChromeWithManagedMcp,让 claude --chrome 能与独占的 managed-mcp.json 共存,被拦截时给出的错误也会指名这个开关。

第四层约束:不是”谁加的”,而是”叫什么名字”(v2.1.285,2026-09-29)。 上面三层讲的都是来源——谁能往工具池里塞东西。这条加的是另一层:名字本身也可以被系统占用。官方 changelog 逐字:

Changed the MCP server name widgets to be reserved in cloud sessions and on self-hosted runners: your own server under it, or a close spelling such as widgets_, no longer loads, so rename it

两个限定要写全:① 作用域是云端会话与 self-hosted runner,不是所有环境;② 被挡的不只是同名,widgets_ 这类近似拼写同样不加载,处理办法只有一个——改名。

这是本章第一次出现命名空间级的限制,它与 v2.1.299 的服务器名匹配收紧(见上文)是同一条线的两端:一个管”你的名字会不会撞上系统保留字”,另一个管”你写的规则能不能命中你想命中的服务器”。两者加起来说明一件事——MCP 服务器名已经不再是一个纯自由的标识符。

10.3.1 Tool Search 懒加载

当 MCP Server 数量增多时,工具描述可能占据大量上下文空间。Claude Code 在 2026 年初引入了 MCP Tool Search 功能:当 MCP 工具描述超过上下文窗口的 10% 时,自动从全量加载模式切换为按需搜索模式。

懒加载的三阶段架构:

  1. 轻量搜索索引:仅为每个工具构建名称+简短描述的索引,而非加载完整工具定义
  2. 按需语义搜索:当模型需要使用 MCP 工具时,基于当前任务语义搜索相关工具
  3. 只加载相关工具定义:仅将匹配的工具完整定义注入上下文

内部测试数据(VentureBeat 报道):

指标全量加载Tool Search变化
Token 占用~134k~5k-85%
Opus 4 MCP 评测准确率49%74%+25pp

这一架构变更说明:工具注册从”全量注入”向”按需检索”演进,与搜索引擎从全量扫描到倒排索引的演进路径类似。当工具生态达到数千个时,懒加载不再是优化项,而是可用性的前提。

除了自动切换,还可以自己声明,而且是两级、方向相反(v2.1.285 / v2.1.287)。 上面讲的 10% 阈值是全局自动机制,无法指定”这个服务器必须常驻”或”这个工具必须延迟”。2026 年 9 月底的两条补上了声明式那一半:

级别写法版本效果
服务器级MCP 服务器配置里 alwaysLoad: falsev2.1.287(2026-10-01)把该服务器的所有工具推迟到 tool search 之后
工具级工具自设 _meta['anthropic/alwaysLoad']: falsev2.1.285(2026-09-29)即使其 --mcp-config、Agent SDK 或插件服务器被设为 alwaysLoad,该工具仍保持 deferred

官方 changelog 逐字(工具级那条):“Changed MCP tools so a tool that sets its own _meta['anthropic/alwaysLoad'] to false stays deferred when its --mcp-config, Agent SDK or plugin server is set to alwaysLoad”。

两级的方向相反,这是本条的核心:服务器级 false 是”把整台服务器推走”,工具级 false 是”压过服务器级的常驻决定”——后者能覆盖前者,且优先级更高。合起来的结果是:Tool Search 从一个自动开关,变成一个可逐服务器、逐工具声明的策略层。

把它与 10.7.3 路线图的 progressive discovery 对读,两者是同一问题的两端:本章客户端侧的按需检索(Tool Search,本节)与官方规划的服务器侧按需暴露(progressive discovery),中间现在还多了一层部署方可以自己写的声明。

体积是另一个维度,此前被当成常数。 懒加载省的是条数——让多少条工具定义不进上下文。还有一条独立的约束管着每条的体积:MCP 工具描述与服务器指令默认被截到 2,048 字符,v2.1.280 起可用 CLAUDE_CODE_MAX_MCP_DESCRIPTION_LENGTH 改动这个上限。

⚠️ 上面那个 2,048 在两周内分叉成了三档,而且不再是”会话内统一上限”。 这是本章最容易记错的一处:

加载路径上限版本官方措辞要点
预发送给模型的 MCP 工具描述与服务器指令4,096 字符(原 2,048)v2.1.296(2026-10-09)“Changed the default limit on MCP tool descriptions sent up front and on MCP server instructions from 2,048 to 4,096 characters”
模型经 tool search 加载的工具描述16,384 字符(原 2,048)v2.1.295(2026-10-08)“Changed MCP tool descriptions the model loads through tool search to be cut at 16,384 characters instead of 2,048”
来自 api.anthropic.com 的第一方 MCP 服务器不截断,完整送达v2.1.299(2026-10-14)“to reach Claude in full instead of being cut at 4,096 characters”

两点必须改掉旧写法。其一,2,048 不是被一个新数字替换,而是按加载路径分叉——同一条描述走”预发送”还是走 tool search,上限差 4 倍;凡记”某个上限被改成 N”,必须写明是哪一条加载路径的上限(与 Ch01 归纳的”四轨化”是同一条规则)。其二,本章此前写的”作用于会话内所有 MCP 服务器”这句已经不成立:v2.1.299 给第一方服务器开了一条不受该上限约束的通道,这个总开关现在有例外了。

与本节三要素串起来:条数由懒加载(以及上文那两级声明)管,单条体积现在按加载路径分三档,服务器指令自 v2.1.283 起进入 /context 计量(见下)。

服务器指令此前还是一块看不见的面积。 上面这张表量化的是工具定义,但 MCP 占的上下文不止工具定义——服务器指令(server instructions)同样要进提示。在 v2.1.283 之前它们不计入 /context:你看到的 /context 总数里没有它们,等于”MCP 到底占多少上下文”这个问题有一块无法观测的面积。v2.1.283 修掉之后,服务器指令作为独立一行显示并计入总数。至此本章 10.3 的核心量化问题(MCP 的上下文成本)才有了完整的观测量:工具定义条数 × 单条体积上限 × 服务器指令。

10.4 MCP Server 生命周期管理

Claude Code 不只是连接 MCP Server——它管理 MCP Server 的完整生命周期:

启动时
  ├── 读取配置中的 mcpServers
  ├── 为每个 Server 创建客户端实例
  ├── 按传输类型建立连接
  └── 注册 Server 提供的工具到工具池

运行中
  ├── 工具调用通过 MCPTool 代理
  ├── 监控连接健康状态
  ├── 认证令牌自动刷新
  └── 错误检测与重连

退出时
  ├── 关闭所有 MCP 连接
  └── 清理子进程

对于 stdio 传输的 MCP Server,Claude Code 会作为父进程管理 Server 进程的生命周期——启动、监控、终止。这意味着 MCP Server 不需要自己管理守护进程化。

10.5 错误处理与重连

MCP 连接的错误处理是一个复杂的工程问题——网络不可靠、Server 可能崩溃、认证可能过期。Claude Code 定义了三种核心错误类型:

错误类型触发条件处理方式
McpAuthErrorHTTP 401标记 needs-auth,提示用户重新授权
McpSessionExpiredErrorHTTP 404 + JSON-RPC -32001清除缓存,下次调用重建连接
McpToolCallError工具返回 isError: true包装为安全错误,传递 _meta 元数据

无状态迁移(10.2.1 节)将淘汰 McpSessionExpiredError——会话概念消失后,HTTP 404 + JSON-RPC -32001 不再有协议级意义。但新的错误类型也随之出现。Backslash Security 在 MCP 2026-07-28 规范锁定后指出,无状态迁移引入了三种新的安全攻击面:

  1. 每次请求携带完整 _meta → 客户端身份信息暴露面增大
  2. server/discover 方法成为新的信息泄露点 → 替代了原来的 initialize 握手时的能力交换
  3. 无状态下的 per-request authorization 比 session-level auth 更复杂 → 错误的实现可能导致权限检查在每个请求中被跳过

建议补充的第四种错误类型:

错误类型触发条件处理方式
McpPerRequestAuthErrorper-request 授权失败(_meta 中客户端身份与请求操作不匹配)立即拒绝请求 + 触发会话级身份重新验证

这一错误类型与 McpAuthError(401 会话级)形成对比:后者是”我根本不认识你”,前者是”我认识你但这次请求你越权了”。在有状态模型下,会话建立时已完成授权检查,单次请求的权限检查只是复查;在无状态模型下,每次请求都要重做授权,实现缺陷的可能性显著增加。这是无状态架构的隐性成本——简单的概念模型(每次请求自包含)背后是复杂的授权实现。

401 的语义漂移:一个已经发生的真实案例。上面把 McpPerRequestAuthError 写成”建议补充的类型”是推测;到 2026-09 已经有了官方层面的现实佐证。Claude Code v2.1.265(2026-09-08)修复了一个云端会话的问题:对不支持的请求返回 HTTP 401 的服务器,会让 claude.ai 连接器在明明已经连接的情况下显示为”需要认证”。同版本还修复了另一处:需要登录的远程 MCP 服务器,在真正认证之前不再向其注册 OAuth 客户端。

两个修复合起来说明同一件事——401 在无状态模型下不再等价于”需要认证”。它也可能是”服务器拒绝了一个它不支持的请求”。在有状态模型下,401 几乎只出现在握手阶段,语义是明确的;无状态化之后每个请求都可能独立返回 401,其语义被稀释了。客户端如果把 401 一律解释为”该重新走 OAuth 了”,就会产生这里的误报;而如果一律解释为”请求不合法”,又可能漏掉真正的过期。这是无状态迁移把一个协议状态码的语义变成客户端实现负担的典型例子。

方向相反的第二个案例。 单有 401 一例还不足以支撑”授权类错误码语义不可靠”这个结论——一个案例可能只是孤例。v2.1.274 补上了第二个,而且方向相反:MCP 工具调用被 403 insufficient_scope 拒绝时,此前被报成”登录已过期”;现在改为点名缺少哪些权限,并指向 /mcp 重新认证。

把两个案例并置才看得出结构:401 那一例是假报需认证(服务器其实是在拒绝一个它不支持的请求,客户端却显示要重新授权),403 这一例是把权限不足报成过期(真的需要认证,但报的口径是”会话过期”而非”缺哪些 scope”)。一例把”不需要认证”报成”需要”,另一例把”需要不同权限”报成”需要重新登录”——同一个客户端判断(要不要走 OAuth)被两个不同的错误码以相反的方式带偏。这正是无状态化的代价:状态码保留了下来,但它原本依赖的握手上下文没了,谁来解释它成了客户端各自的负担。

第三个案例,方向又不一样(v2.1.288,2026-10-02)。 前两例讲的都是”报错报错了”。这一例是真的需要更多权限,且官方给出了正确行为。changelog 逐字:

Added a re-authenticate prompt when an MCP server asks for more OAuth scope during a tool call

三例并置才形成完整的判断结构:

案例版本服务器实际意思客户端原先的读法方向
401v2.1.265拒绝一个它不支持的请求”需要重新授权”不需要认证 → 报成需要
403 insufficient_scopev2.1.274真的缺某些 scope”登录已过期”需要不同权限 → 报成过期
工具调用中要求更多 scopev2.1.288真的需要更多权限(此前无提示)需要更多权限 → 正确提示重新认证

前两例合起来的结论是”错误码语义不可靠”;第三例给出的结论更进一步——正确做法不是去猜错误码,而是在调用路径上单独处理 scope 升级。它把认证从”连接建立时的一次性判断”变成了”调用过程中可再次触发的动作”,这与 10.7.3 路线图的 Agent identity 方向可以直接接上:调用方从人变成 agent 之后,权限不再是一次授予就固定不变的东西。

同一版本还对错误处理的可观测性做了加固(v2.1.257):WebSocket MCP 连接失败此前被记为 [object ErrorEvent]——一个把底层信息吞掉的占位符,现在记录真实底层错误;MCP 连接与 OAuth 的调试日志则会对写在服务器 URL 或请求头里的凭证做脱敏。前者关系到”能不能排查”,后者关系到”排查日志会不会反而泄露凭证”,两者都是错误处理的工程前提。

Akamai 安全视角(云安全/CDN 层面)。Backslash Security 从协议攻击面(per-request _meta 暴露、server/discover 信息泄露、授权实现缺陷)切入,而 Akamai 从云基础设施/CDN 安全角度补充了三个值得关注的风险维度:

  1. MCP Apps XSS 风险:ui:// URI 的沙箱 iframe 是安全边界——Server 提供的 HTML 在隔离环境中运行。但 XSS 仍可能通过 postMessage 机制突破隔离,如果 Host 端没有严格验证消息来源(event.origin),恶意 Server 可窃取用户交互数据。

  2. HTTP 头与 JSON-RPC 内容一致性:Mcp-Method/Mcp-Name 头与请求体中的 method 字段必须一致。不规范的企业代理或 WAF 可能在转发时修改 HTTP 头(如重写路径、注入安全头),造成头-体不一致——这会导致 MCP 中间件拒绝合法请求或误路由。

  3. Tasks DoS 风险:长时间运行的后台任务需要资源限制(最大并发数、最大执行时间、结果存储上限)和工作管理机制。缺乏这些控制时,恶意或失控的任务可能耗尽服务器资源。

Akamai 与 Backslash 的分析视角互补:Backslash 关注协议层攻击面(每个字段、每种方法的潜在风险),Akamai 关注基础设施层安全(部署环境、网络路径、运维控制的健壮性)。两者结合提供了 MCP 无状态部署的完整安全视图——协议安全 + 基础设施安全 = 真正的纵深防护。

WebSocket 传输有独立的重连策略:

连接错误
  ├── 终端错误(ECONNRESET / ETIMEDOUT / EPIPE)
  │     ├── 计数器 +1
  │     └── 连续 3 次 → 强制断开并重连
  │
  └── 非终端错误
        └── 重置连续计数器

上面的计数器逻辑只覆盖了”连接已成、之后断开”的场景,缺两个维度:超时和启动期失败。

超时有了确切数字。v2.1.251(2026-08-28)修复:SDK/云端会话在 SDK MCP 服务器握手确认丢失时不再无限挂起,改为 70 秒超时,且只标记该服务器失败(不影响其他 MCP 服务器)。此前的行为是”整个会话卡在一个服务器的手握上”——这类 hang 之所以难查,是因为它在日志里没有任何错误,只是不动了。

启动期失败不再伪装成成功。v2.1.259(2026-09-02)修复:启动阶段正在列举工具时断连的 MCP 服务器,此前显示为”已连接但无工具”,现在报告错误。这是一个值得单独记住的失败模式——“服务器在线但没有工具”在现象上和”工具配置错了”完全一样,排查方向却截然相反。它与 McpSessionExpiredError(清除缓存、下次调用重建连接)是不同场景:后者发生在运行期、有明确的协议错误码,前者发生在启动期、此前根本没有错误信号。

v2.1.243(2026-08-25)还补上了另一类此前无解的断连:非交互(-p)与 SDK 会话中的远程 MCP 断连后此前永不恢复,现在自动重连或明确报失败。这条对自动化场景尤其关键——一个跑飞无人值守的 -p 任务,如果 MCP 断连后静默等待,表现出来就是”任务卡住”,而没有任何失败信号可供上层判断。

上面三条都是时间维度,还缺一条体积维度(v2.1.295,2026-10-08)。 官方 changelog 逐字:

Changed WebSocket (ws) MCP servers: a message over 16 MiB is no longer parsed and closes the connection, the limit the other transports already have

两点值得记。其一,这是本节第一条体积维度的失败:此前的所有限制都是时间(70 秒握手、10 秒恢复等待、2 秒启动等待,见下)。其二,超限的处理是关闭连接而不是截断——这与 10.3.1 描述被截断的处理方式截然不同:描述超长只会静默丢内容,消息超大会直接把连接断掉。官方措辞里的 “the limit the other transports already have” 也说明:这不是新增限制,而是把 WebSocket 拉齐到其它传输已有的水平。

2026 年 9 月下旬的一批修复,把问题从”能不能连上”推进到”连上了状态是否可信”。 上面几段覆盖的是连接建立与断开,下面这四条是另一类——连接显示为正常,实际已经坏了:

  • 短暂的 404 会让服务器整个会话不可用,却仍显示已连接(v2.1.283)。典型诱因是无状态远程服务器前面那层代理正在重新部署。这是本节最难查的一类故障:UI 说没问题,工具就是调不通。
  • stdio 服务器被遗留运行(v2.1.283):会话已经结束、服务器仍在启动中时,进程不会随之退出。
  • 同一台服务器被连接两次(v2.1.281):仅因 URL 拼写差异——主机大小写、默认端口、结尾斜杠。结果是同一份工具在上下文里出现两遍,正好抵消 10.3.1 的懒加载优化。
  • 恢复会话时服务器还在连接中,工具调用报 “No such tool available”(v2.1.284):现在改为最多等待 10 秒而不是立刻失败。

第五类,性质与上面四类都不同:重定向(v2.1.299,2026-10-14)。 上面四类的共同点是”连上了但状态不可信”。这一类是”连上了,但被带到了别处”。官方 changelog 两条逐字:

Changed requests to claude.ai’s connector proxy and to Anthropic-hosted MCP servers to no longer follow HTTP redirects; redirects by a connector’s own server are unaffected

Changed MCP requests in cloud and self-hosted runner sessions to no longer follow HTTP redirects from the session’s MCP proxy

两个落点:① claude.ai 的 connector proxy 与 Anthropic 托管的 MCP 服务器;② 云端会话与 self-hosted runner 中来自会话 MCP proxy 的重定向。⚠️ 官方明确保留的例外要一并写出:connector 自己的服务器发出的重定向不受影响——被限制的是”通往服务器那一段路径上的重定向”,不是服务器内部的跳转。

它为什么值得单列:在无状态 + 代理的部署形态下(10.2.1 的迁移路径、Akamai 视角里的头-体不一致与代理篡改),重定向是一条此前没有的信任边界——它不产生任何错误,连接状态显示正常,只是你的请求此后发往另一个地址。这与上面四类”连接显示为正常、实际已坏”是同一族,但成因在网络路径而非服务器状态。

启动等待还有一个下限(v2.1.284,2026-09-28)。 上面”恢复会话时最多等待 10 秒”之外,同批还有一条方向相反的:官方 changelog 逐字 “Changed the non-interactive first turn to still wait up to 2s for connecting MCP servers named by --allowedTools or an mcp_tool hook, even when CLAUDE_CODE_MCP_STARTUP_WAIT_MS is 0”。要点是显式点名会覆盖全局的 0——把 CLAUDE_CODE_MCP_STARTUP_WAIT_MS 设成 0 不等于完全不等待,被 --allowedTools 或 mcp_tool hook 点名的服务器仍会等最多 2 秒。对无人值守的 -p 场景尤其相关(上面”任务卡住”那条论述在这里有一个下限兜底)。

运维入口也补了一个:v2.1.284 新增 /mcp reconnect all,一次性重试所有连接失败或需要认证的 MCP 服务器。此前这类批量恢复只能逐个手动触发,或重启会话。

认证失败有 15 分钟的缓存(MCP_AUTH_CACHE_TTL_MS),避免短时间内重复连接已知需要认证的 Server。

MCP 工具调用还有超时保护——如果 Server 在指定时间内没有响应,调用会被取消并返回超时错误。

10.6 端到端:配置一个 MCP Server

以实际配置一个 GitHub MCP Server 为例,走一遍完整流程。

步骤一:配置声明

在 ~/.claude/settings.json 中添加:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxx"
      }
    }
  }
}

上面只是四条路径中的一条。 本节演示的是用户级 settings.json;把它当成唯一入口会漏掉另外三条:项目级 .mcp.json、组织级托管(10.3 节的 managedMcpServers),以及 v2.1.285(2026-09-29)新增的插件自带路径。官方 changelog 逐字:“Added .= to claude plugin install --config, so a bundled .mcpb MCP server’s own settings can be set at install time and it starts without visiting /plugin → Configure”。

也就是说,插件里打包的 .mcpb MCP 服务器,其自身设置可以在安装插件时一次写好,装完即可启动,不必再去 /plugin → Configure 逐个填。这条把”配置一个 MCP 服务器”从”编辑某个 JSON 文件”扩展成了”也可以在装插件时顺带完成”——排查”这台服务器怎么来的”时,第四条路径是常被忽略的一条。

步骤二:启动时发生了什么

Claude Code 启动时,init() 函数读取配置,为每个 Server 创建 McpClient 实例:

init()
  └── initMcpClients()
        └── 对每个 mcpServers 条目:
              ├── 根据 command/args 判断传输类型(这里是 stdio)
              ├── 创建 StdioClientTransport
              ├── spawn 子进程(npx ...)
              ├── 建立 JSON-RPC 连接
              ├── 调用 tools/list 获取工具列表
              └── 注册到工具池(前缀 mcp__github__)

步骤三:工具调用链路

当模型决定调用 mcp__github__create_issue 时:

QueryEngine 收到工具调用
  ├── 权限检查(mcp__github__create_issue 的权限规则)
  ├── 通过 MCPTool 代理
  │     ├── 将参数序列化为 JSON-RPC request
  │     ├── 通过 stdio 发送到 GitHub MCP Server 子进程
  │     └── 等待 JSON-RPC response
  ├── 解析结果
  └── 返回给模型

整个过程对模型是透明的——它不知道 mcp__github__create_issue 是 MCP 工具还是内置工具,调用接口完全一致。

步骤四:错误场景

如果 GitHub token 过期(HTTP 401),流程变为:

MCPTool 调用
  ├── 收到 McpAuthError
  ├── 标记 server 状态为 needs-auth
  ├── 缓存认证失败(15 分钟内不重试)
  └── 返回友好错误信息给模型

这个端到端示例展示了 MCP 集成的三个设计优势:配置简单(一个 JSON 条目)、调用透明(模型无感知)、错误优雅(缓存避免重复失败)。

10.7 MCP 协议的上下文扩展

MCP 协议最初定义了三类上下文原语——Tools(可调用操作)、Resources(只读数据源)、Prompts(提示模板)。2026 年的协议演进将其扩展为五原语,新增 Tasks 和 Triggers,并引入了 MCP Apps 交互式 UI 机制。

Tools / Resources / Prompts(原有三原语)

Claude Code 通过 ListMcpResources 和 ReadMcpResource 工具暴露 MCP 资源。LSP(Language Server Protocol)也通过 MCP 机制集成——LSP 工具封装了语言服务器的能力(类型检查、跳转定义、查找引用等),使得 Claude Code 可以利用已有的语言服务器基础设施。

MCP Tasks(SEP-1686 异步长时任务)

MCP Tasks 解决了工具调用长时间运行的问题。传统工具调用是同步的——请求发出后客户端等待响应。Tasks 引入了异步执行模型:

  1. 客户端发起 Task 请求
  2. 服务器立即返回 Task Handle(而非等待完成)
  3. 客户端通过轮询或订阅获取进度更新
  4. 任务完成后获取最终结果

这对代码分析、大规模重构等耗时操作至关重要——Claude Code 不需要在等待中阻塞整个会话。

上面的”四步异步模型”方向是对的,但需要补上正式版的最终形态:Tasks 已移出实验核心,成为扩展 io.modelcontextprotocol/tasks,与 MCP Apps、Enterprise Managed Authorization(EMA)并列。生命周期改为轮询式的 tasks/get 与新增的 tasks/update(SEP-2663)。

对读者最实际的影响是一句话:如果你按 2025-11-25 的实验 API 实现过 Tasks,那部分代码需要重写。这不是”加一个可选能力”的增量演进,而是方法集层面的改写。正式版还引入了带最短窗口的正式弃用政策,正是为了让这类变更可预期——但可预期不等于可兼容。

官方扩展已经不是三个了。 本节与 10.2.1 都把官方扩展写成”Tasks、MCP Apps、EMA”三项——那是 2026-07-28 发布博文时点的快照。回官方扩展索引(modelcontextprotocol.io/extensions)核验,当前的官方扩展是五个:

扩展仓库说明
MCP Appsmodelcontextprotocol/ext-apps在会话中内联展示交互式 UI
MCP Tasks—异步长时任务,支持轮询、中途输入与持久句柄
Enterprise-Managed Authorizationmodelcontextprotocol/ext-auth面向需要集中访问控制的企业环境
OAuth Client Credentials(新增)modelcontextprotocol/ext-authOAuth 2.0 client credentials 流,机器对机器认证
Skills over MCP(新增)modelcontextprotocol/ext-skills通过 MCP resources 发现工作流指令并读取支撑文件

新增的两个都与本章已有线索相接。OAuth Client Credentials 用应用级凭据,没有浏览器重定向、没有用户同意步骤,面向后台服务与 CI——它与 10.7.3 路线图的 Agent identity 方向直接对应:调用方从人变成 agent 之后,认证形态必须补上这块。Skills over MCP 则是 progressive discovery 的一个现成落点:服务器通过 resources 暴露工作流指令,客户端按需读取,与 10.3.1 的 Tool Search 正好是两端。

📌 方法:查扩展索引,不要查发布博文。 官方扩展位于 MCP GitHub 组织内 ext- 前缀的仓库,标识使用 io.modelcontextprotocol 前缀(实验性扩展另用 experimental-ext- 前缀)。扩展集在发布之后还会继续增长,发布博文是发布时点的快照,索引才是当前状态。这与 10.7.3 处理路线图时的取舍一致——那节已剔除二手报道中的 ETag 说法,改用官方实际措辞。

Triggers(服务器推送通知)

Triggers 允许 MCP Server 主动向 Host 推送通知,而不仅限于响应请求。典型场景:

  • CI/CD 管线完成时通知 Agent
  • 文件系统变更实时推送
  • 监控阈值告警

这使得 Claude Code 可以从”轮询检查”模式转向”事件驱动”模式,减少无效轮询开销。

值得注意的是,Triggers 依赖的变更通知在 2026-07-28 正式版中换了传输形态:从旧的 HTTP GET 端点改为单一的 subscriptions/listen 流,客户端按通知类型逐个订阅。对 Triggers 的使用方来说,这意味着订阅从”连上就全收”变成了按类型声明——这既是省带宽的优化,也把”我需要哪几类事件”从一个隐式假设变成了显式契约。

MCP Apps(SEP-1865 交互式 UI)

MCP Apps 是首个官方 MCP 扩展,由 Anthropic 和 OpenAI 联合制定。它允许 MCP Server 向 Host 提供交互式 UI 组件,通过 ui:// URI 方案实现。关键设计:

  • 沙箱 iframe 隔离渲染,Server 提供的 UI 在独立沙箱中运行
  • 审计通信,所有 UI 交互通过受控通道传递
  • MCP-UI 和 OpenAI Apps SDK 统一标准,确保跨平台兼容

MCP Apps 将 MCP 从”工具调用协议”升级为”应用交付协议”——Server 不仅提供能力,还提供使用这些能力的交互界面。

Roots/Sampling/Logging 三原语弃用。MCP 2026-07-28 规范(已 GA)一并标记了三项原语的弃用(SEP-2577),12 个月弃用窗口至 2027-07-28:

原语弃用原因替代方案影响评估
Roots(资源根)与 tools/list + 资源 URI + 服务器配置重叠显式工具参数/资源 URI/服务器配置几乎无影响——大多数实现未深度使用
Sampling(服务器借用客户端 LLM)难以无状态化、API Key 管理复杂、与 Host 边界模糊重构为 Server 直接调用 LLM API影响最大——这是唯一让 MCP Server 无需自带 API Key 就能借用 Host LLM 的特性,许多 Server(如 Documentation Server、Code Analysis Server)依赖此能力
Logging(MCP 统一日志)与传输层日志机制重叠stdio 传输改用 stderr;Streamable HTTP 改用 OpenTelemetry中等影响——需要修改日志收集管道

Sampling 的弃用是最复杂的迁移项——它打破了”MCP Server 是无状态工具”这一简洁抽象。直接调用 LLM API 意味着 Server 必须管理自己的 API Key、计费、限流,部署复杂度显著上升。但这也是无状态迁移的必然代价:会话级 Sampling 依赖 Host 维护的 LLM 连接,会话概念消失后必须重构。

把上面的弃用清单与本节开头的”五原语”合起来看,准确的口径是”五原语 + 三项进入弃用流程”(Roots / Sampling / Logging),而非”一项被弃用”。三者最早移除时间为 2027-07-28 或之后发布的修订版——注意官方的措辞是 “They still work, and they’ll keep working for at least twelve months”,即”至少 12 个月”是下限而非到期日。

Sampling 的退出标志着 MCP 协议从”灵活的多面手”演进为”专注的工具协议”。这种简化在长期对生态健康有利:核心协议越小,扩展空间越大。

第四项弃用:DCR(Dynamic Client Registration)。官方在授权硬化部分明确写道,DCR 已正式让位于 CIMD(Client ID Metadata Documents),“DCR continues to work for backward compatibility, but will be removed in a future version of the MCP spec”。同批的授权加固还包括 RFC 9207 issuer 校验(授权服务器须返回 iss 参数、客户端须在兑换 code 前校验,SEP-2468),以及客户端在 DCR 时设置 application_type 以避免桌面/CLI 应用的 localhost 重定向被拒(SEP-837)。

需要把 DCR 与前面三项分开计数:Roots/Sampling/Logging 是原语,DCR 是授权机制。前者退出影响的是”能表达什么”,后者退出影响的是”客户端如何被注册”。混在”几项被弃用”这个数字里讨论会让读者误判影响面——一个只做本地 stdio 工具的 Server 完全不受 DCR 影响,但一个做过 OAuth 集成的远程 Server 会。

从工具协议到应用分发层的定位升级。MCP Apps 的意义不仅在于”交互式 UI”,而在于它改变了 MCP 的根本定位:

阶段MCP 定位核心能力开发者角色
MCP 1.0工具调用协议Tools/Resources/Prompts 三原语工具提供者
MCP 1.5上下文协议+ Tasks/Triggers 异步+推送集成开发者
MCP Apps应用分发层+ 交互式 UI(ui:// URI)应用开发者

这种定位升级对 MCP 生态的长期影响深远:开发者不再只是”为 AI 提供工具”,而是”为 AI 构建应用”——类似于从命令行工具到 GUI 应用的演进。MCP Apps 的沙箱 iframe 模型确保了安全性(Server 提供的 UI 在隔离环境中运行),审计通信通道确保了透明性(所有 UI 交互可追踪),而 MCP-UI 和 OpenAI Apps SDK 的统一标准确保了跨平台兼容性。

10.7.1 MCP 成为行业通用标准:2026-05-28 里程碑

2026 年 5 月 28 日是 MCP 协议历史上的标志性日期——三个重量级平台同日宣布 MCP 支持:

平台公告内容战略意义
OpenAI正式支持 MCP 协议从竞争对手到协议采纳者——最大的 AI 公司采纳了对手的协议标准
Runway视频创作平台集成 MCPMCP 从编码领域扩展到创意工具领域
Claude Code v2.1.152MCP 无状态迁移支持协议创始方的实现更新,推动无状态架构落地

OpenAI 支持 MCP 的战略意义:此前 MCP 一直被视为”Anthropic 专有协议”,OpenAI 的采纳彻底改变了这一定位。当一个协议最大的竞争对手选择支持它时,这传递了比任何市场份额数据都强的信号——MCP 已成为 AI 工具交互的事实标准。

MCP 生态数据更新:

  • 10,000+ 公共 MCP Server(⚠️ 过时快照:2026-10 中旬两个第三方口径已分别到 42,753 与 39,653,且两者相差 7.8%——见 10.2 节)
  • 9,700 万安装量(早期快照;截至 2026-07-28,Tier 1 SDK 月下载量已接近 5 亿,TS/Python SDK 各自累计突破 10 亿——见 10.2 节说明)
  • Anthropic + OpenAI 双巨头支持
  • 四大云厂商背书(AWS / Google Cloud / Microsoft Foundry / Cloudflare)+ 四个 Tier 1 SDK 发布当天支持 2026-07-28

比”四大云厂商背书”更能支撑上面这个结论的是治理结构。 背书表达的是态度,治理归属才是结构。MCP 现由 AAIF(Agentic AI Foundation)治理,该基金会隶属于 Linux Foundation(其官网 aaif.io 页脚即为 Linux Foundation 的版权声明);项目列表中 Model Context Protocol(MCP) 与 Agent2Agent(A2A) 并列在册——A2A 已于 2026 年 8 月归入同一基金会(⚠️ 多家报道记为 8 月 20 日,官方一手公告本轮未回源,故只写月份)。

两点值得单列。其一,“这是 Anthropic 专有协议”这一疑虑在治理层面已经解除:一个协议由中立基金会持有与由某家公司持有,对采用方的风险含义完全不同——这也是为什么上面那句”OpenAI 的采纳传递了比市场份额更强的信号”之外,还需要这一层。其二,MCP 与 A2A 不是竞争关系而是两个方向:MCP 管 agent 到工具(纵向),A2A 管 agent 到 agent(横向)。两者进入同一基金会,意味着”先选边再动手”这个前置问题消失了。

这标志着 MCP 的定位转变:从 Anthropic 专有协议 → AI 工具交互的行业标准。对开发者的启示是,为 MCP 开发工具扩展不再是”绑定 Anthropic 生态”的选择,而是”接入 AI 工具通用标准”的选择。

10.7.2 工具 Schema 升级至 JSON Schema 2020-12

MCP 2026-07-28 规范(已 GA)要求工具的 inputSchema 和 outputSchema 全面符合 JSON Schema 2020-12 规范(SEP-2106)。这是协议仅有的两项 strictly breaking changes 之一。

inputSchema:保留 type: "object" 根但允许组合约束。工具的输入 Schema 仍以 type: "object" 为根——这是协议层面的硬约束,确保参数始终以结构化键值对传递。但在根之下的定义中,现在可以使用:

  • oneOf / anyOf / allOf:组合约束,让工具支持”按 ID 查询或按名称查询”等互斥参数模式
  • if-then-else:条件逻辑,根据某个字段的值动态要求其他字段
  • $ref / $defs:Schema 内部引用,避免重复定义

outputSchema:完全无限制。与 inputSchema 不同,outputSchema 不再要求根类型为 object——Server 可返回数组、字符串、数字等任意 JSON 类型。这对于返回列表型数据的工具(如搜索结果列表)尤其方便。

structuredContent:任意 JSON 值。structuredContent 字段不再强制包裹在 {result: [...]} 的 object 格式中,可为任意 JSON 值。这消除了之前版本中数据需要”多一层包装”的不自然约束。

安全注意事项。实施 JSON Schema 2020-12 时需要关注:

  1. 不要自动解引用外部 $ref URI:$ref 可指向远程 Schema,自动下载可能引发 SSRF 或信息泄露
  2. 限制 Schema 深度:嵌套 Schema 的递归验证可能被恶意构造的深度 Schema 用于 CPU DoS
  3. 限制验证时间:为 Schema 验证设置超时,防止复杂的 oneOf/allOf 组合导致组合爆炸
  1. 空 Schema 的类型推断:当参数的 JSON Schema 为空({})时,客户端如何推断参数类型?这是个看似琐碎却真实咬人的边界。Claude Code v2.1.246(2026-08-25)修复的问题正是:MCP 工具参数在 schema 为 {} 时被当作 JSON 字符串发送,而非真实类型。结果是服务端收到一个字符串,而它期待的是对象或数组——错误发生在协议边界之外,报错信息完全指不到根因。

前三条注意事项关注的是”恶意或病态 Schema 会造成什么破坏”,第四条关注的是“Schema 什么都没说时会发生什么”。前者是攻击面,后者是默认行为;安全设计里,默认行为往往比攻击面更容易被忽略。

迁移影响。对绝大多数简单 Schema(纯 type: "object" + properties + required 定义),此次升级不影响现有代码——这些 Schema 天然兼容 JSON Schema 2020-12。但使用了自定义 Schema 解析/验证逻辑的 Server 作者应验证其实现是否兼容新的组合约束和 outputSchema 自由度。

10.7.3 2026-08-22 路线图:7-28 之后的五个优先方向

本章此前的讨论止于 2026-07-28 规范 GA。四周之后(2026-08-22),两位 Lead Maintainer(David Soria Parra、Den Delimarsky)发布了更新版路线图,把 7-28 明确降格为地基而非目的地——原文写的是过去五个月的进展”bulk of the changes landed in the 2026-07-28 specification release”,而”The updated roadmap picks up from here”。上一版(2026 年 3 月)的四个优先方向是传输演进与可扩展性、agent 通信、治理成熟、企业就绪;新版改为五个:

优先方向官方表述的要点与本章的关系
Agentic messaging primitives把 Tasks(SEP-2663)、subscriptions/listen、progress notifications 收敛为一套能协同工作的原语;补服务端主动事件(webhooks 与 channels),使客户端不必轮询;Tasks 扩展成熟后目标是进入核心规范10.7 记的是 Tasks 被移出核心成为扩展,这里是要它再回来
HTTP-native transport unification and hardening7-28 之后远程 MCP 服务器与普通 HTTP 工作负载已无差别;下一步是把无状态 HTTP 模型延伸到更多部署形态,包括本地服务器通过 stdio 讲 Streamable HTTP,统一到一套传输上10.2 六种传输方式的收敛方向:从”多种并存”到”一套为主”
Agent identity and enterprise-ready security现行授权围绕”人在浏览器里批准”,但越来越多调用方是以自身身份运行的云端工作负载,代表不在场的用户行事或向下级 agent 委派更窄的权限。工作包括完成并推动 DPoP(Demonstrating Proof of Possession) 落地,经 Workload Identity Federation、ID-JAG grant(Enterprise-Managed Authorization 的背后机制)与标准 token exchange 给出明确路径;目标是不再依赖长期 API key与 10.5 直接相关:调用方从”人”变成”agent”,授权模型的假设必须重写
Improved primitivestools/call 的响应能以多种形式承载同一输出,服务器开发者无从知晓某个客户端会把哪种形式交给模型——要做统一的 result 契约;同时发起 progressive discovery:服务器先给一个小入口,随对话收窄再逐步展开目录与 10.3.1 的 Tool Search 是同一个问题的两端:Tool Search 是客户端侧按需检索,progressive discovery 是服务器侧按需暴露
Improved SDK developer experience投入 SDK 的人机工效与规范一致性,让各平台各语言的 SDK 直观、文档准确很多开发者现在是”让 agent 对着 SDK 写代码”,API 清晰度直接决定能否跑通

治理层面同时有三项变化:正式采纳 Contributor Ladder、Working Group 在各自领域内 triage SEP、规范有了正式的特性生命周期与弃用策略——10.7 记的 2026-07-28 那批弃用,正是第一批走这套流程的。优先级上的直接影响是:落在这五个方向内的 SEP 走加速评审;方向外的提案不会被自动拒绝,但维护者的 review 时间优先投向这五块。

⚠️ 两点必须说清。第一,这五个方向是路线图,不是已发布规范——读者不应把它们当作已生效特性去查文档。第二,官方原文并未承诺 ETag:部分二手报道把”客户端低成本校验缓存的工具列表是否过期”写成路线图的 ETag 支持,但路线图正文里 ETag 零命中;官方在缓存上的实际表述是 7-28 已落地的”list results are also cacheable(SEP-2549)“。本章只写官方原文里有的内容。

10.8 设计启示

  1. 协议标准化是生态建设的基础。MCP 让任何人都可以为 Claude Code 开发工具扩展,而不需要修改 Claude Code 本身。

  2. 统一的工具抽象。MCP 工具和内置工具在 QueryEngine 看来是一样的——同样的调用接口、同样的权限系统、同样的并发调度。这种统一抽象大幅降低了集成复杂度。

  3. 错误处理要考虑网络的不可靠性。重连、缓存、超时——这些在本地工具中不需要的机制,在网络工具中是必须的。Claude Code 的三种错误类型 + WebSocket 重连策略提供了一个好的参考。

  4. 双重角色(客户端+服务器)极大拓展了集成可能性。Claude Code 不只是 MCP 的消费者,也是 MCP 的提供者。