Skip to main content

MCP server: which rate limit stops a runaway bill?

Rafael Torres
Rafael TorresOctober 27, 202611 min. read
MCP server: which rate limit stops a runaway bill?

The limit that stops a runaway bill is the per-operation ceiling, counted in the layer that sees the tool call, not the per-MCP-server ceiling. The ceiling is not a protection number. It is an economic decision, and whoever fails to make it at design time ends up making it in the middle of the incident, with the chart still climbing.

At 2:40 a.m., the operations dashboard shows the tool-call curve leaving the scale. Nobody knows whether that is a paying customer discovering a new use case or an agent in a loop. The chart only shows the symptom. The answer lies in who the server thinks is calling.

The Model Context Protocol specification, in the 2026-07-28 revision, requires the server to validate every tool input, implement access control, rate limit tool invocations and sanitize outputs. The normative text has four words: "Rate limit tool invocations". Unit, number, window and response are not there. The rest is engineering for whoever operates the server.

Prerequisites: what exists before the first MCP rate limit

Before choosing a number, four things have to exist: per-call identity, a counter that survives the request, a log with one line per operation and a named owner for the ceiling. Without all four, the MCP rate limit becomes a number nobody disputes after the incident.

  • Per-call identity: a counter with no subject counts the server total. The subject is the credential with a validated audience, and clientInfo is a declared label, not identity.
  • A counter that survives the request and is shared across replicas: the protocol went sessionless, and nothing guarantees that the next call lands in the same process.
  • A log with one line per operation, with tool, caller, result and duration.

The fourth item is the cheapest and the one most often missing: a named owner for the ceiling. With no owner, the number goes up on the first complaint and nobody records why.

An operation, here, is one admitted tools/call, a POST. An input_required makes the client repeat with a new id, and the limiter charges both: the ceiling counts requests, not logical invocations.

The six steps:

  1. Choose the unit of the ceiling.
  2. Size the rpm ceiling by the worst case.
  3. Calculate the cost per accepted operation.
  4. Decide where the ceiling runs.
  5. Treat the quota refusal as a business error.
  6. Define the abuse exception before the incident.

Step 1: choose the unit of the per-operation rate limit

The unit decides what the ceiling protects. Per server, it protects the infrastructure and lets a single agent spend unchecked. Per agent, it protects the bill and leaves the server exposed. Per operation, it protects the invoice per call. The choice is which risk to limit first.

The three spend ceiling levels of key and spend per agent limit model consumption; the table below limits tool traffic. They are two different bills.

Ceiling unitWhat it countsWhat it lets through
Per MCP serverevery invocation that arrivesan agent that consumes the quota of the others by itself
Per toolcalls to its tools/callwhat the agent spends on other tools
Per calling agentoperations from one credentialwhat several agents add up to on the server
Per operationeach tools/call admitted in the windowthe sum a thousand small operations make on the bill
Four ceiling units and what each one lets through: per MCP server, per tool, per calling agent and per operation

Each unit misleads in its own way: the per-MCP-server ceiling holds the infrastructure when one agent is the largest consumer, the per-tool one breaks down when the agent switches tools, the per-agent one breaks down when two teams share the credential, and the per-operation one breaks down when the bill that matters is the one for the result.

Step 2: size the rpm ceiling by the worst case, not by the average

The rpm ceiling comes from concurrency and tool latency, not from the monthly average. With N calls in flight and latency L in seconds, the MCP server receives about N times 60 divided by L operations per minute. That number is closed-loop saturation throughput, not an observed peak.

Calls in flight: N. Tool latency: L, in seconds. Operations per minute: N × 60 ÷ L.

Worked example, with no price and no measurement: 40 calls in flight with 1.5 seconds of latency give 1,600 operations per minute, and 25% of slack takes the rpm ceiling to 2,000.

The slack is not generosity, it is the price of not stopping the legitimate operation: a ceiling that is too high documents the blowout, and one that is too low refuses good calls.

The ceiling sits above the legitimate peak and below what the budget sustains, and the published number is the lower of the two. Spend allowed per window divided by the cost of one accepted operation, which the next step defines, gives how many accepted operations the invoice pays for; dividing by the acceptance rate reaches the admitted rpm. The rpm ceiling protects availability, and the budget ceiling protects the invoice: it is the one that refuses the loop when the invoice does not pay the legitimate rate.

The window is a choice: a fixed 60-second window admits up to twice the ceiling at the boundary, so use a sliding window or a token bucket.

The ceiling counts somebody's operations, and caller identity in agent traffic decides who that somebody is.

Step 3: calculate the MCP cost per operation that returned a result

The cost per operation is total spend divided by the operations that returned a usable result. It includes the attempts that failed, the repetitions the model asked for and the tool call that charged without delivering. An attempted operation is not a paid operation.

Total spend has two sides. The tool side is execution and the call itself. The context side is what the operation does to the next model call: definition and result are input billed per token, and the size of the result is the lever. Lists with ttlMs and cacheScope, plus deterministic order, cut the refresh cost.

Acceptance rate is the multiplier nobody sees.

The calculation has two numbers: attempted and accepted operations. An agent that attempts 1,000 operations and delivers 250 carries the cost of the other 750: three failed operations per accepted operation, and one accepted operation costs four operation units.

These are different bills: the operating cost of an AI gateway measures the overhead of the layer in latency, memory and cost per request, and the cost per accepted operation measures the call that returned a result.

The per-operation rate limit has one trap: it counts calls the ceiling admitted, and an admitted call is not a call that returned a result.

Step 4: decide where the ceiling runs, in the MCP server or in the LLM router

The ceiling only holds where identity arrives. RFC 6585, section 4, leaves the identification criterion open: if the server identifies by credential and the gateway presents its own, the counter counts the whole gateway, and the per-agent quota stops existing there.

The 2026-07-28 revision made the protocol sessionless, with a credential per request, and the tool traffic control layer is the only point that sees, in the same request, the operation and who asked for it; the server validates that the token was issued to it and does not pass it on, as caller identity already described.

The layer identifies the operation from the headers: Mcp-Method on every request and Mcp-Name on tools/call, mirroring the tool name. It counts per tool without reading the body.

The credential swap is not a configuration failure: the datum that sustained the per-agent quota does not cross the boundary. The per-agent quota dies there. Whoever operates the layer that sees the operation takes on the per-caller ceiling.

The per-MCP-server ceiling stays where it always was: it is the ceiling that exists with no intermediary in the path, and that is why it stays.

The Nexforce Router is an LLM gateway with routing across more than 300 models, budget per key, per agent and per project, and a trace of every call, which makes model spend per call auditable.

The routing layer measures and governs the model side and the key spend, and no tool decides the ceiling in place of the operation owner.

Step 5: treat the ceiling error as a business error, not as a tool error

The specification defines execution error by where it is reported, in the tool result with isError: true, and recommends that the client return those errors to the model to allow self-correction. The quota refusal, the ceiling error of this piece, is not a tool result. Returning it as a tool error teaches the agent to try again.

There are three layers. A protocol error is a JSON-RPC error object, which the client may omit from the model. An execution error goes in the result with isError: true. Quota refusal is the third: on the transport it arrives as 429, the code from RFC 6585, section 4, with detail and an optional Retry-After.

The separation holds for a limiter refusal, before dispatch. When the tool wraps a third-party API and its 429 comes back as isError: true, the implementer translates the signal into a business error.

RFC 9110, section 10.2.3, defines Retry-After as an HTTP date or a whole number of seconds, the only standardized wait the caller obeys.

Repackaging the refusal as isError is the expensive shortcut: the model reads a correctable failure, tries again, and the repetition consumes the quota the ceiling was protecting. The caller needs the business error, with the ceiling named and the wait stated.

And the wait needs jitter: a Retry-After in whole seconds synchronizes callers and returns the burst at the window boundary. A retry budget and a per-caller ceiling on calls in flight complete the refusal response. An in-flight call is one that has not returned yet, and without limited concurrency a loop occupies every connection.

From the agent loop to the ceiling: model, routing gateway with the identity boundary, and MCP server

Blind repetition after a refusal is the same reading error as treating failover as load balancing, as failover is not a load balancer shows.

Step 6: define the abuse exception before the incident

Agent loop, legitimate batch and abusive client produce the same symptom and demand different responses. The exception is a design item: separate key, its own ceiling, declared validity and a named owner, decided while the system is calm, never during the incident, and the difference only shows up in the record the section asks for.

Identical symptom: volume off the curve on the same MCP server, refusals climbing, and a bad time to find out the difference. The loop is a bug. The legitimate batch asks for a scheduled window and its own ceiling, and the abusive one asks for a contractual limit, not a silent adjustment in the dashboard.

What has to be on record:

  • The separate key and its own ceiling for each exception.
  • The declared validity, with a review date.
  • The named owner who approves the renewal.

An exception nobody reviews is a second ceiling, with the name of the first.

How to verify that the ceiling works

Verification has four readings: the gateway counter closes with the MCP server counter, the refusal rate per ceiling stays in the expected band, p95 latency does not get worse after the limit, and the MCP cost per operation stops rising with volume.

The LLM call trace is the source of all four: each reading compares two counts that only exist if the call was recorded whole.

The first is reconciliation, which only closes when both sides filter the same way: same method, same window and same caller map, with no tools/list and no repetitions.

The second is the refusal band. A refusal rate near zero with volume growing means a loose ceiling; a high refusal rate at a legitimate peak means a low ceiling, and the symptom arrives as a complaint before it arrives on the dashboard.

The third is p95 latency: if it gets worse after the limit, the ceiling queue is wrong. The fourth is the cost per accepted operation, which does not rise with volume.

Common mistakes and how to fix them

A single ceiling for every tool is the first. Search and write do not have the same latency or the same cost, and the single ceiling is too much for one and too little for the other. The fix is a ceiling per tool, with the server one as an umbrella.

A ceiling sized by the average is the second: it never holds the worst case, which is what blows the bill. The fix is the Step 2 calculation, with the slack declared.

An in-memory counter that resets on deploy is the third. Every deploy hands back a full quota. With independent POSTs the hole is bigger, because N replicas with a local counter give N times the published ceiling, and the counter has to be atomic and shared, not just persistent.

A refusal with no detail and no declared wait is the fourth. The caller does not know whether to wait a second or an hour, so it tries again, and the retry is what the ceiling was supposed to prevent. The fix is the Retry-After from RFC 9110, with the ceiling named.

Frequently asked questions

What does the specification require from an MCP server on rate limiting? It requires the server to rate limit tool invocations, with input validation, access control and output sanitization, in the 2026-07-28 revision. The normative text is "Rate limit tool invocations", and it fixes neither unit, number, window nor response: those four stay with whoever operates the server.

Which ceiling unit should be used when the agent is shared? Two at the same time. The rpm ceiling per agent protects the bill when the credential belongs to a single agent; the per-server ceiling protects the infrastructure when several agents add up volume. With a shared credential, attribution disappears and the per-agent ceiling starts applying to the whole group.

What changes when the gateway stops forwarding the caller's key? The server counter starts counting the gateway, not the agent. RFC 6585, section 4, leaves identification open, and the specification forbids forwarding the client token onward. The ceiling runs where the operation is visible, and whoever sees the operation takes on the per-caller ceiling.

How should the agent react to a quota refusal? As a business error, not as a tool error. The refusal arrives on the transport, with the ceiling named and the wait stated, and the agent waits with jitter instead of repeating. Repackaged as an execution error, it becomes an order to retry that consumes the quota the ceiling was protecting.

When is the per-server ceiling still the right choice? When the risk is the infrastructure going down, and not the bill going up. It is the ceiling that exists with no LLM router at all in the path: a client that talks straight to the server goes through it, and on that route the per-caller ceiling only exists if the server counts the credential it already validates.

References and Further Reading

When to review the ceiling

The ceiling is a premise, not a constant. Four changes force Step 2 and Step 3 to be redone instead of the number being raised: a new tool or a tool whose latency changed, a change in agent concurrency, a new caller on the same MCP server, and a change in how the credential arrives at the server. Redoing the calculation costs an afternoon. Discovering the stale premise costs the quarter. The ceiling is one piece of the gateway layer, and what an LLM gateway is shows where it fits.

Nexforce

Save up to 50% in creditswith a single smart API

Connect your operations to our AI Router and optimize the consumption of multiple LLMs

Free Trial

Related articles