🏠 总目录📚 本教程 08 · MCP 接入外部
📑 本页目录(点开跳转)

08 · MCP:接入外部世界

44 分钟 | ⭐ 核心


🎯 一句话

MCP(Model Context Protocol)解决 M×N 问题:M 个 Agent × N 个系统, 不再需要 M×N 个定制集成,而是各自实现一次标准协议。它是 Agent 世界的 USB 接口。


🔌 一、没有 MCP 之前的痛

你的 Agent(Host)MCP = 统一插头GitHubServer数据库Server文件系统Server但每接一个 Server,上下文就先被吃掉一块工具定义(还没干活)真正能用来干活的⚠️ 接 5 个 Server ≈ 60 个工具定义 —— 按需加载,或改用代码执行来调它们
上半张是 MCP 解决的问题:N 个应用 × M 个工具,从 N×M 变成 N+M。⚠️ 下半张是它带来的新问题:工具定义在你还没开口之前就已经占掉了预算。
   每个 Agent 接每个系统都要单独写:
   认证怎么做?工具怎么暴露?返回格式怎么定?错误怎么处理?

   Agent A ──定制──► Slack        3 个 Agent × 4 个系统
   Agent A ──定制──► GitHub         = 12 套定制集成
   Agent B ──定制──► Slack          每次加一个系统,所有 Agent 都要改 💥
   ...

MCP 的答案:定一个标准协议,工具提供方实现一次 MCP Server, 任何支持 MCP 的 Agent(Client)都能即插即用。

SlackMCP ServerGitHubMCP Server数据库MCP Server标准协议任何 Agent即插即用加一个系统 = 只写一个 Server加一个 Agent = 什么都不用写 ✅
要看的是线的条数:左边每个系统只有一条线出去,右边每个 Agent 只有一条线进来 —— 中间那道标准协议把原本 M×N 条定制连接压成了 M+N 条。⭐ 所以接入方越多,MCP 省掉的连接越多,这是它值得存在的全部理由。

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 单拎出来说:因为权限和审计只能做在 Host 上。 Server 是别人写的,Client 只是一根管子。你想做「这个 Server 只允许只读」 「这个工具必须人工确认」,唯一的实现位置就是 Host—— 这正是第 15 章说的「确定性的环境层边界」落地的地方。

两种 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 是互补不是替代。 一个典型的企业形态是:

   A2A  横着连     团队A的Agent ←→ 团队B的Agent ←→ 供应商的Agent
   MCP  竖着连     每个 Agent ↓ 接自己那堆系统(Jira / 数据库 / 内部服务)

⚠️ 给这一层泼一盆冷水:跨组织的 Agent 协作目前还没跑出规模化的成功案例,协议本身也在动。 你应该知道这一层要解决什么问题(那是稳定的),但不必记它今天的字段名(那会过期)—— 这就是 16b · 框架这层皮 那条判据:框架会过期,原理不会。


⚠️ 三、MCP 的甜蜜陷阱:工具定义撑爆上下文

   接上 5 个 MCP Server = 58 个工具
   → 光工具定义就吃掉 55K token
   → Agent 还没干活,注意力预算先被"工具菜单"花光了(第 4 章)

三个官方解法,按你的瓶颈选

瓶颈 解法 实测效果
工具定义太多 Tool Search:工具标记延迟加载,初始只给一个搜索工具(约 500 token),用时再取 token 省 85%;准确率反而(Opus 4.5:79.5% → 88.1%)⭐
中间结果污染上下文 程序化调用:模型写代码编排工具,中间数据在沙箱流转,只有最终结果进上下文 token 省 37%
参数总用错 工具示例input_examples 给最小/部分/完整三类调用样例 复杂参数准确率 72% → 90%

💡 注意 Tool Search 那一行减少上下文的同时准确率上升了。 这再次印证第 4 章的核心命题——上下文不是越多越好,工具菜单也是噪声


🚀 四、更激进:代码执行 + MCP

把「工具调用」改造成「写代码」:

   传统:每次工具调用都往返一次模型,中间结果全过上下文

     模型 → 调 read_sheet() → 【1万行数据进上下文】💀
          → 模型 → 调 filter() → 结果又进上下文
          → 模型 → 调 write() → ...

   代码执行:MCP 工具变成代码 API(沙箱里的模块)

     模型写一段代码:
       rows = await gdrive.sheets.read(...)        # 1万行
       filtered = rows.filter(r => r.amount > 100) # 沙箱里过滤
       await salesforce.update(filtered)           # 只写回结果
     → 上下文里只有【这段代码】+ 最终摘要 ✅

📌 官方案例:150,000 token 降到 2,000(省 98.7%)。

三个红利

红利 说明
渐进式披露 模型用 ls/read 按需探索工具定义,不用预载(第 4 章)
数据不过模型 大数据集在沙箱里处理,既省 token 又保隐私
控制流免费 循环、重试、条件分支用代码写,不烧模型轮次

代价:需要一个安全的代码沙箱(第 15 章)。


🏭 五、生产接入的六条经验

① 远程 Server 是主流形态

   本地 stdio Server  → 只适合桌面开发场景
   远程 HTTP Server   → Web/移动/云部署都能用 ⭐

(两种 Transport 各自的机制和坑,见本章第二节 ②。)

② ⭐ 按意图分组,别镜像 API

这是第 7 章原则 ① 的 MCP 版,也是最常被违反的一条:

   ❌ 把 REST API 的端点一比一暴露
      GET /issues, POST /issues, GET /users, POST /comments...
      → 模型要「从这个讨论串创建一个 issue」得调 4 次

   ✅ 按用户意图设计
      create_issue_from_thread(thread_url, assignee_hint)
      → 一次搞定,内部自己调那 4 个 API

③ 大接口面用代码编排

📌 Cloudflare 的做法:用两个工具覆盖约 2,500 个 API 端点 ——一个搜文档、一个执行代码。

思路:当端点多到无法一一暴露时,别暴露端点,暴露"查文档 + 执行"的能力

④ 认证要标准化

OAuth 流程、token 刷新交给平台层(Vaults 等),别让每个 Server 自己造。

⑤ ⚠️ 「审计过的连接器 ≠ 审计过的数据」

   MCP Server 本身可信(你审过代码)
        ≠
   它取回来的内容可信(那是外部数据)

   → 从 MCP 读到的网页/邮件/工单,都可能携带提示注入

🔗 这是第 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 直接写工具函数

📚 延伸阅读


✅ 检查点

  1. MCP 解决什么问题?用一个类比说明。
  2. MCP Server 能暴露哪三类东西?哪类用得最多?
  3. 58 个工具会带来什么问题?首选解法是什么?效果如何?
  4. 代码执行 + MCP 为什么能省 98% 的 token?三个红利是什么?
  5. 「按意图分组,别镜像 API」什么意思?Cloudflare 怎么处理 2500 个端点的?
  6. 「审计过的连接器 ≠ 审计过的数据」什么意思?
  7. 什么时候不该用 MCP?
  8. Function Calling、MCP、A2A 分别连接谁和谁?三者是替代关系吗?
  9. MCP 的 Host / Client / Server 各干什么?为什么权限和审计只能做在 Host 上?stdio 和 HTTP 怎么选?
  10. 把另一个 Agent 包成一个 MCP Server 来用,会丢掉哪三样东西?
👀 答案
  1. M×N 集成爆炸——M 个 Agent 接 N 个系统本需 M×N 套定制集成。MCP 让两边各实现一次标准协议。类比 USB。
  2. Tools(可调用操作,模型触发,用得最多)、Resources(可读数据)、Prompts(预置模板)。
  3. 工具定义吃掉几万 token,注意力预算先被工具菜单花光。首选 Tool Search:延迟加载,省 85% token,且准确率反而上升(79.5%→88.1%)。
  4. 中间数据在沙箱里用代码处理不经过上下文。三红利:渐进式披露(按需探索工具定义)、数据不过模型(省 token + 保隐私)、控制流免费(循环重试用代码不烧模型轮次)。
  5. 一个工具对应一个用户意图(内部可以调多个 API),而不是把 REST 端点原样暴露。Cloudflare 用两个工具(搜文档 + 执行代码)覆盖 2500 个端点。
  6. MCP Server 本身可信不代表它取回的内容可信——外部网页/邮件/工单可能携带提示注入。每接一个 Server 就多一个攻击面
  7. 单 Agent 接单系统时(直接写工具函数更简单)、本地开发接文件系统/git 时(内置工具够用)。MCP 的价值随「Agent 数 × 系统数」增长。
  8. Function Calling=模型 ↔ 工具(一次调用的格式约定,「怎么说」);MCP=工具 ↔ 宿主(传输与发现,「怎么接」);A2A=Agent ↔ Agent(任务托付,「怎么托付」)。三者叠加不是替代——一次 MCP 工具调用底下走的仍然是 Function Calling。
  9. Host 是用户面对的那个应用,决定接哪些 Server、给什么权限、把工具交给模型并执行返回值;Client 是 Host 为每个 Server 开的一条一对一连接;Server 是工具提供方那个进程,声明并执行 Tools/Resources/Prompts。权限只能做在 Host 上,因为 Server 是别人写的、Client 只是一根管子。Transport 口诀:Server 和用户在同一台机器上就 stdio,不在就 HTTP——stdio 是子进程、一对一、没有租户概念,生产主流是 HTTP。
  10. 对方是自主的(会自己规划、会反问、可能要人批准,包成工具只能拿到最后一个返回值)②过程可见(长任务要中间状态/进度/可取消,而工具调用是一问一答)③跨组织的能力发现(你得先知道对方能做什么、以什么形式交付)。

🛑 可以停在这里

走神救援

MCP=Agent 的 USB,解 M×N 集成爆炸(3 个 Agent × 4 个系统就要 12 套定制集成,加一个系统所有 Agent 都得改;有了协议,加系统只写一个 Server,加 Agent 什么都不用写);Server 暴露 Tools(最常用,日常 90% 场景)/Resources/Prompts。⭐三层协议别混Function Calling=模型↔工具(「怎么说」,只是一次往返的格式约定,它不负责执行,所以 Function Calling≠Agent——循环/状态/何时停还在你这儿)、MCP=工具↔宿主(「怎么接」)、A2A=Agent↔Agent(「怎么托付」);三者叠加不是替代——一次 MCP 工具调用底下走的仍然是 Function Calling。MCP 的三个角色是 Host/Client/Server:⭐权限和审计只能做在 Host 上(Server 是别人写的,Client 只是一根管子);两种 Transport 的口诀是在同一台机器上就 stdio、不在就 HTTP——stdio 是子进程、一对一、⚠️没有租户概念且谁拉起进程谁就给了它全部权限,生产主流是 HTTP。MCP 另一半价值是发现:工具运行时可枚举,才谈得上 Tool Search 那种延迟加载。A2A 那层解决的是「把另一个 Agent 包成 MCP Server 会丢掉的三样东西」:对方是自主的、过程要可见、跨组织的能力发现;⚠️它和 MCP 互补不是替代(A2A 横着连各团队 Agent,MCP 竖着连各自的系统),但知道它解决什么问题就够了,别背今天的字段名甜蜜陷阱:接 5 个 Server = 58 个工具吃掉 55K token,Agent 还没干活,预算先被"工具菜单"花光Tool Search 省 85% 且准确率反升(79.5→88.1,初始只留一个约 500 token 的搜索工具)/程序化调用省 37%/工具示例把参数准确率从 72% 提到 90%。⭐Tool Search 那行要单记:上下文变少的同时准确率上升了,说明工具菜单本身也是噪声。更激进:代码执行+MCP,数据在沙箱流转,150K→2K(省 98.7%),三红利是渐进式披露、数据不过模型(省 token 又保隐私)、控制流免费;⚠️代价是要有安全的代码沙箱。生产六课:远程 HTTP Server 才是主流(本地 stdio 只够桌面开发)、按意图分组别镜像 API(「从讨论串建 issue」不该调四次端点;端点太多时别暴露端点,暴露"查文档+执行"的能力——Cloudflare 用 2 个工具盖 2500 端点)、认证交给平台层、连接器可信≠数据可信(每接一个 Server 多一个攻击面)——取回的网页邮件工单都可能带提示注入、控制返回体积。判断原则:MCP 价值随「Agent 数×系统数」增长,超过 20 个工具就上 Tool Search,单对单时是纯开销

下一节 👉 09-计算机与浏览器使用.md

打卡记录保存在你的浏览器里,首页能看到总进度