MCP 解决的是互操作:一个 LLM 应用用统一协议发现上下文和能力,不必为每个服务发明插件格式。它不自动证明服务器可信、工具安全、用户有权限,也不保证模型调用符合业务策略。把“能通过 MCP 看见工具”理解成“可以执行”,就像把 OpenAPI 文档当成管理员凭证。
本文面向准备接入远程或本地 MCP Server 的应用开发者。你需要理解 JSON-RPC、OAuth 和工具调用。依据核验日可见的最新稳定规范 2025-11-25,我们把协议能力与应用安全分开,再用五道闸门收窄真实权限。
图 1(1600 × 900):WEB/SUN 原创 SVG。Tools、resources、prompts 与 annotations 都是跨边界输入;协议描述能力,不替 Host 作出信任决定。
MCP 标准化了什么
官方MCP Specification定义了三类角色:Host 是发起连接的 LLM 应用,Client 是 Host 内面向某个 Server 的连接器,Server 提供上下文和能力。协议使用 JSON-RPC 2.0,并在生命周期中协商能力。
Server 可以暴露:
- Resources:供用户或模型使用的数据与内容。
- Prompts:面向用户的模板化消息或工作流。
- Tools:供模型请求执行的函数。
Client 还可能提供 roots、sampling、elicitation 等能力。这些名词描述消息流和责任,不描述信任等级。resource 可能包含恶意指令,prompt 可能诱导泄露,tool 可能执行任意代码,sampling 可能把内容发给模型。规范的安全原则甚至明确指出:tool 描述和 annotations 若不是来自可信 Server,应被视为不可信;Host 需要让用户理解并同意数据访问和工具调用。
另一个关键事实是,规范在“实施指南”中说明 MCP 本身无法在协议层强制所有安全原则。清晰同意、访问控制、数据保护和隐私界面仍是 Host、Client、Server 实现者的责任。
闸门一:先信任服务器身份,再读取能力
远程 MCP Server 是第三方服务。验证域名、运营主体、隐私与保留政策、事件响应、版本和供应链;优先使用服务提供方自己托管的官方 Server。OpenAI 的MCP 与 Connectors 指南同样警告远程 Server 未经 OpenAI 验证,恶意 Server 可能从模型上下文外泄敏感数据,并建议优先连接可信官方端点。
Server allowlist 绑定规范化 URL、TLS、组织和允许的协议版本。重定向后的域名重新验证,不能把 Server 返回的任意 URL 直接嵌入页面或由后端抓取。对本地 stdio Server,配置等同执行一个本地命令;显示完整命令和参数,要求同意,并用沙箱限制文件、网络和环境变量。
连接建立后保存工具目录 hash。Server 更新工具名、Schema、描述或 annotations 时先做 diff,高风险变化重新审核,不在后台静默接受。一个原本只读的工具可能在相同名称下改变语义,名称稳定不代表行为稳定。
闸门二:能力发现之后再做最小 allowlist
不要把 tools/list 的全部结果交给模型。按当前任务、用户角色和环境构建 allowlist,只导入必要工具;读、写、删除、外发、shell 和私人数据分别分级。OpenAI Responses 的 MCP 工具支持 allowed_tools 过滤,官方文档指出大型工具目录还会增加成本和延迟,但安全上更重要的是缩小可选攻击面。
能力 annotations 只能是提示。即使 Server 声称工具“readOnly”,Host 仍要依据自己维护的策略决定是否审批、能发送哪些字段、结果能否进入上下文。对关键工具维护本地契约:预期参数、输出上限、副作用类别、需要的 scope、是否可重试和审批方式。
Resources 和 prompts 也要过滤。资源 URI 受 roots、租户和 ACL 限制;prompt 模板在展示和运行前标明来源,不提升为 developer instruction。任何从 Server 返回的文本都作为不可信数据,不能借协议通道跨越消息优先级。
闸门三:OAuth 解决传输授权,不替代业务授权
MCP HTTP 授权是可选能力;使用时,最新Authorization Specification将受保护 MCP Server 视为 OAuth resource server,Client 代表 resource owner 请求访问。stdio 不使用这套 HTTP 流程,而通常从环境或本地凭据获得授权。
规范要求 Client 在授权与 token 请求中使用 RFC 8707 resource 参数,Server 验证 token 是专门发给自己的 audience。Server 不能接受或转发面向其他服务的 token。官方Security Best Practices将 token passthrough 明确列为反模式,因为它绕过 audience、审计和下游控制,并可能形成 confused deputy。
OAuth scope 只说明连接层授予的范围。每次 tool call 仍需按当前主体、租户、资源与动作做业务授权。不要让模型从参数提供 userId、tenantId 或 isAdmin;这些来自经过验证的运行上下文。高权限 scope 采用 step-up 授权和短期 token,不因为首次连接方便就申请“所有访问”。
Token 放秘密存储,不进入 prompt、工具参数、日志或 URL。验证 issuer、audience、有效期和 scope;授权 code 使用 PKCE 与严格 redirect URI。MCP session ID 不能当身份凭证,授权变更后重新建立相应会话边界。
闸门四:审批的是本次数据与动作
连接授权和调用审批是两件事。用户允许应用连接网盘,不等于允许它把某份合同发给模型或删除文件。审批界面显示 Server、工具、规范化参数、将发送的数据类别、读取/写入影响、目标资源和可撤销性;不要只显示“允许使用某插件吗”。
OpenAI MCP 工具默认在向 connector 或 remote Server 共享数据前请求审批,并产生 mcp_approval_request;应用返回对应审批响应后才继续。官方文档建议检查并可选记录所有共享数据。只有在工具、Server、数据范围和风险经过验证后,才对窄小只读集合免审批;敏感读和所有高影响写保持逐次或策略审批。
审批绑定参数 hash、用户、Server、工具版本和短有效期。恢复前重新检查资源与权限;参数或 Schema 改变就失效。拒绝审批是正常终态,Agent 应提供替代路径,不能换一个同义工具绕过。
闸门五:输出仍是不可信数据
MCP output 可能包含提示注入、超长正文、恶意 Markdown、脚本、内部 URL 和虚假状态。先按本地 Schema 与尺寸限制解析,删除不需要字段,标记来源,再作为 tool result 交给模型。不要执行返回的命令,不自动打开 URL,不把 HTML 原样注入 DOM。
URL 经过 scheme、域名、DNS 与重定向策略检查,阻止访问 loopback、云元数据和内网。官方安全指南将 SSRF 单独列为风险;仅检查字符串前缀不足以处理重定向和 DNS 变化。文件结果扫描类型与内容,保存到隔离区,不让 Server 决定任意本地路径。
日志记录 Server、工具版本、调用 ID、参数摘要、审批、scope、输出类别和错误,但脱敏 token 与私人正文。第三方 Server 的数据保留和地域政策独立于模型供应商;发送前就要确认,不可用“我们启用了 ZDR”推断第三方也不留存。
威胁模型清单
| 威胁 | 边界 | 关键缓解 |
|---|---|---|
| 恶意或被接管 Server | Server 身份 | 官方端点、pin、schema diff、隔离 |
| Tool poisoning / prompt injection | 能力与输出 | 本地策略、最小上下文、结构化结果 |
| Confused deputy | OAuth 与同意 | 每 Client 同意、PKCE、严格 redirect |
| Token passthrough | 授权 | audience 绑定、独立下游 token |
| SSRF / 恶意 URL | 输出与网络 | egress allowlist、重定向和 IP 检查 |
| 过度授权 | scope 与工具 | step-up、allowed tools、逐次审批 |
| 本地命令越权 | stdio Server | 显示完整命令、沙箱、最小环境 |
威胁不会因协议实现正确而消失。MCP 可以保证消息符合 Schema,却不能证明 Server 运营者善意、工具描述真实或模型决策符合用户意图。
上线前的验证
建立恶意测试 Server:动态改变工具 Schema;把注入放进 description、resource 和 output;返回内网 URL;请求超大数据;在只读工具中模拟写操作;返回别的租户标识;诱导 Client 转发 token。断言 allowlist、审批、授权、输出过滤与 egress 分别阻断。
同时测试 OAuth:错误 audience、过期 token、scope 不足、redirect 变化、state 重放和多租户 issuer 混淆。每次 Server 或工具目录变化都跑契约回归。生产中监控新工具、调用分布、审批拒绝、异常输出尺寸和域名变化。
失败模式与取舍
常见错误包括:看到 MCP Registry 条目就默认可信;导入全部工具;相信 readOnly annotation;把 resource 文本拼进 developer message;连接时一次同意所有未来动作;转发上游 token;用 session ID 鉴权;自动渲染输出 URL;本地 Server 继承整个用户环境。
逐次审批和最小 scope 增加摩擦,schema pin 降低动态扩展便利。可按证据逐步放宽:稳定官方 Server 的低风险只读工具可用策略审批;敏感读取、外发、写入和本地代码始终保留强边界。性能不能成为跳过信任模型的理由。
结论
MCP 标准化 Host、Client 与 Server 如何交换 resources、prompts、tools 和其他能力;它没有把发现变成许可。安全实现需要依次确认 Server、过滤能力、正确绑定 OAuth audience 与最小 scope、让用户审批本次数据和动作,并隔离不可信输出。
协议让集成可组合,安全边界让组合仍然属于用户。只有两者同时成立,MCP 才是能力接口,而不是把模型上下文、凭据和真实系统连成一条无防护通道。
Sources
- Model Context Protocol Specification 2025-11-25 — Model Context Protocol,访问于 2026-07-16。
- MCP Authorization 2025-11-25 — Model Context Protocol,访问于 2026-07-16。
- MCP Security Best Practices — Model Context Protocol,访问于 2026-07-16。
- MCP and Connectors — OpenAI,访问于 2026-07-16。