1599 字
约 5 分钟
9
MCP协议
无标签

MCP 协议:把工具标准化,让生态流动起来

系列:ToyAgent 智能体知识库 09/26

一句话核心:工具不再写死在智能体里——把工具拆成独立 Server,智能体作为 Client 通过标准协议动态发现与调用。这是智能体世界的 USB-C 接口。

为什么需要

在基础的 Function Calling 实现里,工具是"编译期写死"的:

// 工具硬编码在智能体内部——想换天气供应商?改代码重新部署。
if ("get_weather".equals(toolName)) { return mockWeather.query(args); }

这种写法有几个天花板:

  • 换供应商要改代码:天气 API 从 A 换到 B,智能体代码跟着动,重新构建部署。
  • 上帝类:接 100 个工具,智能体代码里就有 100 个分支、100 份 API 凭据、100 种错误处理。
  • 无法复用:你为自家智能体写的天气工具,别的智能体团队要用,只能复制粘贴。

MCP(Model Context Protocol)的解法:把工具拆成独立服务(Server),智能体作为 Client 通过标准协议使用它们。工具的开发、部署、升级与智能体彻底解耦。

核心机制

协议核心只需要两个方法——tools/list 发现 + tools/call 调用:

// MCP Server:工具的标准化宿主
public interface McpServer {
    List<ToolDescriptor> tools();          // tools/list —— 工具发现
    String call(String tool, String args); // tools/call —— 工具调用
}

// 工具描述符:标准"名片",模型靠 description 选工具
record ToolDescriptor(String name,
                      String description,
                      String parameters) {}   // 生产中为 JSON Schema

// 智能体侧:动态发现,而不是硬编码
List<ToolDescriptor> tools = client.listTools();          // 启动时/按需拉取
String result = client.callTool("get_weather", "{\"city\": \"杭州\"}");

架构上是三方结构:

智能体 (Client) ⇄ 标准协议 ⇄ 工具服务 (Server)

解耦带来三件事:

  • 热插拔:Server 换实现(Mock 换真实天气 API),Client 零改动——名片不变,名片背后的实现随便换。
  • 生态复用:一个合规的 MCP Server 可以被所有智能体接入,写一次到处用。
  • 权限收敛:执行与凭据都在 Server 侧,Client 只能拿到协议允许暴露的能力。

Client 与多个 MCP Server 之间的发现与调用时序:

sequenceDiagram
    participant U as 用户
    participant C as Agent Client
    participant E as Exa Server
    participant J as Jina Server
    U->>C: 调研 MCP 协议最新规范
    C->>E: tools/list
    E-->>C: web_search_exa 工具名片
    C->>J: tools/list
    J-->>C: read_url 工具名片
    C->>E: tools/call web_search_exa
    E-->>C: 5 条搜索结果
    C->>J: tools/call read_url
    J-->>C: 网页正文
    C-->>U: 汇总后的调研报告

图示:Client 先对各 Server 做 tools/list 拉取名片,对话中按需 tools/call 调用——Client 代码不含任何具体 Server 的实现。

举例

结合生产场景:假设你的学习平台智能体要接三个 MCP 预置服务——Exa(联网搜索)、Jina(网页阅读)、Firecrawl(网页抓取)。

[启动阶段]
Agent Client ── tools/list ──► Exa Server      返回 [{name:"web_search_exa", ...}]
Agent Client ── tools/list ──► Jina Server     返回 [{name:"read_url", ...}]
Agent Client ── tools/list ──► Firecrawl Server 返回 [{name:"scrape", ...}]
(注册表把三个服务的工具合并渲染进系统提示词清单)

[对话阶段]
用户:帮我调研一下 MCP 协议的最新规范
模型思考:需要联网搜索 → 选 web_search_exa
Agent Client ── tools/call("web_search_exa", {"query":"MCP spec 2026"}) ──► Exa Server
模型思考:搜到 5 条链接,逐条读正文 → 选 read_url
Agent Client ── tools/call("read_url", {"url":"https://modelcontextprotocol.io/..."}) ──► Jina Server
模型输出:汇总后的调研报告

关键观察:智能体代码里没有一行 Exa 或 Jina 的代码。它只知道"我有一批工具,名片如下"。哪天把 Exa 换成 Tavily,只要新 Server 提供同名/同语义的 tools/list + tools/call,智能体零改动。反过来,一个自研的"知识库检索 MCP Server"写好之后,公司里任何智能体都能挂载,无需各自实现一遍。

LangChain4j 视角:langchain4j-mcp 模块提供 McpToolProvider,把远程 MCP Server 的工具自动桥接成框架的 ToolProvider,与内置工具同场注册——MCP 工具和本地工具对模型来说没有区别。

教学版 vs 真实 MCP

维度 教学版 真实 MCP
通信 进程内 Java 接口 JSON-RPC 2.0(stdio / Streamable HTTP)
Server 形态 嵌套接口模拟 独立进程 / 远程服务
核心方法 完全一致:tools/list + tools/call 同左,另有资源、提示词等扩展能力

教学版把传输层抽掉,只保留协议语义——因为 MCP 的价值不在传输,而在这两个方法构成的契约。

面试考点

  • MCP 解决了什么问题? M×N 集成问题。没有 MCP 时 M 个智能体对接 N 个工具要写 M×N 份胶水代码;有了 MCP 各自实现协议一侧,只需 M+N 份。
  • MCP 的两个核心方法是什么? tools/list(能力发现)与 tools/call(调用执行)。发现与调用分离,是"动态"的关键——Client 启动时不需要知道有哪些工具。
  • MCP 和 Function Calling 的关系? 不竞争而是分层:Function Calling 是模型与宿主之间的调用格式;MCP 是宿主与工具服务之间的连接协议。MCP 工具最终仍以 Function Calling 形式暴露给模型。

生产化路径

  1. 鉴权双链路:MCP 工具经 Adapter 桥接进框架时,注意 Adapter ≠ Registry——注册层与适配层的鉴权、禁用名单要分别配置,否则出现"配置了禁用但工具仍然可用"的缝隙。
  2. 超时预算:远程 MCP Server 的超时要按其真实响应特征设(搜索类几秒,抓取类可能几十秒),一刀切短超时会误杀慢工具,长超时会拖垮对话。
  3. 错误体透传:Server 返回的非 2xx 错误体不要吞掉,里面有模型重试所需的语义(限流、参数错、无结果各不相同)。
  4. 预置 Server 种子化:团队常用 Server(搜索/抓取/内部 KB)做成幂等 seed,随部署自动挂载,新 Agent 开箱即用。
  5. 降级策略:MCP 全连失败时智能体应能降级到内置工具或如实告知,而不是整轮对话断流。
MCP协议
https://clxhxhhr.top/posts/4709/
作者
clxstart
发布于
2026-10-13
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。