Skip to content

MCP

Model Context Protocol 是什么、解决什么问题、架构与调用流程、与 Function Calling 的关系、生产安全与面试追问。

Updated View as Markdown
For humans

MCP

MCP(Model Context Protocol)是 Anthropic 在 2024 年 11 月发布的开放协议,给 AI 应用接外部工具和数据用的。它解决一个具体的问题:每个 AI 应用想接 GitHub、Slack、数据库,都要各写一份集成代码。M 个应用 × N 个工具,就是 M×N 份胶水代码,每份都得自己维护。

MCP 把这件事标准化了,常被叫作“AI 应用的 USB-C 接口”:

M×N 集成问题 vs MCP 的 M+N

工具提供方实现一个 MCP Server,所有支持 MCP 的应用连上就能用,工具只需要实现一次。反过来,你的应用实现了 MCP Client,就立刻获得整个 Server 生态。

架构:三个角色

MCP 的 Host-Client-Server 架构

  • Host:运行 LLM 的应用,管着多个 Client,负责权限决策和用户交互
  • Client:每个 Client 与一个 Server 保持 1:1 连接,做能力协商、工具发现、消息转发。隔离了不同 Server 的生命周期和故障范围
  • Server:能力的提供方,可以是本地进程(stdio)或远程服务(HTTP)

Server 能暴露三种原语,控制方不同:

原语 是什么 谁决定用
Tools 可执行的动作(查数据库、调 API、写文件) 模型根据对话内容自己决定
Resources 数据(文件内容、数据库记录、API 响应) 应用决定放入上下文
Prompts 可复用的交互模板 用户选择

协议分两层。数据层基于 JSON-RPC 2.0,定义了消息格式和三种原语;传输层负责字节怎么传,本地用 stdio(标准输入输出,Host 启动子进程),远程用 Streamable HTTP。协议语义和传输方式解耦,同一个 Server 换传输层不用改业务代码。

一次完整的调用

MCP 是有状态的会话协议,连接建立必须先握手。客户端发起 initialize,双方交换协议版本和能力声明,服务器返回它支持什么(tools、resources、prompts),客户端确认 initialized,之后才能正常通信。

MCP 生命周期与工具调用

两个细节值得记住。一是 tools/list 是运行时动态发现,工具列表可以随时变化,客户端不需要硬编码。二是结果以 content 块数组返回,可以是文本、图片、音频,还有结构化的 structuredContent 字段,程序读后者,文本块是给不识别结构化内容的客户端兜底。

协议在演进。新版本规范把 initialize 握手改成了可选的 server/discover,每个请求自己带协议版本和能力声明,会话可以无状态化,方便负载均衡。面试按经典握手流程讲没有问题,补一句“新版本在向无状态演进”是加分项。

和 Function Calling 的关系

这是被问得最多的一个问题。两者不在同一层,不构成二选一:

  • Function Calling 是模型的能力,解决“模型怎么表达调用意图”:模型输出结构化的工具名和参数,应用执行
  • MCP 是工具的分发协议,解决“工具怎么被发现和接入”:Server 声明能力,Client 动态发现

调用链上它们各管一段:

LLM ──Function Calling──▶ Agent 框架 ──MCP──▶ 工具服务
     "我要调 search"          "帮我调 Server 的 search"

关键认知:MCP 底层依然靠 Function Calling 驱动。Client 从 Server 拉到工具列表后,转换成模型原生的工具声明格式交给模型;模型输出调用意图,Client 再通过 tools/call 转发给 Server。从模型的视角看,它感知不到 MCP 的存在,以为自己只是在做普通的 Function Calling。如果模型本身不支持 Function Calling,MCP 就完全没法用。

维度 Function Calling MCP
是什么 模型能力 + API 格式 工具集成的开放协议
工具注册 写死在应用代码里 运行时从 Server 动态发现
复用性 单应用私有 一次封装,所有 MCP 应用可用
依赖关系 独立存在 底层依赖 Function Calling
额外成本 Server 进程、协议层、鉴权配置

选型就一条判断:这个工具会被多少个应用使用?一个,直接在代码里声明工具,引入 MCP 只是多维护一个进程和一层协议;多个或对外分发,封装成 MCP Server。

生产实践与安全

远程 Server 要上 OAuth。 公网上超过四成的 MCP Server 完全未认证,模型可能被诱导执行破坏性操作。远程传输用 Streamable HTTP 时,按 OAuth 2.1 走授权流程,Token 要带 resource 参数标明受众,防止令牌传递(token passing):签发给 A 服务的 Token 不能拿去调 B 服务。

工具层的最小权限。 OAuth 只回答“谁来了”,不回答“模型这一步该不该执行 rm、delete、transfer”。每个工具都要过一遍最小权限审查:

  • 文件工具限制根目录,路径先 realpath 再和白名单比较,防 ../ 穿透和符号链接逃逸
  • 数据库工具用只读账号,禁止自由 SQL,查询结果限行数
  • 命令执行拆成枚举式专用工具(run_testsgit_diff),别暴露通用的 run_command
  • 写操作、删除、转账这类高风险工具走人工确认(HITL),未确认只返回 pending_approval

Prompt Injection 是常态威胁。 工具描述、资源内容、返回结果都是不可信输入。外部网页、文档统一作为数据块传入,和系统指令隔离;工具返回前做输出脱敏,别把密钥、个人数据原样塞回模型上下文。

可观测性。 每次工具调用记录谁调的、参数摘要、结果大小、状态,审计日志要 append-only、存在 AI 够不到的地方。工具列表按用户身份裁剪,Server 保持无状态,防止用户 A 的会话干扰用户 B。

面试追问

  1. MCP 和 Function Calling 什么关系? 不同层。Function Calling 是模型表达调用意图的能力,MCP 是工具标准化暴露和发现的协议,后者建立在前者之上。模型感知不到 MCP,所有发现、转换、路由发生在宿主层
  2. 用了 MCP 工具调用会更准吗? 不会。准确率取决于模型能力和工具描述质量,与分发协议无关。MCP 解决“接得上”,不解决“调得准”
  3. stdio 和 Streamable HTTP 怎么选? 本地、单机、桌面应用用 stdio(零配置、跨平台、父子进程管道安全);远程、多租户、要鉴权用 Streamable HTTP
  4. 为什么用 JSON-RPC 而不是 REST? MCP 是有状态的双向会话:要握手协商能力、服务器能主动发通知、支持取消和进度。REST 是无状态的请求-响应,表达不了这些
  5. Server 能暴露什么? 三种原语:Tools(模型控制)、Resources(应用控制)、Prompts(用户控制)
Navigation

Type to search…

↑↓ navigate↵ selectEsc close