探针 8|给 AI 接个工具,为什么这么麻烦

给 AI 接个工具,为什么这么麻烦
你想给 AI 接个工具。
可能是让它查你的数据库、读你的日历、调你公司的内部接口,或者往你的跑步 App 推一份训练计划。每接一个工具,你都得专门写一套对接代码:这个工具这么调、那个工具那么调,参数格式、返回格式、鉴权方式,各写各的。
接一两个还行。工具一多,你就纳闷:这事儿怎么这么碎、这么重复?换个 AI 应用,是不是又得从头来一遍?
真相:麻烦不是单个工具难接,是「组合爆炸」
先别怪某个工具难搞。真正的麻烦,是个数学问题。
假设有 N 个 AI 应用(Claude Code、Cursor、ChatGPT、你自己写的 Agent),有 M 个工具(数据库、日历、搜索引擎、你公司的接口)。每个应用要用每个工具,都得专门写一套对接。
N 个应用 × M 个工具 = N×M 套对接代码。
这是个笛卡尔积,两边一多就爆炸。10 个应用、20 个工具,就是 200 套。每套都得有人写、有人维护,工具一改接口,全得跟着改。

这才是「接工具麻烦」的根源:不是某一个难,是组合太多。
MCP 把它压成 N+M
MCP(模型上下文协议,Model Context Protocol)出手的地方就在这。
思路很直:定一个统一协议。所有工具都按同一个标准把自己暴露出来,所有 AI 应用都按同一个标准去连。
角色于是分成了两边:
- server(服务端):工具这一方。每个工具按 MCP 标准写一个 server,把自己的能力暴露出来。
- client(客户端):应用这一方。每个 AI 应用写一个 client,认 MCP 这个标准,能连任意 server。
变化在哪?原来每个应用乘每个工具都要写一套,现在变成:每个应用写一次 client(N 套),每个工具写一次 server(M 套),加起来 N+M。
10 个应用、20 个工具,从 200 套压成 30 套。

这事儿不新鲜,USB、HTTP 干的是一模一样的事。USB 出来之前,键盘一种口、鼠标一种口、打印机一种口;USB 定个统一标准,设备按标准做、电脑按标准认,N+M。MCP 就是 AI 工具界的 USB。
server 能暴露三类东西
那 server 具体按协议暴露什么?MCP 规定,server 能往出摆三类东西,行话叫三个「原语」:
- tools(工具):能执行的函数,比如查个数据、发个邮件、推个计划。它由模型自己决定要不要调、传什么参数——模型看到说明就自己判断。这是最常用的一类,因为它正好接在模型的 Function Calling 上(上一篇讲的那个)。
- resources(资源):server 暴露的数据,比如一份文档、一个数据库的表结构、一段说明。它不由模型自己拿,而是由应用(client 那一侧)决定要不要塞进上下文给模型看。
- prompts(提示模板):server 预置好的对话模板,由用户主动点选触发。
你看,分这三类,本质是按**「谁能决定用它」**来分的:tools 模型说了算、resources 应用说了算、prompts 用户说了算。
现实里,绝大多数人只用 tools,因为它直接接模型、模型会主动调,最省事。resources 和 prompts 用得少,但它们存在是有道理的:有些上下文该让应用把关(比如别把敏感文件一股脑喂给模型),有些操作该让用户主动触发。
那消息怎么传?server 和 client 之间用一种叫 JSON-RPC 的协议通信(简单说就是按 JSON 格式发请求、收响应)。传输方式看 server 在哪:跑在你本机就用 stdio(标准输入输出),跑在远程就用 HTTP(再带个 token 鉴权)。
挖到底:它就接在 Function Calling 上
现在问个关键问题:MCP 这一套,碰模型了吗?
没有。这是最容易被忽略、但最该说清楚的一点。
MCP 的底,就是上一篇讲的 Function Calling。还记得吗,应用把一堆工具的说明书(schema:工具叫啥、要啥参数、干啥活)塞给模型,模型要调工具就按格式输出一段 tool call。
MCP 干的事,是让 server 暴露的每个 tool,都自带这份 schema。client 连上 server,把 server 列出的 tools 拿过来,转成模型认识的那份 schema 喂进去。剩下的,模型该怎么 Function Calling 还怎么 Function Calling。
整条链路是这样转的:
- server 把自己的 tools(带 schema)列出来。
- client 把这些 tool 的 schema 喂给模型。
- 模型按 Function Calling 输出一段 tool call(「我要调 get_training_plans,参数 startDate 是今天」)。
- client 收到 tool call,按 MCP 协议转发给 server。
- server 真正执行,把结果按协议返回。
- client 把结果喂回模型,模型接着想下一步。

所以,模型从头到尾,根本不知道底下走了 MCP。 它只看到一份份熟悉的 tool schema,照常 Function Calling。MCP 是工具和 AI 应用之间的一层协议,模型的脑子一点没动。
我天天在用:给减脂项目接了「跑鸭」
说个我自己的真实例子。
我有个减脂健康管理的小项目,要读跑步数据、往跑步 App 推训练计划。跑步数据在一个叫「跑鸭」的服务里。跑鸭提供了一个 MCP server。
我怎么接的?项目根目录放一个 .mcp.json,写几行配置,指明跑鸭 server 的地址(远程 HTTP),再带个 token 做鉴权(token 放环境变量里,不进 git)。就这点事。
接上之后,跑鸭暴露的两个 tools——get_training_plans(拿现有训练计划)和 push_training_plan(一次能推多条)——就直接进了模型的认识里。我跑每日推送,用的是项目里的一个 Skill:它把流程编排好了,先查今天该推啥、调 get_training_plans 对上现有计划的编号、再调 push_training_plan 推过去。

这件事的好处,正是前面那笔 N+M 的账:跑鸭那边只管按 MCP 协议把能力暴露出来,它不用管是 Claude Code 来连、还是别的 AI 应用来连,谁来都认同一套标准。我这边也不用为「Claude Code 连跑鸭」单独写一套对接,协议两边对齐,插上就用。
要是没有 MCP,我就得专门写一套「我的项目调跑鸭」的代码:怎么请求、怎么解析、怎么把跑鸭的接口翻译成模型能调的工具,全得自己来。换个 AI 应用,再来一遍。
这根探针挖到了什么
一个「给 AI 接工具为什么这么麻烦」的疑问,底下连着这些:麻烦是 N×M 的组合爆炸;MCP 用统一协议把它压成 N+M,分成 server 和 client 两边;server 能摆出 tools、resources、prompts 三类原语,按「谁能决定用它」分;而 MCP 压根没碰模型,它的底就是 Function Calling,server 暴露的 tool 自带 schema,模型照常输出 tool call,从头到尾不知道有 MCP。
这一趟,MCP、server、client、三类原语、JSON-RPC 这些词,你都摸过了。以后再刷到「某某工具支持 MCP」,你大概就知道:它写了个 server,按标准把自己的能力暴露出来,谁来连都行。
下一篇,换个角度扎:大家都在说 Prompt,但「Prompt 工程」这个词,可能已经过时了,现在更流行的是 Context 工程。下回聊。