> ## Documentation Index
> Fetch the complete documentation index at: https://mcp.developerdoc.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 版本管理与兼容性

<div id="enable-section-numbers" />

本页定义客户端和服务器如何就其使用的内容达成一致：每个请求上声明的协议版本；
通过能力协商的可选扩展；以及与早期基于握手的协议版本的互操作。

不存在协商握手。每个请求都携带其协议版本，服务器独立接受或拒绝每个请求：

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Server

    Client->>Server: request (with `_meta`)
    alt server supports requested version
        Server-->>Client: result
    else version unsupported
        Server-->>Client: UnsupportedProtocolVersionError
        Note over Client,Server: Client retries with a mutually supported version
    end
```

## Terminology

本页使用以下术语来描述跨协议版本的互操作：

* **现代**：将版本、身份和能力作为按请求元数据传递的协议版本（`2026-07-28` 及之后版本）。
* **旧版**：通过 `initialize` 握手建立会话的协议版本（`2025-11-25` 及之前版本）。
* **双时代**：同时支持现代和旧版协议版本的实现。

## Protocol Version Negotiation

每个请求都会在其 [`_meta`](/specification/draft/basic/index#meta) 字段中声明正在使用的协议版本。
在 HTTP 上，该版本也会通过
[`MCP-Protocol-Version` 头](/specification/draft/basic/transports/streamable-http#protocol-version-header)
携带。

如果服务器未实现请求的版本（无论该版本对服务器未知，还是服务器已知但选择不支持），
它 **MUST** 以
[`UnsupportedProtocolVersionError`](/specification/draft/schema#unsupportedprotocolversionerror)
响应，并列出它支持的版本：

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32004,
    "message": "Unsupported protocol version",
    "data": {
      "supported": ["2026-07-28", "2025-11-25"],
      "requested": "1900-01-01"
    }
  }
}
```

客户端 **SHOULD** 从 `supported` 列表中选择双方共同支持的版本并重试请求；如果不存在兼容版本，
则向用户显示错误。

服务器 **MUST** 实现 [`server/discover`](/specification/draft/server/discover)。
客户端 **MAY** 在发送任何其他请求之前调用它，以预先了解服务器支持的版本，但这并非必需：
客户端可以直接调用任何 RPC，并在其首选版本不受支持时处理 `UnsupportedProtocolVersionError`。

## 扩展协商

客户端和服务器可以协商对核心协议之外可选[扩展](/docs/extensions/overview)的支持。
扩展通过能力中的 `extensions` 字段声明，该字段是从扩展标识符到各扩展设置对象的映射。
扩展标识符 **MUST** 遵循 [`_meta` 键命名规则](/specification/draft/basic/index#meta)，
并且必须包含前缀。

下面是一个客户端声明
[MCP Apps 扩展](/extensions/apps/overview)的示例，该扩展标识为 `io.modelcontextprotocol/ui`：

```json theme={null}
{
  "capabilities": {
    "roots": {},
    "extensions": {
      "io.modelcontextprotocol/ui": {
        "mimeTypes": ["text/html;profile=mcp-app"]
      }
    }
  }
}
```

下面是标识为 `io.modelcontextprotocol/tasks` 的[任务扩展示例](/extensions/tasks/overview)：

```json theme={null}
{
  "capabilities": {
    "tools": {},
    "extensions": {
      "io.modelcontextprotocol/tasks": {}
    }
  }
}
```

每个扩展都会指定其设置对象的 schema；空对象表示支持该扩展且没有额外设置。

如果一方支持某个扩展而另一方不支持，支持方 **MUST** 要么回退到核心协议行为，
要么以适当错误拒绝请求。扩展 **SHOULD** 记录其预期的回退行为。

## Backward Compatibility with Initialization-Based Versions

希望同时支持[旧版](#terminology)客户端（期望 `initialize` 握手）和[现代](#terminology)客户端
（使用按请求元数据）的服务器 **MAY** 同时实现两种行为。

需要与两类服务器互操作的客户端，会使用绑定页面中指定的、特定于传输的机制来检测服务器所处的时代：

* [stdio](/specification/draft/basic/transports/stdio#backward-compatibility):
  使用 `server/discover` 探测，并在遇到任何非已识别现代错误时回退。
* [Streamable HTTP](/specification/draft/basic/transports/streamable-http#backward-compatibility):
  尝试现代请求，并在回退之前检查 `400 Bad Request` 的正文。

在这两种情况下，已识别的现代 JSON-RPC 错误（例如
[`UnsupportedProtocolVersionError`](/specification/draft/schema#unsupportedprotocolversionerror)）
都表示服务器是现代服务器：客户端会使用受支持版本重试，而不是回退。其他任何情况都表示服务器是旧版服务器。

时代判定是服务器的属性，而不是单个请求的属性。客户端 **SHOULD** 在服务器进程（stdio）
或源（HTTP）的生命周期内缓存结果，并且 **MAY** 在同一服务器配置重启后持久保存该结果；
如果缓存的假设随后失败，则重新探测。

仅支持[现代](#terminology)版本的服务器，在任何传输上对 `initialize` 请求返回错误时，
**SHOULD** 在错误中列出其支持的协议版本：旧版客户端没有向前升级机制，
这条消息可能是它们唯一能向用户显示的诊断信息。

### 兼容矩阵

下表总结了客户端和服务器时代的每种组合所预期的结果：

| 客户端 | 服务器 | 结果                                                                                                                                                                                                                                                                      |
| --- | --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 现代  | 现代  | 可工作。`server/discover` 是可选的；版本不匹配会表现为 `UnsupportedProtocolVersionError`，客户端随后使用双方共同支持的版本重试。                                                                                                                                                                              |
| 现代  | 旧版  | 失败。服务器可能用实现定义的错误拒绝请求、保持静默，甚至按旧版语义处理时代不明确的方法。在 stdio 上，客户端 **SHOULD** 先发送 `server/discover`，以确定性失败；随后客户端向用户显示可操作错误。                                                                                                                                                      |
| 双时代 | 现代  | 可工作。stdio 探测返回 `DiscoverResult`（或 `UnsupportedProtocolVersionError`）；在 HTTP 上，第一个现代请求成功或返回现代错误。客户端保持现代模式。                                                                                                                                                               |
| 双时代 | 旧版  | 可工作。stdio：探测返回非现代错误或超时，客户端回退到 `initialize`。HTTP：现代请求返回 `4xx`，且没有已识别的现代错误正文，客户端回退到 `initialize`（并且可能进一步回退到已弃用的 HTTP+SSE 传输）。                                                                                                                                             |
| 旧版  | 现代  | 失败。stdio：服务器用 JSON-RPC 错误拒绝 `initialize`；具体代码由实现定义（`initialize` 是未知方法，且请求还缺少必需的 `_meta` 字段）。HTTP：请求缺少必需头，并按[服务器校验](/specification/draft/basic/transports/streamable-http#server-validation)以 `400 Bad Request` 拒绝（使用已弃用 HTTP+SSE 传输的客户端则会在打开的 `GET` 上失败）。旧版客户端没有向前升级机制。 |
| 旧版  | 双时代 | 可工作。服务器响应 `initialize`，并根据协商出的旧版协议版本为客户端服务。                                                                                                                                                                                                                             |
| 旧版  | 旧版  | 按旧版协议版本工作；超出本文档范围。                                                                                                                                                                                                                                                      |

双时代**服务器**根据客户端的打开方式选择行为：

* 携带现代按请求 `_meta` 的请求会根据本版本以无状态方式服务。
* `initialize` 请求选择旧版语义，其作用域按协商出的旧版协议版本规定，限定在 stdio 进程（stdio）或会话（HTTP）内。

双时代服务器 **MAY** 在同一端点或进程上并发服务两个时代。
