1. MCP 协议概述

MCP(Model Context Protocol)是一个基于 JSON-RPC 2.0 的标准化协议,定义了 LLM 应用(Host/Client)与外部工具/数据源(Server)之间的通信方式。

1.1 核心角色

角色 职责 举例
Host (Client) 建立连接、路由工具调用、管理生命周期 Claude Code、Cursor 等
MCP Server 提供工具定义、执行实际逻辑 文件系统、数据库、自定义 API
LLM 模型 基于工具定义决策是否调用、调用哪个 Claude、GPT 等

1.2 架构概览

JSON-RPC 2.0
stdio / HTTP+SSE

LLM API 调用

LLM Host
(管理者)

MCP Server
(执行者)

LLM 模型
(推理引擎)

关键认知:LLM 模型本身不知道 MCP Server 的存在。Host 才是真正的"连接管理者",LLM 只负责决策。


2. 传输层

MCP 支持两种传输方式:

2.1 stdio(本地场景,最常用)

Host 将 MCP Server 作为子进程启动,通过 stdin/stdout 传输 JSON-RPC 消息:

  • 每条 JSON-RPC 消息占一行,\n 分隔
  • stderr 保留给日志输出
  • 适合本地开发、CLI 工具

2.2 HTTP + SSE(远程场景)

  • Server 作为 HTTP 服务启动,暴露 SSE 端点
  • Client 通过 HTTP POST 发送请求
  • 通过 SSE 接收 Server 推送的响应
  • 适合跨网络、跨进程的远程场景

3. 交互全流程

3.1 建立连接与初始化

连接建立后,Host 和 Server 进行能力交换:

Client 发送 initialize 请求

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

Server 返回 initialize 响应

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

随后 Client 发送 notifications/initialized 通知,握手完成。

3.2 能力发现

Host 查询 Server 提供了哪些能力:

{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }

Server 响应:

{
  "jsonrpc": "2.0", "id": 2,
  "result": {
    "tools": [
      {
        "name": "read_file",
        "description": "读取文件内容",
        "inputSchema": {
          "type": "object",
          "properties": {
            "file_path": { "type": "string", "description": "文件绝对路径" }
          },
          "required": ["file_path"]
        }
      }
    ]
  }
}

4. 工具定义如何进入 LLM 上下文

这是理解 Agent Loop 的关键环节。

4.1 格式转换

MCP Server 返回的工具定义(inputSchema)本身就是 JSON Schema,与主流 LLM API 的 tool format 高度兼容,Host 只需做简单字段映射:

MCP 格式 Anthropic API 格式 OpenAI API 格式
inputSchema input_schema function.parameters
name name function.name
description description function.description

4.2 请求体结构

工具定义作为 顶层字段 传入,与 messages 平级:

{
  "model": "claude-sonnet-4-6",
  "max_tokens": 4096,
  "tools": [
    {
      "name": "read_file",
      "description": "读取文件内容",
      "input_schema": { ... }
    }
  ],
  "messages": [
    { "role": "user", "content": "帮我读取 /tmp/test.txt" }
  ]
}

4.3 内部序列化

LLM 服务端收到请求后,在内部将 tools 序列化为系统级提示词的一部分,拼入上下文窗口:

tools tokens
工具定义

统一 token 流

system prompt tokens
角色设定

message tokens
用户消息和历史

Transformer 模型推理

最终整个 token 序列输入 Transformer 模型。

4.4 tools 与 messages 的关系

LLM 上下文

API 请求体

客户端本地存储

tools
工具配置

messages
对话历史

tools + messages

统一 token 流

关键区别

维度 tools messages
持久化在对话历史里?
每轮 API 调用都传? 是(重新拼接) 是(完整历史)
能被动态修改? 是(随时增减工具) 否(已发送的消息不能改)
上下文压缩时被截断? 否(受保护) 是(中间消息可能被压缩)

tools 是"能力配置",messages 是"对话记录",两者在客户端分开管理,每次请求时临时组装。对话历史中永远只存消息本身,不包含工具 schema。


5. Agent Loop 完整流程

5.1 流程图

用户输入

Host 追加到 messages
拼接 tools 与 messages

POST /v1/messages
发给 LLM API

LLM 内部序列化
tools 转 system tokens
messages 转 message tokens

Transformer 推理

需要工具调用?

返回文本给用户

Host 解析 tool_use
路由到对应 MCP Server

JSON-RPC tools/call
MCP Server 执行实际逻辑

工具执行结果
text 或 image 或 resource

Host 追加 tool_result
到 messages

下一轮迭代
重新发送 tools 与 messages

用户

5.2 调用时序

MCP Server A MCP Router LLM API tools[] messages[] Host (Client) 用户 MCP Server A MCP Router LLM API tools[] messages[] Host (Client) 用户 第 N 轮对话 tools 是独立字段,不在 messages 中 内部序列化 system tokens + tools tokens + messages tokens Host 解析 tool_use 路由到对应 MCP Server 进入下一轮迭代 alt [直接回复 无需工具] [需要调用工具] 用户输入 1 追加 role user 到 messages 2 组装请求体 tools 与 messages 3 POST /v1/messages 携带 tools 与 messages 4 响应 文本 或 tool_use 5 追加 role assistant 文本 6 返回回答 7 追加 role assistant tool_use 8 JSON-RPC tools/call 携带 name 与 arguments 9 stdio 或 SSE 转发 10 执行结果 content text 11 JSON-RPC result 12 追加 role user tool_result 13 POST /v1/messages 含 tool_result 14 最终回答 或 继续 tool_use 15 追加 assistant 回复 16 返回回答 17

5.3 多 Server 场景

一个 Host 可以同时连接多个 MCP Server:

read_file write_file

query_db

create_ticket

Host Client
tools 包含 read_file write_file query_db create_ticket

MCP Server A
文件系统
read_file write_file

MCP Server B
数据库
query_db

MCP Server C
工单系统
create_ticket

当 LLM 返回 tool_use: read_file 时,Host 根据工具名称路由到对应的 MCP Server。


6. 关键约束与限制

约束 说明
工具数量上限 Anthropic 限制最多 50 个工具,OpenAI 通常限制 128 个
消耗上下文窗口 工具定义会消耗 token 额度,工具越多、schema 越复杂,占用越多
每轮必传 多轮对话中,tools 字段必须在每次 API 调用时都带上
影响延迟 工具定义越多,输入 token 越多,首 token 延迟越高

7. 总结

MCP 本质上是 LLM 与外部世界之间的"USB 接口":

  1. Host 从 MCP Server 获取工具 schema,转换为 LLM API 格式
  2. 工具定义作为顶层字段随每次 API 请求传入,不在对话历史中
  3. LLM 服务端将工具定义序列化为系统级提示词,拼入上下文窗口
  4. LLM 基于工具定义决策是否调用、调用哪个
  5. Host 通过 JSON-RPC 将调用请求路由到对应 MCP Server 执行
  6. 执行结果追加到对话历史,触发下一轮迭代

整个循环中,工具定义与对话历史是分开管理、临时组装的。这保证了工具列表不会因为对话变长而被压缩或截断。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐