第 5 章 · MCP 协议详解

Harness 锚点|判别清单第 2 项「工具执行」——通过 MCP 协议接入外部工具。

每个系统都自己写一遍,太累了

上一章的卖家现在胃口大了:他想让 Agent 不光能查自家数据库,还能读 GitHub 上的选品清单、查物流单号、发 Slack 通知、操作谷歌表格……

按第 4 章的办法,每接入一个系统,你都得重新写一遍工具封装——处理它的认证、它的接口格式、它的报错。接入十个系统就是十套重复劳动。更糟的是:你为 pi 辛辛苦苦写的这些工具,换个 Agent(比如 Claude、Cursor)又得从头再来一遍。

这显然不合理。业界需要一个统一标准:工具提供方按标准把能力暴露出来,任何 Agent 按标准接入——一次编写,处处可用。这个标准,就是 MCP

MCP 是什么:AI 工具的通用接口

MCP 全称 Model Context Protocol(模型上下文协议),由 Anthropic 在 2024 年提出,如今正在成为 Agent 工具接入的事实标准。它的核心思想是把工具从 Agent 里解耦出去,变成独立的“服务”

  • MCP Server(服务端):一个独立进程,对外暴露一组能力——工具、资源、提示模板。比如一个“GitHub MCP Server”会提供 create_issuelist_prs 等工具。
  • MCP Client(客户端):Agent 这一侧。它连接到若干 MCP Server,把这些 Server 暴露的工具,当成自己的工具来用。

一个恰当的类比是 USB:不管什么牌子的鼠标、键盘、U 盘,插上标准的 USB 口就能用,不用为每个设备重装驱动。MCP 就是“AI 工具的 USB 标准”——工具作者做一次 MCP Server,所有支持 MCP 的 Agent 都能即插即用。

这带来两个直接的好处:

  • 工具作者只实现一次,惠及所有 MCP 生态里的 Agent。
  • 你的 Agent 想要新能力,往往不用改代码,连一个 MCP Server 就行

用 pi 实现:接入一个 MCP Server

pi 作为 MCP Client,接入一个 Server 通常只需在配置里声明它。比如接入 GitHub:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "ghp_xxx" }
    }
  }
}

pi 启动时会:拉起这个 Server 进程 → 握手拿到它暴露的工具清单 → 把这些工具自动注册进 Agent——效果和你用第 4 章的 registerTool 手写的一模一样。对模型来说完全无感,它只是发现“手上多了几个可用工具”。

它和自定义工具的分工很清楚:

  • 自定义工具(第 4 章):你业务独有的逻辑——内部 API、私有数据库。这些别人没有,得自己写。
  • MCP 工具:通用的、别人已经实现好的能力——GitHub、文件系统、Slack、各种 SaaS。直接连。

实践中一个成熟的 Agent,往往就是“几个自定义工具 + 几个 MCP Server”的组合:自家业务自己写,通用能力靠 MCP 接。

MCP vs A2A vs RPC:工具、协作者、远程会话

讲到这里,很容易把几个“连接 Agent 世界”的词混在一起:MCP、A2A、RPC。它们都在解决“系统之间怎么连接”,但连接对象完全不同。

机制连接对象核心问题典型形态
MCPAgent 接外部工具 / 数据源“我怎么复用别人写好的能力?”GitHub、Slack、数据库、浏览器等 MCP Server
A2A / Agent-to-Agent一个 Agent 把任务交给另一个 Agent“两个独立 Agent 系统怎么协作?”研究 Agent 委托法务 Agent 审条款
RPC客户端远程驱动一个有状态 Agent 会话“Web/App 怎么操作远端 Agent?”浏览器通过 sessionId 继续一个 pi 会话

一句话区分:

  • MCP 把外部能力变成工具:模型看到的是 search_docscreate_issue 这类可调用动作。
  • A2A 把另一个 Agent 当协作者:你交给它一个目标,它用自己的上下文、工具和策略完成任务。
  • RPC 把 Agent 变成可远程操作的服务:客户端不是让它“做一个工具动作”,而是在驱动一个有状态会话继续运行。

什么时候把 Agent 当工具,什么时候当服务

企业级 Harness 里最容易做错的,是把一个完整 Agent 硬塞成普通工具,或者反过来,为一个简单工具部署一套 Agent 服务。可以按这张表判断:

场景更像工具更像 Agent 服务
输入输出一次调用,输入清楚、输出结构固定多轮、多步骤,中间会自己规划
状态不需要长期会话状态需要 sessionId、进度、断线恢复
自主性只执行一个动作会选择工具、反思、重试、交接
责任边界调用方负责整体任务被调用方负责完成一段子任务
观测只看这次工具调用结果要看完整 trace、成本、步骤和失败点

如果一个能力只是“查订单”“搜文档”“发消息”,把它做成 MCP 工具最合适。工具应该窄、可描述、可测试,最好一次调用就有明确结果。

如果一个能力本身就是“做一轮法务审查”“完成一次竞品研究”“跑一个后台分析任务”,它就不再是普通工具,而是一个 Agent 服务。这时更稳的接口不是把它伪装成 run_agent() 大工具,而是给它独立会话、任务 ID、可观测 trace 和失败语义:调用方提交任务,被调用方在自己的 harness 里完成,再返回结构化结果。

折中的做法也常见:用 MCP 暴露一个窄入口,背后由远端 Agent 服务执行。但要记住边界——MCP 只负责“让调用方能发起这个动作”,远端 Agent 的会话管理、权限、预算、评测和可观测性仍然要按第 23、24、25、26 章那套生产标准来做。

关键原则是:

简单、无状态、可一次完成的能力,当工具;复杂、有状态、需要自主完成子任务的能力,当 Agent 服务。

一个必须讲清的边界:MCP 管接入,不管安全

这一点新手常忽略,务必记牢:

MCP 解决的是“接入标准”,不解决“安全”。

连上一个 MCP Server,等于把它的全部能力交给了模型。如果这个 Server 能删文件、能发钱,那模型理论上就能触发这些操作。所以:

  • 只连你信任的 Server——第三方 MCP Server 的代码你未必审过,别随便连。
  • 权限和沙箱仍要自己把关——危险操作要有确认门(第 8 章),高风险场景要隔离执行(第 28 章)。
  • 凭据要管好——像上面 GITHUB_TOKEN 这样的密钥,别硬编、别泄露。

MCP 让接入变简单了,但“该不该让模型碰这个能力”的判断,永远是你的责任。

动手看看

去 MCP 的官方生态看看有哪些现成 Server(文件系统、GitHub、数据库、浏览器等)。挑一个和你业务相关的,读它的 README,看它暴露了哪些工具、需要哪些配置和凭据。你会发现,接入一个成熟能力,往往比自己从零写工具省事得多——这正是 MCP 的价值。

实战中的几个坑

坑一:什么都想连,结果工具泛滥。

  • 现象:接了七八个 Server,模型面对几十个工具反而选不准。
  • 原因:忽视了“上下文经济学”(第 7 章)。
  • 对策:只连当前任务真正需要的 Server。

坑二:盲目信任第三方 Server。

  • 现象:连了个来路不明的 Server,它的工具能力超出预期。
  • 原因:连接前没审查它能做什么。
  • 对策:连之前审一眼它的能力,敏感操作放沙箱。

坑三:凭据配置出错或泄露。

  • 现象:Server 起不来,或密钥被提交进代码库。
  • 原因:密钥硬编、误入版本控制。
  • 对策:用环境变量管密钥,别写进版本控制。

坑四:把该自己写的也硬找 MCP。

  • 现象:为一个简单的内部接口满世界找 MCP Server。
  • 原因:混淆了“业务独有”和“通用能力”。
  • 对策:业务独有的逻辑,直接用 registerTool 写更快。

对比:其他框架

MCP 是个跨框架的开放标准,主流框架都在快速支持:

框架怎么接入 MCP特点
LangGraph通过 langchain-mcp-adapters 转成 LangChain 工具借适配层接入
CrewAI提供 MCP 适配,把工具挂到角色上以角色为中心
PydanticAI内建 MCP 客户端,工具纳入类型化体系类型安全
Agno内置 MCP 封装,声明即接入开箱即用
pi作为 MCP Client,配置声明后自动注册工具与手写工具无异

值得注意:正因为 MCP 是开放标准,你写的一个 MCP Server 可以同时被这五家(以及 Claude Desktop、Cursor 等)复用——这正是标准化的意义,也是它区别于各家私有工具生态的地方。

小结

  1. MCP 是“AI 工具的 USB 标准”:工具作为独立 Server 暴露,Agent 作为 Client 接入,一次编写、处处可用。
  2. pi 通过配置声明接入 MCP Server,其工具会自动注册进 Agent,和手写工具用起来没区别。
  3. 自定义工具管“业务独有”,MCP 管“通用能力”,二者互补,成熟 Agent 常是两者的组合。
  4. MCP、A2A、RPC 的边界不同:MCP 接工具,A2A 交子任务,RPC 远程驱动有状态会话。
  5. 简单、无状态、可一次完成的能力适合做工具;复杂、有状态、需要自主完成子任务的能力更适合做 Agent 服务。
  6. MCP 只管接入、不管安全:只连信任的 Server,权限、沙箱、凭据仍需你自己把关。

前两章讲的是“给 Agent 一个个动作能力”。下一章换个角度——不再关注 Agent 能调什么,而是关注它吐出来的东西长什么样:如何让输出变成程序能直接消费的结构化数据。