协议版本:2025-06-18
stdio
在 stdio 传输中:- 客户端将 MCP 服务器作为子进程启动。
- 服务器从其标准输入(
stdin)读取 JSON-RPC 消息,并通过其标准输出(stdout)发送消息。 - 消息是单独的 JSON-RPC 请求、通知或响应。
- 消息以换行符分隔,不能 包含嵌入的换行符。
- 服务器 可以 将 UTF-8 字符串写入其标准错误(
stderr)用于日志记录。客户端 可以 捕获、转发或忽略这些日志。 - 服务器 不能 在其
stdout中写入任何非有效的 MCP 消息。 - 客户端 不能 向服务器的
stdin写入任何非有效的 MCP 消息。
可流式 HTTP
这替代了协议版本 2024-11-05 中的 HTTP+SSE 传输。请参阅下面的 向后兼容性 指南。
- 服务器作为一个独立进程运行,能够处理多个客户端连接。
- 此传输使用 HTTP POST 和 GET 请求。
- 服务器可以可选地使用 Server-Sent Events (SSE) 来流式传输多个服务器消息。
- 这允许基本的 MCP 服务器以及支持流式传输和服务器到客户端通知与请求的更高级服务器。
https://example.com/mcp 的 URL。
安全警告
实现可流式 HTTP 传输时:- 服务器 必须 验证所有传入连接的
Origin头,以防止 DNS 重绑定攻击。 - 本地运行时,服务器 应 仅绑定到 localhost(127.0.0.1),而不是所有网络接口(0.0.0.0)。
- 服务器 应 为所有连接实现适当的身份验证。
向服务器发送消息
客户端发送的每条 JSON-RPC 消息 必须 是一个发送到 MCP 端点的新 HTTP POST 请求。- 客户端 必须 使用 HTTP POST 将 JSON-RPC 消息发送到 MCP 端点。
- 客户端 必须 包含一个
Accept头,列出application/json和text/event-stream作为支持的内容类型。 - POST 请求的正文 必须 是一个单独的 JSON-RPC 请求、通知 或 响应。
- 如果输入是 JSON-RPC 响应 或 通知:
- 如果服务器接受输入,必须 返回 HTTP 状态码 202 Accepted,且无响应体。
- 如果服务器无法接受输入,必须 返回 HTTP 错误状态码(如 400 Bad Request)。HTTP 响应体 可以 包含一个没有
id的 JSON-RPC 错误响应。
- 如果输入是 JSON-RPC 请求,服务器 必须 返回
Content-Type: text/event-stream以启动 SSE 流,或返回Content-Type: application/json以返回一个 JSON 对象。客户端 必须 支持这两种情况。 - 如果服务器启动了 SSE 流:
- SSE 流 应该 最终包含与 POST 请求体中 JSON-RPC 请求 对应的 JSON-RPC 响应。
- 服务器 可以 在发送 JSON-RPC 响应 前发送 JSON-RPC 请求 和 通知。这些消息 应该 与原始客户端 请求 相关。
- 除非 会话 过期,服务器 不应 在发送 JSON-RPC 响应 前关闭 SSE 流。
- 发送 JSON-RPC 响应 后,服务器 应该 关闭 SSE 流。
- 断开连接 可能 随时发生(如由于网络状况)。因此:
- 断开连接 不应 被解释为客户端取消了请求。
- 要取消,客户端 应 显式发送一个 MCP
CancelledNotification。 - 为避免因断开连接导致消息丢失,服务器 可以 使流 可恢复。
监听来自服务器的消息
- 客户端 可以 向 MCP 端点发送 HTTP GET 请求。这可用于打开 SSE 流,使服务器可以在客户端未先通过 HTTP POST 发送数据的情况下向客户端通信。
- 客户端 必须 包含一个
Accept头,列出text/event-stream作为支持的内容类型。 - 服务器 必须 在响应此 HTTP GET 请求时返回
Content-Type: text/event-stream,或返回 HTTP 405 Method Not Allowed,表示服务器在此端点不提供 SSE 流。 - 如果服务器启动了 SSE 流:
- 服务器 可以 在流上发送 JSON-RPC 请求 和 通知。
- 这些消息 应该 与客户端当前运行的任何 JSON-RPC 请求 无关。
- 除非 恢复 与之前客户端请求关联的流,否则服务器 不能 在流上发送 JSON-RPC 响应。
- 服务器 可以 在任何时候关闭 SSE 流。
- 客户端 可以 在任何时候关闭 SSE 流。
多连接
- 客户端 可以 同时保持多个 SSE 流连接。
- 服务器 必须 将其每条 JSON-RPC 消息只发送到其中一个连接流;也就是说,不能 在多个流上广播相同的消息。
- 可通过使流 可恢复 来减轻消息丢失的风险。
可恢复性与重传
为支持断开连接后的恢复以及可能丢失的消息重传:- 服务器 可以 按照 SSE 标准 在其 SSE 事件中附加一个
id字段:- 如果存在,ID 必须 在该 会话 内的所有流中全局唯一——或在未使用会话管理的情况下,与该特定客户端的所有流中全局唯一。
- 如果客户端希望在断开连接后恢复,应该 向 MCP 端点发送一个 HTTP GET 请求,并包含
Last-Event-ID头,以指示其接收到的最后一个事件 ID:- 服务器 可以 使用此头在断开连接的流上重放在最后一个事件 ID 之后应发送的消息,并从该点恢复流。
- 服务器 不能 重放应发送到其他流的消息。
会话管理
一个 MCP “会话” 包括客户端与服务器之间的一系列逻辑相关交互,始于 初始化阶段。为支持希望建立有状态会话的服务器:- 使用可流式 HTTP 传输的服务器 可以 在初始化时通过在包含
InitializeResult的 HTTP 响应中添加Mcp-Session-Id头来分配会话 ID:- 会话 ID 应 是全局唯一且加密安全的(如安全生成的 UUID、JWT 或加密哈希)。
- 会话 ID 必须 仅包含可见 ASCII 字符(范围 0x21 到 0x7E)。
- 如果服务器在初始化期间返回了
Mcp-Session-Id,使用可流式 HTTP 传输的客户端 必须 在其后续所有 HTTP 请求的Mcp-Session-Id头中包含该 ID:- 要求会话 ID 的服务器 应 对未包含
Mcp-Session-Id头的请求(除初始化请求外)返回 HTTP 400 Bad Request。
- 要求会话 ID 的服务器 应 对未包含
- 服务器 可以 随时终止会话,之后 必须 对包含该会话 ID 的请求返回 HTTP 404 Not Found。
- 当客户端收到包含
Mcp-Session-Id的请求返回 HTTP 404 时,必须 通过发送不带会话 ID 的新InitializeRequest开始一个新会话。 - 不再需要特定会话的客户端(如用户退出客户端应用)应 向 MCP 端点发送一个带有
Mcp-Session-Id头的 HTTP DELETE 请求,以显式终止会话:- 服务器 可以 对此请求返回 HTTP 405 Method Not Allowed,表示服务器不允许客户端终止会话。
时序图
协议版本头
如果使用 HTTP,客户端 必须 在所有后续请求中包含MCP-Protocol-Version: <protocol-version> HTTP 头,以便 MCP 服务器可以根据 MCP 协议版本进行响应。
例如:MCP-Protocol-Version: 2025-06-18
客户端发送的协议版本 应 是 初始化期间协商的版本。
为向后兼容,如果服务器 未 收到 MCP-Protocol-Version 头,并且没有其他方式识别版本——例如,通过初始化期间协商的协议版本——服务器 应 假定协议版本为 2025-03-26。
如果服务器收到带有无效或不支持的 MCP-Protocol-Version 的请求,必须 返回 400 Bad Request。
向后兼容性
客户端和服务器可以通过以下方式保持与废弃的 HTTP+SSE 传输(协议版本 2024-11-05)的兼容性: 希望支持旧客户端的服务器 应该:- 继续托管旧传输的 SSE 和 POST 端点,同时提供新“MCP 端点”用于可流式 HTTP 传输。
- 也可以将旧 POST 端点和新 MCP 端点合并,但这可能引入不必要的复杂性。
- 接收用户提供的 MCP 服务器 URL,该 URL 可能指向使用旧传输或新传输的服务器。
- 尝试向服务器 URL 发送一个带有上述
Accept头的InitializeRequestPOST 请求:- 如果成功,客户端可以假设这是一个支持新可流式 HTTP 传输的服务器。
- 如果失败并返回 HTTP 4xx 状态码(如 405 Method Not Allowed 或 404 Not Found):
- 向服务器 URL 发送 GET 请求,期望这将打开一个 SSE 流,并在第一个事件中返回一个
endpoint事件。 - 当
endpoint事件到达时,客户端可以假设这是一个运行旧 HTTP+SSE 传输的服务器,并应使用该传输进行所有后续通信。
- 向服务器 URL 发送 GET 请求,期望这将打开一个 SSE 流,并在第一个事件中返回一个