MCP 的版本管理和兼容性如何处理?
MCP 版本号机制与 SemVer 的区别
MCP 协议没有采用常见的语义化版本号(SemVer,如 1.2.3),而是使用 日期格式版本号,例如 2025-03-26、2024-11-05。这种选择并非随意,而是反映了协议的迭代节奏:版本号直接标识该版本最后一次引入破坏性变更的日期。
MCP 规范定义了三种版本状态:
| 状态 | 含义 |
|---|---|
| Draft | 草稿阶段,尚未准备好用于生产 |
| Current | 当前版本,可正常使用,仍可接收向后兼容的更新 |
| Final | 已完结的历史版本,不再变更 |
关键区别在于:当更新保持向后兼容时,协议版本号不会递增。这意味着同一版本号下的规范可能在细节上有所完善,但不会破坏已有实现。只有引入不兼容变更时,才会产生新的日期版本号。
初始化阶段的版本协商流程
MCP 的版本协商发生在客户端与服务器的 初始化握手阶段,这是连接建立后的第一个交互。整个流程如下:
- 客户端发送
initialize请求,其中包含protocolVersion字段,声明自己支持的协议版本 - 服务器收到请求后,从自身支持的版本列表中选择一个兼容版本,在响应中返回该版本号和自身的能力声明
- 客户端收到响应后,如果支持服务器返回的版本,发送
initialized通知确认就绪 - 如果客户端不支持服务器返回的版本,应当主动断开连接
json// 客户端发送 initialize 请求 { "jsonrpc": "2.0", "method": "initialize", "params": { "protocolVersion": "2025-03-26", "capabilities": { "tools": { "listChanged": true }, "resources": { "subscribe": true } }, "clientInfo": { "name": "my-mcp-client", "version": "1.0.0" } } } // 服务器响应 { "protocolVersion": "2025-03-26", "capabilities": { "tools": { "listChanged": true }, "resources": {} }, "serverInfo": { "name": "my-mcp-server", "version": "2.1.0" } }
需要注意的是:在初始化握手完成之前,双方不能发送任何功能请求(如列出工具、读取资源等)。对于 HTTP 传输,服务器还要求客户端在后续所有请求中携带 MCP-Protocol-Version 头,以便中间代理正确路由。
能力协商:比版本号更灵活的兼容机制
版本号只能粗粒度地判断兼容性,MCP 引入了 能力协商(Capabilities Negotiation) 来实现更精细的兼容控制。
在初始化握手时,客户端和服务器各自声明自己支持的能力集合(capabilities)。只有双方都声明支持的功能,才能在会话中使用。这意味着:
- 新版客户端连接旧版服务器时,新版功能自动禁用,但已有功能正常工作
- 旧版客户端连接新版服务器时,服务器不会调用客户端不支持的特性
- 双方可以独立演进,只要遵守"不使用对方未声明的能力"这一约定
typescript// 能力协商后的安全调用模式 interface NegotiatedCapabilities { client: ClientCapabilities; server: ServerCapabilities; } function safeCall( caps: NegotiatedCapabilities, feature: string ): boolean { // 只有双方都支持才返回 true return caps.client[feature] !== undefined && caps.server[feature] !== undefined; }
这种设计让 MCP 的兼容性保障从"版本号对齐"升级为"能力对齐",大幅降低了版本升级的摩擦。
正式弃用策略与功能生命周期
MCP 在 2026 年引入了正式的弃用策略(SEP-2596),建立了明确的三阶段功能生命周期:
Active → Deprecated → Removed
核心规则:
- 最小弃用窗口期为 12 个月——从标记为 Deprecated 到最早可能被移除,至少间隔一年
- 弃用仅为"注解级别"(annotation-only):被标记为 Deprecated 的方法、类型和能力标志在当前版本和弃用后一年内的所有规范版本中继续正常工作
- 每个弃用项必须提供明确的替代方案
以 2026-07-28 发布候选版本为例,三个核心功能被标记为弃用:
| 被弃用功能 | 替代方案 |
|---|---|
roots | 使用工具参数、资源 URI 或服务器配置 |
sampling | 直接集成 LLM 提供商 API |
logging | stdio 传输使用 stderr;结构化可观测性使用 OpenTelemetry |
这种渐进式弃用策略让开发者有充足时间迁移,而不是突然面对破坏性变更。
向后兼容性保证与破坏性变更处理
MCP 1.x 系列承诺向后兼容性,以下核心组件被认为是稳定的:
- 核心消息格式(JSON-RPC 2.0)
- 传输协议(stdio、Streamable HTTP)
- 工具/资源/提示的基本生命周期
- 错误类型层级
- 能力协商机制
当必须引入破坏性变更时,MCP 采用以下处理方式:
1. 双格式过渡期
在传输协议迁移中(如从 HTTP+SSE 迁移到 Streamable HTTP),客户端被期望在过渡期内同时支持新旧两种格式,确保不会因服务器升级而断连。
2. 错误码迁移
错误码的变更也遵循渐进策略。例如,资源缺失的错误码从 MCP 自定义的 -32002 迁移到 JSON-RPC 标准的 -32602(Invalid Params),通过 SEP 流程明确迁移时间和方式。
3. 扩展优先原则
新功能优先作为可选扩展发布,而非直接加入核心规范。扩展不会修改或破坏已有核心功能,开发者可以选择性采用。
扩展框架如何降低版本升级成本
MCP 的扩展框架(Extensions Framework)是版本管理的重要组成部分,它让协议能够在不频繁升级核心版本的前提下持续演进。
扩展具备四个关键特性:
- 可选采用:服务器和客户端实现者可以自行决定是否采纳某个扩展
- 纯粹增量:扩展只增加功能,不修改也不破坏核心协议功能
- 独立版本控制:扩展可以跟随核心 MCP 版本周期,也可以按需独立发版
- 可组合:扩展之间模块化设计,可以同时使用多个扩展而不冲突
这种架构意味着:当你只需要核心功能时,版本升级的压力很小;当你需要新特性时,通过扩展获取,而不必等待核心规范的大版本更新。
生产环境中的版本迁移实践
在实际项目中处理 MCP 版本迁移时,以下策略被证明是有效的:
1. 版本范围锁定
在项目配置中明确声明兼容的协议版本范围,而非依赖最新版本:
json{ "mcp": { "protocolVersion": "2025-03-26", "minProtocolVersion": "2024-11-05" } }
2. 兼容性测试集成
将 MCP 版本兼容性测试纳入 CI/CD 流程,在部署前自动验证客户端与目标服务器版本的兼容性。重点关注:初始化握手是否成功、能力协商后双方功能是否正常、已弃用功能是否有替代方案。
3. 弃用监控
建立弃用功能清单,定期对照 MCP 规范更新检查项目中是否使用了已弃用的 API。利用 MCP 服务器在 initialize 响应中返回的版本信息,自动检测弃用风险。
4. 渐进式迁移
当新版本发布时,不要一次性全量迁移。先在新实例上验证新版本的兼容性,确认无问题后再逐步替换旧实例。对于 HTTP 传输场景,确保所有客户端都更新到支持新版本后再下线旧版服务器。
5. 关注 SEP 提案
MCP 的变更通过 Specification Enhancement Proposals(SEP)提出和推进。关注与自身项目相关的 SEP,可以在变更正式生效前提前准备,避免被动应对。