首先本文的面向对象是开发人员,所以直接聚焦 MCP 的运行交互逻辑,跳过产品方向的功能解释。
MCP的存在意义
MCP作为一个双端交互协议,其核心在于通过jsonrpc机制,使LLM的客户端能够清晰地了解服务器所具备的各项能力。
运行逻辑四步走
1. 初始化
在初始化阶段,客户端会向服务端发送一个initialize
请求,该请求中包含了客户端的相关能力信息。服务端在接收到该请求后,会回复一个包含服务端能力信息的报文。对于 http 请求还会额外通过 header 返回 mcp-session-id
。此后的所有请求,客户端都需要在 header 中携带这个mcp-session-id
参数。
-
入参示例:
{ "jsonrpc": "2.0", "id": 0, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": { "sampling": {}, "roots": { "listChanged": true } }, "clientInfo": { "name": "mcp-inspector", "version": "0.11.0" } } }
-
返回示例:
{ "id": 0, "jsonrpc": "2.0", "result": { "capabilities": { "tools": { "listChanged": false } }, "protocolVersion": "2024-11-05", "serverInfo": { "name": "小助手", "version": "1.0.0" } } }
2. 初始化完成通知
客户端在成功接收到服务端的初始化回复后,会向服务端发送一个notifications/initialized
通知,告知服务端初始化已完成。此步骤的回复通常为一个简单的状态码(如202),不需要包含消息体。
-
入参示例:
{ "jsonrpc": "2.0", "method": "notifications/initialized" }
-
回复:202(无需消息体)
3. 加载工具列表
客户端接下来会向服务端发送一个tools/list
请求,以获取服务端提供的工具列表。服务端在接收到该请求后,会返回一个包含工具详细信息的报文。
-
入参示例:
{ "jsonrpc": "2.0", "method": "tools/list", "params": {}, "id": "123" }
-
返回示例:
{ "id": "123", "jsonrpc": "2.0", "result": { "tools": [ { "annotations": { "title": "xx" }, "description": "xxx", "inputSchema": { "properties": { "param1": { "description": "xxx", "type": "string" } }, "required": [ "param1" ], "type": "object" }, "name": "tool_name_xxxxx" } ] } }
4. 执行方法调用
最后,客户端会根据需要调用某个具体的工具,发送一个tools/call
请求。服务端在接收到该请求后,会执行相应的工具,并返回一个包含执行结果的报文。
-
入参示例:
{ "method": "tools/call", "params": { "name": "tool_name_xxxxx", "arguments": { "param1": "北京" } }, "jsonrpc": "2.0", "id": 21 }
-
返回示例:
{ "id": 21, "jsonrpc": "2.0", "result": { "content": [ { "text": "xxxxxxxxxxxxxxx", "type": "text" } ] } }
到这一个最简单模型的交互流程就完成了,只要服务端按上面的格式返回就是可用的。
关于MCP交互协议
MCP一共三种交互协议,出入参的报文规划一致,只在具体的交互方式上存在差异:
- stdio:入参和出参分别对应输入、输出流。
- sse(Server-Sent Events):入参通过POST请求提交,返回结果通过SSE获取。不过,这种协议目前已不推荐使用。
- streamHTTP:通过普通的HTTP请求和响应进行交互,是综合最优的选择,既便于客户端接入,也便于服务端进行扩展。
对于VO(View Object)对应的字段和详细解释,可以参考MCP的官方schema文档。
对于其它协议细节可以参考MCP官方文档
发表回复