从 OAuth、scope 与用户同意,到 CLI 争论、工具上下文膨胀和企业治理
MCP 曾被比作 AI 应用的 USB-C,后来又在 X 和 Hacker News 上被宣布“死了”。两句话都抓住了一部分事实:MCP 的确降低了 Host 与外部系统之间的连接成本;在某些本地 Coding Agent 场景里,它也的确会带来工具描述、运行时和认证摩擦。1
真正的问题不是 MCP 活不活,而是连接之后,谁被授予了什么权力。
给 Agent 接上一个 MCP Server,可能只需要几行配置。让它安全地读取一个团队项目、创建一张工单、发送一封邮件,却要重新回答一串无法由连接协议替你拍板的问题:请求代表谁?token 发给哪个资源?scope 覆盖什么动作?用户是否同意这一次副作用?工具能访问哪些文件和网络?权限变化后如何撤销?出了问题又如何追到具体调用?
截至 2026 年 8 月,继续说“MCP 没有认证”已经不准确。2026-07-28 版 Authorization 规范对 HTTP 传输给出了更完整的 OAuth 轮廓,包括受保护资源元数据、授权服务器发现、resource 参数、audience 校验、PKCE、scope challenge 与 step-up authorization。2 但反过来,把 OAuth 成功、schema 合法或用户曾经点过同意理解为“权限问题已经解决”,同样是把协议能力外推得太远。
本文想同时守住两句话:MCP 不是没有价值,它提供了一段可复用、可发现、可跨 Host 的连接契约;MCP 也不是完整权限系统,它不会自动完成业务授权、当前意图确认、执行隔离、审计与撤销。 本文是基于规范、产品公告、论文和社区讨论完成的设计与研究文章,不把这些材料写成作者已经完成远程 MCP 生产验证的证据。
把 2024-2026 年的信号分成两条轨道看,会更清楚:
两条轨道并行,但不互相证明:上轨说明生态投入,下轨说明工程成本被重新审视。判断趋势时,两条轨道都要看,且不能互相替代。
一、MCP 为什么一度看起来像正确答案
2024 年 11 月 25 日,Anthropic 开源 MCP 时,瞄准的不是“世界上没有 API”,而是另一个真实问题:每个 AI 应用都在为每个数据源和业务工具重复写连接逻辑。初始发布同时提供规范、SDK、Claude Desktop 的本地 Server 支持,以及一组开源 Server。它希望把“每个 Host 对接每个系统”的碎片化关系,收敛为 Client 与 Server 之间的一套公共协议。3
如果有三个 AI Host 和五个外部系统,最朴素的做法可能维护十五组定制集成。MCP 的承诺是:外部系统以 Server 暴露工具、资源和 Prompt,Host 实现 Client 后便能复用同一套能力描述与调用格式。
这条链路中,MCP 标准化的是中间一段,不是整条业务动作。连接协议可以约定怎样列出工具、怎样发送参数、怎样返回结果;它不会天然知道“这个员工是否属于 repo-123”“当前工单是否允许关闭”或者“这次部署是否已经通过变更审批”。
2025 年的产品采用证明这段公共契约解决了真实需求。Claude 从本地 Server 扩展到远程 Integrations;OpenAI 把远程 MCP Server 接入 Responses API,并加入 MCP steering committee;Microsoft 在 GitHub、Copilot Studio、Azure AI Foundry、Semantic Kernel、Windows 11 等产品和框架中宣布广泛支持;Google 也宣布 Gemini API 与 SDK 兼容 MCP tools。4
这些信号说明厂商愿意围绕 MCP 投入,并不说明所有实现已经兼容,更不说明所有 Server 都具备生产级安全性。开放标准不等于实现一致,连接互操作也不等于权限互操作。 但它至少解释了 MCP 为什么不是凭空制造的概念:当一个远程服务需要同时面向聊天产品、IDE、Coding Agent 和企业 Copilot 时,一次实现、多处接入具有明确价值。
二、为什么后来有人说 MCP 没用
对 MCP 的反弹也不是无知造成的。很多批评来自非常具体的工程成本,只是这些成本常被从一个场景外推到了所有场景。
工具越多,发现和选择越贵
MCP 的 tools/list 会返回工具名称、描述和 schema。Host 如果把大量工具定义常驻模型上下文,模型不仅要为这些描述付出输入成本,还要从更大的候选集中判断该调用哪个工具。工具没有进入上下文,是 discovery failure;工具出现了却选错,是 selection failure;工具返回了大量低质量内容,又会形成 quality failure。它们都会消耗上下文,但根因并不相同。
成本由静态定义与动态结果两部分构成;缓解手段改的是“什么时候、带多少工具进上下文”,而不是协议本身。
RAG-MCP 与 JSPLIT 分别用检索和分类树按需选择工具,两项研究都把 prompt bloat 与工具选择压力视为可测量的系统问题。RAG-MCP 在自己的基准中报告,筛选相关工具描述后可减少提示 token 并改善工具选择;JSPLIT 也报告了在大工具集下缩短提示且不显著损害任务表现的结果。5 这些论文能证明“问题存在,而且可以工程化缓解”,不能证明所有 MCP Host 都会消耗固定数量的 token,也不能把论文基准结果直接当成某个生产系统的收益。
更稳健的判断是:工具目录规模、描述质量和 Host 的加载策略共同决定上下文成本。MCP 的工具 schema 不是天然浪费,预加载全部 schema 也不是唯一实现方式。分页、缓存、按授权返回工具、工具搜索、分层分类和动态发现,都可以改变成本函数。
在本地 stdio 场景里,它可能是过度封装
对已经被模型熟悉的 git、rg、curl、jq、psql 等 CLI,再包一层本地 MCP Server,收益确实可能很小。CLI 已经有成熟的安装方式、帮助文本、管道组合和 Shell 生态;Agent 可以先列子命令,需要时再加载 --help。MCP Server 则可能额外引入 Node/Python 运行时、依赖安装、配置文件、启动失败和版本管理。
这类批评尤其适用于单人、本机、已有稳定 CLI 的 Coding Agent。此时 MCP 若只是把一个命令原样换成 JSON-RPC,连接层节省不了多少重复集成,反而增加了一层故障面。
但“CLI 渐进披露”也不是免费午餐。自定义 CLI 若不在模型训练分布中,Agent 仍要知道它存在,再逐层读取帮助文本;复杂 REST API 也仍需要 OpenAPI、示例或领域文档。社区围绕 CLI 与 MCP 的争论,真正揭示的不是哪一种接口永远更省,而是能力说明在什么时候进入上下文,以及系统是否能只加载当前任务需要的那部分。6
安装一个 Server,本身就是供应链决策
本地 MCP Server 不是一段被动配置,而是一个会以当前用户权限启动的进程。它可能读取环境变量、访问文件和网络、拉取依赖,甚至在启动命令中执行任意代码。远程 Server 则把风险换成了服务身份、网络暴露、跨租户隔离、下游凭证和服务端变更。
一项覆盖 Host、Server 与 Registry 的安全研究分析了六个公共 Registry 中的 67,057 个 Server,指出弱审核、所有权校验不足、恶意工具元数据与代码漏洞可以形成“接入前进入生态、接入后影响调用”的两阶段攻击面。论文识别出的条件和样本不能直接外推为每个 Registry 或 Server 都存在漏洞,但它足以说明:安装、登记和升级 Server 都应进入正常的软件供应链治理。7
传输方式决定了问题的形状
把所有 MCP 都写成同一种东西,是这场争论中最常见的错误。
| 部署形态 | 主要收益 | 主要风险 | 典型治理点 |
|---|---|---|---|
本地 stdio | 低网络延迟、直接利用本地能力、适合开发工具 | 本机进程、依赖包、环境变量、文件与用户权限 | 启动命令审查、固定版本、沙箱、最小目录与网络权限 |
| 远程 Streamable HTTP | 多客户端复用、集中升级、统一身份与遥测 | OAuth、反向代理、跨租户、下游凭证、网络暴露 | audience/scope、租户校验、限流、审计、撤销、服务端变更控制 |
官方安全实践也明确区分了本地 Server 与远程授权风险:本地 Server 若缺少沙箱和明确同意,可能直接获得用户权限;HTTP 授权则必须防范 confused deputy、token passthrough、SSRF 与授权 URL 等问题。8
因此,“MCP 有用吗”更适合改写成一个任务成本问题:
连接层净收益 = 节省的重复集成与集中治理成本
- 上下文、延迟、部署、认证和审计成本
单人、单一服务、已有成熟 CLI 时,净收益可能为负;多 Host、远程服务、非技术用户、需要统一身份和审计时,净收益可能为正。判断不能靠口号,而应测量工具选择成功率、任务成功率、输入 token、P95 延迟、审批次数、拒绝正确率和升级后的回归结果。
三、“MCP 死了”到底死了什么
2026 年初,X、技术博客和 Hacker News 上的 CLI-first 讨论迅速升温。“MCP is dead; long live MCP”一文及其 Hacker News 讨论,集中呈现了两组相反意见:一组认为本地 stdio 经常只是对 CLI/API 的昂贵封装,工具 schema 还会挤占上下文;另一组认为远程 HTTP、企业身份、集中凭证、遥测和多客户端复用是 CLI 无法自动提供的组织级能力。该 Hacker News 页面快照有 295 points 和 205 条评论,但这只能证明讨论热度,不能当成行业民调。6
X 上的个人观点也应放在同一证据层:它适合告诉我们“大家正在争论什么”,不适合证明“行业普遍在做什么”。人物转述、单个 CTO 的内部实践和高浏览量帖子,都必须与规范、产品公告、论文或可复现实验分开。
真正被否定的,主要是早期那个过度宽泛的命题:所有工具都应该包装成 MCP,只要实现协议就能获得更好的 Agent 体验。这个命题本来就站不住。更有用的是按场景选接口:
| 场景 | 更合适的起点 | MCP 的位置 | 关键风险 |
|---|---|---|---|
| 单人、本地、熟悉 CLI 的 Coding Agent | CLI / 直接 API | 可选,只保留边界清晰且确有分发收益的工具 | Shell 权限过宽、凭证散落、审计依赖本机 |
| Hosted Chat、手机端、非技术用户 | 远程 MCP | 连接发现、OAuth、跨服务操作入口 | 业务授权、工具投毒、当前意图确认 |
| 多 Agent、多 Host、企业内网 | 远程 MCP / Gateway | 集中身份、策略、版本、遥测与撤销 | 跨租户、统一身份映射、变更审批 |
| 高吞吐、大工具目录 | MCP + Tool Search / Gateway | 作为能力目录或后端调用契约 | 工具描述膨胀、结果污染、成本与延迟 |
| 单个稳定内部服务 | 直接 API / SDK | 不必为了“支持 MCP”重复封装 | 两套契约漂移、维护成本 |
CLI 和 MCP 不是互斥阵营。一个常见的混合架构是:Agent 在本地执行内循环时优先使用成熟 CLI;需要跨设备、跨 Host、统一凭证和集中治理的能力时,通过远程 MCP 或 Gateway 暴露。甚至同一个服务,也可以同时提供 REST API、CLI 与 MCP,让不同客户端在同一业务授权内核上选择接口。
评价趋势时,还要避免把四类信号混在一起:
- 传播信号:X 浏览量、Hacker News points、GitHub stars,说明关注度。
- 采用信号:厂商宣布支持、SDK 下载、Server 数量,说明生态投入。
- 运行信号:活跃调用、任务成功率、上下文成本、延迟,说明实际使用。
- 安全信号:拒绝率、权限变更、事故、审计与回归结果,说明控制是否有效。
“某帖子很火”和“某能力在生产稳定运行”,中间隔着至少两层证据。
四、为什么 2026 年 MCP 又重新升温
2026 年的“再火”不是回到 2024 年“万能连接标准”的原始叙事,而是 MCP 的价值发生了重新定价:从本地插件协议,转向远程连接、企业治理和产品控制面。
第一类变化发生在协议层。2026-07-28 版规范把协议核心改成显式无状态:Streamable HTTP 移除了 GET stream 端点与协议级 session,每个 HTTP 请求在 _meta 里自带协议版本与客户端能力,server 不再从连接推断上下文;同时为工具列表增加更明确的缓存与路由能力,并推进 Tasks、MCP Apps、trace context 和更贴近 OAuth/OIDC 部署的授权流程。9 无状态化不是简化,而是一次工程交换:连接不再是会话,应用必须自己用显式句柄保存跨调用状态;换来的是请求可以穿过普通负载均衡、Gateway 与缓存层,而不需要 session affinity。这些变化不直接提升模型判断力,却改变了远程 MCP 的部署形状。
第二类变化发生在产品层。Figma 开放 Agent 操作原生设计资产,X 提供面向 X API 与开发者文档的 hosted MCP,Perplexity 在 macOS 提供本地 MCP 并宣布远程 MCP 逐步推出。它们共同说明 MCP 的需求并不限于“替代一个 Shell 命令”:设计画布、Hosted Chat 和第三方账号授权,本来就不是传统 CLI 最自然的交互面。10
OpenAI 的产品控制也很能说明方向。ChatGPT 的 full MCP 支持正在 Business、Enterprise 和 Edu 中以 beta 形式提供,包含写入/修改动作;组织需要先测试和发布 MCP App,Enterprise/Edu 还可用 RBAC 与动作级控制管理访问,新增或变化的 action 需要管理员刷新和审查。11 这里最有价值的不是“又多一个 MCP 客户端”,而是 MCP 工具开始进入发布、RBAC、动作审批和变更 diff 组成的产品化控制面。
第三类变化发生在治理层。MCP 于 2025 年 12 月加入 Linux Foundation 旗下 Agentic AI Foundation。项目方当时披露超过 10,000 个活跃 Server 和每月 9,700 万以上 SDK 下载;这些是官方生态规模信号,不是独立审计,也不能推导出生产活跃率或安全质量。12 2026 年 6 月稳定的 Enterprise-Managed Authorization extension 则尝试把组织 IdP 变成 MCP Server 访问的集中决策点,减少逐 Server OAuth 和重复同意,并将组、角色和条件访问带入连接流程。13
可以把这轮升温拆成三句话:
- 协议升温:远程部署更像可路由、可缓存、可追踪的普通基础设施。
- 产品升温:MCP 变成用户可见的连接入口,而不只是开发者配置文件。
- 治理升温:Registry、Gateway、企业 IdP、RBAC、动作级发布和审计开始进入控制面。
三者不能相互替代。产品有入口,不代表 Server 实现安全;协议有 OAuth,不代表组织配置了正确的业务 scope;治理有日志,也不代表模型不会被不可信内容诱导。
五、从连接到授权:一条工具调用的五层边界
一段真实的工具调用
MCP 的消息体是 JSON-RPC 2.0:请求带 jsonrpc、id、method 与 params,响应回带相同 id 的 result 或 error。通过 Streamable HTTP 传输时,每次调用就是一个独立的 HTTP POST,头部与请求体互为镜像:20
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: create_ticket
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"create_ticket","arguments":{"title":"...","priority":"high"},
"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28",
"io.modelcontextprotocol/clientCapabilities":{}}}}
这段消息里藏着三个直接决定后文的细节。
第一,连接不是会话。 _meta 中的 io.modelcontextprotocol/protocolVersion 与 clientCapabilities 由每个请求自己携带,server 不得从“这个连接之前说过什么”推断状态。2026-07-28 规范移除协议级 session,正是为了让请求能穿过普通负载均衡与网关而不需要 session affinity;代价是应用若要保存跨调用状态,必须自己用显式句柄(basket_id、browser_id)在每次请求里传递——句柄只是状态引用,不是身份。
第二,HTTP 头与请求体互为镜像。 Mcp-Method、Mcp-Name 以及由工具 schema 的 x-mcp-header 扩展提升的 Mcp-Param-* 头,把路由所需信息复制到中间层可见的位置;server 必须校验头与体一致,不一致返回 JSON-RPC 错误 -32020 HeaderMismatch。这既防止“负载均衡按 header 路由、server 按 body 执行”的信任分裂,也让工具参数能在网关层参与租户隔离、限流与审计,而不必解析 body。
图里的关键点不是多了一组头,而是同一份数据在两个位置各出现一次:中间层只能看到头,执行层必须验证头与体一致。任何只信任其中一边的组件,都会把“路由决定”和“执行决定”交给不同的事实来源。
第三,schema 是输入,不是证明。 工具的 inputSchema 描述参数结构,不描述副作用;而且 schema 本身来自 Server——规范默认禁止解析网络 $ref、对组合校验设复杂度上限,正是因为恶意 schema 可以把校验器变成 DoS 面。20
这段消息里,协议保证的只有“能发现、能调用、格式合法”:不含身份、资源范围、当前意图,更不含执行边界。这就是五层模型的起点。
讨论走到这里,应该把“MCP 是否有用”的趋势问题,换成“这一层到底负责什么”的架构问题。一条工具调用至少经过五层判断:
| 层 | 要回答的问题 | MCP 能提供的部分 | 应用仍要设计的部分 |
|---|---|---|---|
| 连接 | Client 能否找到并调用 Server? | 传输、能力发现、工具/资源描述、调用格式 | 可用性、版本兼容、重试与降级 |
| 身份 | 请求是谁发出的? | HTTP 授权流程、OAuth/OIDC 发现 | 用户、Host、Client、Server、下游身份映射 |
| 授权 | 这个身份能访问哪个资源? | token、resource、scope、受保护资源元数据 | 角色、租户、资源范围、动作级业务策略 |
| 用户意图 | 用户是否真的想做这一次动作? | 可拒绝调用、人机在环、elicitation 能力 | 风险分级、参数预览、二次确认、审批疲劳控制 |
| 执行隔离 | 即使模型被诱导,影响能否被限制? | 协议不替代沙箱 | 文件、网络、进程、凭证、配额、超时、撤销、审计 |
OAuth 成功应该画在身份与授权层之间,而不是整个系统的安全终点。
这五层还需要一张主体与资产表。用户拥有账号、私有数据和当前意图;Host/Client 持有工具清单、token 与审批状态;MCP Server 持有工具实现、租户上下文和下游凭证;外部网页、邮件、issue 与文档承载不可信内容;真正被改变的是文件、数据库、CRM、支付和部署系统。任何一层把相邻层当成“已经替我验证”,都可能形成越权。
最典型的错误是把 Server 当成权限粒度:用户要么能连接这个 Server,要么不能。现实中,读、写、发、删、部署不是同一级别。读可能泄露敏感数据;写会改变持久状态;发送会把影响扩散到第三方;删除和部署通常不可逆,或恢复成本极高。
因此,权限至少要同时考虑工具动作、资源范围、数据敏感度和副作用。低风险读操作可以在稳定策略下放行;高风险写、发、删、部署应展示目标与最终参数,并绑定一次性确认、step-up authorization 或外部审批。首次安装时的一次同意,不能永久覆盖以后新增的工具、变化的 schema 和更大的副作用。
把动作分级展开,得到一张贯穿 scope、确认方式与撤销策略的映射表:
| 动作级别 | 典型工具 | scope 粒度 | 确认方式 | 隔离与撤销 |
|---|---|---|---|---|
| 读 | read_docs、search_issues | 资源级只读 | 稳定策略放行 | 敏感数据脱敏、读取审计 |
| 写 | create_issue、update_record | 资源 + 动作 | 参数预览 + 一次性确认 | 版本快照、可回滚 |
| 发 | send_email、post_message | 动作 + 接收方范围 | 最终内容与接收方确认 | 外发审计、接收方白名单 |
| 删 | delete_record、close_issue | 对象级 | step-up / 外部审批 | 软删除、恢复窗口 |
| 部署 | deploy、publish | 环境约束 | 变更审批链 | 仅 staging、审批留痕 |
这张表说明的不是“按工具名分级”,而是同一工具的不同参数也可能落在不同级别——“删除一个草稿”与“关闭整个工单”不应共用同一确认策略。
六、OAuth 解决了什么,没解决什么
新版 MCP Authorization 最值得肯定的地方,是它不再把远程授权留给每个客户端和 Server 自由发挥。规范明确把受保护的 MCP Server 视为 OAuth resource server,把 MCP Client 视为 OAuth client,授权服务器负责与用户交互并签发 access token。它还要求受保护资源元数据与授权服务器发现,并通过 resource 参数和 audience 校验把 token 绑定到目标 Server。2
一个不绑定厂商的远程流程可以写成:
这条流程解决的是“谁可以把什么 token 发给哪个资源服务器”。规范没有让这些环节停留在口头要求,而是落到具体的协议行为:2 21
- 挑战即指引。 未授权请求返回
401,响应头为WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource", scope="files:read"。resource_metadata指向 RFC 9728 定义的受保护资源元数据(server 必须实现),scope是这次操作真正需要的权限集合。客户端按最小权限原则优先采用挑战给出的 scope,而不是一次性申请scopes_supported里的全部。 resource参数绑定目标。 按 RFC 8707,授权请求与 token 请求都要带resource=https%3A%2F%2Fmcp.example.com,且必须是规范 URI(无 fragment、语义上不带尾斜杠)。签发的 token 的 audience 就是这个 server;server 校验 token 是否签发给自己的,不是自己的一律拒绝。- token passthrough 是明文禁止的 MUST。 规范原话是 server “MUST NOT accept or transit any other tokens”——不能接收一个并非签发给自己的 token,再转交下游 API。这堵住的是凭证转发放大面:偷到一个 token,不该能拿它在别的 server 上碰运气。8
RFC 9700 进一步给出了 OAuth 2.0 当前安全基线,包括 redirect URI 精确匹配、PKCE、issuer/mix-up 防护、token 权限限制、audience-restricted token 与 refresh token 保护;2026-07-28 规范还要求客户端校验授权响应中的 iss 参数(RFC 9207),防止两个授权服务器之间的 mix-up 攻击。14 21
这些能力非常重要。没有 resource 与 audience 约束,一个被盗或误发的 token 更容易在不相关服务间复用;没有 PKCE 与 issuer 校验,授权码流程会暴露在注入和 mix-up 风险下;没有 scope challenge 与 step-up,客户端要么一开始申请过宽权限,要么无法在需要时增量授权。
scope challenge 与 step-up 把“最小权限”从原则变成协议流程。运行时 token 的 scope 不够,server 返回 403,响应头为 WWW-Authenticate: Bearer error="insufficient_scope", scope="files:write", resource_metadata="..."。客户端解析后,用“已有 scope ∪ 挑战 scope”的并集发起一次增量授权,再重试原请求;规范要求客户端限制重试次数、追踪升级尝试,服务端负责处理 scope 层级(宽 scope 蕴含窄 scope)。2 换句话说,一次写操作不必在安装时就申请所有写权限——它可以在第一次真正需要时,才触发一次针对性的用户确认。
但协议流程正确以后,业务判断才刚开始。
假设 token 带有一个笼统的 project.full_access,MCP Server 即使正确校验了 token 有效性、issuer、audience、expiry 和 scope,仍然不知道用户是否属于目标项目、工单当前是否允许修改、部署环境是否只能是 staging,以及这次变更是否需要审批。更好的 scope 可以先拆细:
project.read:repo-123
issue.create:repo-123
issue.comment:repo-123
deploy.request:staging
但这仍不是完整业务授权。资源服务器还要逐请求校验用户角色、tenant_id、资源归属、对象状态与环境条件。scope 是权限输入,不是领域策略本身。
把一次授权决策拆开,至少需要五类输入:
主体(who) 用户、Host、Client、Server 的身份与角色
动作(what) 读、写、发、删、部署,以及各自的风险等级
资源(which)租户、仓库、工单、文件、部署环境
条件(when) 时间、来源、审批状态、对象当前状态
渠道(how) stdio 本地进程、远程 HTTP、Gateway 转发
OAuth 的 scope 只覆盖前两类的协议层表达,其余都留给应用:RBAC/ABAC 的角色与属性、对象级归属校验、“只有 staging 允许部署”这类条件访问,都属于这一层,MCP 不提供。
MCP Authorization 还有两个容易被忽略的边界。第一,授权在协议层是 optional,但措辞是分明的:HTTP 传输实现授权时应遵循该规范(SHOULD),stdio 则应从环境取得凭证,不走同一套远程 OAuth 流程(SHOULD NOT)。第二,OAuth 无法判断工具描述是否投毒,也不能让模型稳定地区分网页中的数据与指令。
所以,准确的结论不是“MCP 已经解决授权”,而是:MCP 已经为远程连接定义了协议级授权骨架;业务系统仍要完成资源级授权、当前意图确认和执行边界。
七、合法工具也会造成越权
假设 OAuth、audience、scope 与 schema 全部正确,系统仍可能做出用户没有真正授权的动作。原因在于 Agent 的攻击面不只来自伪造身份,还来自工具语义、外部内容和工具之间的数据流。
工具列表不是权限清单
工具名、description 和 JSON Schema 只描述“怎样调用”,不证明实现可信、参数安全或副作用符合预期。MCP Tools 规范建议(SHOULD)应用让用户看见暴露给模型的工具、显示调用并提供拒绝能力,也允许 Server 按请求携带的授权返回不同工具集合。15 这些是重要的 Host 责任,但规范不会替应用定义什么叫“敏感操作”。
一项对 GitHub 上 1,723 个 MCP 应用的样本研究发现,90.8% 有日志、77.2% 有启停控制,但只有 37.2% 在工具执行前设置阻塞式审批。16 这个比例不能当作全部 MCP 生态的合规率;它说明的是,在该论文的样本和分类方法下,“能记录”和“能关闭”比“每次高风险执行前阻断并确认”更常见。
工具集合还会变化。一个初次审批时只读的 Server,之后可能新增写工具;同名工具可能修改 description 或扩大 schema;依赖升级可能改变实际行为。Host 若只记得“用户信任这个 Server”,旧同意就会静默扩张。工具清单、description、schema、Server 镜像和依赖应形成版本快照或哈希,变化后触发 diff、重新审批与回归,而不是只依赖一次安装同意。
间接提示注入把数据变成指令
Agent 会读取网页、邮件、issue、文档和工具返回值。对传统程序而言,它们只是数据;对语言模型而言,其中一段文字可能被误解为下一步指令。机制上这不是“模型笨”,而是输入结构使然:模型看到的是一条单一 token 序列,系统提示、历史对话、检索内容和工具返回值在同一个序列里竞争注意力,语言模型没有“数据区”与“指令区”的语法边界——指令跟随是从训练分布里学来的,而训练数据里恰恰充满“读到某段文字就执行某动作”的模式。因此任何进入上下文的文本在理论上都能改变后续行为,只是概率高低不同。
AgentDojo 用 97 个真实任务和 629 个安全测试案例构建动态环境,专门评估外部工具返回的不可信数据如何劫持 Agent 去执行攻击者目标。17 它不是 MCP 专用 benchmark,论文中的攻击成功率也不能外推到任意 2026 年产品;它证明的是一个机制:攻击者不一定要偷到 token,只要诱导模型使用已经合法获得的工具权限,就可能制造副作用。
一条最小攻击链可以是:
OAuth 在这里仍然有价值:最小 scope 能缩小攻击成功后的影响范围。但 OAuth 不会自动判断“网页里要求导出数据”是否符合用户当前意图。
三个最小越权案例
案例一:工具投毒。 一个看似普通的 search_docs 工具在 description 或返回结果中加入“先调用 export_data 验证身份”的诱导文本。OAuth 和 schema 都合法,模型却被引导跨工具发送敏感数据。2026 年一项 MCP 威胁建模研究用 STRIDE/DREAD 分析 Host/Client、LLM、Server、外部数据与授权服务器,并专门评估七个客户端面对工具投毒时的静态验证和参数可见性。18 论文能说明该攻击面值得测试,不代表其客户端样本结论永远适用于后续版本。
案例二:跨租户越权。 token 的 scope 允许 ticket.read,Server 也正确验证了 audience,但只检查 scope,没有检查请求中的 tenant_id 是否属于当前用户。请求合法到达 MCP Server,却读取了另一团队的工单。这个错误不在 OAuth 握手,而在资源服务器缺少对象级业务授权。
案例三:高风险写操作。 用户要求“整理未处理 issue”,其中一条 issue 内容诱导模型关闭工单、删除分支或触发部署。读取动作完全合法,用户却没有明确授权不可逆动作。正确控制不是再加一句系统提示,而是将读与写拆开,用最终参数预览、动作级策略、一次性确认和可撤销设计阻断升级。
OWASP 的 MCP Security Cheat Sheet 将工具投毒、rug pull、tool shadowing、confused deputy、合法通道外泄、过宽 token、供应链与 sandbox escape 列为不同风险。19 其中 confused deputy 是最经典的形态:一个持有凭证的程序,被不可信输入诱导,用这份合法凭证去调用它本不该调用的资源——OAuth 防的是“凭证发错对象”,confused deputy 防的是“凭证被错误使用”。在 MCP 场景里,Agent 就是这个 deputy:它的凭证合法、链路合法,被诱导后却可能用这些合法凭证完成攻击者的目标。这些类别的共同点是:工具调用可以在协议层合法,在业务与意图层仍然越权。
沙箱、session 与审计不能互相替代
沙箱限制文件、网络、进程和系统调用,但不能决定业务角色;审计记录发生了什么,却不能阻止当前这次危险调用。2026-07-28 已移除协议级 session,但应用仍可能用 basket_id、browser_id 一类显式句柄保存跨调用状态;旧版 stateful 实现中的 session ID 与新版应用级状态句柄,都不能直接充当用户身份——原因在协议层已经定死:连接不是会话,句柄只是客户端自报的状态引用,server 若信任它,等于让任何拿到句柄的调用方伪装成状态所有者。2025-11-25 安全实践对旧版 session 的要求仍说明了同一原则:身份来自经过验证的授权信息,Server 不能因为客户端带着某个状态标识就跳过入站请求校验。8 9
三者都需要,职责却不同:
- 沙箱缩小执行爆炸半径:允许哪些目录、域名、进程、系统调用与资源配额。
- 授权与状态绑定防止跨用户混淆:身份来自 token,不来自客户端自报的 session ID 或应用句柄。
- 审计提供可追溯与撤销线索:记录主体、Host、Server/工具版本、scope/audience、参数与结果摘要、审批、拒绝原因和下游 request ID。
审计本身也可能变成秘密复制面。日志不应保存 access token、Cookie、完整凭证或无边界的敏感原文;能关联调用链,不等于复制所有输入输出。
八、把权限边界写成可回归验收
权限边界若只存在于架构图、系统提示和“请谨慎操作”的文案里,就无法证明它在版本变化后仍然成立。接入 MCP Server 应被当作一次权限与供应链变更,至少经过接入前、运行时和变更后三个阶段。
接入前:先固定你准备信任什么
- Server 的来源、维护者、版本、镜像与依赖是否可追溯?
- 使用本地
stdio还是远程 Streamable HTTP?凭证存放、网络出口和信任边界是否明确? - 启动命令是否完整展示并经过审查?本地进程是否固定版本并运行在最小权限沙箱?
- 工具是否按读、写、发、删、部署分级?哪些动作默认拒绝?
- 工具集合、description 与 schema 是否有快照、变更通知和升级审批?
- scope 是否映射到租户、资源和动作,而不是只提供一个全能权限?
运行时:正常路径与拒绝路径一起测
- Server 是否逐请求校验 issuer、audience/resource、expiry、scope 和 token 有效性?
- 是否拒绝 token passthrough、scope 不足、跨租户和无关下游调用?
- 高风险动作是否显示最终目标、参数、影响范围与不可逆后果?
- 恶意工具描述、间接提示注入和跨工具数据流能否触发明确拒绝?
- 文件、网络、进程、凭证、调用频率和执行时长是否隔离?
- 日志是否能关联调用链,同时无法恢复 token、Cookie 与敏感凭证?
变更后:证明旧授权没有静默扩张
- 工具列表、schema、依赖、Server 镜像和授权配置变化是否自动触发 diff 与回归?
- 新工具和扩大后的参数是否默认禁用,直到重新批准?
- 过期 token、撤销、scope 不足、错误 audience 与跨角色访问是否留下真实拒绝证据?
- 用户或管理员能否看见当前启用的 Server、工具与动作权限?
- 能否只撤销某个 Server、工具或 scope,而不必重建整个 Agent?
- 是否同时测量任务成功率、拒绝正确率、上下文成本、延迟和审批次数?
最终验收矩阵至少要同时包含“应该成功”和“必须失败”:
| 测试维度 | 正常路径 | 必须失败的路径 | 需要保留的证据 |
|---|---|---|---|
| 身份 | 正确用户 token 可访问 | issuer、audience 或 expiry 错误 | HTTP 响应、策略事件、调用链 ID |
| scope 与资源 | 允许的读取成功 | scope 不足、跨租户、错误资源 | 401/403、拒绝码、策略日志 |
| 当前意图 | 确认后执行写操作 | 无确认、最终参数被改写 | 审批记录、最终参数、下游结果 |
| 不可信内容 | 普通文档可完成任务 | 提示注入不能触发敏感动作 | 攻击样例、阻断层与拒绝原因 |
| 工具变更 | 兼容升级继续工作 | 新工具/新 schema 未批准不可调用 | 工具快照、diff、回归报告 |
| 执行隔离 | 允许范围内访问文件/网络 | 越界文件、未授权出站、超额资源 | 沙箱日志、网络策略与配额命中 |
| 撤销与审计 | 合法调用可追踪 | 撤销后继续使用、日志泄露凭证 | 撤销事件、失败请求、脱敏检查 |
把“必须失败”落成可断言的期望,至少要有这样的形态:2
说明:用 server A 签发的 token 调 server B → 期望 401(audience 不匹配)
curl -i https://b.example.com/mcp \
-H 'Authorization: Bearer <A 签发的 token>' -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"read_ticket","arguments":{}}}'
预期:HTTP 401,WWW-Authenticate 带 resource_metadata 与 scope
说明:有 token 但 scope 不足 → 期望 403 且 error="insufficient_scope"
预期:HTTP 403,WWW-Authenticate: Bearer error="insufficient_scope", scope="..."
说明:HTTP 头与请求体不一致 → 期望 400 且 JSON-RPC error code=-32020
预期:HTTP 400,{"error":{"code":-32020,...}}
三个用例分别对应本文讲过的三个机制:audience 校验、scope challenge、header–body 镜像校验。它们都能在真实 Host 与 Server 上直接执行,不需要测试替身。
一套最小可接受的回归可以从五条开始:只读工具成功、写工具在无批准时失败;错误 audience、scope 不足、过期和撤销 token 明确失败;恶意网页文本不能诱导 Agent 发信或删除资源;Server 更新 schema 后旧授权不会自动覆盖新动作;审计可以还原调用链,但无法从日志恢复凭证。
这里最重要的不是清单长度,而是证据来自真实公共边界。直接调用一个内部策略函数,只能证明函数行为;模拟 OAuth 成功,只能证明测试替身;真正的验收要从 Host 或 Client 的正常入口发起请求,让实际 Server、授权中间件、业务策略、沙箱与审计共同参与,并保留正常与拒绝路径的结果。
九、不要再问 MCP 是否“死了”
MCP 没有替代 API、CLI、SDK 或权限系统。它做的是把 Agent 与外部能力之间的一段连接契约变得可复用、可发现、可跨 Host。在本地单人 Coding Agent 中,成熟 CLI 或直接 API 常常仍是更好的起点;只有 MCP 明确降低分发、跨客户端或集中治理成本时,才值得增加这一层。
对远程、多客户端、非技术用户和企业系统,MCP 的价值则越来越像公共连接与治理入口:统一发现能力,把 token 绑定到目标资源,让组织集中发布工具、限制动作、观察调用和撤销权限。但这些价值成立的前提,是业务授权、当前意图和执行隔离没有被协议名词遮住。
进入生产后,真正需要回答的不是“我们是否支持 MCP”,而是下面这组问题:
谁通过哪个 Host,在什么身份和 scope 下,看到了哪些版本的工具;这一次调用指向哪个租户与资源;用户是否同意最终参数和副作用;文件、网络与凭证被限制在哪里;工具变化是否触发重新审批;出了问题能否拒绝、追踪和撤销。
只要其中一个问题仍靠“模型应该会理解”回答,授权闭环就没有完成。
MCP 可以成为企业 Agent 控制面的一部分,但不会自动变成控制面本身。连接是协议问题;把连接变成一项可控、可撤销、可回归的权力,仍然是应用工程。
参考资料
参考资料
What is the Model Context Protocol (MCP)?,MCP 官方入门文档,将 MCP 类比为 AI 应用的 USB-C;MCP is dead; long live MCP,Hacker News 讨论快照,仅作为社区观点样本。 ↩
Model Context Protocol. Authorization - 2026-07-28 Specification. ↩ ↩ ↩ ↩ ↩
Anthropic. Introducing the Model Context Protocol, 2024-11-25. ↩
Anthropic. Claude can now connect to your world, 2025-05-01;OpenAI. New tools and features in the Responses API, 2025-05-21;Microsoft. Microsoft Build 2025: The age of AI agents and building the open agentic web, 2025-05-19;Google. Google I/O 2025: Sundar Pichai's opening keynote, 2025-05-20. ↩
Tiantian Gan, Qiyao Sun. RAG-MCP: Mitigating Prompt Bloat in LLM Tool Selection via Retrieval-Augmented Generation, 2025-05-06;Emanuele Antonioni et al. JSPLIT: A Taxonomy-based Solution for Prompt Bloating in Model Context Protocol, 2025-10-16. ↩
Charles Chen. MCP is Dead; Long Live MCP!, 2026-03-14;Hacker News discussion,观点样本,不是行业测量;Niels Rogge. On CLIs vs. MCP,社区综述。 ↩ ↩
Xiaofan Li, Xing Gao. A First Look at the Security Issues in the Model Context Protocol Ecosystem, revised 2026-04-27, accepted to DSN 2026. ↩
Model Context Protocol. Security Best Practices - 2025-11-25. 当前可访问安全页仍带
2025-11-25版本标识;本文以2026-07-28Authorization 规范校准授权部分。 ↩ ↩ ↩Model Context Protocol. The 2026-07-28 MCP Specification Release Candidate, 2026-05-21;最终规范版本为
2026-07-28。 ↩ ↩Figma. Agents, Meet the Figma Canvas, 2026-03-24;X Developer Platform. MCP servers for the X API and X developer docs;Perplexity. Local and Remote MCPs for Perplexity, updated 2026-07-16. ↩
OpenAI Help Center. Developer mode and MCP apps in ChatGPT, accessed 2026-08-05. 页面明确标注 full MCP 与写入/修改能力仍处于 beta,功能、UI 与权限可能变化。 ↩
Model Context Protocol. MCP joins the Agentic AI Foundation, 2025-12-09. Server 与 SDK 下载数字为项目方披露。 ↩
Model Context Protocol. Enterprise-Managed Authorization: Zero-touch OAuth for MCP, 2026-06-18. ↩
Model Context Protocol. Base Protocol - 2026-07-28 Specification;Streamable HTTP - 2026-07-28 Specification. ↩ ↩
IETF. RFC 6750 (Bearer Token Usage)、RFC 8414 (Authorization Server Metadata)、RFC 8707 (Resource Indicators)、RFC 9207 (Authorization Server Issuer Identification)、RFC 9728 (Protected Resource Metadata)、RFC 7591 (Dynamic Client Registration) 与 OAuth 2.1 草案;2026-07-28 Authorization 规范正构建于这一组标准之上。 ↩ ↩
Torsten Lodderstedt et al. RFC 9700: Best Current Practice for OAuth 2.0 Security, 2025-01. ↩
Model Context Protocol. Tools - 2026-07-28 Specification. ↩
Muhammad Hamza Arshad Majeed, May Mahmoud, Sarah Nadi. An Empirical Study of Model Context Protocol Applications, revised 2026-07-29. ↩
Edoardo Debenedetti et al. AgentDojo: A Dynamic Environment to Evaluate Prompt Injection Attacks and Defenses for LLM Agents, revised 2024-11-24. ↩
Charoes Huang, Xin Huang, Ngoc Phu Tran, Amin Milani Fard. Model Context Protocol Threat Modeling and Analyzing Vulnerabilities to Prompt Injection with Tool Poisoning, 2026-03-23. 该来源修正了研究大纲中误写的 arXiv 编号。 ↩
OWASP Cheat Sheet Series. MCP Security Cheat Sheet, accessed 2026-08-05. ↩