MCP客户端与服务端之间的通信模式详解

1. 核心概述

MCP协议官方提供了两种主要通信方式:stdio(标准输入输出)和 SSE (Server-Sent Events,服务器发送事件)。这两种方式均采用全双工通信模式,通过独立的读写通道实现服务器消息的实时接收和发送。本文将重点剖析基于SSE的实现方案,该方案不仅便于在浏览器中直观观察,还能作为实现其他通信方式(如WebSocket)的优质参考。

2. 通信架构图

3. 通信流程详解

3.1 建立 SSE 连接

客户端首先需要与服务端建立一个SSE长连接,该连接用于接收服务端推送的所有消息:http://localhost:8000/sse

实用提示:

  • 您可以直接在浏览器中打开此链接实时查看接收到的消息流
  • 同步使用curl、Postman等工具进行消息发送测试,便于双向操作验证

建立连接后,服务端会首先返回一个专用的消息发送端点(Endpoint),这是后续通信的关键:

event: endpoint
data: /messages/?session_id=2b3c8777119444c1a1b26bc0d0f05a0a

重要说明: 客户端之后发送的所有消息请求都必须指向这个专用Endpoint。当请求格式正确时,该Endpoint会返回一个”Accepted”状态码,但真正的服务器响应内容都是通过SSE端点异步推送的。

3.2 通信初始化流程

客户端需要完成两个关键的初始化步骤,确保通信渠道正常建立:

a) 发送初始化请求

客户端需要先向服务端发送初始化请求,表明自身身份和期望的通信参数:

curl -X POST 'http://localhost:8000/messages/?session_id=2b3c8777119444c1a1b26bc0d0f05a0a' -H 'Content-Type: application/json' -d '{
    "jsonrpc": "2.0",
    "id": 0,
    "method": "initialize",
    "params": {
      "protocolVersion": "2024-11-05",
      "capabilities": {},
      "clientInfo": {
        "name": "mcp",
        "version": "0.1.0"
      }
    }
}'

服务端会返回其支持的功能列表,便于客户端了解可用的交互能力:

event: message
data: {"jsonrpc":"2.0","id":0,"result":{"protocolVersion":"2024-11-05","capabilities":{"experimental":{},"prompts":{"listChanged":false},"resources":{"subscribe":false,"listChanged":false},"tools":{"listChanged":false}},"serverInfo":{"name":"weather","version":"1.3.0"}}}

b) 发送初始化完成通知

初始化协商完成后,客户端需要明确通知服务端初始化已完成:

curl -X POST 'http://localhost:8000/messages/?session_id=2b3c8777119444c1a1b26bc0d0f05a0a' -H 'Content-Type: application/json' -d '{
    "jsonrpc": "2.0",
    "method": "notifications/initialized",
    "params": {}
}'

3.3 工具调用示例

MCP协议的核心价值在于其工具调用能力,以下是一个完整的调用流程:

a) 获取可用工具列表

客户端首先应该获取服务端提供的工具列表,如果已经知道其工具参数也可跳过,直接去调用工具:

curl -X POST 'http://localhost:8000/messages/?session_id=2b3c8777119444c1a1b26bc0d0f05a0a' -H 'Content-Type: application/json' -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list",
    "params": {}
}'

服务端会返回所有可用的工具及其参数规范:

event: message
data: {"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"get_alerts","description":"Get weather alerts for a US state.\n\n    Args:\n        state: Two-letter US state code (e.g. CA, NY)\n    ","inputSchema":{"properties":{"state":{"title":"State","type":"string"}},"required":["state"],"title":"get_alertsArguments","type":"object"}},{"name":"get_forecast","description":"Get weather forecast for a location.\n\n    Args:\n        latitude: Latitude of the location\n        longitude: Longitude of the location\n    ","inputSchema":{"properties":{"latitude":{"title":"Latitude","type":"number"},"longitude":{"title":"Longitude","type":"number"}},"required":["latitude","longitude"],"title":"get_forecastArguments","type":"object"}}]}}

b) 调用特定工具

客户端根据需求,选择并调用特定工具:

curl -X POST 'http://localhost:8000/messages/?session_id=2b3c8777119444c1a1b26bc0d0f05a0a' -H 'Content-Type: application/json' -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {"name": "get_alerts", "arguments": {"state": "CA"}}
}'

服务端执行工具调用并返回结果:

event: message
data: {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"\nEvent: Wind Advisory\nArea: San Gorgonio Pass Near Banning\nSeverity: Moderate\nDescription: * WHAT... \n"}],"isError":false}}

4. 通信特点

  1. 双向异步通信 : 接收通道通过 SSE 长连接接收服务端消息,发送通道通过 HTTP POST 向专用端点发送客户端消息
  2. 会话状态管理 :使用 session_id 维护客户端与服务端的会话状态,支持多客户端并发连接
  3. 标准通信协议 :基于 JSON-RPC 2.0 规范,确保通信格式统一,便于跨平台
  4. 可扩展性 :支持动态发现和调用服务端工具

5. 注意事项

  1. 所有客户端请求必须使用服务端分配的 Endpoint
  2. 初始化流程必须严格按照顺序完成

6. 结语

MCP协议通过其灵活而高效的通信机制,为客户端与服务端之间的交互提供了可靠保障。基于SSE的实现方案不仅便于开发和调试,还具备良好的性能表现。

对于开发者而言,深入理解MCP通信模式不仅有助于实现高质量的客户端应用,也为设计其他分布式通信系统提供了宝贵经验。希望本文的详细解析能为您的技术实践提供有益参考。


(文:NLP工程化)

欢迎分享

发表评论