什么是 Model Context Protocol (MCP)?和 Function Calling、Agent 什么关系?
MCP(Model Context Protocol)用一套标准协议统一了 AI 应用接入外部工具与数据源的方式,把集成复杂度从 N×M 降到 N+M。本文讲清它解决的问题、Host/Client/Server 三个角色的分工、Tools/Resources/Prompts 三种原语、与 Function Calling 的关系,以及上线前必须自己补齐的安全边界。
它解决什么问题
没有 MCP 之前,工具接入是一个乘法问题:同一个 Git 工具要接进 Claude Desktop、Cursor 和你自建的 Agent 平台,就得写三套适配层;工具的参数格式、鉴权方式一变,N 个客户端全要跟着改。N 个 AI 应用乘 M 个工具,集成成本是 N×M,且每一格都是私有约定,无法复用。
MCP 的思路与 USB-C 相同:定义一个标准接口,工具方按协议实现一次 Server,所有支持该协议的 AI 应用都能即插即用;反过来,应用方实现一次 Client,就能接入整个 Server 生态。集成成本从 N×M 降为 N+M,这就是它存在的全部理由。
需要划清的边界是:MCP 只管「能力怎么被发现、怎么被调用」,不管「模型什么时候决定调用、任务怎么编排」——后者仍是 Function Calling 与 Agent 的职责。
核心原理
三个架构角色
- Host(宿主):用户直接使用的 AI 应用,如 Claude Desktop、IDE 插件、自建 Agent 平台。它承载用户交互和模型调用。
- Client(客户端):位于 Host 内部的协议组件,与每个 Server 维持一对一的会话,负责收发协议消息。
- Server(服务端):能力的提供方,由开发者编写,把文件读取、数据库查询、工单系统等能力按协议暴露出去。Server 背后的真实数据源不属于协议角色。
一次完整调用前还有一步容易被忽略的握手:Client 先发送 initialize 请求,双方交换支持的协议版本与能力清单,确认后进入可用状态。很多「Server 配好了但工具不出现」的问题,根源就在初始化协商失败。
通信机制:JSON-RPC 2.0
MCP 底层采用 JSON-RPC 2.0——工具调用天然是「执行某个方法」而非「操作某个资源」,所以方法调用风格的 JSON-RPC 比资源风格的 REST 更贴合。一次工具调用的报文大致是:
{ |
传输层有两种主流方式:本地 Server 用 stdio,Host 把它作为子进程启动,经标准输入输出交换消息,零网络成本;远程 Server 用 Streamable HTTP,认证、网关、负载均衡可以复用普通 HTTP 服务的整套运维设施。
深入机制
三种原语:Tools、Resources、Prompts
Server 对外暴露的能力分三类,区别不仅在功能,还在「由谁决定使用」:
| 原语 | 提供什么 | 由谁触发 | 典型例子 |
|---|---|---|---|
| Tools | 可执行的动作,可能有副作用 | 模型自主决策 | 查数据库、发消息、创建工单 |
| Resources | 只读上下文数据 | 应用或用户选择 | 文件内容、日志片段、库表 Schema |
| Prompts | 可复用的提示词模板 | 用户在界面选择 | 「按团队规范做代码审查」 |
简单记忆:Resources 是「给你看的材料」,Tools 是「替你做的动作」,Prompts 是「约定好的任务入口」。会改变外部状态的能力必须放进 Tools,只读数据放 Resources,这个划分直接影响后续的权限分级。
此外 Client 侧还能向 Server 提供反向能力:Roots 告知 Server 当前会话授权的文件根目录范围,Sampling 允许 Server 反向请求 Host 的模型做一次生成(如读到日志后请求摘要)。这些属于可选能力,取决于 Host 是否实现。
与 Function Calling 的关系:意图与传输
这是最容易混淆的一组概念。Function Calling 是模型侧的能力:模型输出「调用 read_file,参数是这个路径」这样的结构化意图,但它自己不会也无法真的去读文件。MCP 是应用侧的协议:负责把这个意图翻译成对远端 Server 的标准请求、执行、并把结果带回来。
一条典型链路是:模型通过 Function Calling 产生调用意图 → Host 校验参数 Schema → Host 内的 MCP Client 把调用路由到对应 Server → Server 执行并返回 → 结果写入模型上下文 → Agent 决定下一步。Function Calling 产生命令,MCP 传递命令,Agent 决定何时继续、何时结束——三者各居一层,互不替代。
工程实践
一个最小 MCP Server(官方 Python SDK)只需要几行:
from mcp.server.fastmcp import FastMCP |
写生产级 Server 时有几条经验:工具按业务动作拆分(get_user_by_id、list_active_orders),不要提供 execute_sql 这类万能接口——参数越自由,模型误用和越权的空间越大;工具的 description 要写清适用与禁用场景,它直接影响模型的选择质量;大文件结果先返回摘要与可读取范围,按需分块,避免一次响应塞爆上下文;调试期用 MCP Inspector 模拟 Host 发请求,初始化、能力发现、参数校验问题都能提前暴露。
对比与权衡
| 维度 | MCP | Function Calling | 私有插件/直连 API |
|---|---|---|---|
| 层级 | 应用间通信协议 | 模型输出格式能力 | 各写各的适配层 |
| 能力发现 | 协议内置(list_tools 等) | 由应用手工注入工具描述 | 无标准,各自实现 |
| 跨宿主复用 | 一次实现,处处接入 | 不可复用 | 不可复用 |
| 部署形态 | 本地子进程或远程服务 | 无(模型内) | 随应用耦合 |
| 安全责任 | 协议不兜底,自行补齐 | 无 | 自行补齐 |
安全边界
必须明确:MCP 协议本身不解决安全问题。协议标准化了接入,鉴权、审计、隔离全部要自己补:
- 鉴权与授权:远程 Server 接 OAuth 或等价机制,按 scope 限制可调用工具;「能连上」绝不等于「生产可用」。
- 参数不可信:模型生成的参数一律视为不可信输入。文件读写在路径规范化后校验目录边界,SQL 必须参数化,命令执行要白名单。
- 提示词注入面扩大:Server 的 description、返回内容都可能夹带恶意指令,第三方 Server 上线前要审源码、依赖与权限范围。
- 写操作分级:删除、修改、发送类操作默认收紧,加人工确认与审计日志;返回数据中的密钥、手机号要脱敏。
- Roots 不是沙箱:它只是范围提示,Server 侧仍要自己做越界检查和系统级隔离。
面试视角
MCP 解决了什么核心问题? 工具接入的 N×M 问题:没有标准协议时,N 个 AI 应用接 M 个工具要写 N×M 套适配;MCP 让工具方实现一次 Server、应用方实现一次 Client,复杂度降为 N+M,能力得以跨宿主复用。
Host、Client、Server 各自负责什么? Host 是面向用户的 AI 应用,承载交互与模型调用;Client 是 Host 内的协议组件,与每个 Server 维持一对一的会话;Server 是能力提供方,把工具、资源、提示词模板按协议暴露。一个 Host 可同时连多个 Server。
Tools、Resources、Prompts 怎么区分? Tools 是可执行动作(有副作用,模型自主调用),Resources 是只读上下文(应用或用户选择附加),Prompts 是可复用模板(用户显式触发)。划分标准是「谁决定使用」和「是否改变外部状态」。
MCP 和 Function Calling 是什么关系? Function Calling 是模型输出结构化调用意图的能力,MCP 是把意图送达外部系统并取回结果的协议;前者产生命令,后者传递命令。实际系统中两者串联:模型走 FC 格式,Host 负责映射到 MCP 调用并校验参数。
MCP 上生产要补哪些安全功课? 鉴权与 scope 授权、参数严格校验(路径遍历、SQL 注入)、写操作人工确认与审计、返回数据脱敏、第三方 Server 供应链审查、限流与调用链追踪。协议只标准化接入,不降低任何安全要求。
小结
- MCP 的本质是把工具接入从 N×M 的私有适配变成 N+M 的标准协议,价值在复用而非新能力。
- Host 管交互、Client 管会话、Server 管能力;Tools/Resources/Prompts 三原语按「谁触发、有无副作用」划分。
- 它与 Function Calling 是传输与意图的串联关系,不是替代关系。
- 协议不附带安全:鉴权、校验、审计、隔离每一项都要自己落实,否则只是把风险打包成了 JSON-RPC。

