Cloudflare 如何识别 MCP 流量并保障其安全
标题:Cloudflare 如何识别并保护 MCP 流量
大多数公司在设计资源权限时,默认使用对象是人类用户。比如,一位资深工程师可能有权部署到生产环境、查询敏感数据库,或者撤销其他用户的访问权限。这些权限本身带有风险,但传统上风险一直被两个前提约束着:工程师会运用人类判断力,并且只能以人的速度行事。工程师看到意外结果时,通常会停下来重新考虑自己的操作。而且任何人在一天之内能点击、输入和检查的内容都是有限的。AI 代理的出现改变了这两个门槛。它们的决策是非确定性的,而且可以无限次地执行同一个操作(或调用同一个工具),不会疲倦,也不会停下来吃午饭。一个看似合理但实际错误的决策,可能在人类察觉之前就演变成数千次错误操作。今天,我们宣布推出新的 Cloudflare One 功能,用于识别已检查的 MCP 流量,显示哪些用户和服务器在产生这类流量,并控制受管网络路径上的直连。结合 MCP Server Portals,这些控制措施可以帮助管理员判断代理是否在使用已批准的路径,还是在以某种方式绕过它。模型上下文协议(MCP)服务器为代理提供了一种通用方式,用来发现和调用由第三方 SaaS 产品、内部应用和 API 支持的各类工具。底层权限可能并不陌生;真正改变的是每个决策由谁做出,以及一个错误决策能传播得多快。将代理连接到这些工具之一,可能只需要一行配置。员工可以不经任何审批,就把 Claude Code、Codex、Cursor、OpenCode、VS Code 或任何 AI 工具指向一个 MCP 服务器。产生的流量没有明显的固定特征。模型上下文协议并不强制使用特定主机名,也不要求在路径中包含 /mcp,因此一条直连看起来和其他 HTTPS API 调用没什么两样。为了说明这些控制措施如何配合,我们先从一次工具调用的结构及其暴露的信息讲起,然后再比较安全团队可以采取行动的三个位置:客户端内部、网络上,以及 MCP 服务器端。
接下来,我们会展示 Cloudflare Gateway 如何利用协议信号发现影子 MCP 流量,并强制只有通过 MCP Portal 才能访问受信任的 MCP 服务器。
一次 MCP 工具调用的完整过程
同一个 MCP 工具调用,在系统里流转时会呈现三种形态。在客户端内部,它是携带一组参数调用工具的决定;在网络上,它是一笔承载 JSON-RPC 消息的 HTTP 事务;到了服务器端,它就变成对工具处理函数的一次调用,可能读取数据、修改状态或完成其他操作。
假设一个智能体想知道奥斯汀的天气,它发出的远程 MCP 请求大致是这样的:
这个请求里藏着几个很有用的信号。主机名和路径指明目标地址;authorization 请求头携带调用方的凭据,供服务器在需要时进行身份认证。MCP-Protocol-Version 请求头标明协议版本,而在新的无状态协议中,Mcp-Method 和 Mcp-Name 两个请求头分别暴露了操作类型和工具名称。
JSON-RPC 信封里重复了方法名,给请求一个 id 方便客户端与响应配对,并用 params 字段携带工具参数。参数是最敏感的部分,里面可能是搜索查询、源代码、客户数据,也可能是某个动作的指令,比如创建工单或更改基础设施。
工具名称表明智能体打算调用什么;参数则说明它会发送哪些数据、希望服务器执行什么操作。如果调用成功,服务器会返回一个带相同 id 的 JSON-RPC 响应以及工具结果,这个响应同样可能包含敏感数据。检查请求可以在动作执行前拦下不安全操作;而检查响应并记录日志,则能看清工具到底向智能体返回了什么内容。
控制 MCP 请求的三个位置
安全团队可以在三个位置观察或控制这个请求。
MCP 客户端内部
客户端钩子可以在模型选定工具之后、客户端序列化请求之前运行。在这个位置,不需要解密网络流量就能看到目标服务器、工具名称和参数。这是整个请求链路中最早可以施加控制的一环。
客户端可以拒绝不在白名单(allowlist)中的服务器、在敏感操作前请用户确认,或在数据离开设备之前从参数中剔除相关内容。这种方式也能覆盖本地 stdio(即本地)MCP 服务器——它们不会产生任何网络流量。但这带来了标准化难题:安全团队要想从中受益,就得在员工使用的每个客户端上,把这些安全策略重新实现一遍。当企业同时管理客户端和设备时,客户端侧的控制效果最好;但单个客户端上报的遥测数据,永远无法完整反映 MCP 的整体使用情况。
设备网络边界
安全 Web 网关能观察到客户端发出的 HTTP 请求。借助 TLS 解密,它可以把请求关联到具体的用户和设备,检查目标地址与协议头,并按策略处理,而无需依赖某个特定的 MCP 客户端。网络层是检测受管路径上远程 MCP 流量时视野最广的位置:网关能识别出指向已批准 Portal 之外服务器的直连,并在请求到达目的地前将其阻断。在支持数据防泄漏(DLP)扫描的场景下,代理还能检查 JSON-RPC 的方法名和参数里是否带有敏感数据。不过,代理无法看到本地 stdio 调用,也看不到企业网络之外的流量。
MCP 服务器调用工具之前
服务器拥有最丰富的执行上下文:它已完成调用方身份认证,解析了 MCP 消息,把 get_weather 路由到对应的处理函数,并按照工具的输入 schema 校验了参数。这是工具真正运行之前,最后一个能拒绝请求的位置。
Agents SDK 的处理函数或类似的服务器中间件,可以针对具体工具授权调用方、应用
WriteGuard 可以原样放行读请求,也可以给允许的写操作加上代理归属信息和审计事件,还能在危险操作的处理函数执行前直接将其拦截。由于控制逻辑在服务端,终端用户没法通过更换客户端或禁用本地钩子来绕过它。
服务端控制只对实现了它的服务器生效,但客户端和服务端拥有最好的请求纵深。网络层能看到最广的远程连接范围。把这几层配合起来用,就能在敏感数据离开设备之前拦住它、发现不受管控的 MCP 流量,也能在某个工具真正执行前拒绝未授权的操作。
网络控制点覆盖范围最广,但它需要先具备把 MCP 从普通 HTTPS 流量中区分出来的能力;同时,用户得运行代理,MCP 服务器(或 Portal)还得验证这条连接确实经过了代理。Cloudflare One 负责这条链路中的网络环节:Cloudflare One Client 会把受管设备上的流量送入 Gateway,Gateway 在协议层对 MCP 请求进行分类,判断流量是来自 MCP Portal,还是已经脱离了受控范围。管理员可以据此统计、甚至直接封禁那些不走既定路径的连接。
而这一切,都始于可靠地识别出 MCP 请求。
单看 URL,你判断不了一个请求是否在使用 MCP。
我们最初识别 MCP 流量的方法,是通过 GraphQL Analytics API 在 Gateway 的 HTTP 日志中搜索主机名,找那些包含 mcp 字段、或使用了 /mcp、/sse 等常见路径的请求。我们的 MCP 流量检测教程里有对应的查询语句,还讲解了如何为请求体中的 MCP JSON-RPC 方法(比如 initialize、tools/call、resources/read)配置数据防泄露(DLP)规则。
这些信号对查找旧客户端的流量、做历史回溯仍然有用,但识别逻辑本身很粗糙:如果一个 MCP 服务器挂在普通 URL 下,比如 https://tools.example.com/api,这招就会失灵——而这种部署并不少见;反过来,它也可能把某个与 MCP 无关、只是主机名或路径里恰好带 "mcp" 字样的服务误判成 MCP(这种情况虽然不多,但我们确实遇到过)。
对于符合 Streamable HTTP 规范的客户端来说,协议头是更精确的信号。
MCP 2025-11-25 规范要求客户端在初始化完成后发出的每个 HTTP 请求都必须带上 MCP-Protocol-Version 头;2026-07-28 规范更进一步,要求每个 POST 请求都必须携带该头。即便如此,光靠这个头还无法做到完整识别:旧版客户端的初始请求可能不带它,2025-06-18 之前的协议版本根本没有定义它,本地 stdio(标准输入输出)、自定义传输或不合规的流量也可能永远不会带上它。所以,请求头存在是 MCP 的有力信号,但请求头缺失并不能证明这个请求不是 MCP。
协议在网络上越来越容易识别
旧版 MCP 流程以一次 initialize 请求开始,这个请求不包含 MCP-Protocol-Version HTTP 头,因此网络管控设备单凭请求头,可能无法对发往未知端点的第一个请求做出判断。信号要等客户端和服务器完成初始化之后才会后续的工具调用看起来像这样。不过,MCP 2026-07-28 规范大大改变了这一模式。核心协议变成了无状态,完全移除了 initialize 握手,把协议版本和操作直接放在每个请求上。Mcp-Method 和 Mcp-Name 请求头让普通 HTTP 基础设施无需解析请求体就能识别操作。负载均衡器可以路由请求,限流器可以区分 tools/list 和 tools/call,安全产品也能从每个请求中获得更多信息。这些协议信号让 Cloudflare Gateway 有了具体可评估的对象,而不必依赖一份“看起来像 MCP”的 URL 清单。
影子 MCP 与已批准路径绕过是两个不同的问题
一旦 Gateway 能识别 MCP 流量,你就可以评估某个连接对安全态势意味着什么。影子 MCP 是指连接到组织未批准的服务器。员工可能在仓库、产品指南或同事的消息中找到这个服务器,然后直接将其添加到自己的 MCP 客户端。安全团队不知道它暴露了哪些工具,也不知道员工向它发送了什么数据。
Portal bypass 则与此不同:它始于组织已批准、放入 MCP Portal 的一个服务器,但员工直接连接到它的上游 URL,绕过了 Portal 的 Access 策略、精选工具目录、数据丢失防护以及工具级审计跟踪。对于受管网络路径上的影子 MCP,Gateway 是主要控制点:它能识别经过 TLS 检查的 MCP 流量,显示目的地和用户,并应用策略。要应对门户绕过,仅靠网络控制还不够,还需要一个能够拒绝直接请求的源端——这可以是 Access 策略、源 IP 限制,或由 MCP 服务器本身发起的企业授权机制。
在 Gateway 中检测 MCP 流量
对于已经采用带 TLS 检查的 Cloudflare Gateway 的客户,我们新增了一种检测启发式机制,它会对每个被检查的请求回答一个简单问题:这是 MCP 流量吗?对于基于会话的 Streamable HTTP 连接,MCP 客户端会在初始化后发送一个 MCP-Protocol-Version 头。Gateway 会在每个经过 TLS 检查的请求中检查该请求头,并据此对流量进行分类;这套检测基于我们每天在 Cloudflare 网络处理的数百万请求中观察到的模式构建。这种分类无需事先知道具体主机或 URL,就能识别 MCP 协商以及到某个主机名的代理行为。
从今天起,所有 Cloudflare Zero Trust 客户都可以在 Gateway HTTP 日志中看到 MCP 流量的迹象,并通过新的 Gateway 选择器 experimental.is_mcp == true 来显式阻止或允许这类流量。该选择器是一个布尔值。如果 Gateway 在某个 TLS 检查请求上检测到 MCP-Protocol-Version 请求头,该值即为 true。管理员可以将其用于允许或阻止策略,而无需自行维护一份看起来像 MCP 的域名列表。对于直接加密的流量,必须先经过 TLS 解密,Gateway 才能检查这些请求头;此外,本地 stdio 服务器、网络外的连接、Do Not Inspect 流量以及从未经过 Gateway 的请求,都不在本视图的范畴内。
全面掌握网络中的 MCP 流量
今天,我们推出了一款专门的 MCP 流量仪表盘,用来展示你网络中有哪些主机在提供 MCP 流量、哪些用户在产生这些流量,以及这些请求是经由 Cloudflare MCP Portal 转发,还是完全绕过了 Portal。仪表盘提供以下信息:
- 可配置时间窗口内的 MCP 请求总数、独立用户数和独立服务器数
- MCP 服务器随时间的变化,以及每台服务器的请求量
- 按接入方式划分的流量构成,区分来自 MCP Portal 的流量和来自设备的直连客户端连接
- 在 Portal 之外观察到的最热门 MCP 服务器——也就是最需要留意的“影子 MCP”流量
- 按 MCP 请求量排序的用户排名
管理员可以按服务器、用户或接入方式进行筛选,也可以直接跳转到按相关主机或用户过滤后的 Gateway HTTP 日志中,做进一步深入排查。
把发现的服务器接入 MCP Portal
MCP 发现功能会把未知流量整理成一份清单,供管理员审查。当组织批准了其中某台服务器后,就可以把它放到 Cloudflare MCP 服务器 Portal 后面。这个 Portal 为员工提供一个统一管理的端点,并在上游服务器前面加上 Access 身份认证、精选工具目录和日志记录。
管理员可以通过 Portal 或针对单台服务器,将兼容的上游调用路由到 Gateway,以执行 HTTP 策略、可预测出口和数据防泄漏(DLP)。工具调用活动也可以通过 Logpush 导出。之后,发现仪表盘还能区分经由 Portal 发出的请求和直接连到同一台服务器的连接。
这样一来,就形成了一条从发现到治理的路径:先找到服务器,再决定是否批准;批准后的使用流量纳入 Portal,同时继续调查那些绕过 Portal 的流量。最后一步尤其重要,因为未经批准的服务器和绕过已批准服务器是两种性质不同的问题。
强制仅允许通过 Portal 访问
我们正在给 Gateway 的网络策略和 HTTP 策略增加“流量来源”(Traffic Source)选择器,让管理员可以根据流量是否来自你的 MCP Portal 来编写精细规则,从而更有效地控制 MCP 流量。
Cloudflare 如何识别 MCP 流量并保障安全
当 MCP Portal 的流量经过 Gateway 时,会携带 mcp_portal 流量来源标记,这样一来,策略就能区分「经由 Portal 代理的请求」和「员工直连的请求」。一条最基本的执行规则是:所有被检测为 MCP 流量、但不是通过 Portal 进入的请求,一律拦截;从 Portal 进来的流量则不受影响。如果组织想先观察再执行,现在可以在解密后的 HTTP 日志中看到流量来源和 MCP 检测结果,也就是说,不需要配置任何策略,就能先监控代理流量的行为。
更多 MCP 服务器可以走受管路径了
一条被批准的路径,只有当它能覆盖员工实际需要的大多数服务器时才有意义。早期的 MCP 规范推荐使用「动态客户端注册」(Dynamic Client Registration),也就是客户端自行向授权服务器注册,而不需要创建 OAuth 应用。但许多常见的 OAuth 提供商采用不同模式:它们要求管理员提前注册一个应用,并配置固定的 client ID、client secret、回调 URL 和权限范围。此外,MCP 2026-07-28 规范最近也废弃了动态注册。
为了缓解这个问题,MCP Portal 现在支持预注册的 OAuth 客户端。管理员可以手动配置 OAuth 凭据:把控制台显示的回调 URL 注册到上游提供商,再填入客户端凭据。Portal 会在可用时自动发现标准的 OAuth 元数据;如果无法自动发现,管理员也可以手动提供授权、令牌、撤销和签发者等端点。每个用户仍然需要单独授权自己的上游数据源,而保存的 client secret 只用于获取最新的工具和提示词列表。
手动 OAuth 支持现在已经能覆盖各种不同的 OAuth 实现方式。有些提供商要求自定义请求头、个人访问令牌或显式的客户端白名单,这些属于另外的兼容性问题。未来几个月,我们还会继续扩展 MCP Portal 的 OAuth 支持。
把私有 MCP 服务器也纳入同一个 Portal
公共 SaaS 工具只是企业 MCP 目录的一部分。
企业依赖的绝大部分安全信息并不在公共互联网上,而是存放在公有云、私有云或本地部署的环境中,只有通过私有网络连接才能访问。目前,MCP Portal 必须能够通过公共互联网解析并访问上游服务器。也就是说,那些只通过私有 DNS 解析、或只存在于私有 IP 网段内的服务器,Portal 现在无法触达。
我们正在着手让 MCP Portal 能够通过 Cloudflare Gateway 路由,借助 Cloudflare One 网络(这套网络已经在为其他私有应用提供服务)连接私有服务器。私有服务器保留自己的私有主机名,Portal 通过 Cloudflare 的私有路由访问它,并将其工具与公共上游服务器的工具并列展示;同时,Access 策略、Portal 日志和工具管控依然在同一个入口生效。Portal 流量经过 Gateway 时,还会被打上 mcp_portal 流量来源标记,这样 Gateway 策略就能区分来自 Portal 的请求和员工直连的请求。MCP 服务器的私有连接能力目前正在积极开发中,敬请留意 Changelog 获取后续信息。