MCP

MCP简介

通过一个通用的协议,解决AI应用与外部工具的集成难题,是MCP设计的出发点。

MCP采用主机-客户端-服务器架构。

MCP使用JSON-RPC作为客户端与服务器的通信基础。

JSON-RPC 2.0协议规范

请求对象

字段是否必填类型说明
jsonrpc字符串指定JSON-RPC协议的版本,必须为2.0
method字符串表示要调用的方法名
id字符串/数字/null用于将请求与对应的响应关联起来
params对象/数组包含传递给方法的参数

响应对象

字段是否必填类型说明
jsonrpc字符串指定JSON-RPC协议的版本,必须为2.0
id字符串/数字/null用于将请求与对应的响应关联起来
result对象响应成功时必须,表示方法调用的结果
error对象响应失败时必须,表示错误消息

批处理

请求方可以同时发送多个请求对象,并将它们封装在一个数组中。被请求方应返回一个包含对应响应对象的数组,但对于通知类型的请求,不应返回任何响应。

1[ 
2  { "jsonrpc": "2.0", "method": "sum", "params": [1, 2, 4], "id": "1" }, 
3  { "jsonrpc": "2.0", "method": "notify_hello", "params": [7] }, 
4  { "jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": "2" } 
5]
6[ 
7  { "jsonrpc": "2.0", "result": 7, "id": "1" }, 
8  { "jsonrpc": "2.0", "result": 19, "id": "2" } 
9]

MCP 连接生命周期

MCP连接生命周期主要分为三个阶段:

  • 初始化阶段,客户端与服务器进行协议版本和能力协商
  • 操作阶段,客户端与服务器按照协议正常通信,交换消息
  • 关闭阶段,客户端与服务器各自优雅地终止连接

MCP通信双方应为所有发送的请求设置超时,以防止连接挂起和资源耗尽。当请求在超时期间未收到成功响应或收到错误响应时,发送者应发出对该请求的取消通知并停止等待响应。

MCP通信双方应准备处理以下错误情况:

  • 协议版本不匹配
  • 无法协商所需能力
  • 请求超时

MCP 传输机制

MCP支持两种主要的传输机制:stdio传输和SSE传输。

stdio传输

stdio即standard input & output(标准输入/输出),是MCP推荐使用的一种传输机制,主要用于本地进程通信。

SSE传输

Server-Sent Events (SSE) 是一种Web标准,允许服务器向客户端推送实时数据。基于HTTP协议的单向通信机制,服务器可以持续向客户端发送数据流。

MCP支持使用SSE传输来解决远程资源访问的问题。底层基于HTTP通信,通过类似API的方式,让客户端直接访问远程资源,而不用通过stdio传输做中转。在SSE传输中,服务器作为一个独立进程运行,可以处理多个客户端连接。

服务器必须提供两个端点,分别是:

  • SSE端点,供客户端与服务器建立双向通信连接(GET请求)
  • 消息端点,供客户端向服务器发送消息(POST请求)

通信步骤如下:

  1. 客户端向服务器的SSE端点发送请求(一般是GET请求),建立SSE连接
  2. 服务器通过该连接发送事件消息,告知客户端发送所需要的端点地址
  3. 客户端根据地址向服务器发送消息请求
  4. 服务器返回状态码,确认已接收消息
  5. 服务器通过SSE连接向客户端推送处理结果或其他事件消息
  6. 客户端从SSE流中持续接收服务器发送的事件消息
  7. 通信结束之后,客户端关闭SSE连接

SSE传输适用于客户端和服务器不在同一网络下的通信场景。

SSE传输的主要优势如下:

  • 支持远程资源访问,解决了stdio传输仅适用于本地资源的问题
  • 基于HTTP实现,兼容性好,便于与现有Web基础设施集成
  • 服务器可作为独立进程运行,支持处理多个客户端连接
  • 相比WebSocket,实现更简单,因为它是HTTP的扩展,不需要协议升级

SSE传输的主要劣势如下:

  • 复杂的双通道响应机制,SSE传输要求服务器在接收客户端消息后,既要给当前请求响应,也要给之前建立的SSE连接发送事件消息,实现复杂
  • 连接不稳定,在无服务器环境中,SSE连接会随机、频繁断开,不能提供可靠连接
  • 不方便持久连接,无服务器架构通常自动扩缩容,不适合长时间连接,而SSE需要维持持久连接
  • 需要大量会话管理,SSE传输需要为每个SSE连接分配一个唯一的标识符(sessionId)来防止数据混淆,这意味着实现方必须承担额外的会话管理工作,增加了系统的实现复杂度
  • 额外实现成本,需要实现心跳检测和超时机制来避免资源泄露

流式HTTP传输

在流式HTTP传输中,服务器必须提供一个同时支持POST请求和GET请求的HTTP端点。

流式HTTP传输通信流程的主要步骤如下:

  1. 客户端向服务器的通信端点发送消息
  2. 服务器返回响应
  3. 客户端继续向服务器发送下一条消息
  4. 服务器继续响应客户端消息

MCP服务器能力

MCP为服务器的实现提供提示词(Prompts)、资源(Resources)、工具(Tools)三大核心能力:

提示词

MCP为服务器向客户端暴露提示词提供了一种标准方式。提示词允许服务器提供与大模型交互的结构化消息和指令。客户端可以发现可用的提示词,检索其内容,并提供自定义参数来使用它们。提示词被设计为由用户控制,这意味着它们从服务器暴露给客户端之后,由用户来进行选择和使用。通常,在客户端的UI界面中,用户通过输入命令来触发提示词,用户可以自然地发现和调用可用的提示词。

资源

MCP为服务器向客户端暴露资源提供了一种标准方式。资源允许服务器共享为大模型提供上下文的数据,例如文件、数据库结构或特定的应用程序信息。每个资源由一个URI(Uniform Resource Identifier,统一资源标识符)进行唯一标识。

MCP中的资源被设计为由应用驱动,也就是说由主机来根据其自身的需求,将服务器的资源融入其上下文。主机可以这样实现:

  • 通过一个列表或者目录树,显示可用的资源
  • 允许用户搜索和筛选可用的资源
  • 将资源整合到上下文中

工具

MCP允许服务器暴露可供大模型调用的各类工具,支持与外部系统交互,比如数据库查询、API调用、数据处理等。每一个工具必须定义唯一的标识符(name)和对其功能的描述(description)。

MCP中的工具设计为由模型控制,这意味着大模型可以根据其对上下文的理解和用户输入的内容自动发现和选择工具。

从信任和安全角度考虑,工具调用应该让用户感知,并且用户有拒绝调用工具的权利。

实现工具调用的应用应该:

  • 提供清晰的UI,以明确展示哪些工具被暴露给了大模型
  • 当工具被调用时,视觉呈现上要有明确的提示
  • 设置弹框用来提示用户确认对工具的调用操作

MCP客户端能力

MCP为客户端的实现提供了两个能力:

  • 根(root)
  • 采样(sampling)

基于这两个能力,客户端可以为服务器提供文件系统访问控制和大模型代理服务。

MCP为客户端提供了一种标准方式,使其能够向服务器暴露文件系统的“根”。根定义了服务器在文件系统中可以操作的边界,使它们能够理解自己有权访问哪些目录和文件。服务器可以从支持的客户端请求根列表,并在该列表发生变化时接收通知。

MCP中的根通常通过工作区或项目配置界面暴露。例如,主机可以提供工作区/项目选择器,允许用户选择服务器有权访问的目录和文件,也可以通过版本控制系统或打开的文件自动检测工作区。

根本质上是一种针对文件系统的访问控制机制。客户端根能力的设计,主要出于以下几方面的考虑:

  • 安全边界控制,为提升安全性,应限制服务器只能访问指定目录和文件,避免接触敏感或未授权的内容
  • 最小权限原则,服务器只有在需要操作文件系统时,才向客户端申请根列表,减少权限过大带来的安全风险
  • 用户控制和透明度,服务器操作文件系统时需要向客户端申请根列表,由用户选择同意或拒绝,操作过程对用户透明
  • 多项目隔离,服务器在操作不同项目时需要申请不同的根列表,实现多项目隔离

采样

MCP为服务器提供了一种标准方式,通过客户端请求大模型采样(补全或生成内容)。此流程允许客户端保持对模型访问、选择和权限的控制,同时使服务器能够利用大模型的能力,而无须在服务器端设置大模型的API密钥。

采样的本质是客户端为服务器调用大模型提供代理服务。客户端采样能力的设计,主要出于以下几方面的考虑:

  • 控制权分离与安全性。由客户端控制大模型的访问、选择和权限,服务器只关注功能实现,无须关注大模型的接入问题。大模型的API密钥由客户端统一管理,以提高安全性
  • 实现智能代理行为。服务器可以在处理复杂任务时通过客户端代理,动态调用大模型的能力。• 灵活的模型选择机制。采样允许服务器建议特定模型,并由客户端做最终决定
  • 支持多模态。采样支持文本、音频和图像交互,为复杂的AI应用场景提供基础