Rate Limiting and Abuse Prevention for Public MCP Endpoints
Protect MCP servers from the abuse patterns that autonomous agents create, not the ones people do.

MCP servers went stateless in July 2026. That single spec change dropped sticky sessions, session stores, and stream management from the operator's job, and in exchange it turned every MCP interaction into a plain HTTP POST. So every abuse vector that's ever hit a REST API now applies cleanly to MCP, plus a batch of new ones that only show up when the client on the other end is an autonomous agent instead of a person typing on a keyboard. This piece covers both layers, the old threats and the new ones, and the controls that actually stop them.
How AI agent traffic differs from the human-driven requests that existing rate limiters were built for
Rate limiters were built for people. A human clicking through a web app fires off requests at a pace bounded by attention span and finger speed, maybe a few per second at most, with natural pauses baked into the interaction. Agents don't pause, and a single conversation can trigger dozens of tool calls back to back with zero think time. When one of those calls errors out, the agent often retries immediately and keeps retrying. Without a circuit breaker, that retry turns into a loop that feeds itself.
Request count stops meaning much too. A tool call with a short argument and a tool call with a multi-thousand-token payload look the same to a limiter that just counts POSTs, but one of them costs a hundred times more in compute and downstream API spend. In shared environments this compounds fast: one agent stuck in a retry loop eats connections and memory that every other agent on the box was counting on.
Bot-detection heuristics fall apart the same way. Bot traffic is normally unauthenticated and follows a pattern, easy to fingerprint and block, while agent traffic is authenticated, purposeful, and high-volume all at once. The signal security teams have leaned on for a decade just doesn't apply anymore. A February 2026 scaling incident on a public MCP server with no rate limiting showed this exact failure: agents firing sequential requests with no pause between them, saturating the server in a pattern no human would ever produce.
Cost is where this stops being an abstract concern. Unthrottled agent traffic hitting paid downstream services, email sends, database queries, scraping jobs, racks up bills faster than any human traffic spike ever could. A reported five-figure Azure incident resulted from a single agent loop nobody caught in time, and SaaS vendors noticed first: Notion, Salesforce, and HubSpot all tightened their own rate limits specifically because agent traffic forced their hand. If the vendors downstream of you are already adapting, waiting to do the same on your own MCP server isn't a plan, it's a bet you'll get lucky.
The threat categories that make MCP endpoints genuinely different from standard REST APIs
Start with the obvious gap: authentication in the MCP spec is optional, not required. Researchers have found production MCP servers with direct database access sitting behind zero authentication, and analysis of public MCP servers found 22% carry path traversal flaws. That's the kind of bug that lets a caller reach files outside the intended directory, the sort of thing REST APIs mostly stamped out a decade ago.
Then there's secrets sprawl. A 2026 report counted over 24,000 unique secrets exposed in public MCP configuration files, more than 2,100 of them still live and usable credentials. Most of that traces back to quickstart docs showing hardcoded API keys as the fast path to a working demo. Demos have a habit of becoming production without anyone updating the credentials.
Two threats are unique to how MCP actually works. Tool poisoning happens because tool outputs feed straight back into the model as trusted context; if a tool returns hidden instructions buried in its response, the agent can execute them as if the user had asked. Prompt injection via tool responses is the same attack wearing a different coat, a fetched webpage or a returned database row carrying instructions instead of data. Both exploit the same blind spot: the assumption that whatever a tool sends back is safe.
Supply chain risk pushes the threat surface past the endpoint and into the toolchain itself. In September 2025, an unofficial Postmark MCP server with a large weekly install base got quietly modified to BCC every outbound email to an attacker's address. Nobody breached anything. They just poisoned the tool everyone had already installed.
SSRF is the fastest route to full infrastructure compromise in remote deployments: a crafted tool argument can make the server fire outbound requests at internal infrastructure it was never meant to touch. CVE-2025-49596, found in MCP-Inspector, accepted unverified input and allowed remote code execution via crafted messages before it got patched in version 0.14.1. Good reminder that basic input hygiene doesn't stop mattering just because the client is an LLM now.
The NSA's May 2026 Cybersecurity Information Sheet on MCP says it plainly: organizations need to go past what the protocol suggests and build deliberate controls it doesn't require. The Coalition for Secure AI lists Resource Management as one of twelve core MCP threats needing active mitigation, which puts rate limiting inside a real security taxonomy instead of a nice-to-have.
Rate limiting strategies that actually work for MCP's request model
Every MCP operation, tools/list, tools/call, resources/read, arrives as one HTTP POST to the same endpoint. The enforcement layer has to look inside the body of the request, not just count how many POSTs hit /mcp, or it's blind to what's actually happening on the wire.
Tracking by IP address doesn't hold up here either, since agent traffic often routes through shared infrastructure that makes IP a noisy, unreliable signal. API key, agent identifier, or session ID are the dimensions that actually tell one caller apart from another.
Per-tool limits matter because tools aren't equally expensive. A tool that scrapes the web or sends email costs orders of magnitude more than one that reads a cached value, so a flat per-endpoint limit either wastes headroom on cheap operations or leaves the expensive ones wide open. Enterprise gateway products support policy rules that inspect the body of the MCP request and set different ceilings by tool name, but that only works if the enforcement layer can parse JSON-RPC. A rate limiter that only reads HTTP headers never sees any of this.
Token-based quotas beat request-count limits for the same reason: prompt length varies wildly, and counting tokens instead of requests actually reflects the load hitting the server. At enterprise scale, hierarchical policies help too, a global baseline with team- and user-level overrides underneath it, so one team's runaway agent can't eat the capacity meant to be shared across everyone else.
Window strategy is a small detail with a real consequence. Sliding windows beat fixed windows, because fixed windows can be gamed at the boundary, and agent retry loops will find that boundary and exploit it without even trying.
On calibration: start generous, somewhere around the 95th percentile of observed usage, then tighten as monitoring data comes in. Launching with limits set too tight just makes legitimate agents fail silently, and that's worse than no limits at all, because nobody notices until a user complains.
When a limit does trigger, return a 429 with a Retry-After header, and make sure the error reaches the LLM in language it can act on: wait, try a different tool, tell the user what happened. Cascading retries within a single turn are the number one cause of production MCP outages, and a clear error message prevents that failure mode entirely. Exponential backoff belongs in the client code, and every rate-limit event should get logged with agent ID, tool name, and timestamp, because that log is the only way to tune the policy later instead of guessing at it.
Identity, authentication, and the OAuth layer that rate limiting depends on
Rate limiting without identity is just IP-based rate limiting with a nicer name, and IP-based limiting is trivial to route around. Meaningful enforcement needs a verified caller attached to every request, no exceptions.
OAuth 2.0 and OIDC are the standard answer. The March 2025 spec update let MCP servers delegate authentication to outside identity providers, Microsoft Entra ID, Auth0, Keycloak, so the infrastructure to do this properly already exists, even if adoption across the ecosystem still lags. Short-lived access tokens are the other half of the fix: they replace static API keys, and a leaked short-lived token has a bounded blast radius instead of an open-ended one. Mutual TLS is worth adding for machine-to-machine agent traffic, since there's no human in the loop to notice a suspicious credential prompt the way there would be in a browser session.
Building an OAuth provider correctly inside a Worker-style deployment from scratch is genuinely hard. Libraries like the workers-oauth-provider TypeScript package handle the authorization layer and hand the MCP server an already-authenticated user context as a parameter, which takes token management out of application code entirely.
Authentication answers who is calling, while authorization has to answer what they're allowed to call. Role-based access control at the tool level is how that gets enforced: not just whether access exists, but which tools and which argument ranges a given caller can touch. In multi-agent chains, each agent should carry its own identity token rather than inherit trust because an upstream agent already authenticated. Trusting the chain that way is a lateral-movement risk waiting to happen. And identity on every request is what makes an audit trail possible at all; without it, a post-incident review can't tell you which agent or which user made which call.
WAF, bot management, and DDoS controls that sit in front of the identity layer
MCP endpoints are HTTP endpoints, so they're exposed to the same volumetric and Layer 7 attacks aimed at any public API. Layer 7 DDoS attacks against APIs grew substantially year-over-year through 2025 and 2026, and API-related security incidents hit a large majority of organizations over 2025. A big share of those incidents involved unauthorized workflows and abnormal activity rather than classic exploit patterns like SQL injection, which means signature-based WAF rules alone won't catch them.
Bot management runs into the same wall the rate limiter does. Legitimate agent traffic and malicious bot traffic look alike: both are automated, both run at volume, neither carries a browser fingerprint. Telling the two apart has to rely on authenticated identity, behavioral baselines, and anomaly detection instead of the classic bot signals. Challenge-response mechanisms like CAPTCHA are the wrong tool here entirely, since they'll block the legitimate agent traffic right alongside the malicious kind.
SSRF mitigation belongs at the network layer, not just in application code: strict egress allowlists, VPC isolation, zero-trust network controls, so a crafted tool argument physically can't reach internal infrastructure even if it slips past every other check. WAF rules written specifically for MCP should validate JSON-RPC structure, enforce the expected schema for tool_name and argument fields, and reject oversized payloads before they ever reach the model or a downstream API. DDoS protection needs to run always-on and globally distributed, because a defense concentrated in one region leaves a latency gap attackers will find from anywhere else. DDoS mitigation running across 330-plus globally distributed data centers is the kind of geographic spread that closes that gap. And TLS in transit is assumed at this point, not optional; certificate pinning for known agent clients is a practical add-on wherever the client list is controlled.
How the gateway architecture maps to MCP's two distinct traffic surfaces

There are two separate traffic surfaces here, and conflating them is the single most common architecture mistake teams make. One is the agent-to-tool surface: requests from the LLM or its orchestrator to the MCP server, carrying tool descriptions, arguments, and responses. An AI gateway that proxies calls to an LLM API sits on a completely different path, and it never sees tool arguments or tool responses, because it simply isn't on that leg of the trip.
That gap has real consequences. Tool poisoning, credential leaks buried in tool arguments, and per-tool rate limiting can't be handled by an AI gateway alone, no matter how well it's configured, because the gateway physically can't see the traffic in question. It needs a dedicated enforcement layer sitting on the MCP path itself.
The AI gateway still has a job, just on a different surface: rate limiting by model or provider, cost-based budgets tracking cumulative spend, caching, retries, model fallback, content moderation on prompts and responses, PII scanning. All of that lives on the LLM API surface.
The MCP-specific layer has to cover different ground: per-tool rate limits with JSON-RPC body inspection, token-based quotas on tool arguments, schema validation on tool responses before they reach the model, egress allowlisting against SSRF, authentication checked on every single request. A reasonable reference architecture stacks these in order: WAF and DDoS at the perimeter, then identity and authentication, then MCP-specific rate limiting and schema enforcement, then the AI gateway on the LLM API path, then downstream APIs enforcing their own limits on top of everything else. Dedicated MCP gateway tools, Solo's agentgateway among them, or custom Workers-based enforcement layers, are how teams actually build the MCP-specific piece. The one requirement that can't be skipped: the layer has to inspect JSON-RPC payloads directly, not just HTTP headers, because headers alone will never tell you which tool got called or what argument it carried.
Monitoring, anomaly detection, and the operational feedback loop that keeps limits calibrated
Limits set on launch day go stale fast. Agent workflows shift as they mature, tool call patterns change, and a ceiling that looked generous at deployment can turn too tight or too loose within a few months, often without anyone noticing until something breaks.
Every rate-limit event needs a minimum set of fields logged: agent or user ID, tool name, argument size (not the full content, just the size), timestamp, and whether the request succeeded or got blocked. That log is the only real input for retuning the policy later, and guessing doesn't scale past a handful of tools.
A few anomaly signals are specific to MCP and worth watching on purpose. A sudden spike in calls to one tool from a single agent identity often means a retry loop, or worse, an injection attack driving repeated calls it shouldn't be making. Argument sizes that sit far outside the normal distribution can signal a prompt injection attempt or a payload probing for a parsing bug, and tool combinations that have never shown up in the baseline before can mean a prompt injection has steered the agent somewhere it was never supposed to go.
None of these signals replace the rate limit itself. They tell you whether the limit set six months ago still makes sense today. Treat the limits as something that changes as often as the traffic does, not a checkbox from deployment day, because the pattern on the other end of that endpoint is going to keep shifting whether the policy keeps up or not.


