Model Context Protocol(模型上下文协议)
模型上下文协议(Model Context Protocol,MCP) 是 Anthropic 于 2024 年 11 月提出的开放标准,定义了 AI 模型与外部工具、数据源、服务之间的通信方式。目标是让任何 AI 客户端都能用同一套协议连接任何工具服务器,而不是为每对「模型 + 工具」单独写集成代码。
核心思路
传统做法:每个工具都要为每个模型单独实现一套集成,M 个模型 × N 个工具 = M×N 个集成。MCP 引入统一协议层,变成 M + N:工具只需实现一次 MCP 服务器,模型只需实现一次 MCP 客户端。
组成部分
- MCP 服务器(MCP Server):封装具体工具能力(读数据库、查 Issue、搜索文件等),对外暴露标准接口
- MCP 客户端(MCP Client):AI 模型或 Agent 框架,通过标准协议调用服务器提供的工具
- 工具(Tools):服务器提供的可调用函数,模型可以选择调用哪个、传什么参数
- 资源(Resources):服务器提供的可读数据(文件、数据库记录、API 响应等)
- 提示模板(Prompts):服务器提供的预设提示,供客户端复用
在循环工程中的作用
MCP 是Loop Engineering(循环工程)「插件与连接器」模块的底层实现机制。没有 MCP,每接入一个新工具都需要定制集成;有了 MCP,Agent 可以:
- 读取 Issue 跟踪系统(GitHub/Linear/Jira)
- 查询数据库或内部 API
- 在 Slack/飞书发通知
- 触发 CI/CD 流水线
- 调用任意内部系统
主流工具(Claude Code、Codex、Cursor 等)都支持通过 MCP 服务器扩展 Agent 能力。
Codex 的 CLI 会把用户在配置中接入的 MCP 工具转换为 Responses API(响应 API) 的工具定义,和内置 shell、计划工具、Web search 等一起提供给模型。Codex 的权限说明只约束自身提供的 shell 工具;MCP 服务器暴露的工具需要在服务器侧实现自己的权限边界和安全策略。
与传统函数调用的区别
| 维度 | Function Calling(函数调用) | MCP |
|---|---|---|
| 定义位置 | 在调用请求里临时声明 | 由外部服务器持久提供 |
| 复用性 | 每次请求都要重新传 schema | 一次部署,所有客户端共用 |
| 工具发现 | 由开发者手动指定 | 客户端可动态列举服务器提供的工具 |
| 跨模型 | 各家格式不同 | 统一协议,换模型不需改工具 |
两者也可以组合使用:客户端从 MCP 服务器发现工具,再把这些工具转换为目标模型 API 支持的 function/tool calling schema。此时 MCP 是工具供应和发现层,Function Calling 是模型请求工具调用时的表达层。
OpenAI 的 Responses API 也支持 Remote MCP:开发者可在 tools 中配置 type: "mcp"、服务器标签、说明、URL 和审批策略,让模型访问远程 MCP 服务器提供的能力。这个入口属于 OpenAI API Tools(OpenAI API 工具)的一部分;它降低了接入成本,但不替代 MCP 服务器自己的权限控制、工具描述治理和审计机制。
在 Responses API 中,Remote MCP 的运行过程更像“协议桥接”而不是普通函数定义注入:API 先向服务器列举工具,返回 mcp_list_tools;模型需要动作时再产生 mcp_call,由 API 向远程 MCP server 发起调用并把输出放回模型上下文。连接器场景下,OpenAI API Connectors也复用同一套 type: "mcp"、mcp_call 输出形态,只是配置项从 server_url 变成 connector_id。
这带来两个工程含义。第一,工具列举结果应尽量保留在对话上下文里,否则每轮重复发现工具会增加延迟。第二,大 MCP server 不宜完整暴露给模型:可以用 allowed_tools 限定导入范围,或用 defer_loading: true 配合 tool search 延迟加载函数定义。
Claude Messages API 中的 MCP connector 也扮演类似角色:把远程 MCP 服务器接入 Claude API Tools,让 Claude 在当前请求中发现并调用外部工具。这里 MCP 仍是工具供应和发现层,Claude tool_use / tool_result 是模型调用层的表达格式。
Claude Agent SDK也支持在 options 中声明 MCP servers,让 Claude Code 风格的 Agent 在自己的工具循环中连接 Playwright、数据库、内部 API 等外部能力。工程边界仍然相同:SDK 可以发现和调用 MCP 工具,但 MCP 服务器自己的权限、审计和工具描述治理不能被 SDK 自动代替。
Claude Code 中的 MCP 客户端实现
Claude Code 展示了 MCP 从“协议标准”落到编码 Agent harness 时会新增哪些工程问题。它不只是连接 server,还要处理配置作用域、信任确认、OAuth、工具上下文膨胀、工具输出体积、动态工具变化和人类审批。
Claude Code 支持 HTTP、SSE、stdio、WebSocket、插件内置 server 和 claude.ai connector。团队共享通常用 project scope,把配置写入 .mcp.json;个人实验或带私密凭证的 server 更适合 local/user scope。重名 server 按 local > project > user > plugin > claude.ai connector 覆盖,且整条 server 配置替换,不做字段级合并。这个设计把 MCP 配置也纳入了代码仓库信任模型:项目提交 .mcp.json 可以共享能力,但不能让克隆者在未信任仓库前自动执行任意 server。
在上下文管理上,Claude Code 默认启用 MCP tool search:启动时只加载工具名和 server instructions,具体工具 schema 等需要时再进入上下文。server 作者因此要把 server instructions 写得像工具目录的索引:说明工具类别、何时搜索、核心能力,并把关键内容放在前 2KB 内。若某个小型 server 的工具每轮都要可见,可以在配置里设置 alwaysLoad: true,代价是启动时阻塞连接并持续消耗上下文。
MCP 的三类能力在 Claude Code 里有不同用户界面:tools 由模型按需调用;resources 可用 @server:protocol://resource/path 像文件一样引用;prompts 会变成 /mcp__servername__promptname 形式的 slash command。它们共同说明 MCP 不只是 Function Calling(函数调用)的工具列表来源,也是一套把外部知识、流程和执行能力映射到 Agent 工作台的接口。
治理上,Claude Code 给 MCP server 作者提供了几种 Anthropic 专用 _meta 注解:anthropic/maxResultSizeChars 可提高特定文本工具的大结果阈值;anthropic/requiresUserInteraction 可要求某个工具每次调用都必须触达人类确认;anthropic/alwaysLoad 可让特定工具跳过 tool search 延迟加载。客户端还会处理 root-level anyOf / oneOf / allOf 这类 Claude API 不接受的 schema 形态,把它们压平成对象并在描述里提示参数组合,但最终仍要求 server 端重新校验参数组合。
这类实现细节强化了 MCP 的核心边界:协议能标准化发现和调用,但不能自动解决权限、最小 scope、输出分页、schema 兼容、工具投毒和 prompt injection。生产系统仍要把 MCP server 当作有执行能力的第三方程序来审查,而不是当成普通文档源。
Anthropic 后续的 containment 经验进一步强调:审查 MCP server 代码不等于审查 MCP server 返回的数据。一个 GitHub connector 可以通过了软件供应链审查,却把被投毒的 README 原样加载进模型上下文。任何会把外部内容放进 Agent 上下文的工具输出,都应按网页内容一样做 prompt injection 扫描;否则日志里最后只会看到一次“合法且授权”的 API 调用。
远程和本地 MCP 的信任边界也不同。本地工具可以读源码、pin 版本、纳入企业软件分发;远程 MCP server 或云 connector 在安装批准之后仍可能改变行为。对不在受审 connector directory 内的远程工具,应先用假数据和低 blast radius 环境试运行,再授予真实数据访问。
Claude Cowork 的架构变化也给 MCP 接入一个现实取舍:把本地 MCP server 放进 VM 会更难审计、依赖更脆弱,也无法连接 host 上的数据库或本地进程;把它放在 host 上更实用,但它就更像用户主动安装的软件,必须由管理员决定是否启用。Remote MCP server 不运行在本机,问题则转向数据权限、工具输出扫描和 connector 持续审查。
代码执行式 MCP
Anthropic 在《Code execution with MCP》中提出了另一种大规模 MCP 使用模式:代码执行式 MCP。核心做法不是把所有 MCP 工具定义都作为模型 tool schema 预先加载,而是把 server 和 tool 生成成代码 API 或文件树,让 Agent 在 Agent Sandbox(Agent 沙箱)里写代码调用 MCP 工具。
这个模式把 MCP 从“模型直接调用的一组工具”变成“代码可调用的外部能力库”。模型通过列目录、搜索工具或读取具体工具文件来渐进披露接口;长文档、表格和 transcript 等中间结果可以在执行环境里作为变量流动、过滤、聚合或写入另一个工具,只把摘要和必要样本返回给模型。
它对应 MCP 规模化后的新瓶颈:工具生态越大,直接把工具定义和工具结果塞进上下文越昂贵,也越容易触发 Context Engineering(上下文工程)里的上下文混乱和上下文腐烂。传统直连 MCP 通常有两类成本:
- 工具定义前置膨胀:模型在读用户请求前就要处理大量工具名称、描述、参数和返回值说明。
- 中间结果反复穿过模型:从一个工具读出的长文档、表格或 transcript,如果要写入另一个工具,往往先进入模型上下文,再由模型作为参数写出去。
Anthropic 的例子是“从 Google Drive 下载会议 transcript,再写入 Salesforce lead”。直连工具调用会让完整 transcript 通过上下文至少两次;2 小时会议可能额外消耗约 50,000 token,并增加复制错误概率。代码执行式 MCP 的关键是让 transcript 在执行环境中作为变量流动,模型只看到代码、必要日志和最终摘要。
一种实现方式是把所有 MCP server 生成成文件树,每个工具对应一个 TypeScript 文件:
servers/
├── google-drive/
│ ├── getDocument.ts
│ └── index.ts
└── salesforce/
├── updateRecord.ts
└── index.ts工具文件暴露普通函数,内部再调用 MCP client:
export async function getDocument(input: GetDocumentInput): Promise<GetDocumentResponse> {
return callMCPTool<GetDocumentResponse>("google_drive__get_document", input);
}Agent 通过列目录和读文件来发现能力:先看有哪些 server,再只打开当前任务需要的工具文件。这与上下文工程中的渐进披露一致:模型不需要一次性持有整个工具生态,只要知道去哪里查。
传统直连 MCP 的消息循环可以表示为:
sequenceDiagram
participant M as Model
participant C as MCP Client
participant S as MCP Server
C->>S: tools/list
S-->>C: tools/list result
C->>M: system prompt + tool definitions
M-->>C: tool call
C->>S: tools/call
S-->>C: tools/call result
C->>M: tool result enters context
代码执行式 MCP 在这个循环中插入执行环境:模型写代码,代码在沙箱里调用 MCP 工具、保存变量、过滤结果、执行循环和条件分支,最后只 console.log 或返回模型真正需要的摘要。
主要收益有五类:
- 渐进披露工具定义:把工具作为文件或可搜索 API 暴露,模型只读取相关接口。Anthropic 在示例中声称,这能把某类任务的工具定义上下文从 150,000 token 降到 2,000 token,节省 98.7%。
- 结果在模型外处理:读取 10,000 行表格后,可以在代码里筛选
Status === "pending",只打印前 5 行给模型审核。聚合、join、字段抽取和格式转换都可以在执行环境中完成,而不是让模型直接阅读全量结果。 - 复杂控制流更自然:循环、条件、等待、重试和错误处理可以用代码表达。比如轮询 Slack 是否出现部署完成通知,不必让模型在每次工具调用和 sleep 之间反复进入 Agent Loop(智能体循环)。
- 隐私边界更细:中间结果默认留在执行环境里,模型只看到显式日志。MCP client 还可以对 PII 做 tokenization:模型看见
[EMAIL_1]、[PHONE_1]这类占位符,真实值只在 Google Sheets 到 Salesforce 的工具调用路径中解 token。 - 状态和技能可持久化:Agent 可以把中间文件写入 workspace,后续执行继续读取;也可以把常用代码保存成函数,再配上
SKILL.md演化成 Agent Skills式的可复用能力。
代价也很明确:代码执行式 MCP 可以降低 token 和延迟,但把复杂度转移给 Harness Engineering(驾驭工程)。执行环境需要沙箱、资源限制、网络出口控制、敏感数据 tokenization、日志审计、MCP 工具权限治理,以及对 Agent 生成代码的超时、重试和异常包装。
因此它不替代 Agent-Computer Interface(智能体计算机接口)和面向 Agent 的工具设计。底层工具仍要有清晰命名、参数 schema、错误返回和高信号输出;只是模型不必在每一步都直接阅读所有 schema 和所有结果。
与 Agent Skills 的关系
Agent Skills和 MCP 经常一起出现,但解决的是不同层的问题。MCP 标准化的是“外部系统如何向 Agent 暴露工具、资源和提示”;Agent Skills 标准化的是“Agent 如何按需加载某类任务的流程知识、参考材料和辅助脚本”。
因此,MCP 更偏工具连接层,Skills 更偏流程与知识包装层。一个发布审查 Agent 可以通过 MCP 读取 GitHub、Linear 和日志系统,同时通过 Agent Skill 学会组织内的发布 checklist、风险判断规则、回滚脚本和报告模板。Anthropic 在 Agent Skills 文章中也把 Skills 定位为 MCP 的补充:外部工具给 Agent 能力,Skill 教 Agent 怎样组合这些能力完成真实工作。
A2A:Agent 间通信的对应标准
MCP 解决的是 Agent ↔ 工具(外部能力)边界的问题;A2A(Agent-to-Agent Protocol) 解决的是 Agent ↔ Agent 边界的问题。两者互补,不竞争:
- MCP:一个 Agent 进程调用外部工具/数据源(runtime-to-tool 解耦)
- A2A:多个 Agent 应用之间的发现、同步/流式交互和长期任务协作(cross-process delegation)
ETCLOVG Taxonomy(ETCLOVG 分类法)中,MCP 和 A2A 都归属 T 层(工具接口与协议),但跨越不同集成边界。
MCP 的安全问题
MCP 最初规范缺乏原生安全原语,这一空缺已催生攻防两端的研究:
攻击面:
- 工具投毒(Tool Poisoning):Trail of Bits(2025)展示 MCP 服务器可在用户实际调用工具之前通过投毒工具描述来影响 LLM 行为——恶意指令在工具注册时即注入
- MCP 强制执行:Radosevich & Halloran(2025)证明广泛使用的商业 LLM 可被诱导通过 MCP 工具执行恶意代码、建立远程访问、窃取凭证
防御方向:
- ETDI(Enhanced Tool Definition Interface):用密码学签名和版本化工具定义扩展 MCP,确保对工具代码、schema 或权限的任何修改都需要新的签名版本,防止已批准工具被静默更新为执行恶意操作的"地毯拉动(rug-pull)“攻击
- 供应链风险:Spracklen et al.(2025)分析 576,000 个代码样本,21.7% 的开源 LLM 生成代码中存在幻觉包名(slopsquatting),攻击者可注册这些名称并注入恶意代码
OpenAI 的 MCP 文档把生产防线落到几个具体配置上:默认审批 MCP tool call,敏感动作始终要求审批;用 allowed_tools 缩小工具面;只连接可信或官方服务器;记录并定期审查发送给第三方 MCP server 的数据;谨慎处理工具输出里的 URL 和图片 URL。即使组织启用了 Zero Data Retention 或 Data Residency,数据一旦发给第三方 MCP server,就受该服务器自己的保留和驻留政策约束。
Claude Managed Agents 还展示了 MCP 凭证隔离的托管形态:Claude 通过专用代理调用 MCP 工具,代理拿到与 session 关联的 token,再从 sandbox 外部 vault 取真实 OAuth 凭证并调用外部服务。harness 与 sandbox 都不直接持有这些凭证。这个模式把 MCP 的安全边界从“工具描述可信不可信”扩展到“凭证是否可被模型生成代码读取”。
对 Prompt Caching 的影响
MCP 的动态工具发现会影响Prompt Caching(提示缓存)。工具 schema 通常位于 prompt 前缀,工具列表顺序或内容一变,后续请求就不再拥有同一个精确前缀。OpenAI 在 Codex CLI 中曾遇到 MCP 工具枚举顺序不稳定导致 cache miss 的问题;此外,MCP 的 notifications/tools/list_changed 允许服务器在会话中途改变工具列表,若立即反映到 prompt,也会造成昂贵的缓存失效。
因此,MCP 不只是 T 层的工具协议,也会跨层影响 C 层的上下文成本管理。
相关概念
- ETCLOVG Taxonomy(ETCLOVG 分类法) — MCP 是 T 层(工具接口与协议)的核心标准
- Harness Engineering(驾驭工程) — MCP 安全问题属于 G 层(治理与安全)的工具加固范畴
- Loop Engineering(循环工程) — MCP 是其「连接器」模块的实现基础
- AI Agent(智能体) — MCP 让 Agent 的工具调用能力可以任意扩展
- Prompt Caching(提示缓存) — MCP 工具列表稳定性会影响 prompt 前缀缓存
- Function Calling(函数调用) — MCP 工具在模型调用层常被映射成函数/工具调用格式
- OpenAI API Tools(OpenAI API 工具) — OpenAI API 中 Remote MCP 所属的工具层
- OpenAI API Connectors — OpenAI API 中复用 MCP 工具形态的内置第三方服务连接器
- Claude API Tools — Claude Messages API 中 MCP connector 所属的工具层
- Claude Agent SDK — 在 Claude Code 风格 Agent run 中配置 MCP servers
- Agent Skills — 与 MCP 互补的流程知识与脚本打包格式