Skip to main content
协议版本: 2025-03-26
MCP使用JSON-RPC编码消息。JSON-RPC消息必须使用UTF-8编码。 协议当前定义了两种标准传输机制用于客户端-服务器通信:
  1. stdio,通过标准输入和标准输出进行通信
  2. 可流式HTTP
客户端应该尽可能支持stdio。 客户端和服务器也可以以可插拔方式实现自定义传输

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传输。请参阅下面的向后兼容性指南。
可流式HTTP传输中,服务器作为独立进程运行,可以处理多个客户端连接。此传输使用HTTP POST和GET请求。服务器可以选择使用服务器发送事件(SSE)来流式传输多个服务器消息。这允许基本的MCP服务器,以及支持流式传输和服务器到客户端通知和请求的更丰富功能的服务器。 服务器必须提供一个支持POST和GET方法的单一HTTP端点路径(以下称为MCP端点)。例如,这可能是像https://example.com/mcp这样的URL。

安全警告

实现可流式HTTP传输时:
  1. 服务器必须验证所有传入连接的Origin标头,以防止DNS重绑定攻击
  2. 在本地运行时,服务器应该仅绑定到localhost(127.0.0.1)而不是所有网络接口(0.0.0.0)
  3. 服务器应该为所有连接实现适当的身份验证
没有这些保护措施,攻击者可能会使用DNS重绑定从远程网站与本地MCP服务器交互。

向服务器发送消息

从客户端发送的每个JSON-RPC消息必须是对MCP端点的新HTTP POST请求。
  1. 客户端必须使用HTTP POST向MCP端点发送JSON-RPC消息。
  2. 客户端必须包含一个Accept标头,列出application/jsontext/event-stream作为支持的内容类型。
  3. POST请求的正文必须是以下之一:
    • 单个JSON-RPC 请求通知_或_响应
    • 一个批处理一个或多个_请求和/或通知_的数组
    • 一个批处理一个或多个_响应_的数组
  4. 如果输入仅由(任意数量的)JSON-RPC _响应_或_通知_组成:
    • 如果服务器接受输入,服务器必须返回HTTP状态码202 Accepted,没有正文。
    • 如果服务器无法接受输入,它必须返回HTTP错误状态码(例如,400 Bad Request)。HTTP响应正文可以包含没有id的JSON-RPC 错误响应
  5. 如果输入包含任意数量的JSON-RPC 请求,服务器必须返回Content-Type: text/event-stream以启动SSE流,或返回Content-Type: application/json以返回一个JSON对象。客户端必须支持这两种情况。
  6. 如果服务器启动SSE流:
    • SSE流应该最终包含每个在POST正文中发送的JSON-RPC 请求_对应的一个JSON-RPC 响应。这些_响应可以批处理
    • 服务器可以在发送JSON-RPC 响应_之前发送JSON-RPC 请求_和_通知。这些消息应该与发起的客户端_请求_相关。这些_请求_和_通知可以批处理
    • 服务器不应该在为每个收到的JSON-RPC _请求_发送JSON-RPC _响应_之前关闭SSE流,除非会话过期。
    • 在所有JSON-RPC _响应_都已发送后,服务器应该关闭SSE流。
    • 断开连接可能随时发生(例如,由于网络条件)。因此:
      • 断开连接不应该被解释为客户端取消其请求。
      • 要取消,客户端应该明确发送MCP CancelledNotification
      • 为避免由于断开连接导致的消息丢失,服务器可以使流可恢复

监听来自服务器的消息

  1. 客户端可以向MCP端点发出HTTP GET请求。这可以用来打开SSE流,允许服务器与客户端通信,而无需客户端先通过HTTP POST发送数据。
  2. 客户端必须包含一个Accept标头,列出text/event-stream作为支持的内容类型。
  3. 服务器必须返回Content-Type: text/event-stream以响应此HTTP GET请求,或者返回HTTP 405 Method Not Allowed,指示服务器不提供此端点的SSE流。
  4. 如果服务器启动SSE流:
    • 服务器可以在流上发送JSON-RPC 请求_和_通知。这些_请求_和_通知_可以批处理
    • 这些消息应该与任何并发运行的JSON-RPC _请求_无关。
    • 服务器不得在流上发送JSON-RPC 响应,除非恢复与先前客户端请求相关的流。
    • 服务器可以在任何时候关闭SSE流。
    • 客户端可以在任何时候关闭SSE流。

多个连接

  1. 客户端可以同时保持多个SSE流的连接。
  2. 服务器必须在每个连接的流上发送其JSON-RPC消息;即,它不得在多个流上广播相同的消息。
    • 消息丢失的风险可能通过使流可恢复来降低。

可恢复性和重传

为了支持断开连接的恢复和可能丢失的消息的重传:
  1. 服务器可以id字段附加到其SSE事件,如SSE标准中所述。
    • 如果存在,ID必须在会话内的所有流中全局唯一,或在没有会话管理的情况下与特定客户端的所有流中全局唯一。
  2. 如果客户端希望在断开连接后恢复,它应该向MCP端点发出HTTP GET请求,并包含Last-Event-ID标头,以指示它收到的最后一个事件ID。
    • 服务器可以使用此标头来重放断开连接后应该发送的消息,并从该点恢复流。
    • 服务器不得重放应该在不同流上发送的消息。
换句话说,这些事件ID应该由服务器分配,以在特定流中充当游标。

会话管理

MCP“会话”由客户端和服务器之间的逻辑相关交互组成,始于初始化阶段。为了支持希望建立有状态会话的服务器:
  1. 使用可流式HTTP传输的服务器可以在初始化时分配会话ID,方法是将其包含在HTTP响应中的Mcp-Session-Id标头中,响应包含InitializeResult
    • 会话ID应该是全局唯一的和加密安全的(例如,安全生成的UUID、JWT或加密哈希)。
    • 会话ID必须仅包含可见的ASCII字符(从0x21到0x7E)。
  2. 如果服务器在初始化期间返回Mcp-Session-Id,则使用可流式HTTP传输的客户端必须在其后续HTTP请求的Mcp-Session-Id标头中包含它。
    • 需要会话ID的服务器应该响应不包含Mcp-Session-Id标头的请求(除了初始化请求),并返回HTTP 400 Bad Request。
  3. 服务器可以在任何时候终止会话,此后它必须响应包含该会话ID的请求,并返回HTTP 404 Not Found。
  4. 当客户端收到HTTP 404响应包含会话ID的请求时,它必须通过发送不带会话ID的新InitializeRequest来启动新会话。
  5. 不再需要特定会话的客户端(例如,因为用户离开了客户端应用程序)应该向MCP端点发送HTTP DELETE请求,并包含Mcp-Session-Id标头,以显式终止会话。
    • 服务器可以响应此请求,并返回HTTP 405 Method Not Allowed,指示服务器不允许客户端终止会话。

序列图

向后兼容性

客户端和服务器可以通过以下方式保持与弃用的HTTP+SSE传输(来自协议版本2024-11-05)的向后兼容性: 服务器希望支持旧客户端应该:
  • 继续托管旧传输的SSE和POST端点,以及新定义的“MCP端点”。
    • 也可以将旧POST端点和新MCP端点合并,但这可能会引入不必要的复杂性。
客户端希望支持旧服务器应该:
  1. 从用户那里接受MCP服务器URL,它可能指向使用旧传输或新传输的服务器。
  2. 尝试向服务器URL发送InitializeRequest,带有上面定义的Accept标头:
    • 如果成功,客户端可以假设这是一个支持新可流式HTTP传输的服务器。
    • 如果失败并返回HTTP 4xx状态码(例如,405 Method Not Allowed或404 Not Found):
      • 发出GET请求到服务器URL,期望它将打开SSE流并返回第一个事件endpoint
      • endpoint事件到达时,客户端可以假设这是一个运行旧HTTP+SSE传输的服务器,并且应该使用该传输进行所有后续通信。

自定义传输

客户端和服务器可以实现其他自定义传输机制,以满足其特定需求。协议是传输不可知的,可以在支持双向消息交换的任何通信通道上实现。 选择支持自定义传输的实现者必须确保它们保留MCP定义的JSON-RPC消息格式和生命周期要求。自定义传输应该记录其特定的连接建立和消息交换模式,以促进互操作性。