MCP是一种轻量级协议,用于在语言模型和托管它的运行时之间建立双向通信,使模型可以调用外部工具,访问上下文信息,并于宿主系统进行结构化数据交换。它的核心思想是创建一个通过的“语言”和“接口”,解决AI生态系统中M个模型与N个工具/数据源集成时的M×N复杂性问题。
MCP的核心架构与组件
MCP遵循 客户端-服务器(Client-Server)架构,但其中引入了一个额外的角色:Host (宿主应用)。
-
Host (宿主应用)
- 用户之间交互AI的应用,比如Claude Desktop、一个IDE(集成开发环境)中AI助手、一个企业内部聊天机器人页面等。
- 它负责解释用户的请求,并在需要时与MCP客户端协作来获取上下文或执行工具。
- Host 内部包含 MCP Client
-
MCP Client (客户端)
- 一个轻量化的协议客户端,通常内置在Host应用中。
- 负责与MCP Service 建立并维护连接
- 主要职责是将Host 或LLM发出的工具调用请求翻译成MCP协议格式的消息,发送给MCP Service。
- 同时,也负责接收MCP Service 返回的结果,并将其传递回Host 或LLM。
- 负责会话管理、中断处理、超时、重连和错误处理等。
-
MCP Service (服务器)
- MCP架构的核心,负责 暴露具体的能力给AI模型。
- 每个MCP Service 可以封装一个或多个工具(Tools)、资源(Resource) 或提示词模板(Prompt)
- 当MCP Client 发送请求时,MCP Service 会执行相应的工具,查询数据源或提供预定义的提示内容
- MCP Service的设计原则是 轻量级且高度可组合,它只关注 特定、明确的功能,不应该“看到” LLM的完整对话历史,从而增强安全性和隔离性。
协议内容与消息格式
MCP 协议的核心通信机制是基于 JSON-RPC 2.0. 所有在客户端和服务器之间交换的消息都是 JSON 格式的,并且遵循 JSON-RPC 2.0 的规范。三种基本消息类型如下
-
请求(Requests)
- 由客户端发个服务器,用于发起一个操作
- 格式示例
-
{ "jsonrpc": "2.0", "id": 1, // 唯一的请求标识符 "method": "tools/call", // 要调用的方法名,例如 "tools/call" 或 "resources/read" "params": { // 方法的参数 "name": "weather_api", "arguments": { "location": "Singapore" } } }
- 解释: 在这个例子中,客户端请求服务器调用名为
weather_api
的工具,并传入location="Singapore"
作为参数。
-
响应(Responses):
-
由服务器返回给客户端,用于回应一个请求。
-
包含与原请求相同的id
-
成功响应格式示例
-
{ "jsonrpc": "2.0", "id": 1, "result": { // 操作成功的结果 "temperature": 30, "conditions": "Partly cloudy" } }
-
-
错误响应格式示例:
-
{ "jsonrpc": "2.0", "id": 1, "error": { // 操作失败的错误信息 "code": -32602, "message": "Invalid location parameter", "data": { "details": "The provided location 'Singapore' is invalid." } } }
-
-
-
通知(Notifications)
-
一种单向消息,不需要响应
-
通常由服务器发送给客户端,用于提供更新、进度信息或异步事件。
-
格式示例
-
{ "jsonrpc": "2.0", "method": "progress", // 方法名,例如 "progress" 或 "log" "params": { "message": "Processing data...", "percent": 50 } }
-
-
MCP 的传输机制
JSON-RPC 定义了消息格式,但 MCP 也指定了这些消息如何在客户端和服务器之间传输。主要的传输机制包括:
-
STDIO (标准输入/输出):
- 这是最简单的传输方式,适用于客户端和服务器在同一台机器上运行,或者作为同一个进程的不同子进程时。
- 客户端通过标准输出来发送请求,服务器通过标准输出来接收请求;服务器通过标准输出来发送响应/通知,客户端通过标准输出来接收。
- 这种方式在本地开发和测试时非常方便。
-
HTTP/WebSocket (通常是 SSE - Server-Sent Events):
- 适用于客户端和服务器位于不同机器或需要跨网络通信的场景。
- 它允许更复杂的部署模式,例如远程 MCP 服务器。
- HTTP 通常用于发送请求,而 SSE 或 WebSocket 可以用于服务器向客户端发送实时更新和通知,保持连接的状态性。
MCP 的内部实现流程(简化版)
-
初始化与能力协商:
- MCP Client 连接到 MCP Server。
- 双方会进行一个初始化握手 (
initialize
请求/响应),交换协议版本、客户端/服务器信息,并协商各自支持的能力(例如,哪些工具可用、支持哪些资源类型、是否支持日志等)。这是一个关键步骤,确保了兼容性和功能发现。
-
工具/资源发现:
- LLM (通过 Host 和 Client) 可能首先会询问 MCP Server 有哪些可用的工具 (
tools/list
或在初始化阶段获取)。 - MCP Server 会返回可用工具的列表,包括它们的名称、描述和参数 schema (通常是 JSON Schema),以便 LLM 能够理解如何使用它们。
- LLM (通过 Host 和 Client) 可能首先会询问 MCP Server 有哪些可用的工具 (
-
LLM 推理与工具调用:
- 用户向 Host 应用提问。
- Host 将用户问题连同 MCP Server 提供的工具描述发送给 LLM。
- LLM 经过推理 (例如 ReAct 模式),决定需要调用某个工具。它生成一个工具调用请求的文本或结构。
- MCP Client 捕获 LLM 的工具调用意图,将其翻译成 MCP 的 JSON-RPC
tools/call
请求消息。
-
请求执行与结果返回:
- MCP Client 通过选定的传输机制(如 HTTP 或 STDIO)将
tools/call
请求发送给 MCP Server。 - MCP Server 接收请求,查找对应的工具实现(例如一个 Python 函数或一个对外部 API 的调用),并执行它。
- 工具执行完成后,MCP Server 将结果封装成 MCP 的 JSON-RPC 响应消息(
result
或error
),返回给 MCP Client。 - MCP Client 接收响应,将其格式化为 LLM 可以理解的文本(通常是
Observation:
格式) ,并将其作为新的上下文反馈给 LLM。
- MCP Client 通过选定的传输机制(如 HTTP 或 STDIO)将
-
LLM 继续推理或给出最终答案:
- LLM 接收到工具执行的
Observation:
后,继续其推理过程,最终给出用户问题的答案。
- LLM 接收到工具执行的
示例交互流程图