跳到主要内容

MCP(Model Context Protocol)

问题

MCP 如何标准化 AI 应用与工具、数据源和工作流的连接?Host、Client、Server、Tools、Resources、Prompts、Sampling、Elicitation、Roots 和 Tasks 分别是什么?如何安全地开发与接入 MCP?

面试速答版

MCP 是基于 JSON-RPC 2.0 的上下文交换协议。它解决的是“AI 应用如何发现和调用外部能力”,不规定模型如何推理,也不等于 Agent 框架。

  • Host:AI 应用,负责用户体验、权限、模型与多个连接。
  • Client:Host 内与某一个 Server 维持一对一会话的协议组件。
  • Server:提供 Tools、Resources、Prompts。
  • 本地传输:stdio。
  • 远程传输:Streamable HTTP;旧 HTTP+SSE 仅用于兼容历史实现。
  • 安全核心:能力协商、最小权限、参数校验、用户确认、OAuth 2.1、PKCE、token audience 校验和禁止 token passthrough。

一、MCP 的边界

MCP 负责:

  • 初始化、版本和能力协商。
  • 工具、资源和提示模板的发现与调用。
  • 日志、进度、通知、用户补充输入和长任务状态。
  • 传输与远程授权规范。

MCP 不负责:

  • 替你决定用哪个模型。
  • 自动保证工具安全或结果正确。
  • 定义完整 Agent 规划、记忆和评估框架。
  • 替代业务 API 的授权、审计和数据隔离。

二、参与者与连接关系

参与者职责典型例子
Host管理用户、模型、权限、多个 ClientIDE、桌面助手、企业 Agent 平台
Client与一个 Server 协商能力并路由请求Host 内部的 MCP 会话对象
Server暴露上下文和操作能力Git、数据库、知识库、监控平台

一个 Host 通常为每个 Server 创建一个 Client。不要把“浏览器里的用户”“模型”“MCP Client”混为一谈:用户授权由 Host 驱动,模型只是提出使用工具的建议,Client 才负责协议通信。

三、能力分类

1. Server Primitives

Server 向 Client 暴露三类核心原语:

原语用途是否可能产生副作用
Tools执行查询、计算或动作取决于工具,可能有
Resources读取文件、Schema、文档或状态通常只读
Prompts提供可复用的提示模板通常无

2. Client Features

能力方向用途
SamplingServer → Client请求 Host 使用模型生成内容
ElicitationServer → Client请求用户补充结构化信息或确认
RootsClient → Server告知 Server 可操作的文件系统边界
LoggingServer → Client发送结构化日志

3. Utilities

  • Notifications:工具、资源或提示列表发生变化时主动通知。
  • Progress:报告长操作进度。
  • Tasks:为延迟执行、轮询和长任务提供实验性封装。
Elicitation 不是绕过 UI 的后门

Host 决定是否展示请求、展示哪些字段以及用户是否同意。Server 不能假设用户一定会提供敏感信息,也不能把密码、密钥等字段偷偷塞入通用表单。

四、生命周期与版本协商

初始化顺序:

initialize.json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {
"elicitation": {},
"roots": { "listChanged": true }
},
"clientInfo": {
"name": "knowledge-app",
"version": "1.0.0"
}
}
}

远程 HTTP 请求应携带协商后的 MCP-Protocol-Version。双方没有兼容版本时应终止连接,而不是静默猜测;只调用对端声明支持的能力。

五、Tools

工具发现

{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}

工具描述应做到:名称稳定、描述具体、输入 Schema 严格、副作用明确。不要把一个万能 execute(command: string) 暴露给模型。

工具调用

{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "issue_get",
"arguments": { "issueId": "FE-1024" }
}
}

工具安全设计:

  1. Client/Host 先按用户、租户和会话过滤允许工具。
  2. Server 再做真正的鉴权,不能信任模型或 Host 传来的用户 ID。
  3. JSON Schema 只验证形状,资源归属和状态必须单独检查。
  4. 读写工具拆开,例如 issue_getissue_update
  5. 写操作支持幂等键、预览、确认和审计。
  6. 设定超时、并发、结果大小和网络出站限制。

六、Resources 与 Prompts

Resource 使用 URI 标识内容:

{
"jsonrpc": "2.0",
"id": 4,
"method": "resources/read",
"params": { "uri": "docs://frontend/auth-design" }
}

适合 Resource 的内容:数据库 Schema、只读文档、日志片段、代码文件、业务对象快照。资源列表不等于授权列表,读取时仍要逐资源检查权限。

Prompt 是由 Server 管理的参数化模板。它适合团队共享工作流入口,但不应隐藏危险操作,也不构成不可覆盖的系统安全策略。

七、传输层

传输场景关键点
stdioHost 启动本地子进程stdout 只写协议消息,日志写 stderr;限制环境变量和文件权限
Streamable HTTP多用户远程服务HTTPS、Origin 校验、会话管理、授权、可恢复流和负载均衡

对于本地 HTTP 服务,需要绑定 loopback、校验 Origin 并防止 DNS rebinding。对于远程服务,需要把会话状态放到可共享存储或使用无状态设计,不能依赖某一台实例内存。

WebSocket 可以作为应用自己的传输选择,但不是核心规范规定的默认远程传输;不要把推测中的路线图写成既定能力。

八、远程授权

当前规范采用 OAuth 2.1 的受约束方案。核心流程包括:

  1. Client 从 MCP Server 的 Protected Resource Metadata 发现授权服务器。
  2. 通过 OAuth Authorization Server Metadata 或 OIDC Discovery 获取端点。
  3. 使用 Authorization Code + PKCE;公开客户端必须安全处理刷新 token。
  4. 授权请求和 token 请求包含目标 resource
  5. MCP Server 校验 token audience、scope、有效期和签名。
  6. MCP Server 调用下游 API 时使用自己的下游凭据,禁止转发收到的用户 token。
禁止 Token Passthrough

MCP Server 不能把 Client 给它的 access token 原样转发给 GitHub、数据库或其他下游。这会破坏 token audience 边界并造成 confused deputy。Server 应作为独立 OAuth Client 获取下游 token。

九、前端如何展示 MCP 执行过程

前端不应该只显示“AI 正在处理”。建议使用类型化状态:

types/mcp-ui.ts
type MCPActionState =
| { type: 'approval-required'; tool: string; summary: string }
| { type: 'running'; tool: string; startedAt: string }
| { type: 'progress'; tool: string; current: number; total?: number }
| { type: 'completed'; tool: string; resultSummary: string }
| { type: 'failed'; tool: string; errorCode: string };
  • 对写操作展示工具名、目标资源、关键参数和预期副作用。
  • 用户确认后生成不可重放的 approval token,Server 仍要再次鉴权。
  • 工具结果做摘要和大小限制,原始数据通过受权资源链接查看。
  • 取消只表示 Host 不再等待;还需要向 Server 传播取消并确认后台任务状态。

十、服务发现与供应链

不要在教程中维护“官方 MCP Server 大全”。生态变化快,部分早期 @modelcontextprotocol/server-* 包已废弃。推荐流程:

  1. 从 MCP Registry 或供应商官方页面发现 Server。
  2. 核对发布者、源码、包签名、权限与维护状态。
  3. 固定版本和完整性,生成 SBOM,先在隔离环境运行。
  4. 审查工具清单变化;新增高风险工具不能自动进入允许列表。
  5. 企业内优先维护经过审核的私有目录。

十一、MCP 与 Function Calling、A2A 的区别

技术解决的问题
Function Calling某个模型 API 如何表达“想调用函数”
MCPAI 应用如何发现、连接和调用外部上下文能力
A2A独立 Agent 之间如何发现能力、委派任务和交换结果
AG-UIAgent 与用户界面如何同步事件、状态和人工操作

MCP 工具最终常被转换成模型供应商的 Function Calling 描述,但它还包含资源、提示、生命周期、通知、授权和传输,不等同于 Function Calling。

常见面试问题

Q1: MCP 的 Host、Client、Server 分别是什么?

答案:Host 是完整 AI 应用;Client 是 Host 内与单个 Server 建立会话的协议组件;Server 提供 Tools、Resources 和 Prompts。一个 Host 通常有多个 Client,每个 Client 对应一个 Server。

Q2: MCP Server 到底暴露几种核心原语?

答案:Server Primitives 是 Tools、Resources、Prompts 三类。Sampling、Elicitation、Roots、Logging 属于 Client 能力或双向能力,不能统称为 Server 暴露的五种原语。

Q3: Tools 和 Resources 如何选择?

答案:有参数、需要执行并可能产生副作用的能力用 Tool;可寻址、以读取内容为主的数据用 Resource。不要为了让模型“看见数据”就把所有读取都做成高权限工具。

Q4: stdio 和 Streamable HTTP 有什么区别?

答案:stdio 适合 Host 管理的本地进程,安全边界依赖操作系统和进程权限;Streamable HTTP 适合远程多用户服务,需要 HTTPS、授权、Origin 校验、会话和横向扩展设计。

Q5: MCP 的能力协商有什么价值?

答案:初始化时双方交换协议版本和 capabilities,避免调用对方不支持的功能,也让客户端知道工具列表是否会变化、是否支持 Elicitation、Roots 等能力。

Q6: 为什么 MCP 工具仍要在 Server 端鉴权?

答案:模型、Prompt、Client 传入的用户信息都不可信。只有 Server 掌握真实资源和授权策略,因此必须对每次调用校验主体、租户、资源和操作权限。

Q7: 为什么禁止 token passthrough?

答案:上游 token 的 audience 只应指向 MCP Server。原样转发会让下游误信不属于自己的 token,引发 confused deputy。Server 应用独立凭据访问下游。

Q8: Elicitation 和普通工具确认有什么区别?

答案:Elicitation 是协议化的“向用户补充信息或请求确认”;Host 控制展示和同意。它可以用于工具前确认,但不能代替 Server 最终授权。

Q9: Tasks 适合什么场景?

答案:适合耗时较长、需要延迟获取结果或跟踪状态的操作。它仍是实验性能力,应做能力检测和降级,不要假设所有 Client/Server 都支持。

Q10: 如何防止恶意 MCP Server?

答案:审查来源和权限、固定版本、隔离进程、限制文件和网络、过滤工具列表、要求高风险操作确认、监控工具变化,并避免把环境中的全部凭据传给本地进程。

Q11: MCP 能替代 REST API 吗?

答案:不能。REST/GraphQL 是业务系统的确定性接口,MCP 是让 AI 应用发现和消费这些能力的适配层。业务授权、事务和一致性仍应留在 API 服务中。

Q12: 前端接入 MCP 最重要的体验是什么?

答案:可理解的工具状态、明确的副作用确认、取消与失败恢复、结果来源和权限解释。不要只显示模糊的“思考中”,也不要把工具原始 JSON 全部倾倒给用户。

相关链接