MCP 到底接在了哪一层?从“Agent 调工具”说起

0 阅读6分钟

“最后不还是 Agent 在调工具吗?那 MCP 多做了什么?”

这个问题比背定义有用。因为第一次看 MCP,很容易把模型、Agent、Harness、Client、Server 都画成一团,然后得出一个模糊的结论:MCP 就是 Function Calling 的另一种写法。

先说结论:模型负责提出要做什么,应用负责把它做成一次真实调用;MCP 约定的是应用与外部服务之间怎么对接。

先从一次工具调用看起

假设我对一个代码助手说:“帮我看看 PR 123,有没有明显问题。”模型发现自己还没看到改动,于是提出:调用 get_pr_diff,参数是 123

到这里,模型只给出了调用意图。真正去取 PR、处理权限、拿回结果的,是运行这个助手的应用。Function Calling 主要解决前半段:让模型以结构化方式表达工具名和参数,再由执行方把结果交回来。OpenAI Function Calling 文档

如果 get_pr_diff 来自一个独立的服务,应用还得知道:服务在哪儿?它有哪些工具?参数长什么样?调用后会返回什么?MCP 给这段对接提供了共同的协议。MCP 架构规范

所以两者可以连起来用,但不在同一层:

模型提出调用 → 应用接收并检查 → MCP Client 请求 MCP Server → 返回结果给模型

有的平台也原生支持 MCP 接入,并不要求应用先把每个 MCP 工具都转换成普通的 function tool。上面这条链路是帮助理解职责的简化图,不是所有平台内部唯一的实现方式。OpenAI MCP 接入文档

MCP Client 到底放在哪里?

MCP 文档把参与者分为 Host、Client 和 Server。Host 是使用这些能力的应用;它创建和管理 MCP Client。一个 Client 与一个 Server 通信,Server 则提供工具、资料等能力。MCP 架构规范

在 Codex 这类 Agent 应用里,Client 通常由 Harness 管理。但它不属于模型,也不只能放在 Harness 里。IDE、桌面应用、自己写的后端,只要实现 MCP Client,都能连接 MCP Server。普通程序甚至可以不接模型,直接读取 Resource 或调用 Tool。

也不必先建一个统一注册中心。本地 Server 可以由应用启动,远程 Server 可以按地址连接;应用需要知道要连接谁,并在执行时落实自己的权限规则。MCP Server 本身不需要再“提供一个 Client 端”。MCP TypeScript Client 入门

Tools、Resources、Prompts:别把三者都当成函数

继续用 PR 审查的例子:

Server 提供的能力可以是什么谁通常决定何时用
Toolget_pr_diff(123),获取这次改动模型选择,应用执行
Resourcerepo://CONTRIBUTING.md,项目开发规范应用决定怎样展示或加入上下文
Promptreview_pr(123),一套审查提问模板用户选择,应用取回模板消息

Resource 像“可寻址的资料”。它不一定是静态文件,也可以是由 Server 在读取时生成的内容;关键是 Client 能通过 URI 找到并读取它。Tool 也能查询数据,两者的区别主要是调用接口和使用方式,不是“读操作只能用 Resource、写操作只能用 Tool”。Resources 规范Tools 规范

Prompt 则像应用里可选的提问方式:用户点“审查 PR”,填入编号,Server 返回适合放进对话的消息。它不会因为 Server 连上了,就自动变成模型的系统指令Prompts 规范

一个 Server 可以同时提供三种能力,也可以只提供 Tool。MCP 没要求“凑齐三件套”才能工作。MCP Server 能力概览

放到同一张图里

下面画的是一种常见用法。虚线表示按需读取 Prompt 或 Resource;三类能力没有固定调用顺序,也不要求每轮都用到。

image.png

这张图只画了一轮。实际任务里,模型可能连续调用多个 Tool;应用也可能在工具返回后再读取 Resource。协议规定了这些能力怎么请求,没有规定必须按 Prompt → Resource → Tool 的顺序走。

什么场景下值得用 MCP?

我更愿意把判断标准放在“这项能力要被谁使用”上。假如同一个代码仓库服务,既要接 IDE,又要接桌面 Agent,后面可能还要接内部审查平台,那么每个宿主各写一套工具适配,很快就会变成重复劳动。把能力放进独立的 MCP Server,几个应用就能用同一套方式发现和调用它。

下面几种情况,MCP 往往比较合适:

  • 一项外部能力要被多个 Host 复用,例如代码平台、知识库、工单系统同时服务于 IDE 和 Agent 应用。
  • Client 需要按协议发现 Server 当前提供的 Tools、Resources 或 Prompts,而不是在应用里长期写死一份能力清单。
  • 能力本来就有独立的服务边界,希望把参数、返回结构和接入方式稳定下来,方便服务与应用各自演进。

反过来,如果只有一个应用、两三个稳定的本地函数,而且没有跨宿主复用和动态发现的需求,直接使用 Function Calling 配合普通函数通常更省事。少一层服务,也少一套连接、部署和故障排查成本。

一个很实用的做法是:先用简单工具把需求跑通;当第二个宿主出现,或者同一套接入开始被重复实现时,再认真考虑 MCP。它解决的是连接规模变大后的协作问题,不是每个工具调用都必须经过的仪式。

FAQ:前面几个问题,一次答完

MCP 是不是 Function Calling 的另一种写法?

不是。Function Calling 让模型结构化表达“调用哪个工具、传什么参数”;MCP 约定应用怎样发现并连接外部能力。它们可以出现在同一条调用链上,但解决的是不同层的问题。

MCP Server 一定要注册到统一中心吗?

不需要。应用可以按配置连接远程 Server,也可以直接启动本地 Server。统一目录或服务市场可以作为额外设施,但不是使用 MCP 的前置条件。

MCP Client 一定在 Agent Harness 里吗?

不一定。Host 负责创建和管理 Client;在 Agent 应用里,这部分常由 Harness 承担。IDE、桌面应用或后端服务也可以自己实现 Client,甚至不接模型也能使用 Server 提供的能力。

Resource、Prompt、Tool 有固定使用顺序吗?

没有。用户可以先选 Prompt,应用可以在任意合适的时机读取 Resource,模型也可以按任务需要调用一次或多次 Tool。具体顺序由产品交互和任务流程决定。

最后怎么记?

下次再看到 MCP,可以先问三个问题:

  1. 谁做决定? 模型通常决定要不要调用 Tool;Prompt 通常由用户选择;Resource 怎样进入上下文由应用安排。
  2. 谁真正发请求? 是应用里的 MCP Client,不是模型自己连到 Server。
  3. Server 提供什么? 它可以提供 Tool、Resource、Prompt 中的一种或多种。

把“模型决策”和“协议通信”分开,MCP 就没那么玄了。它没有替 Agent 思考,也没有替应用处理所有权限和流程;它让不同应用与外部能力之间有了一套共同的接法。