范围
Model Context Protocol 包括以下项目:- MCP 规范:MCP 的一份规范,概述了客户端和服务器的实现要求。
- MCP SDK:用于不同编程语言、实现 MCP 的 SDK。
- MCP 开发工具:用于开发 MCP 服务器和客户端的工具,包括 MCP Inspector
- MCP 参考服务器实现:MCP 服务器的参考实现。
MCP 仅专注于上下文交换协议——它不规定 AI 应用如何使用 LLM 或管理所提供的上下文。
MCP 概念
参与者
MCP 采用客户端-服务器架构,其中一个 MCP 主机——例如 Claude Code 或 Claude Desktop 这样的 AI 应用——会与一个或多个 MCP 服务器建立连接。MCP 主机通过为每个 MCP 服务器创建一个 MCP 客户端来实现这一点。每个 MCP 客户端都与其对应的 MCP 服务器保持专用连接。 使用 STDIO 传输的本地 MCP 服务器通常只服务于一个 MCP 客户端,而使用 Streamable HTTP 传输的远程 MCP 服务器通常会服务于多个 MCP 客户端。 MCP 架构中的关键参与者包括:- MCP 主机:协调并管理一个或多个 MCP 客户端的 AI 应用
- MCP 客户端:与 MCP 服务器保持连接,并从 MCP 服务器获取上下文供 MCP 主机使用的组件
- MCP 服务器:向 MCP 客户端提供上下文的程序
分层
MCP 由两层组成:- 数据层:定义基于 JSON-RPC 的客户端-服务器通信协议,包括生命周期管理,以及工具、资源、提示和通知等核心原语。
- 传输层:定义支持客户端与服务器之间数据交换的通信机制和通道,包括传输特定的连接建立、消息分帧和授权。
数据层
数据层实现了基于 JSON-RPC 2.0 的交换协议,定义了消息结构和语义。 这一层包括:- 生命周期管理:处理客户端与服务器之间的连接初始化、能力协商和连接终止
- 服务器功能:使服务器能够提供核心功能,包括供 AI 执行的工具、供上下文数据使用的资源,以及用于从客户端到客户端的交互模板提示
- 客户端功能:使服务器能够请求客户端从主机 LLM 进行采样,并向客户端记录日志消息
- 实用功能:支持额外能力,例如用于实时更新的通知,以及用于长时间运行操作的进度跟踪
传输层
传输层管理客户端与服务器之间的通信通道和身份验证。它处理连接建立、消息分帧以及 MCP 参与者之间的安全通信。 MCP 支持两种传输机制:- Stdio 传输:使用标准输入/输出流在同一台机器上的本地进程之间进行直接进程通信,提供无网络开销的最佳性能。
- Streamable HTTP 传输:使用 HTTP POST 进行客户端到服务器的消息传输,并可选地使用 Server-Sent Events 提供流式能力。该传输支持远程服务器通信,并支持标准 HTTP 身份验证方法,包括 bearer token、API key 和自定义请求头。MCP 推荐使用 OAuth 来获取身份验证令牌。
数据层协议
MCP 的核心部分是定义 MCP 客户端与 MCP 服务器之间的模式和语义。开发者很可能会发现数据层——尤其是 原语 集合——是 MCP 中最有趣的部分。它定义了开发者如何将上下文从 MCP 服务器共享给 MCP 客户端。 MCP 使用 JSON-RPC 2.0 作为其底层 RPC 协议。客户端和服务器会相互发送请求并作出相应响应。在不需要响应时可以使用通知。生命周期管理
MCP 是一种 ,因此需要生命周期管理。生命周期管理的目的是协商客户端和服务器都支持的 。详细信息可参见 规范,而 示例 展示了初始化序列。原语
MCP 原语是 MCP 中最重要的概念。它们定义了客户端和服务器可以彼此提供什么。这些原语指定了可与 AI 应用共享的上下文信息类型,以及可执行操作的范围。 MCP 定义了三种可由 服务器 暴露的核心原语:- 工具:AI 应用可以调用以执行操作的可执行函数(例如,文件操作、API 调用、数据库查询)
- 资源:向 AI 应用提供上下文信息的数据源(例如,文件内容、数据库记录、API 响应)
- 提示:帮助构建与语言模型交互的可复用模板(例如,系统提示、少样本示例)
*/list)、检索(*/get),以及在某些情况下执行(tools/call)。
MCP 客户端会使用 */list 方法来发现可用原语。例如,客户端可以先列出所有可用工具(tools/list),然后再执行它们。这种设计使列表内容可以是动态的。
作为一个具体示例,考虑一个提供数据库上下文的 MCP 服务器。它可以暴露用于查询数据库的工具、包含数据库模式的资源,以及包含用于与这些工具交互的少样本示例的提示。
有关服务器原语的更多细节,请参见 服务器概念。
MCP 还定义了可由 客户端 暴露的原语。这些原语使 MCP 服务器作者能够构建更丰富的交互。
- 采样:允许服务器从客户端的 AI 应用请求语言模型补全。当服务器作者希望使用语言模型,但又希望保持模型无关并且不在其 MCP 服务器中包含语言模型 SDK 时,这非常有用。他们可以使用
sampling/createMessage方法,从客户端的 AI 应用请求语言模型补全。 - 日志记录:使服务器能够向客户端发送日志消息,用于调试和监控。
- 任务(实验性):持久执行包装器,支持 MCP 请求的延迟结果检索和状态跟踪(例如,昂贵计算、工作流自动化、批处理、多步骤操作)
通知
该协议支持实时通知,以便在服务器和客户端之间进行动态更新。例如,当服务器可用工具发生变化时——例如新增功能可用或现有工具被修改——服务器可以发送工具更新通知,告知已连接的客户端这些变化。通知作为 JSON-RPC 2.0 通知消息发送(不期望响应),使 MCP 服务器能够向已连接的客户端提供实时更新。示例
数据层
本节通过一个逐步演示,讲解 MCP 客户端与服务器之间的交互,重点关注数据层协议。我们将使用 JSON-RPC 2.0 消息来展示生命周期序列、工具操作和通知。1
初始化(生命周期管理)
MCP 从通过能力协商握手进行生命周期管理开始。正如 生命周期管理 部分所述,客户端发送一个
initialize 请求以建立连接并协商支持的特性。理解初始化交换
初始化过程是 MCP 生命周期管理中的关键部分,并承担几个重要作用:-
协议版本协商:
protocolVersion字段(例如 “2025-03-26”)确保客户端和服务器都在使用兼容的协议版本。这可以防止不同版本尝试交互时可能出现的通信错误。如果无法协商出双方都兼容的版本,应终止连接。 -
能力发现:
capabilities对象允许双方声明他们支持哪些特性,包括他们可以处理哪些 原语(工具、资源、提示),以及是否支持诸如 通知 之类的特性。这通过避免不受支持的操作来实现高效通信。 -
身份交换:
clientInfo和serverInfo对象提供用于调试和兼容性目的的标识与版本信息。
"sampling": {}- 客户端声明其可以处理服务器的采样请求(可以接收sampling/createMessage方法调用)
"tools": {"listChanged": true}- 服务器支持工具原语,并且当其工具列表发生变化时可以发送tools/list_changed通知"resources": {}- 服务器也支持资源原语(可以处理resources/list和resources/read方法)
Notification
这在 AI 应用中如何工作
在初始化期间,AI 应用的 MCP 客户端管理器会连接到已配置的服务器,并保存它们的能力以供后续使用。应用会利用这些信息来确定哪些服务器可以提供特定类型的功能(工具、资源、提示),以及它们是否支持实时更新。Pseudo-code for AI application initialization
2
工具发现(原语)
现在连接已经建立,客户端可以通过发送
tools/list 请求来发现可用工具。这个请求是 MCP 工具发现机制的基础——它允许客户端在尝试使用之前了解服务器上有哪些工具可用。理解工具发现请求
tools/list 请求很简单,不包含任何参数。理解工具发现响应
响应包含一个tools 数组,提供了关于每个可用工具的完整元数据。这种基于数组的结构允许服务器同时暴露多个工具,同时保持不同功能之间的清晰边界。响应中的每个工具对象都包含几个关键字段:name:服务器命名空间内该工具的唯一标识符。这是工具执行的主键,应遵循清晰的命名模式(例如,使用calculator_arithmetic而不是简单的calculate)title:工具的人类可读显示名称,客户端可以展示给用户description:对工具功能以及何时使用的详细说明inputSchema:定义预期输入参数的 JSON Schema,可用于类型校验,并清晰地说明必填和可选参数
这在 AI 应用中如何工作
AI 应用会从所有已连接的 MCP 服务器获取可用工具,并将它们合并到一个统一的工具注册表中,供语言模型访问。这样,LLM 就能理解自己可以执行哪些操作,并在对话过程中自动生成合适的工具调用。Pseudo-code for AI application tool discovery
3
工具执行(原语)
客户端现在可以使用
tools/call 方法执行工具。这展示了 MCP 原语在实践中的使用方式:在发现可用工具之后,客户端可以使用适当的参数调用它们。理解工具执行请求
tools/call 请求遵循结构化格式,以确保客户端和服务器之间的类型安全与清晰通信。注意,我们使用的是发现响应中的正确工具名称(weather_current),而不是简化名称:工具执行的关键要素
请求结构包含几个重要组件:-
name:必须与发现响应中的工具名称(weather_current)完全匹配。这可确保服务器能够正确识别要执行的工具。 -
arguments:包含工具的inputSchema所定义的输入参数。在此示例中:location:“San Francisco”(必填参数)units:“imperial”(可选参数,若未指定则默认值为 “metric”)
-
JSON-RPC 结构:使用标准的 JSON-RPC 2.0 格式,并通过唯一的
id进行请求-响应关联。
理解工具执行响应
该响应展示了 MCP 灵活的内容系统:-
content数组:工具响应返回一个内容对象数组,允许丰富的多格式响应(文本、图片、资源等) -
内容类型:每个内容对象都有一个
type字段。在此示例中,"type": "text"表示纯文本内容,但 MCP 支持多种内容类型以适应不同场景。 - 结构化输出:响应提供了可操作的信息,AI 应用可以将其作为语言模型交互的上下文。
这在 AI 应用中如何工作
当语言模型在对话中决定使用某个工具时,AI 应用会拦截该工具调用,将其路由到相应的 MCP 服务器,执行后再将结果作为对话流程的一部分返回给 LLM。这样,LLM 就能访问实时数据,并在外部世界中执行操作。4
实时更新(通知)
MCP 支持实时通知,使服务器能够在未被显式请求的情况下告知客户端发生的变化。这展示了通知系统,这是保持 MCP 连接同步和响应迅速的关键功能。
理解工具列表变更通知
当服务器可用工具发生变化时——例如新增功能可用、现有工具被修改,或工具暂时不可用——服务器可以主动通知已连接的客户端:Request
MCP 通知的关键特性
-
无需响应:请注意通知中没有
id字段。这符合 JSON-RPC 2.0 的通知语义,即不期望也不发送响应。 -
基于能力:只有在初始化期间于工具能力中声明了
"listChanged": true的服务器才会发送此通知(如第 1 步所示)。 - 事件驱动:服务器根据内部状态变化决定何时发送通知,使 MCP 连接具有动态性和响应性。
客户端对通知的响应
收到此通知后,客户端通常会重新请求更新后的工具列表。这样就形成了一个刷新循环,使客户端对可用工具的理解始终保持最新:Request
为什么通知很重要
这种通知系统至关重要,原因如下:- 动态环境:工具可能会根据服务器状态、外部依赖或用户权限而出现或消失
- 效率:客户端无需轮询变化;当有更新时会收到通知
- 一致性:确保客户端始终拥有关于服务器可用能力的准确信息
- 实时协作:使响应式 AI 应用能够适应不断变化的上下文