1.传输协议概述 #
MCP(Model Context Protocol)使用 JSON-RPC 对消息进行编码,必须使用 UTF-8 编码。该协议为客户端-服务器通信定义了两套标准传输机制,并支持自定义传输以满足特定需求。
2. 标准传输机制 #
2.1 标准输入输出 (stdio) #
推荐使用:客户端应该尽可能支持 stdio 传输。
2.1.1 工作原理 #
在标准输入输出传输中:
- 客户端将 MCP 服务器作为子进程启动
- 服务器从其标准输入 (
stdin) 读取 JSON-RPC 消息,并向其标准输出 (stdout) 发送消息 - 消息是独立的 JSON-RPC 请求、通知或响应
- 消息以换行符分隔,且不得包含嵌入的换行符
2.1.2 重要规则 #
- 服务器可以将 UTF-8 字符串写入其标准错误输出 (
stderr) 用于日志记录目的 - 客户端可以捕获、转发或忽略此日志记录
- 服务器不得向
stdout写入任何非有效的 MCP 消息 - 客户端绝不可向服务器的
stdin写入任何非有效的 MCP 消息
2.1.3 通信流程 #

2.2 可流式传输的 HTTP #
注意:这将取代协议版本 2024-11-05 中的 HTTP+SSE 传输。详见向后兼容性部分。
2.2.1 基本概念 #
在可流式传输的 HTTP 中:
- 服务器作为独立进程运行,能够处理多个客户端连接
- 采用 HTTP POST 和 GET 请求进行通信
- 服务器可选择性地利用服务器发送事件 (SSE) 用于流式传输多个服务器消息
- 这使得基础 MCP 服务器以及支持流式传输、服务器到客户端通知和请求的更功能丰富的服务器成为可能
2.2.2 服务器端点要求 #
服务器必须提供一个单一的 HTTP 端点路径(以下简称该MCP 端点),支持 POST 和 GET 两种方法。例如:https://example.com/mcp
2.2.3 安全警告 ⚠️ #
在实现 Streamable HTTP 传输时:
- 服务器必须验证
Origin头部信息,对所有传入连接添加头部信息以防止 DNS 重绑定攻击 - 在本地运行时,服务器应该仅绑定到本地主机(127.0.0.1),而非所有网络接口(0.0.0.0)
- 服务器应该为所有连接实施适当的认证机制
若缺乏这些防护措施,攻击者可能利用 DNS 重绑定技术,通过远程网站与本地 MCP 服务器进行交互。
3. 向服务器发送消息 #
客户端发送的每一条 JSON-RPC 消息必须向 MCP 端点发起一个新的 HTTP POST 请求。
3.1 发送规则 #
HTTP 方法:客户端必须使用 HTTP POST 方法向 MCP 端点发送 JSON-RPC 消息
Accept 头部:客户端必须包含一个
Accept头部,列出application/json和text/event-stream作为支持的内容类型请求体:POST 请求的主体部分必须成为一个单一的 JSON-RPC 请求、通知或响应
响应处理:
- 如果输入是 JSON-RPC 响应或通知:
- 如果服务器接受了输入,服务器必须返回 HTTP 状态码 202 Accepted 且无响应体
- 如果服务器无法接受输入,它必须返回一个 HTTP 错误状态码(例如,400 Bad Request)
- 如果输入是一个 JSON-RPC 请求:
- 服务器必须要么返回
Content-Type: text/event-stream发起一个 SSE 流,或Content-Type: application/json返回一个 JSON 对象 - 客户端必须支持这两种情况
- 服务器必须要么返回
- 如果输入是 JSON-RPC 响应或通知:
SSE 流处理:
- SSE 流应该最终将包含 JSON-RPC 响应
- 服务器可以发送 JSON-RPC 请求和通知在发送 JSON-RPC 响应之前
- 服务器不应在发送 JSON-RPC 响应之前关闭 SSE 流
- JSON-RPC 响应发送后,服务器应该关闭 SSE 流
- 断开连接可以随时发生,因此:
- 断开连接不应被理解为客户端取消了其请求
- 要取消,客户端应该明确发送一个 MCP
CancelledNotification - 为避免因断开连接导致消息丢失,服务器可以让数据流可恢复的
4. 监听来自服务器的消息 #
4.1 监听规则 #
GET 请求:客户端可以向 MCP 端点发起 HTTP GET 请求,用于开启 SSE 流
Accept 头部:客户端必须包含一个
Accept头部,列出text/event-stream作为支持的内容类型服务器响应:服务器必须要么返回
Content-Type: text/event-stream,否则返回 HTTP 405 Method Not AllowedSSE 流处理:
- 服务器可以发送 JSON-RPC 请求和通知在直播中
- 这些消息应该与任何当前运行的 JSON-RPC 请求无关
- 服务器不得发送一个 JSON-RPC 响应在直播中,除非恢复与之前客户端请求相关联的流
- 服务器可以随时关闭 SSE 流
- 客户端可以随时关闭 SSE 流
5. 多个连接 #
客户端可以同时保持连接到多个 SSE 流
服务器必须将其每条 JSON-RPC 消息仅通过其中一个已连接的流发送;也就是说,它不得在多个流中广播相同的消息
- 消息丢失的风险可以通过使流式传输可恢复的来降低
6. 可恢复性与重传机制 #
为了支持恢复中断的连接,并重新传递可能丢失的消息:
事件 ID:服务器可以附加一个
id字段到 SSE 事件中,如 SSE 标准所述- 如果存在,该 ID必须在该流的所有流中保持全局唯一性,或者所有使用该特定客户端的流(如果未启用会话管理功能时)
恢复机制:如果客户端希望在连接中断后恢复,应该向 MCP 端点发起 HTTP GET 请求,并包含
Last-Event-ID头部用于指示它接收到的最后一个事件 ID- 服务器可以使用此头部来回放自最后一个事件 ID 后本应发送的消息,并从该点恢复流传输
- 服务器不得重播原本会在另一个流上传递的消息
换句话说,这些事件 ID 应由服务器在每流作为该特定流中的游标基础。
7. 会话管理 #
一个 MCP"会话"由客户端与服务器之间逻辑相关的交互组成,始于初始化阶段。为了支持希望建立有状态会话的服务器:
7.1 会话 ID 分配 #
- 使用 Streamable HTTP 传输的服务器可以在初始化时通过包含一个会话 ID 来分配
Mcp-Session-IdHTTP 响应头- 会话 ID应该全局唯一且具备加密安全性(例如,安全生成的 UUID、JWT 或加密哈希)
- 会话 ID必须仅包含可见 ASCII 字符(范围从 0x21 到 0x7E)
7.2 会话 ID 使用 #
- 如果
Mcp-Session-Id在初始化期间由服务器返回,使用 Streamable HTTP 传输的客户端必须将其包含在它们所有后续的 HTTP 请求头中- 需要会话 ID 的服务器应该响应无
Mcp-Session-IdHTTP 头部的请求为 HTTP 400 Bad Request(初始化除外)
- 需要会话 ID 的服务器应该响应无
7.3 会话终止 #
服务器可以随时终止会话,之后它将必须对包含该会话 ID 的请求响应 HTTP 404 Not Found
当客户端收到包含请求的 HTTP 404 响应时,它必须通过发送新的
InitializeRequest来开始一个新会话,不附带会话 ID不再需要特定会话的客户端(例如,因为用户正在退出客户端应用程序)应该向 MCP 端点发送一个 HTTP DELETE 请求,包含
Mcp-Session-Id头部,用于显式终止会话- 服务器可以对此请求返回 HTTP 405 Method Not Allowed 响应,表明服务器不允许客户端终止会话
8. 协议版本头部 #
如果使用 HTTP,客户端必须包括 MCP-Protocol-Version: <protocol-version> 在所有后续发往 MCP 服务器的请求中添加 HTTP 头部,使 MCP 服务器能根据 MCP 协议版本进行响应。
例如:MCP-Protocol-Version: 2025-06-18
客户端发送的协议版本应该成为在初始化期间协商的版本。
为了向后兼容,如果服务器没有接收一个 MCP-Protocol-Version 头部,且无法通过其他方式识别版本,服务器应该假设协议版本为 2025-03-26。
如果服务器收到包含无效或不支持的 MCP-Protocol-Version 的请求,它必须响应 400 Bad Request。
9. 向后兼容性 #
客户端和服务器可以保持与已弃用功能的向后兼容性,支持 HTTP+SSE 传输(来自协议版本 2024-11-05)。
9.1 服务器兼容性 #
服务器想要支持旧版客户端应当:
- 继续托管旧传输协议的 SSE 和 POST 端点,同时为可流式 HTTP 传输新定义的"MCP 端点"提供支持
- 也可以将旧的 POST 端点与新的 MCP 端点结合使用,但这可能会引入不必要的复杂性
9.2 客户端兼容性 #
客户端想要支持旧版服务器应当:
接收用户提供的 MCP 服务器 URL,该 URL 可能指向使用旧传输协议或新传输协议的服务器
尝试发起一个 POST 请求
InitializeRequest连接到服务器 URL,附带一个Accept头部:- 如果成功,客户端可以认为这是一个支持新 Streamable HTTP 传输的服务器
- 如果请求失败并返回 HTTP 4xx 状态码(例如 405 Method Not Allowed 或 404 Not Found):
- 向服务器 URL 发出 GET 请求,预期这将开启一个 SSE 流并返回
endpoint事件作为首个事件 - 当
endpoint事件到达时,客户端可以假定这是一个运行旧版 HTTP+SSE 传输协议的服务器,并应在后续所有通信中使用该传输方式
- 向服务器 URL 发出 GET 请求,预期这将开启一个 SSE 流并返回
10. 自定义传输 #
客户端与服务器可以实现额外的自定义传输机制以满足其特定需求。该协议与传输方式无关,可在任何支持双向消息交换的通信通道上实现。
选择支持自定义传输的实现者必须确保它们保留由 MCP 定义的 JSON-RPC 消息格式和生命周期要求。自定义传输应该记录其特定的连接建立与消息交换模式,以促进互操作性。
10.1 可流式传输的 HTTP #
注意:这将取代协议版本 2024-11-05 中的 HTTP+SSE 传输。详见向后兼容性部分。
10.1.1 基本概念 #
在可流式传输的 HTTP 中:
- 服务器作为独立进程运行,能够处理多个客户端连接
- 采用 HTTP POST 和 GET 请求进行通信
- 服务器可选择性地利用服务器发送事件 (SSE) 用于流式传输多个服务器消息
- 这使得基础 MCP 服务器以及支持流式传输、服务器到客户端通知和请求的更功能丰富的服务器成为可能
10.1.2 服务器端点要求 #
服务器必须提供一个单一的 HTTP 端点路径(以下简称该MCP 端点),支持 POST 和 GET 两种方法。例如:https://example.com/mcp
10.1.3 安全警告 ⚠️ #
在实现 Streamable HTTP 传输时:
- 服务器必须验证
Origin头部信息,对所有传入连接添加头部信息以防止 DNS 重绑定攻击 - 在本地运行时,服务器应该仅绑定到本地主机(127.0.0.1),而非所有网络接口(0.0.0.0)
- 服务器应该为所有连接实施适当的认证机制
若缺乏这些防护措施,攻击者可能利用 DNS 重绑定技术,通过远程网站与本地 MCP 服务器进行交互。
11. 向服务器发送消息 #
客户端发送的每一条 JSON-RPC 消息必须向 MCP 端点发起一个新的 HTTP POST 请求。
11.1 发送规则 #
HTTP 方法:客户端必须使用 HTTP POST 方法向 MCP 端点发送 JSON-RPC 消息
Accept 头部:客户端必须包含一个
Accept头部,列出application/json和text/event-stream作为支持的内容类型请求体:POST 请求的主体部分必须成为一个单一的 JSON-RPC 请求、通知或响应
响应处理:
- 如果输入是 JSON-RPC 响应或通知:
- 如果服务器接受了输入,服务器必须返回 HTTP 状态码 202 Accepted 且无响应体
- 如果服务器无法接受输入,它必须返回一个 HTTP 错误状态码(例如,400 Bad Request)
- 如果输入是一个 JSON-RPC 请求:
- 服务器必须要么返回
Content-Type: text/event-stream发起一个 SSE 流,或Content-Type: application/json返回一个 JSON 对象 - 客户端必须支持这两种情况
- 服务器必须要么返回
- 如果输入是 JSON-RPC 响应或通知:
SSE 流处理:
- SSE 流应该最终将包含 JSON-RPC 响应
- 服务器可以发送 JSON-RPC 请求和通知在发送 JSON-RPC 响应之前
- 服务器不应在发送 JSON-RPC 响应之前关闭 SSE 流
- JSON-RPC 响应发送后,服务器应该关闭 SSE 流
- 断开连接可以随时发生,因此:
- 断开连接不应被理解为客户端取消了其请求
- 要取消,客户端应该明确发送一个 MCP
CancelledNotification - 为避免因断开连接导致消息丢失,服务器可以让数据流可恢复的