引言
之前内容中,我们介绍了MCP的基础内容,并简单实现了一个获取天气信息的MCP服务器。总之,MCP就像是LLM所使用的HTTP协议,LLM可以通过使用MCP协议从网络中获取资源,其架构也与HTTP类似。本节将介绍MCP协议核心概念与协议字段
概念
概念来自于官方文档,具体内容包含个人理解
MCP通信
MCP层主要处理消息帧、请求/响应链接和高级通信模式。其主要支持两种通讯方式
-
标准IO流
- 使用标准输入/输出进行通信
- 面向字节流(Windows系统可能要处理编码问题)
- 仅适用于本地进程
-
HTTP+SSE
- 使用服务器发送事件(SSE)进行服务器到客户端的消息传输
- 使用 HTTP POST 进行客户端到服务器的消息传输
- 适用于网络传输
生命周期
初始化阶段

这个阶段主要涉及到初始化请求、初始化响应、以及初始化通知
- 客户端发送带有协议版本和功能的
initialize
请求 - 服务器响应其协议版本和功能
- 客户端发送
initialized
通知作为确认 - 开始正常的消息交换
上面是初始化请求的抓包结果
上面是对初始化请求响应的抓包结果
上面是初始化通知的抓包结果
通信阶段
初始化后,支持以下模式:
- 请求-响应: 客户端或服务器发送请求,另一方响应
- 通知: 任何一方发送单向消息
断开链接
任何一方都可以终止连接:
- 通过
close()
进行优雅关闭 - 传输断开
- 错误条件
消息格式
该部分将介绍协议的格式。模型上下文协议(MCP)中的传输为客户端和服务器之间的通信提供基础。传输层负责处理消息如何发送和接收的底层机制。
MCP协议使用HTTP作为自己的底层协议,使用JSONRPC格式进行传输,其主要有四类消息
- 请求:客户端向服务端请求
- 响应:服务端向客户端响应
- 通知:客户端通知服务端,不需要响应
- 错误:告知请求出现错误
请求消息
在上方初始化请求时,消息格式就是请求消息
json
{
jsonrpc: "2.0", // jsonrpc的版本号
id: number | string, // 请求的id号
method: string, // 当前请求想调用的方法
params?: {
[key: string]: unknown;
} // 在此字段存放需要传递的参数
}
响应消息
json
{
jsonrpc: "2.0",
id: number | string, // 与请求的id相对应
// result与error二选一
result?: {
[key: string]: unknown;
},
error?: {
code: number,
message: string,
data?: unknown
}
}
通知
json
{
jsonrpc: "2.0",
method: string,
params?: {
[key: string]: unknown;
}
}
采样
虽然采样似乎看着难以理解,但实际功能描述非常简单。在MCP的架构中,分为三个部分,LLM + MCP Client(客户端层)
、MCP(协议端层)
、MCP Server + Service(服务端层)
。一般情况下,LLM利用MCP协议获取服务器服务。但在采样功能下,它允许服务端利用MCP调用LLM来获取回答。
采样工作原理
采样流程遵循以下步骤:
- 服务器向客户端发送
sampling/createMessage
请求 - 客户端审查请求并可以修改它
- 客户端从 LLM 采样
- 客户端审查补全结果
- 客户端将结果返回给服务器
工具
工具是模型上下文协议(MCP)中的一个强大原语,使服务器能够向客户端暴露可执行的功能。通过工具,LLM 可以与外部系统交互、执行计算并在现实世界中采取行动。通过工具,LLM不是知识一个单纯的对话模型,而是成为了一个可影响现实社会的Agent。
MCP 中的工具允许服务器暴露可执行的函数,这些函数可以被客户端调用并被 LLM 用来执行操作。工具的关键方面包括:
- 发现 :客户端可以通过
tools/list
端点列出可用工具 - 调用 :工具通过
tools/call
端点调用,服务器执行请求的操作并返回结果 - 灵活性:工具可以从简单的计算到复杂的 API 交互
为了方便展示,下面将使用MCP Server的SSE模式
tools/list
在连接到服务器之后,客户端去请求服务器的工具

服务器将按如下格式进行响应
json
// 放在result内tools内
{
name: string; // 工具的唯一标识符
description?: string; // 人类可读的描述
inputSchema: { // 工具参数的 JSON Schema
type: "object",
properties: { ... } // 工具特定的参数
}
}

tools/call
客户端通过如下格式调用

服务端则通过如下格式进行数据响应

由于使用中文字符,有些响应信息无法直接显示