15 · MCP 核心原理

本章目标:搞懂 MCP(Model Context Protocol)到底是什么、解决什么问题、协议怎么运转——最后能回答"我们团队要不要上 MCP"。

本章你将学到

  1. 工具集成的 "N×M 困局",以及 MCP 为什么被类比成"AI 界的 USB-C";
  2. Host / Client / Server 三层架构与连接的完整生命周期;
  3. Tools / Resources / Prompts 三大原语各自解决什么问题;
  4. stdio 与 Streamable HTTP 两种传输怎么选;
  5. MCP 与 Function Calling、插件体系的边界,以及技术选型判断。

前置知识

  • 第 02 章的 Agent 循环与第 08 章的工具调用——理解"工具"在 Agent 里的位置;
  • 第 13 章的 Java 生态——理解 Java 侧怎么消费 AI 能力。

15.1 一个正在爆发的问题:工具集成的 N×M 困局

先看一个你大概率遇到过的场景。

你们的客服系统接了大模型(第 14 章),为了让模型查航班、查订单,你写了一套"工具"(第 8 章):@tool 定义 + bind_tools 绑定 + 自己写执行循环。模型能调了,但——这套工具只能给这一个模型、这一个服务用。

现在业务说要加一个大模型 B(换供应商 / 多模型路由),或者要多一个 AI 应用(内部问答机器人、代码助手、数据分析助手)都用同一套工具。你要怎么办?给每个应用 × 每个模型,重复做一遍工具对接。工具种类一多(航班、订单、库存、知识库、审批……),就变成 N 个应用 × M 种工具的矩阵,每个格子都是一份集成工作:

        模型 / 应用                需要对接的工具
   ┌──────────────────┐
   │  客服 Agent       │ ──→ 航班API、订单API、知识库、审批……
   │  代码助手         │ ──→ Git、CI/CD、JIRA、文件系统……
   │  数据分析助手     │ ──→ 数据库、BI、报表……
   │  内部问答机器人   │ ──→ 知识库、Wiki、工单……
   │  ……              │
   └──────────────────┘              × M 种工具
       N 个应用             = N×M 次「对接 - 维护 - 升级」

每次对接都要重复:写工具描述、转换参数、处理错误、维护权限、跟进供应商 API 变化。这是所有做 AI 应用的团队的共同痛点——Anthropic 在 2024 年 11 月推出 MCP,就是冲着这个来的。

一句话:模型需要"手"去碰外部世界,MCP 就是给这些"手"定的一套标准插口。

15.2 MCP 是什么

MCP(Model Context Protocol,模型上下文协议)是一个开放的客户端-服务端协议,目标是标准化"AI 应用怎么接入外部工具与数据源"。

  • 提出:Anthropic,2024 年 11 月开源;
  • 治理:2025 年 12 月捐赠给 Linux Foundation 旗下的 Agentic AI Foundation(AAIF),由 Anthropic、Block、OpenAI 共同发起,Google / Microsoft / AWS / Cloudflare / Bloomberg 等支持,MCP 是其创始项目之一;
  • 演进:协议按日期版本迭代(2024-11-05、2025-03-26、2025-06-18、2025-11-25、2026-07-28……),规范与 SDK 持续演进,以 modelcontextprotocol.io 和官方 GitHub 为准。2026 年的规范走向 Stateless(无状态)——连接不再有 initialize 握手,具体见 15.5。

它的核心思路,是把"工具"从"某个模型私有"变成"协议公开":

  • 工具/数据提供方写一次 MCP Server,任何支持 MCP 的客户端都能用;
  • AI 应用接 MCP Client,不再关心工具背后的实现细节。

两个常见类比:

  • "AI 界的 USB-C"——一个口子通吃鼠标、键盘、显示器;
  • "AI 的打印机驱动"——任何文档程序都能打印,驱动写一次就行。

需要特别强调:MCP 本身不涉及模型推理。它不管模型选哪个、Prompt 怎么写,只负责"把工具与数据描述搬运给客户端、把调用结果搬运回来"。这是它与 Function Calling 最大的区别(15.6 详述)。

15.3 架构:Host / Client / Server

┌───────────────────────────────────────────────┐
│  Host(宿主应用:用户直接面对的那层)             │
│  ┌───────────────────────────────────────────┐ │
│  │  MCP Client A ──连接──▶ MCP Server 1        │ │
│  │                                            │ │
│  │  MCP Client B ──连接──▶ MCP Server 2        │ │
│  └───────────────────────────────────────────┘ │
│  一个 Host 可以挂多个 Client,                   │
│  每个 Client 只连一个 Server                   │
└───────────────────────────────────────────────┘
角色是什么举例
Host用户操作的应用程序,负责调度模型与工具Claude Desktop、Claude Code、你的客服系统、IDE 插件
ClientHost 内部的一个组件,与一个 Server 建立会话并维护连接状态每个 Server 对应一个 Client 实例
Server独立进程 / 服务,暴露工具、资源、提示词文件系统服务器、GitHub 服务器、你写的航班查询服务器

三个关键点:

  • Host 与 Client 是"1 对 N":一个应用里可以同时连"文件系统、数据库、GitHub"多个 Server,互不影响;
  • Client 与 Server 是"1 对 1":一个连接就是一个会话,有自己的生命周期与能力协商;
  • 模型不在协议里:Host 拿到 Server 的工具描述后,决定把这些描述交给哪个模型。换句话说,同一个 Server 可以被不同的模型消费。

15.4 三大原语:Tools / Resources / Prompts

MCP Server 对外暴露三种能力,理解了这三个词就理解了 MCP 的一半:

原语语义类比第 8 章谁来触发
Tools(工具)可执行的操作,有入参/出参,可能产生副作用@tool模型(经 Host 转发调用请求)
Resources(资源)只读数据,把"数据源"暴露给模型RAG 检索结果客户端 / Host 按需获取
Prompts(提示词)可复用的提示模板,面向用户工作流Prompt 模板用户 / Host

Tools 是主角:它就是第 8 章 @tool 的"联网版"——定义、描述、JSON Schema 这些概念一模一样,只是现在跨进程、走标准协议。执行权仍然完全在调用方手里:MCP 只传递"调用请求"和"调用结果",真正执行工具逻辑的是 Server 端代码。

Resources 解决的是"模型需要看数据、但不需要执行动作"的场景。比如给模型读一份航班政策文档:Server 把它暴露成一个 Resource(带 URI),客户端按需拉取内容塞进上下文。典型资源:file:///etc/hosts、database://orders/latest。

Prompts 是"预置工作流"。例如文件系统服务器可以暴露一个"整理目录"的 Prompt,用户选中即触发,Host 把它展开成一条对话模板。

三个原语对 Java 工程师来说很好理解:Tools = RPC 服务,Resources = 只读数据接口,Prompts = 预置的 Prompt 模板。

15.5 传输层与生命周期

MCP 规定了两类传输(transport):

传输场景特点
stdio(标准输入输出)本机、进程级客户端负责拉起服务器子进程,通过 stdin/stdout 走 JSON-RPC;部署最简单,安全边界 = 本机进程
Streamable HTTP(HTTP)远程、跨机器服务器是独立 HTTP 服务,客户端用 POST 发请求、支持服务端流式推送;适合"一个团队部署、多个应用共享"

早期还有 HTTP+SSE(Server-Sent Events)传输,2025 年被 Streamable HTTP 取代,规范不再推荐新项目使用。

消息流:发现 → 调用

所有消息走 JSON-RPC 2.0(UTF-8 编码)。对 Java 工程师来说,MCP 就是一个"定义清晰的 RPC 协议 + 明确的接口契约",服务定义、参数校验、错误码都有规范。

一次交互的主线是"发现 → 调用":

  1. 能力发现:客户端询问服务器支持的版本与能力。早期规范(2025-11-25 之前)通过 initialize 握手建立会话;2026 年后的 Stateless(无状态) 规范取消了握手,改为 server/discover,服务器按请求独立处理、不再维护长会话;
  2. 工具/资源发现:tools/list、resources/list 拉取清单(含 JSON Schema 与描述);
  3. 执行:tools/call 调用工具,服务器返回结果或结构化错误;
  4. 结束:任一方结束会话(stdio 通常由客户端终止子进程)。

规范按日期版本迭代,每次都有行为差异,但"发现 → 调用"的主线不变。版本协商由官方 SDK 处理,你按对应文档版本写代码即可,不必手写协议细节。

15.6 与 Function Calling / 插件体系的边界

这是最容易被搞混的地方,用一张表说清:

机制范围谁实现特点
Function Calling / Tool Calling单个模型 API 的能力模型供应商模型可以"声明想调工具",但执行必须在你的进程里(第 8 章)
MCP跨进程 / 跨应用的协议社区 + 各家公司工具由独立 Server 提供,任何 Client 都能连;不绑定任何模型
LangChain 工具框架内的工具抽象LangChain 生态绑定在 LangChain / LangGraph 运行时里
插件体系(OpenAI 插件、浏览器扩展等)特定平台的扩展机制各平台平台私有,跨平台不能复用

要点:

  • Function Calling 是"模型的一个特性",MCP 是"工具的一份标准"。两者不冲突,反而互补:MCP 把工具描述交给客户端,客户端再通过 Function Calling 把描述塞给模型。MCP 协议本身并不改变模型怎么调工具——最终落到模型头上,多半还是"Function Calling + JSON Schema"那一套。
  • 执行权永远在调用方:无论走 Function Calling 还是 MCP,"真正去调航班 API"都是你的代码/你的 Server 做的,模型只输出"我想调、参数是什么"。这一点第 8 章讲过,在 MCP 里依然成立。
  • MCP 的价值是"一次接入、处处可用":你的航班查询 Server 写一次,客服 Agent 能用、数据分析助手能用、换模型也能用。

15.7 真实世界的 MCP

2025 年之后 MCP 生态已经铺开,不再是"要不要上"的问题,而是"用哪几个 Server"的问题:

  • Claude Desktop / Claude Code:原生支持 MCP,用户配一段 JSON 就能挂工具;
  • 官方/社区 Server 一大把:GitHub、文件系统、数据库(Postgres / SQLite)、浏览器(Playwright)、Context7(文档检索)、Slack、飞书……;
  • 注册表 / 市场:Smithery、官方生态目录等,搜索即得;
  • Java 生态:Spring AI 提供 MCP 服务端/客户端 starter;LangChain4j 提供 langchain4j-mcp 模块——第 16 章你会亲手用它们。

15.8 价值判断:什么时候该上 MCP

场景建议
一个应用、一个模型、几个内部工具,只在自家 Agent 里用不必上。Function Calling + 内部代码就够了(第 8 章)
同一套工具要被多个应用 / 多个模型复用值得上。写一次 Server,处处消费
要接外部第三方工具(GitHub、数据库、浏览器等)强烈建议。用现成 Server 省去集成
工具由不同团队 / 不同技术栈提供值得上。协议解耦,Java / Python / Node 各自实现 Server
安全要求极高、工具极少、链路很短权衡。MCP 多一层进程/网络与攻击面(16.7 节有安全清单)

15.9 小结

  • MCP 解决的是工具接入的标准化问题,本质是一个 RPC 协议(JSON-RPC 2.0 + 传输层 + 能力协商);
  • 架构三件套:Host(应用)→ Client(连接)→ Server(能力),模型不在协议里;
  • 三大原语:Tools(可执行)、Resources(只读数据)、Prompts(预置流程);
  • 两种传输:stdio(本机进程) 与 Streamable HTTP(远程服务);
  • 与 Function Calling 互补不冲突:MCP 负责"工具描述跨进程传递",最终模型调用仍走 Function Calling 那套机制。

练习

  1. 用你手头的项目举一个"N×M 困局"的例子,画出接入矩阵,标出重复工作量最大的格子。
  2. 在 Claude Desktop / Claude Code 里配置任意一个现成 MCP Server(文件系统或 GitHub),观察 Host / Client / Server 三层在配置里各对应什么。
  3. 判断你的团队现在该不该上 MCP,写出 3 条理由。

参考答案(简版)

<details>
<summary>练习 2:观察三层结构</summary>

以 Claude Code 的配置为例(~/.claude.json 或项目 .mcp.json):

  • Host = Claude Code 本身;
  • Client = Claude Code 为这个 Server 创建的连接组件(你看不到实体,但配置里每个 server 一条就是"一个 Client 要连谁");
  • Server = 配置里的 command / args(stdio)或 url(HTTP)指向的进程/服务。

连上后让模型"读当前目录文件"或"查 GitHub issue",观察对话里模型是怎么先 list_tools、再 call_tool 的。
</details>

<details>
<summary>练习 3:上不上 MCP 的样板理由</summary>

  • 该上:3 个以上 AI 应用要共享同一套业务工具;要接外部数据源(GitHub/DB);工具团队与模型团队分属不同组,需要接口解耦。
  • 不上:工具只服务一个 Agent、模型固定、链路要求极简;或安全团队暂不能接受额外进程/网络暴露面。
    </details>

延伸阅读

  • 第 16 章:亲手写 Server,并用 Python / Java 消费
  • 第 08 章:Function Calling / 工具调用(MCP 的"本体")
  • modelcontextprotocol.io:官方规范
  • MCP 官方 TypeScript / Python SDK(GitHub: modelcontextprotocol)