协议版本: 2025-03-26
stdio
在stdio传输中:- 客户端将MCP服务器作为子进程启动。
- 服务器从其标准输入(
stdin)读取JSON-RPC消息,并将消息发送到其标准输出(stdout)。 - 消息可以是JSON-RPC请求、通知、响应——或包含一个或多个请求和/或通知的JSON-RPC批处理。
- 消息由换行符分隔,并且不得包含嵌入的换行符。
- 服务器可以为日志记录目的向其标准错误(
stderr)写入UTF-8字符串。客户端可以捕获、转发或忽略此日志记录。 - 服务器不得向其
stdout写入任何不是有效MCP消息的内容。 - 客户端不得向服务器的
stdin写入任何不是有效MCP消息的内容。
Streamable HTTP
这取代了协议版本2024-11-05中的HTTP+SSE传输。请参阅下面的向后兼容性指南。
https://example.com/mcp这样的URL。
安全警告
实现可流式HTTP传输时:- 服务器必须验证所有传入连接的
Origin标头,以防止DNS重绑定攻击 - 在本地运行时,服务器应该仅绑定到localhost(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 _响应_或_通知_组成:
- 如果服务器接受输入,服务器必须返回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 _请求_发送JSON-RPC _响应_之前关闭SSE流,除非会话过期。
- 在所有JSON-RPC _响应_都已发送后,服务器应该关闭SSE流。
- 断开连接可能随时发生(例如,由于网络条件)。因此:
- 断开连接不应该被解释为客户端取消其请求。
- 要取消,客户端应该明确发送MCP
CancelledNotification。 - 为避免由于断开连接导致的消息丢失,服务器可以使流可恢复。
监听来自服务器的消息
- 客户端可以向MCP端点发出HTTP GET请求。这可以用来打开SSE流,允许服务器与客户端通信,而无需客户端先通过HTTP POST发送数据。
- 客户端必须包含一个
Accept标头,列出text/event-stream作为支持的内容类型。 - 服务器必须返回
Content-Type: text/event-stream以响应此HTTP GET请求,或者返回HTTP 405 Method Not Allowed,指示服务器不提供此端点的SSE流。 - 如果服务器启动SSE流:
多个连接
- 客户端可以同时保持多个SSE流的连接。
- 服务器必须在每个连接的流上发送其JSON-RPC消息;即,它不得在多个流上广播相同的消息。
- 消息丢失的风险可能通过使流可恢复来降低。
可恢复性和重传
为了支持断开连接的恢复和可能丢失的消息的重传:- 服务器可以将
id字段附加到其SSE事件,如SSE标准中所述。- 如果存在,ID必须在会话内的所有流中全局唯一,或在没有会话管理的情况下与特定客户端的所有流中全局唯一。
- 如果客户端希望在断开连接后恢复,它应该向MCP端点发出HTTP GET请求,并包含
Last-Event-ID标头,以指示它收到的最后一个事件ID。- 服务器可以使用此标头来重放断开连接后应该发送的消息,并从该点恢复流。
- 服务器不得重放应该在不同流上发送的消息。
会话管理
MCP“会话”由客户端和服务器之间的逻辑相关交互组成,始于初始化阶段。为了支持希望建立有状态会话的服务器:- 使用可流式HTTP传输的服务器可以在初始化时分配会话ID,方法是将其包含在HTTP响应中的
Mcp-Session-Id标头中,响应包含InitializeResult。- 会话ID应该是全局唯一的和加密安全的(例如,安全生成的UUID、JWT或加密哈希)。
- 会话ID必须仅包含可见的ASCII字符(从0x21到0x7E)。
- 如果服务器在初始化期间返回
Mcp-Session-Id,则使用可流式HTTP传输的客户端必须在其后续HTTP请求的Mcp-Session-Id标头中包含它。- 需要会话ID的服务器应该响应不包含
Mcp-Session-Id标头的请求(除了初始化请求),并返回HTTP 400 Bad Request。
- 需要会话ID的服务器应该响应不包含
- 服务器可以在任何时候终止会话,此后它必须响应包含该会话ID的请求,并返回HTTP 404 Not Found。
- 当客户端收到HTTP 404响应包含会话ID的请求时,它必须通过发送不带会话ID的新
InitializeRequest来启动新会话。 - 不再需要特定会话的客户端(例如,因为用户离开了客户端应用程序)应该向MCP端点发送HTTP DELETE请求,并包含
Mcp-Session-Id标头,以显式终止会话。- 服务器可以响应此请求,并返回HTTP 405 Method Not Allowed,指示服务器不允许客户端终止会话。
序列图
向后兼容性
客户端和服务器可以通过以下方式保持与弃用的HTTP+SSE传输(来自协议版本2024-11-05)的向后兼容性: 服务器希望支持旧客户端应该:- 继续托管旧传输的SSE和POST端点,以及新定义的“MCP端点”。
- 也可以将旧POST端点和新MCP端点合并,但这可能会引入不必要的复杂性。
- 从用户那里接受MCP服务器URL,它可能指向使用旧传输或新传输的服务器。
- 尝试向服务器URL发送
InitializeRequest,带有上面定义的Accept标头:- 如果成功,客户端可以假设这是一个支持新可流式HTTP传输的服务器。
- 如果失败并返回HTTP 4xx状态码(例如,405 Method Not Allowed或404 Not Found):
- 发出GET请求到服务器URL,期望它将打开SSE流并返回第一个事件
endpoint。 - 当
endpoint事件到达时,客户端可以假设这是一个运行旧HTTP+SSE传输的服务器,并且应该使用该传输进行所有后续通信。
- 发出GET请求到服务器URL,期望它将打开SSE流并返回第一个事件