前言

上一篇MCP介绍概念和背景,这一篇会重点以2025年3月26号最新版的MCP协议规范为背景,包括MCP协议生命周期、通讯方式及Server的功能规范,主要以Tool为主。

MCP协议生命周期

image-ztpj.png
如上步骤包括:
1、初始化
2、协议通讯
3、连接关闭

初始化

交互之前必须要进行的动作。
目的:包括确定通讯协议版本(协商)和交换实现能力说明。

1、客户端首先初始化并发送 initialize 请求(包括支持最新的版本、客户端实现的能力、客户端信息)

{  "jsonrpc": "2.0",  
   "id": 1,  
   "method": "initialize",  
   "params": {  "protocolVersion": "2025-03-26",  "capabilities": {  "roots": {  "listChanged": true  },  "sampling": {}  },  "clientInfo": {  "name": "ExampleClient",  "version": "1.0.0"  }  
   }  
 }

2、服务端响应它的能力和信息

{  "jsonrpc": "2.0",  
   "id": 1,  
   "result": {  "protocolVersion": "2025-03-26",  "capabilities": {  "logging": {},  "prompts": {  "listChanged": true  },  "resources": {  "subscribe": true,  "listChanged": true  },  "tools": {  "listChanged": true  }  },  
   "serverInfo": {  "name": "ExampleServer",  "version": "1.0.0"  },  
   "instructions": "Optional instructions for the client"  } 
}

3、初始化成功后,客户端必须发送一个 initialized 通知给服务端,说明其可以准备正常的操作了。

{  "jsonrpc": "2.0",  
   "method": "notifications/initialized"  
}

初始化后就是正常的消息交换,消息类型JSON-RPC 2.0,客户端和服务商双方应该就初始化期间协商的协议版本和能力进行通讯。

另外,如果通讯过程中,出现失败情况,返回错误信息:

{  "jsonrpc": "2.0",  
   "id": 1,  
   "error": {  "code": -32602,  "message": "Unsupported protocol version",  "data": {  "supported": ["2024-11-05"],  "requested": "1.0.0"  }  
   }  
}

MCP协议通讯方式

MCP使用JSON-RPC编码消息,消息本身需要是UTF-8编码。
据最新(25-03-26版本)规范,通讯协议定义了两种模式:stdioStreamable HTTP。其中Streamable HTTP取代SSE + HTTP方式。

协议说明Client端要尽可能支持stdio模式。

stdio

image-nedb.png

首先,Client启动Server服务作为一个子进程;
然后,双方通过输入、输出流写入数据进行通讯;
最后,通讯结束,Client关闭子进程。

例如,npx,java,uv 分别启动 js/ts,java,python/lua语言的MCP Server。

Streamable HTTP

该模式下,MCP Server可以处理多个客户端连接。

1、MCP服务端会提供一个endpoint,即支持Get请求,也支持Post请求。
2、MCP客户端发送消息需要包括Accept header,包括application/json、text/event-stream
3、MCP客户端通过GET请求打开一个SSE stream,同时Accept为text/event-stream。
4、MCP服务端不在响应流上响应JSON-RPC格式数据。
5、如果要使用有状态的通讯方式,使用Mcp-Session-Idheader进行传输,包括在初数据连接阶段。

SSE + HTTP(被取代)

虽然SEE被渐渐取代,了解下其实现与弊端。
image-zlru.png
服务器端必须实现两个端点:
1、一个SSE端点,用来和客户端建立连接,及发送消息
2、一个正常的HTTP端点,用来接收客户端的请求

当有客户端连接的时候,服务端会发送一个HTTP端点,用来告知客户端发送消息使用。

弊端:
1、需要长连接,消耗资源
2、强依赖会话粘性,不利于水平扩容
3、断开连接后,必须重新建立连接

MCP Server功能

通过Client和Server为LLM提供三种附加能力:
1、提示词:用于设置模型指令的说明;由用户控制,如指令。
2、工具:提供模型执行行为并获取反馈;由模型控制,如文件内容、git历史。
3、资源:为模型提供额外的结构化数据和内容;由应用控制,如api 请求。

下面以Tool工具为例,说明Server的功能。
工具是提供给大模型,供大模型决策使用哪个工具来获取需要的内容,如查询数据库、请求api或执行计算。
image-iblh.png
Tool协议消息有如下:
1、客户端获取工具列表

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {
    "cursor": "optional-cursor-value"
  }
}

2、客户端调用工具

{  "jsonrpc": "2.0",  
   "id": 2,  
   "method": "tools/call",  
   "params": {  "name": "get_weather",  "arguments": {  "location": "New York"  }  }  
}

3、服务端发送变更通知

{  
   "jsonrpc": "2.0",  
   "method": "notifications/tools/list_changed"  
}

Tool响应的结果类型包括有text、image、audio。

总结

通讯模式不管是SEE+HTTP还是 Streamable HTTP,都是需要经过初始化阶段的。因为SEE+HTTP的弊端目前已经被Streamable HTTP所取代,但是对于java-sdk目前还在开发中,python、ts等生态已经有相关依赖包支持最新的Streamable HTTP,其部署扩容下更方便,同时支持有状态和无状态请求调用。