协议规范

Model Context Protocol 的详细技术规范

协议概述

模型上下文协议 (MCP) 遵循客户端-主机-服务器架构,其中每个主机可以运行多个客户端实例。该架构使用户能够跨应用程序集成 AI 能力,同时保持清晰的安全边界并隔离问题。MCP 基于 JSON-RPC 构建,提供了一个有状态会话协议,专注于客户端和服务器之间的上下文交换和采样协调。

架构

核心组件架构如下所示:

组件详情

主机

主机进程是 MCP 协议的核心协调者。它负责管理客户端实例的生命周期,控制连接权限,并执行安全策略。主机还负责协调 AI/LLM 集成,确保整个系统的平稳运行。

管理客户端实例的生命周期
控制连接权限和执行安全策略
协调 AI/LLM 集成
确保系统稳定运行

客户端

客户端由主机创建,用于维护与服务器的独立连接。每个客户端都与一个服务器保持 1:1 的关系,确保连接的隔离性和安全性。

维护与服务器的独立连接
建立有状态会话
处理协议协商
管理消息路由

服务器

服务器负责公开资源和工具,可以独立运行并通过客户端请求采样。服务器可以是本地的也可以是远程的,为系统提供各种功能。

公开特定的资源和工具
独立运行和管理
通过客户端处理请求
支持本地和远程服务

协议基础

MCP 中的所有消息必须遵循 JSON-RPC 2.0 规范。协议定义了三种类型的消息:

请求

双向消息,可以从客户端发送到服务器,也可以反向发送

必须包含字符串或整数类型的 ID
ID 不能为 null
在同一会话中,请求方不能重复使用相同的 ID
可以包含可选的参数对象

请求示例

{
  "jsonrpc": "2.0",
  "id": "string | number",
  "method": "string",
  "param?": {
    "key": "value"
  }
}

响应

作为对请求的回复而发送

必须包含与对应请求相同的 ID
必须设置 result 或 error 其中之一,不能同时设置
错误码必须是整数
可以包含可选的结果数据

响应示例

{
  "jsonrpc": "2.0",
  "id": "string | number",
  "result?": {
    "[key: string]": "unknown"
  },
  "error?": {
    "code": "number",
    "message": "string",
    "data?": "unknown"
  }
}

通知

不需要响应的单向消息,可以从客户端发送到服务器,也可以反向发送

不能包含 ID 字段
用于状态更新和事件通知
可以包含可选的参数对象
减少通信开销,支持异步操作

通知示例

{
  "jsonrpc": "2.0",
  "method": "string",
  "params?": {
    "[key: string]": "unknown"
  }
}

生命周期

MCP 为客户端-服务器连接定义了严格的生命周期,确保正确的能力协商和状态管理。

初始化阶段

初始化阶段必须是客户端和服务器之间的第一次交互。在此阶段,双方:

建立协议版本兼容性
交换和协商能力
共享实现细节

初始化请求

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": {
        "listChanged": true
      },
      "sampling": {}
    },
    "clientInfo": {
      "name": "ExampleClient",
      "version": "1.0.0"
    }
  }
}

初始化响应

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "logging": {},
      "prompts": {
        "listChanged": true
      },
      "resources": {
        "subscribe": true,
        "listChanged": true
      },
      "tools": {
        "listChanged": true
      }
    },
    "serverInfo": {
      "name": "ExampleServer",
      "version": "1.0.0"
    }
  }
}

初始化完成通知

{
  "jsonrpc": "2.0",
  "method": "initialized"
}

版本协商

在初始化请求中,客户端必须发送其支持的协议版本。

客户端应发送其支持的最新版本
服务器必须响应相同版本或其支持的其他版本
如果客户端不支持服务器的版本,应断开连接

能力协商

客户端和服务器能力确定会话期间可用的可选协议功能。

客户端能力

roots
提供文件系统根目录的能力
sampling
支持 LLM 采样请求
experimental
描述对非标准实验性功能的支持

服务器能力

prompts
提供提示模板
resources
提供可读资源
tools
提供可调用工具
logging
发出结构化日志消息
experimental
描述对非标准实验性功能的支持

操作阶段

在操作阶段,客户端和服务器根据协商的能力交换消息。

遵守协商的协议版本
仅使用成功协商的能力

关闭阶段

在关闭阶段,连接被优雅地终止。

客户端发送断开连接通知
服务器关闭连接
清理相关资源

传输机制

MCP 目前定义了两种标准的客户端-服务器通信传输机制:stdio(标准输入输出)和基于 SSE 的 HTTP。客户端应尽可能支持 stdio。此外,客户端和服务器也可以以可插拔的方式实现自定义传输机制。

标准输入输出(stdio)

在 stdio 传输机制中:

  • 客户端将 MCP 服务器作为子进程启动
  • 服务器通过标准输入(stdin)接收 JSON-RPC 消息,并通过标准输出(stdout)写入响应
  • 消息以换行符分隔,且不能包含嵌入的换行符
  • 服务器可以将 UTF-8 字符串写入标准错误(stderr)用于日志记录。客户端可以捕获、转发或忽略这些日志
  • 服务器不能向标准输出写入任何非有效 MCP 消息的内容
  • 客户端不能向服务器的标准输入写入任何非有效 MCP 消息的内容

基于 SSE 的 HTTP

在 SSE 传输机制中,服务器作为独立进程运行,可以处理多个客户端连接。

服务器必须提供两个端点:

  • SSE 端点 - 用于客户端建立连接并接收来自服务器的消息
  • HTTP POST 端点 - 用于客户端向服务器发送消息
  • 当客户端连接时,服务器必须发送一个包含客户端用于发送消息的 URI 的 endpoint 事件
  • 所有后续的客户端消息必须作为 HTTP POST 请求发送到此端点
  • 服务器消息作为 SSE message 事件发送,消息内容以 JSON 格式编码在事件数据中

自定义传输机制

��户端和服务器可以实现额外的自定义传输机制以满足其特定需求。协议与传输机制无关,可以在任何支持双向消息交换的通信通道上实现。

  • 选择支持自定义传输机制的实现者必须确保保留 MCP 定义的 JSON-RPC 消息格式和生命周期要求
  • 自定义传输机制应该记录其特定的连接建立和消息交换模式,以帮助实现互操作性

服务端功能

服务器提供了通过 MCP 将上下文添加到语言模型的基本构建块,提供了三个基本原语来管理上下文:提示词、资源和工具。

原语控制描述示例
提示词系统定义模型的行为和角色你是一个专业的代码审查者
资源用户提供额外的上下文信息代码文件、文档
工具系统/用户扩展模型的能力代码搜索、文件编辑

资源管理

为AI模型提供上下文和数据

  • 支持多种资源类型
  • 动态资源加载
  • 资源生命周期管理

工具集成

扩展AI模型的能力范围

  • 灵活的工具注册机制
  • 工具调用权限控制
  • 异步工具执行支持

上下文控制

精确控制AI模型的行为

  • 系统级提示词管理
  • 动态上下文更新
  • 多轮对话状态维护