📑 本页目录(点开跳转)
08 · MCP:接入外部世界
⏱ 44 分钟 | ⭐ 核心
🎯 一句话
MCP(Model Context Protocol)解决 M×N 问题:M 个 Agent × N 个系统, 不再需要 M×N 个定制集成,而是各自实现一次标准协议。它是 Agent 世界的 USB 接口。
🔌 一、没有 MCP 之前的痛
对照
每个 Agent 接每个系统都要单独写:
认证怎么做?工具怎么暴露?返回格式怎么定?错误怎么处理?
Agent A 定制 → Slack 3 个 Agent × 4 个系统
Agent A 定制 → GitHub = 12 套定制集成
Agent B 定制 → Slack 每次加一个系统,所有 Agent 都要改 💥
·
MCP 的答案:定一个标准协议,工具提供方实现一次 MCP Server, 任何支持 MCP 的 Agent(Client)都能即插即用。
MCP Server 能暴露三类东西
| 类型 | 是什么 | 例子 | 谁触发 |
|---|---|---|---|
| Tools | 可调用的操作 | create_issue() |
模型(用得最多)⭐ |
| Resources | 可读取的数据 | 一份文档、一张表 | 应用/用户 |
| Prompts | 预置的提示模板 | 「代码审查」模板 | 用户 |
日常 90% 的场景用的是 Tools。
🧱 二、三层协议:Function Calling / MCP / A2A 各在哪一层
读完第 7 章(工具怎么设计)和上一节(MCP 解决 M×N), 几乎所有人都会冒出同一个疑问:Function Calling 和 MCP 到底是不是一回事?
不是。它们根本不在一层上,加上 Agent 之间的 A2A,一共三层:
| Function Calling | MCP | A2A | |
|---|---|---|---|
| 连的是谁和谁 | 模型 ↔ 工具 | 工具 ↔ 宿主程序 | Agent ↔ Agent |
| 解决什么 | 模型怎么把「我要调这个」说出口 | 工具怎么被接进来、被发现 | 两个自主系统怎么互相托付任务 |
| 谁在实现它 | 模型厂商(训练 + API 格式) | 工具提供方 + Agent 宿主 | 双方的 Agent 平台 |
| 没有它会怎样 | 模型只能吐散文,你得自己正则解析 | 每接一个系统写一次定制集成(M×N) | 只能把对方当成一个工具来调 |
| 换掉它意味着 | 换模型 | 换适配层 | 换协作方 |
🔑 一句话记住三层: Function Calling 是「怎么说」,MCP 是「怎么接」,A2A 是「怎么托付」。 ⭐ 三者是叠加不是替代——一次 MCP 工具调用,底下走的仍然是 Function Calling。
① Function Calling:模型和工具之间的接口约定
它只约定两件事:
操作步骤
- 你怎么把工具告诉模型 名字 + 描述 + 参数 schema(第 7 章讲的就是这个的内容)
- 模型怎么把调用意图说出来 一个结构化的 tool_use 块,而不是一段散文
⭐ 关键认知:它不负责执行。 模型只是「说出」它想调什么,真正去调的是你的代码—— 第 1 章那个循环里的分支。
这也正是「Function Calling ≠ Agent」的原因:它只提供了一次往返的格式, 而循环、状态、错误处理、什么时候停,全都还在你这儿(第 1 章 + 第 12 章)。
💡 模型为什么知道该输出 tool_use 而不是散文:这是训练出来的,不是提示词技巧。 所以不同模型的工具调用可靠性差别很大——参数漏填、该并行调却串行调、该停不停, 都是模型能力问题而不是协议问题(选型见第 2 章)。
⚠️ 一个容易混的邻居:Structured Outputs / JSON mode 和 Function Calling 长得很像 (都是让模型吐结构化数据),但目的不同:前者是「输出要有格式」,后者是「我要调外面的东西」。 见 16c · 接进真实产品。
② MCP:工具和宿主之间的传输与发现协议
MCP 比 Function Calling 高一层:它压根不关心模型怎么表达调用意图(那是上一层的事), 它关心的是——工具从哪来、怎么被发现、怎么连上。
三个角色(上一节只讲了 Server 和 Client 两端,还差最重要的 Host):
| 角色 | 是谁 | 干什么 |
|---|---|---|
| Host(宿主) ⭐ | 用户面对的那个应用:IDE、聊天客户端、你自己的 Agent 服务 | 决定接哪些 Server、谁有什么权限、把工具交给模型、拿回返回值。管理宿主侧信任边界 |
| Client(客户端) | Host 内部为每个 Server 开的一条连接 | 处理连接、版本与能力;是否握手/维持会话取决于协议版本 |
| Server(服务端) | 工具提供方写的那个进程或服务 | 声明自己有哪些 Tools / Resources / Prompts,被调时执行 |
Host 和 Server 各自承担信任边界。 Host 决定接哪些服务、向模型暴露什么、何时要求用户确认;Server 验证调用身份、权限和资源归属,并实施业务规则。不能因为 Host 应该检查过,就允许 Server 跳过授权。
Client 负责协议适配。旧协议维护连接与协商;2026-07-28 使用逐请求能力和版本元数据。受保护 HTTP 服务还要验证 token 的有效期、audience 和 scope,双方用 trace ID 贯通审计。见官方授权规范与08c 的完整实验。
两种 Transport:
| stdio | HTTP(含流式) | |
|---|---|---|
| 怎么连 | Host 把 Server 当子进程拉起来,走标准输入输出 | 网络请求 |
| 天然形态 | 一对一,随宿主进程生死 | 一对多,独立部署、独立扩容 |
| 认证 | 靠操作系统的进程边界,通常没有额外认证 | 必须自己做(见本章第五节 ④) |
| 适合 | 本地工具、桌面开发、要读本机文件 | ⭐ 生产主流:多用户、要审计、要独立发版 |
| ⚠️ 坑 | 子进程继承所授予的权限,须按需要限制;Server 挂了 Host 不一定感知得到 | 长连接的超时与重连要自己扛,跨网络多一个攻击面 |
🔑 判断口诀:Server 和用户在同一台机器上 → stdio;不在 → HTTP。 别拿 stdio 去做多用户共享——它根本没有租户的概念。
还有一半价值容易被忽略:发现。Server 能自报家门(我有哪些工具、参数长什么样), 所以 Host 可以在运行时把工具列表拿到再交给模型。 ⭐ 这正是上一节 Tool Search 能成立的前提:工具是运行时可枚举的,才谈得上延迟加载。
③ A2A:Agent 和 Agent 之间的协作协议
一个很自然的反问:既然 MCP 什么都能接进来,把另一个 Agent 也包成一个 MCP Server 不就行了?
能,但会丢掉三样东西:
| 丢掉什么 | 为什么 |
|---|---|
| 对方是自主的 | 工具调用的心智模型是「我给参数,你返回结果」。而另一个 Agent 会自己规划、可能反问你、可能中途需要人批准——包成工具,你只能拿到最后那个返回值 |
| 过程可见 | 跑几十分钟的长任务需要中间状态、进度、可取消。工具调用是一问一答 |
| 能力发现是跨组织的 | 你接一个 MCP Server 是因为你决定接它;跨组织协作时,你得先知道对方能做什么、以什么形式交付 |
所以 A2A 这一层要定义的东西和 MCP 完全不同:对方是谁、能干什么(能力描述)、 一个任务的生命周期(提交 / 进行中 / 需要补充输入 / 完成 / 失败)、 交付物长什么样(结构化的产物,而不是一段文本)、长任务怎么推送进度。
⭐ 它和 MCP 是互补不是替代。 一个典型的企业形态是:
结果对照
⚠️ 给这一层泼一盆冷水:跨组织的 Agent 协作目前还没跑出规模化的成功案例,协议本身也在动。 你应该知道这一层要解决什么问题(那是稳定的),但不必记它今天的字段名(那会过期)—— 这就是 16b · 框架这层皮 那条判据:框架会过期,原理不会。
⚠️ 三、MCP 的甜蜜陷阱:工具定义撑爆上下文
关键信息
三个官方解法,按你的瓶颈选:
| 瓶颈 | 解法 | 实测效果 |
|---|---|---|
| 工具定义太多 | Tool Search:工具标记延迟加载,初始只给一个搜索工具(约 500 token),用时再取 | token 省 85%;准确率反而升(Opus 4.5:79.5% → 88.1%)⭐ |
| 中间结果污染上下文 | 程序化调用:模型写代码编排工具,中间数据在沙箱流转,只有最终结果进上下文 | token 省 37% |
| 参数总用错 | 工具示例:input_examples 给最小/部分/完整三类调用样例 |
复杂参数准确率 72% → 90% |
💡 注意 Tool Search 那一行:减少上下文的同时准确率上升了。 这再次印证第 4 章的核心命题——上下文不是越多越好,工具菜单也是噪声。
🚀 四、更激进:代码执行 + MCP
把「工具调用」改造成「写代码」:
流程图
📌 官方案例:150,000 token 降到 2,000(省 98.7%)。
三个红利:
| 红利 | 说明 |
|---|---|
| 渐进式披露 | 模型用 ls/read 按需探索工具定义,不用预载(第 4 章) |
| 数据不过模型 ⭐ | 大数据集在沙箱里处理,既省 token 又保隐私 |
| 控制流免费 | 循环、重试、条件分支用代码写,不烧模型轮次 |
代价:需要一个安全的代码沙箱(第 15 章)。
🏭 五、生产接入的六条经验
① 远程 Server 是主流形态
信息关系
(两种 Transport 各自的机制和坑,见本章第二节 ②。)
② ⭐ 按意图分组,别镜像 API
这是第 7 章原则 ① 的 MCP 版,也是最常被违反的一条:
结果对照
③ 大接口面用代码编排
📌 Cloudflare 的做法:用两个工具覆盖约 2,500 个 API 端点 ——一个搜文档、一个执行代码。
思路:当端点多到无法一一暴露时,别暴露端点,暴露"查文档 + 执行"的能力。
④ 认证要标准化
登录、授权码与刷新流程复用身份平台;MCP Server 仍须验证 token 签名或内省结果、audience、scope 与过期时间,再查资源权限。Host 的确认弹窗和协议会话 ID 都不能替代服务端授权。
⑤ ⚠️ 「审计过的连接器 ≠ 审计过的数据」
关键信息
🔗 这是第 15 章的核心议题。MCP 扩大了攻击面—— 每接一个 Server,就多一个外部内容入口。
⑥ 工具返回也要控制体积
MCP 工具和自己写的工具一样,返回内容会永久占据上下文(第 7 章原则 ④)。 接第三方 Server 时,先看它的返回有多大——有些 Server 的默认返回非常臃肿。
🧭 六、什么时候用什么(决策表)
| 场景 | 建议 |
|---|---|
| 本地开发,接文件系统/git | 内置工具或 CLI 就够,别为用 MCP 而用 MCP |
| 接一两个内部 API,只有你自己用 | 直接写工具函数更简单 |
| 多个 Agent 要共用同一批系统 | ⭐ MCP,一次实现处处可用 |
| 接第三方 SaaS(Slack/GitHub/Jira…) | 用现成的官方 MCP Server,别重复造 |
| 工具超过 20 个 | 上 Tool Search |
| 数据量大 / 编排复杂 | 代码执行 + MCP |
| 需要给外部团队提供能力 | MCP(这正是它的设计目标) |
🔑 一个判断原则:MCP 的价值随「Agent 数量 × 系统数量」增长。 只有一个 Agent 接一个系统时,它是纯开销。
🕳️ 七、六个常见坑
| 坑 | 症状 | 修 |
|---|---|---|
| 以为 MCP 取代了 Function Calling ⭐ | 概念错位,出问题时找错层:明明是模型参数填错(上层),却去改 Server(下层) | 三层是叠加的——MCP 工具调用底下走的仍是 Function Calling |
| 一比一镜像 API ⭐ | 一个简单意图要调四五个工具 | 按意图重新分组 |
| 接太多 Server | 上下文被工具定义吃掉一大半 | Tool Search / 只接真正需要的 |
| 第三方返回臃肿 | 几轮就烧光预算 | 包一层做裁剪,或用代码执行 |
| 把 MCP 数据当可信 | 提示注入 | 外部内容一律当不可信(第 15 章) |
| 为用而用 | 单 Agent 单系统还搭 MCP | 直接写工具函数 |
📚 延伸阅读
✅ 检查点
- MCP 解决什么问题?用一个类比说明。
- MCP Server 能暴露哪三类东西?哪类用得最多?
- 58 个工具会带来什么问题?首选解法是什么?效果如何?
- 代码执行 + MCP 为什么能省 98% 的 token?三个红利是什么?
- 「按意图分组,别镜像 API」什么意思?Cloudflare 怎么处理 2500 个端点的?
- 「审计过的连接器 ≠ 审计过的数据」什么意思?
- 什么时候不该用 MCP?
- Function Calling、MCP、A2A 分别连接谁和谁?三者是替代关系吗?
- MCP 的 Host / Client / Server 各干什么?Host 与 Server 分别检查哪些权限?stdio 和 HTTP 怎么选?
- 把另一个 Agent 包成一个 MCP Server 来用,会丢掉哪三样东西?
👀 答案
- M×N 集成爆炸——M 个 Agent 接 N 个系统本需 M×N 套定制集成。MCP 让两边各实现一次标准协议。类比 USB。
- Tools(可调用操作,模型触发,用得最多)、Resources(可读数据)、Prompts(预置模板)。
- 工具定义吃掉几万 token,注意力预算先被工具菜单花光。首选 Tool Search:延迟加载,省 85% token,且准确率反而上升(79.5%→88.1%)。
- 中间数据在沙箱里用代码处理不经过上下文。三红利:渐进式披露(按需探索工具定义)、数据不过模型(省 token + 保隐私)、控制流免费(循环重试用代码不烧模型轮次)。
- 一个工具对应一个用户意图(内部可以调多个 API),而不是把 REST 端点原样暴露。Cloudflare 用两个工具(搜文档 + 执行代码)覆盖 2500 个端点。
- MCP Server 本身可信不代表它取回的内容可信——外部网页/邮件/工单可能携带提示注入。每接一个 Server 就多一个攻击面。
- 单 Agent 接单系统时(直接写工具函数更简单)、本地开发接文件系统/git 时(内置工具够用)。MCP 的价值随「Agent 数 × 系统数」增长。
- Function Calling=模型 ↔ 工具(一次调用的格式约定,「怎么说」);MCP=工具 ↔ 宿主(传输与发现,「怎么接」);A2A=Agent ↔ Agent(任务托付,「怎么托付」)。三者叠加不是替代——一次 MCP 工具调用底下走的仍然是 Function Calling。
- Host 是用户面对的那个应用,决定接哪些 Server、给什么权限、把工具交给模型并执行返回值;Client 是 Host 为每个 Server 开的一条一对一连接;Server 是工具提供方那个进程,声明并执行 Tools/Resources/Prompts。Host 管连接、工具暴露和用户同意;Server 必须验证调用身份、资源权限及业务规则,两边都要留痕。Transport 按部署与宿主能力选择:本地子进程常用 stdio,也可使用本地 HTTP;远程服务通常用 HTTP。stdio 不自动提供多用户身份系统,业务层仍可能需要租户隔离。
- ①对方是自主的(会自己规划、会反问、可能要人批准,包成工具只能拿到最后一个返回值)②过程可见(长任务要中间状态/进度/可取消,而工具调用是一问一答)③跨组织的能力发现(你得先知道对方能做什么、以什么形式交付)。
🛑 可以停在这里
⚡ 走神救援
回来时接住这四点
- MCP 统一工具发现和调用接口,模型调用意图与业务执行仍各有职责。
- Host 管工具暴露与用户同意;Server 验证身份、资源权限和业务规则。
- 按协议版本处理传输;会话 ID 不是用户身份,stdio 也需要进程权限限制。
- 先按意图设计少量工具,再控制返回体积;可信连接器取得的内容仍可能含注入。
下一节 👉 08b-写一个MCP-Server.md