跳到主要内容

MCP 要解决的那件事 — 30 个连接件变成 13 个

这一章讲三件事: MCP 出现之前工具是怎么接给模型的、为什么那样接会爆炸; 那份共同的规矩到底规定了什么;以及参与这件事的三个角色各自站在哪儿。

它在全书链条里的位置: 第 01、02 章讲清了「动手」是什么。 从这一章起,全书转向「怎么让动手这件事不必每次重做一遍」。 第 04 章开始动手写代码,而这一章是那些代码的地图。

1. 先看现象:每加一个模型,工具都要重接一遍

这一节说明:在共同规矩出现之前,把一个工具接给模型是一件多不划算的事。

假设你写了一个「读文件」的小程序,想让模型能用上它。 你去查文档,发现每家模型厂商收工具的方式都不一样:

  • 有的要你在请求里放一个 tools 列表,每项按它规定的那几格填;
  • 有的没有这个位置,要你把工具的名字、说明、参数写进发给模型的那段话里;
  • 那几格各叫什么名字、参数怎么描述、模型答应用工具时回复长什么样——三家三个样

于是你为「读文件」写了三段接线代码,一家一段。

接下来你写第二个工具「跑测试」——三段又要重写一遍。

书里把这件事的历史交代得很清楚:在 MCP 之前,自建生成式 AI 平台的公司、 以及 LangChain 这样的公开框架,各自想出了不同的办法让用户实现工具再传给模型, 而每一种模型都要有自己的接线件1

2. 30 和 13:这两个数怎么算出来的

这一节是本章主走查的第 1 步。

本章主走查的输入,就是上一节那个「读文件」工具。它走三步: 第 1 步(本节) 算清老办法下它要被写几遍; 第 2 步(第 3 节) 看它按共同规矩摆出来、每一格填的是什么; 第 3 步(第 5 节) 把它真的接上一次,看清谁站在哪儿。

上面那件事有名字,而且能算出账。

书里给它的名字是 MxN 问题:要支持 M 个模型,而你想接进来 N 个工具或数据源, 你就得写 M × N 个接线件1

下面的 3、10、30、13 全部来自书里,不是我们编的; 只有「重复的部分占多少」那一步是我们拆开算的。

假设:3 个模型(比如 Claude、Gemini、以及 OpenAI 的那一系列模型),10 个工具。

做法要写几段接线代码怎么算的
老办法30每个工具都要为每个模型单写一段:10 × 3
有了共同规矩13每个工具写 1 份(10),每个模型写 1 份(3),10 + 3

省下的 17 段是什么? 把「读文件」那三段摊开对比一下就看得见:

给 Claude 的那一段 给 Gemini 的那一段 给 OpenAI 的那一段
─────────────────── ─────────────────── ───────────────────
① 打开文件、读、返回内容 ①(一模一样) ①(一模一样)
② 出错了怎么办 ②(一模一样) ②(一模一样)
③ 按 Claude 的格子名打包 ③ 按 Gemini 的格子名打包 ③ 按 OpenAI 的格子名打包
↑ 只有这一行是真的不同

图说:三段里真正不同的只有最外面那层打包。①和②被抄了三遍。

书里对这 17 段的评价很直接:它们大体上是彼此重复的,而这会增加 「难以诊断的 bug 冒出来」的机会1

为什么重复的代码最容易出 bug? 因为改一处等于要改三处。 「读文件」的错误处理漏了一种情况,你在 Claude 那段里修好了, Gemini 那段和 OpenAI 那段还错着——而且它们看起来一模一样,你不会想到再去看一眼。 换成共同规矩之后,同一个修复只改 1 处

3. 「共同的规矩」到底规定了什么

这一节回答:这份规矩是一纸君子协定,还是有强制力的东西?

先把词说清楚。这类东西的正式名字是协议—— 双方事先约好的一套死规矩:消息长什么样、里面哪一格叫什么名字、 一问一答按什么顺序来、出错了回什么。

协议不是「大家自觉遵守的文档约定」,它是可以被机器验证的: 你发过来的消息少了一格必填的东西,对方那一侧直接报错,不需要人来判断你守没守规矩。

这份规矩摆出来的那个面,叫接口——双方交接东西的那个固定形状。 就像插座:插头和插座谁也不知道对方是哪家厂做的,但孔的位置是定死的,插上就通电。

书里对 MCP 的描述正是这个形状:它为「构建工具、话术和数据源、 并把它们接到模型上」提供了一个共同接口2

关键在最后半句:「谁也不必知道对方是谁做的」。 你写的「读文件」提供方,不知道来问的是 Claude 还是 Gemini; 你写的使用方也不知道对面那台提供方是谁写的、用什么语言写的。 双方只认那份规矩。

主走查第 2 步:同一个「读文件」,摆到接口上长什么样

「固定的形状」是句空话,除非把格子填出来。 还是那个「读文件」:

接口上的那一格你的「读文件」往里填什么
名字read_file
一句说明「读一个文件的全部内容并返回」
收哪些参数path,一段文字,必填

而使用方那一侧问的那句话,对三家模型是同一句:方法名 tools/list

上面三格的值是我们为演示编的;这台「读文件」提供方是我们假设出来的,不是书里的例子。

对照第 1 步: 老办法里这三格在 Claude 那边叫一套名字、在 OpenAI 那边叫另一套, 所以同一个「读文件」要照三套名字各填一遍。现在只填一遍,三家都认。 省下的 17 段就省在这儿——省掉的正是「换一家模型,再照它的名字填一遍」。

协议管的是「一问一答按什么规矩来」(问 tools/list,答一条工具描述,答不上来要报什么错); 接口管的是「摆出来的那个形状」(就是上面那三格)。 一个管流程、一个管形状——这一格填的是什么,第 05 章还会细讲一遍。

4. 这个点子是从代码编辑器那边抄来的

这一节回答:这是一个全新的设计,还是一次移植?

是移植,而且书里明写了源头:MCP 受到语言服务器协议(Language Server Protocol,LSP)的启发2

代码编辑器那边当年遇到的是形状完全一样的一道题:

编辑器那边MCP 这边
一侧有多少种N 个编辑器(VS Code、Vim、Emacs…)M 个模型
另一侧有多少种M 种编程语言(每种要一套自动补全、跳转定义、报错)N 个工具与数据源
老办法要写几件N × MM × N
解法定一份规矩:语言那一侧做一个「语言服务器」,编辑器那一侧做一个通用的问法一模一样
结果N + MM + N

认出这层血缘有用:如果你想知道 MCP 未来会长成什么样, 去看 LSP 走过的路通常八九不离十——它们解的是同一道题。

顺带一句时间坐标:MCP 是 2024 年年底由 Anthropic 发布的, 发布时同步带上了几款主流 AI 代码编辑器和 Claude 桌面版的支持, 所以铺开得很快3

5. 三个角色:宿主、客户端、提供方

这一节把参与者摆清楚。这三个词后面每一章都会用,现在必须钉死。

先说一句提醒:这里的「客户端 / 提供方」不是浏览器和网站那一套。 它们在这里就是两段代码,而且很可能跑在你自己这一台机器上

第一个角色:宿主应用——用户真正在用的那个程序, 一个聊天框脚本、一个代码编辑器、一个内部工具网站,都算。

书里说得很宽:从「接收用户输入、发给模型、打印回复」的几十行小脚本, 一直到 Cursor、Windsurf 这种完整的代码编辑器,都可以是宿主应用4。 它只需要满足两条:会跟模型说话,并且装着至少一个客户端5

第二个角色:客户端。 它是宿主应用装在自己肚子里的一小段代码, 专门负责跟一台提供方通信。书里把它的位置说得很准: 正是因为宿主应用装着客户端,它才成为「宿主」; 而客户端反过来让宿主应用能够和提供方对话6

第三个角色:上面一直说的那个「提供方」——它正式的名字叫服务器: 把「我能干什么」摆出来的那一侧,提供工具、数据和话术的那个程序。 它可能跟你跑在同一台机器上(第 04 章讲这种),也可能跑在别人的机器上。

┌──────────── 宿主应用(用户在用的程序)────────────┐
│ │
│ 跟模型说话 ←──────→ 模型(在厂商那边) │
│ │
│ ┌─ 客户端 A ─┐ ┌─ 客户端 B ─┐ │
└───┼────────────┼───┼────────────┼────────────────┘
│ │ │ │
▼ │ ▼ │
服务器甲(本机) │ 服务器乙(远程)│
└────────────────┘

图说:一个宿主可以装很多个客户端,但**一个客户端只连一台服务器**。
模型在图的另一侧,它和服务器之间没有直接连线——
中间隔着宿主应用,这一点第 05 章会反复用到。

主走查第 3 步:把「读文件」真的接上一次

上面那张图是静止的。现在让它动一遍,每一步旁边写出手里的具体东西。

下面的程序名、服务器名、客户端编号和状态,是我们为演示编的; 书里没有给出这样一条带具体值的流程。

场景:一个 40 行的聊天框脚本 chat.py,配置文件里写着两台服务器—— files(启动命令 python file_server.py)和 git(启动命令 python git_server.py)。

第几步谁在动动完之后,手里的具体东西
0chat.py 启动它现在只是个会跟模型说话的程序,手里 0 个客户端——还不算宿主应用
1chat.py读配置,看到 files 这一台 → 新建 client#1,状态 未连接装上第一个客户端的这一刻,它才成了宿主应用
2client#1python file_server.py 把服务器 files 起来 → 状态 已连接
3client#1files按协议问一句:方法名 tools/list
4filesclient#1回一条工具描述:read_file / 「读一个文件的全部内容并返回」/ 参数 path——正是第 2 步那三格
5chat.py把这条描述转给模型。模型这一侧全程没跟 files 说过一句话
6chat.py还要连 gitclient#1 不能兼职,新建 client#2git;手里变成 2 个客户端

第 1 步和第 5 步各钉死了一件事: 宿主应用之所以叫宿主,是因为它肚子里装着客户端(第 1 步); 而模型和服务器之间那条线根本不存在,中间永远隔着宿主(第 5 步)。 第 6 步则是下面那条硬规矩的实际样子。

一条硬规矩:一个客户端只对一台服务器

书里把这条叫做「有一个坑」:一个客户端只能跟一台服务器说话。 你想连多台,就得开多个客户端,或者用一个客户端不停地短连短断7

这条规矩现在看起来无关紧要,但它会在第 09 章变成一件麻烦事: 连五台服务器就意味着五份连接要管、五份工具清单要合并、 两台服务器上重名的工具要处理。(那一章讲官方工具包给了什么办法。)

6. 边界:这一章的协议部分是我们补的

这一节必须说清楚,否则你会以为上面全是书里的。

原书目录里,专门讲这份规矩本身的那一章标着「不可用」—— 它本该讲协议的历史、它解决的问题、它的架构,以及真实案例8。 它没有写出来。

所以本章的内容分成两部分:

哪部分来自哪儿
MxN 问题、30 与 13、LSP 血缘、宿主/客户端/服务器的分工、一对一那条规矩书里有(第 1 章与第 3 章),脚注 1–7
三个角色的正式定义、以及「一个宿主为每台服务器建一个客户端」这个说法官方规范,脚注 9

官方规范对这三个角色的定义是:宿主是那个 AI 应用,它协调管理一个或多个客户端; 客户端维持与一台服务器的连接、替宿主从服务器取回可以喂给模型的材料;服务器就是提供这些材料的那个程序。 宿主为每一台服务器建一个专属的客户端9

和书里的说法完全一致,只是措辞更严格。 后面凡是这样两边都有的地方, 我们优先用书里的说法,只在书里没讲到时才补规范。

7. 可带走的

  1. 共同规矩出现之前,工具的接法跟着模型走——换个模型就得重写一遍;
  2. 这道题叫 MxN 问题:M 个模型 × N 个工具 = M×N 个接线件;
  3. 3 个模型 10 个工具 = 30 段,有共同规矩之后 3+10 = 13 段;
  4. 省下的 17 段几乎是彼此的复制品,而重复代码最容易藏 bug——改一处要改三处;
  5. 协议 = 双方事先约好的死规矩,可以被机器验证,不靠自觉;
  6. 接口 = 双方交接东西的固定形状,双方谁也不必知道对方是谁做的;
  7. MCP 的点子来自语言服务器协议,那边解的是「N 个编辑器 × M 种语言」同一道题;
  8. 三个角色:宿主应用(用户在用的程序)→ 装着客户端(负责通信)→ 连到服务器(摆出能力);
  9. 一个客户端只连一台服务器——这条会在第 09 章变成一件要专门处理的麻烦事。

8. 原文地图

主题原书章原文位置
MxN 问题、30 段重复Chapter 1. Agentic AI and MCPtext/04-ch01-chapter-1-agentic-ai-and-mcp.txt:72(搜「MxN problem」) · :72(搜「30 connectors that largely repeat themselves」)
共同接口、LSP 血缘、M+NChapter 1. Agentic AI and MCPtext/04-ch01-chapter-1-agentic-ai-and-mcp.txt:76(搜「inspired by the Language Server Protocol」)
MCP 何时发布、为什么铺得快Chapter 1. Agentic AI and MCPtext/04-ch01-chapter-1-agentic-ai-and-mcp.txt:12(搜「Towards the end of 2024」)
宿主应用是什么、能是什么Chapter 2. Hosting Clientstext/05-ch02-chapter-2-hosting-clients.txt:44(搜「from a simple chatbot script」) · :51(搜「host one or more MCP clients」)
客户端的位置与职责Chapter 2. Hosting Clientstext/05-ch02-chapter-2-hosting-clients.txt:22(搜「This is what makes the host」)
一个客户端只连一台服务器Chapter 2. Hosting Clientstext/05-ch02-chapter-2-hosting-clients.txt:26(搜「a single client can only talk to a single」)
协议那一章不可用Brief Table of Contents (Not Yet Final)text/03-fm-brief-table-of-contents-not-yet-final.txt:6(搜「An Introduction to the Model Context Protocol」)

Footnotes

  1. 出处:「Chapter 1. Agentic AI and MCP」第 72 段(text/04-ch01-chapter-1-agentic-ai-and-mcp.txt:72,搜「MxN problem」)。原文的算法是:要支持 M 个模型,就要为每一个想接进来的工具、数据源等等各写 N 个接线件;支持 3 个模型 10 个工具就是 30 个「大体上彼此重复」的接线件,而这会增加难以诊断的 bug 出现的机会。 2 3

  2. 出处:「Chapter 1. Agentic AI and MCP」第 76 段(text/04-ch01-chapter-1-agentic-ai-and-mcp.txt:76,搜「inspired by the Language Server Protocol」)。原文一句话里同时给了三件事:受 LSP 启发、提供构建工具/话术/数据资源并接到模型的共同接口、把 M×N 变成 M+N。 2

  3. 出处:「Chapter 1. Agentic AI and MCP」第 12 段(text/04-ch01-chapter-1-agentic-ai-and-mcp.txt:12,搜「Towards the end of 2024」)。原文还提了一句本书没展开的事实:服务器那一侧被设计得极容易搭起来,于是社区里很快涌出大量用户自建的服务器。

  4. 出处:「Chapter 2. Hosting Clients」第 44 段(text/05-ch02-chapter-2-hosting-clients.txt:44,搜「from a simple chatbot script」)。原文的跨度是「从一个接收用户输入、发给模型取回复的简单聊天脚本,到 Cursor、Windsurf 这样功能完整的代码编辑器」。

  5. 出处:「Chapter 2. Hosting Clients」第 51 段(text/05-ch02-chapter-2-hosting-clients.txt:51,搜「host one or more MCP clients」)。原文还加了一条:如果你打算用工具,你的宿主应用所用的模型也得支持工具调用。

  6. 出处:「Chapter 2. Hosting Clients」第 22 段(text/05-ch02-chapter-2-hosting-clients.txt:22,搜「This is what makes the host」)。客户端作为「服务器、应用、模型三者之间的界面」这个说法见「Example: A Simple Host Application」第 98 段(text/06-fm-example-a-simple-host-application.txt:98,搜「one of the most important components」)。

  7. 出处:「Chapter 2. Hosting Clients」第 26 段(text/05-ch02-chapter-2-hosting-clients.txt:26,搜「a single client can only talk to a single」)。原文给的两条出路是:开多个客户端实例,或者用一个只做短暂临时连接的客户端。作者说会比较两种做法的利弊——但那一节没有写出来

  8. 出处:「Brief Table of Contents (Not Yet Final)」第 6 段(text/03-fm-brief-table-of-contents-not-yet-final.txt:6,搜「An Introduction to the Model Context Protocol」)。第 1 章末尾对这一章的预告见「Chapter 1. Agentic AI and MCP」第 14 段(text/04-ch01-chapter-1-agentic-ai-and-mcp.txt:14,搜「its history, the problems it solves」)。

  9. 补充(不在书里):官方架构文档对三个角色的定义是——宿主是协调管理一个或多个客户端的 AI 应用;客户端维持与一台服务器的连接,替宿主从服务器获取上下文;服务器是向客户端提供上下文的程序。文档还写明:宿主为每一台服务器分别创建一个客户端,本机服务器通常只服务一个客户端,而远程服务器通常同时服务很多个——最后这半句正是第 11 章那场改动的起点。来源:MCP 官方架构总览 https://modelcontextprotocol.io/docs/2026-07-28/learn/architecture(查阅于 2026-08-25)。