协议修订: 2025-11-25
- stdio,通过标准输入和标准输出进行通信
- 可流式 HTTP (Streamable HTTP)
stdio
在 stdio 传输方式中- 客户端将 MCP 服务器作为子进程启动。
- 服务器从其标准输入 (
stdin) 读取 JSON-RPC 消息,并向其标准输出 (stdout) 发送消息。 - 消息是单独的 JSON-RPC 请求、通知或响应。
- 消息由换行符分隔,且 不得 包含嵌入的换行符。
- 服务器 可以 将 UTF-8 字符串写入其标准错误 (
stderr),用于任何日志记录目的,包括信息性、调试和错误消息。 - 客户端 可以 捕获、转发或忽略服务器的
stderr输出,并且 不应 假设stderr输出表示错误情况。 - 服务器 不得 向其
stdout写入任何非有效 MCP 消息的内容。 - 客户端 不得 向服务器的
stdin写入任何非有效 MCP 消息的内容。
可流式 HTTP (Streamable HTTP)
这取代了 2024-11-05 协议版本中的 HTTP+SSE 传输方式。请参阅下文的 向后兼容性 指南。
https://example.com/mcp 这样的 URL。安全警告
在实现可流式 HTTP 传输方式时- 服务器 必须 验证所有传入连接的
Origin请求头,以防止 DNS 重新绑定攻击- 如果
Origin请求头存在且无效,服务器 必须 响应 HTTP 403 Forbidden。HTTP 响应体 可以 包含一个不带id的 JSON-RPC 错误响应
- 如果
- 在本地运行时,服务器 应当 仅绑定到本地主机 (127.0.0.1),而不是所有网络接口 (0.0.0.0)
- 服务器 应当 为所有连接实现适当的身份验证
向服务器发送消息
从客户端发送的每条 JSON-RPC 消息 必须 是一个指向 MCP 端点的新 HTTP POST 请求。- 客户端 必须 使用 HTTP POST 向 MCP 端点发送 JSON-RPC 消息。
- 客户端 必须 包含
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 流
- 服务器 应当 立即发送一个由事件 ID 和空
data字段组成的 SSE 事件,以便引导客户端在断开后重新连接(使用该事件 ID 作为Last-Event-ID)。 - 在服务器向客户端发送了带有事件 ID 的 SSE 事件后,服务器 可以 随时关闭 连接(而不终止 SSE 流),以避免长时间占用连接。客户端随后 应当 通过尝试重新连接来“轮询” SSE 流。
- 如果服务器在终止 SSE 流 之前关闭了 连接,它 应当 在关闭连接前发送一个带有标准
retry字段的 SSE 事件。客户端 必须 遵守retry字段,在等待指定的毫秒数后再尝试重新连接。 - SSE 流最终 应当 包含针对 POST 请求体中发送的 JSON-RPC 请求 的 JSON-RPC 响应。
- 服务器 可以 在发送 JSON-RPC 响应 之前发送 JSON-RPC 请求 和 通知。这些消息 应当 与发起的客户端 请求 相关联。
- 如果 会话 过期,服务器 可以 终止 SSE 流。
- 在 JSON-RPC 响应 发送后,服务器 应当 终止 SSE 流。
- 断开连接 可能 在任何时候发生(例如由于网络状况)。因此:
- 断开连接 不应当 被解释为客户端取消了其请求。
- 要取消请求,客户端 应当 显式发送一个 MCP
CancelledNotification。 - 为了避免由于断开连接导致的消息丢失,服务器 可以 使流变为 可恢复的。
- 服务器 应当 立即发送一个由事件 ID 和空
监听来自服务器的消息
- 客户端 可以 向 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 流。
- 如果服务器关闭了 连接 但未终止 流,它 应当 遵循与 POST 请求描述相同的轮询行为:发送
retry字段并允许客户端重新连接。 - 客户端 可以 随时关闭 SSE 流。
多重连接
- 客户端 可以 同时保持与多个 SSE 流的连接。
- 服务器 必须 仅在其中一个已连接的流上发送其每条 JSON-RPC 消息;也就是说,它 不得 在多个流中广播同一条消息。
- 通过使流变为 可恢复的,可以 降低消息丢失的风险。
可恢复性与重新交付
为了支持恢复中断的连接,并重新交付可能丢失的消息:- 服务器 可以 为其 SSE 事件附加一个
id字段,如 SSE 标准 中所述。- 如果存在,该 ID 在该 会话 内的所有流中 必须 是全局唯一的——如果未使用会话管理,则在与该特定客户端的所有流中保持唯一。
- 事件 ID 应当 编码足够的信息以识别源流,使服务器能够将
Last-Event-ID关联到正确的流。
- 如果客户端希望在断开连接后恢复(无论是由于网络故障还是服务器启动的关闭),它 应当 向 MCP 端点发起 HTTP GET 请求,并包含
Last-Event-ID请求头,以指示其接收到的最后一个事件 ID。- 服务器 可以 使用此请求头在 已断开的流上 重放原本会在最后一个事件 ID 之后发送的消息,并从该点恢复流。
- 服务器 不得 重放本应在不同流上交付的消息。
- 无论原始流是如何发起的(通过 POST 还是 GET),此机制均适用。恢复始终通过带有
Last-Event-ID的 HTTP GET 进行。
会话管理
一个 MCP “会话”由客户端和服务器之间逻辑上相关的交互组成,从 初始化阶段 开始。为了支持想要建立有状态会话的服务器:- 使用可流式 HTTP 传输方式的服务器 可以 在初始化时分配一个会话 ID,方法是在包含
InitializeResult的 HTTP 响应中加入MCP-Session-Id请求头。- 会话 ID 应当 是全局唯一且加密安全的(例如安全生成的 UUID、JWT 或加密哈希)。
- 会话 ID 必须 仅包含可见的 ASCII 字符(范围从 0x21 到 0x7E)。
- 客户端 必须 以安全的方式处理会话 ID,更多细节请参阅 会话劫持缓解措施。
- 如果服务器在初始化期间返回了
MCP-Session-Id,使用可流式 HTTP 传输方式的客户端 必须 在其随后的所有 HTTP 请求中包含MCP-Session-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 服务器的所有请求中包含MCP-Protocol-Version: <protocol-version> HTTP 请求头,以便 MCP 服务器根据 MCP 协议版本进行响应。 例如:MCP-Protocol-Version: 2025-11-25 客户端发送的协议版本 应当 是在 初始化期间协商 的版本。 为了向后兼容,如果服务器 没有 收到 MCP-Protocol-Version 请求头,且没有其他方式识别版本(例如,依赖初始化期间协商的协议版本),服务器 应当 假定协议版本为 2025-03-26。 如果服务器收到包含无效或不受支持的 MCP-Protocol-Version 的请求,它 必须 响应 400 Bad Request。向后兼容性
客户端和服务器可以按如下方式保持与已弃用的 HTTP+SSE 传输方式(来自 2024-11-05 协议版本)的向后兼容性: 想要支持旧版客户端的 服务器 应当:- 继续托管旧传输方式的 SSE 和 POST 端点,同时保留为可流式 HTTP 传输方式定义的新的“MCP 端点”。
- 也可以将旧的 POST 端点和新的 MCP 端点合并,但这可能会引入不必要的复杂性。
- 接受来自用户的 MCP 服务器 URL,该 URL 可能指向使用旧传输方式或新传输方式的服务器。
- 尝试向服务器 URL 发送一个
InitializeRequest的 POST 请求,并附带如上定义的Accept请求头- 如果成功,客户端可以假设这是一个支持新的可流式 HTTP 传输方式的服务器。
- 如果失败并返回以下 HTTP 状态码:“400 Bad Request”、“404 Not Found”或“405 Method Not Allowed”
- 向服务器 URL 发起 GET 请求,预期这将开启一个 SSE 流,并返回一个
endpoint事件作为第一个事件。 - 当
endpoint事件到达时,客户端可以假设这是一个运行旧版 HTTP+SSE 传输方式的服务器,并应在随后的所有通信中使用该传输方式。
- 向服务器 URL 发起 GET 请求,预期这将开启一个 SSE 流,并返回一个