I run an agent stack that talks to a fair number of external services through an MCP-style gateway — email, calendars, deploy pipelines, a Proxmox host, a Cloudflare account with DNS and tunnel edit access. Every one of those is a tool call an agent can make autonomously, at machine speed, without a human clicking “approve” first. That’s the whole value proposition. It’s also exactly the blind spot most network security tooling wasn’t built for, because traditional access control assumes a human is the one deciding when and how often to hit an endpoint. Cloudflare just shipped protocol-level MCP detection into Gateway, and reading through how it works is a useful forcing function for anyone running their own agent infrastructure to actually think about what’s calling out on their network.
Why this is a genuinely different threat model
The core issue: AI agents change both the thresholds that make an action worth reviewing. A human clicking through a UI to delete 500 records would notice something was wrong halfway through. An agent executing the same tool call 500 times in a loop, because a retry condition never resolved or because it was given a slightly wrong instruction, does not notice anything — it just keeps calling. Rate limiting designed around human behavior doesn’t catch this, because the request pattern looks perfectly reasonable per-request; it’s the volume and autonomy that’s the anomaly, not any single call.
How MCP traffic actually gets identified
The detection approach is protocol-level fingerprinting, not app-layer guessing. Every MCP client, post-handshake, is required to send an MCP-Protocol-Version header on every HTTP request:
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather
Content-Type: application/json
That header presence alone is treated as a strong positive signal — it’s built from patterns observed across a large volume of real traffic, not a hardcoded signature. For MCP servers running older spec versions without that header, there’s a fallback: hostname patterns containing “mcp”, URL paths like /mcp or /sse, and JSON-RPC method names such as initialize, tools/call, resources/read in the request body. The newer 2026-07-28 spec is fully stateless — no persistent handshake session — so every single request carries enough metadata to be independently classified, which is actually a nice property from a security-tooling perspective: nothing to lose track of mid-session.
What you can actually do with that signal
Once traffic is classified, a Gateway policy becomes a one-liner:
experimental.is_mcp == true and not traffic.onramp in ("mcp_portal")
Read that as: any MCP traffic that didn’t come through my managed portal gets blocked. That’s the actual pattern worth adopting even outside Cloudflare specifically — the point isn’t the product, it’s the shape of the policy. Direct, unmediated MCP connections from an agent to an arbitrary upstream server are the risky case; connections routed through a managed proxy layer that enforces identity, logs every call, and curates which tools are even reachable are the safe case. The proxy — a “portal,” in Cloudflare’s naming, but the concept generalizes to any gateway sitting between your agent and the outside world — gets you three things a raw connection doesn’t: an identity check before the call goes out, a durable log of what was actually called, and a curated allowlist instead of an agent being able to reach whatever MCP endpoint it’s told to.
The checklist I actually run now
Before wiring a new MCP server into my own stack, this is the sequence:
- Does it go through the gateway, or direct? If an agent can reach it without going through the proxy layer, that’s the first thing to fix — not a config nice-to-have.
- What’s actually logged? Not just “a call happened” — which tool, which arguments, which agent session. You cannot investigate an incident from a boolean.
- What’s the blast radius of the credential behind it? A token scoped to “read calendar” and a token scoped to “admin the whole Cloudflare account” should never be treated as equivalent risk just because they’re both “just an MCP server.”
- Would a loop be visible? If an agent called this tool 500 times in ten minutes, would anything alert — or would it just look like 500 unremarkable, individually-valid requests?
The honest limitation worth naming: this kind of detection needs TLS inspection to work, so it doesn’t cover local stdio-based servers, off-network connections, or traffic explicitly marked “do not inspect.” That’s not a flaw in the tooling — it’s a reminder that network-layer detection is one layer of a defense that also needs identity scoping and logging at the application layer, because the network can’t see what it isn’t allowed to decrypt.
The actual takeaway
MCP made it trivial to wire an agent up to a dozen real-world services in an afternoon. The security model for that hasn’t caught up as fast as the convenience has, and the gap is mostly invisible until an agent does something autonomous and wrong at 2am with nobody watching. Treating every MCP connection as “just another API call I already trust” is the mistake; treating it as a new class of traffic that needs its own identity, logging, and allowlist — the same way you’d never let a service account skip your existing IAM review — is the fix, and it doesn’t require waiting for a vendor feature to start doing it.