# MCP Server Rate Limiting and Throttling Policies: A Complete Guide

> Understand MCP server rate limiting and throttling policies. Discover request limits per second, hourly quotas, and concurrent GraphQL execution caps. Get the complete guide.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: how-to-guide
- Published: 2026-09-13

---

**The MCP server enforces a hard limit of 5 requests per second (burstable to 20), a 1,000 request hourly quota per organization, and a maximum of 3 concurrent GraphQL executions, returning HTTP 429 with `error_type: "RATE_LIMIT_EXCEEDED"` when thresholds are exceeded.**

The `anthropics/claude-plugins-community` repository implements strict rate limiting and throttling policies for MCP server calls to protect backend resources and ensure fair access across Claude-enabled agents. These limits are codified in the TRES Finance plugin source code and govern every interaction with the Model Calling Platform (MCP) gateway.

## Core Rate Limiting Policies

The MCP gateway applies three distinct throttling tiers that developers must observe when building skills.

### Request Throughput Limits

Clients are restricted to **5 requests per second** sustained, with a short-term **burst capacity of up to 20 requests per second**. Exceeding the burst threshold triggers immediate throttling. According to the protocol documentation in [`quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md`](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md), clients should insert a minimum 200ms delay between calls (`sleep(0.2)`) when approaching the sustained limit.

### Hourly Quotas and Organization Limits

Each organization is allocated **1,000 requests per hour**. Once this quota is exhausted, the server rejects subsequent calls with an **HTTP 429** status code. The response body includes a structured error object with `error_type: "RATE_LIMIT_EXCEEDED"` and a `retryAfter` integer field indicating the seconds remaining until the window resets.

### Concurrent Execution Constraints

The server permits **no more than 3 simultaneous GraphQL executions** per user token. Parallel calls beyond this limit result in a 429 error accompanied by the `X-MCP-Concurrent-Calls` response header, which indicates the current number of active calls for that token. Skills must serialize operations or implement client-side semaphores to respect this ceiling.

## Implementation in the Claude Plugins Source Code

The `McpClient` implementation in [[`tres-finance-plugin/skills/tres-report-create/tests/run_report_matrix.py`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/tests/run_report_matrix.py)](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/tests/run_report_matrix.py) demonstrates the required client-side logic for rate limit compliance. The class wraps the raw `execute()` call with tracking for the `MCP-Protocol-Version` header and handles 429 responses.

```python
import time
import random
from mcp_client import McpClient, McpError

def execute_with_retry(client, query, variables=None, max_retries=5):
    """
    Execute MCP query with exponential backoff for rate limits.
    Implements base × 2^n + random(0–0.5s) backoff strategy.
    """
    for attempt in range(max_retries):
        try:
            return client.execute(query, variables)
        except McpError as e:
            if e.error_type == "RATE_LIMIT_EXCEEDED":
                # Calculate backoff: base 1s, doubling each attempt + jitter

                sleep_time = (2 ** attempt) + random.uniform(0, 0.5)
                
                # Respect server's Retry-After if provided

                if hasattr(e, 'retry_after'):
                    sleep_time = max(sleep_time, e.retry_after)
                
                time.sleep(sleep_time)
                continue
            raise
    raise Exception("Rate limit retries exhausted after 5 attempts")

```

The code specifically checks for the `RATE_LIMIT_EXCEEDED` error type and extracts the `retry_after` value from the error metadata, falling back to calculated exponential backoff if the header is absent.

## Error Handling and Retry Strategies

When throttling occurs, the MCP server returns specific metadata that clients must parse correctly to resume operation.

### Detecting 429 Errors and Retry-After Headers

Rate limit responses carry the **HTTP 429** status code and include two critical pieces of information:
- The **`Retry-After`** HTTP header (seconds to wait)
- The JSON error field **`retryAfter`** (integer seconds)

The `McpClient` captures both values, preferring the explicit server directive over client-side calculations when available.

### Implementing Exponential Backoff

The reference implementation uses an exponential backoff formula with jitter to prevent thundering herd scenarios. The delay calculation is:

```python
delay = (2 ** attempt_number) + random.uniform(0, 0.5)

```

This ensures that in a distributed scenario, multiple failing clients do not simultaneously retry after identical intervals. The maximum retry count is capped at **5 attempts** before the error is surfaced to the user with the message: *"Please wait X seconds before trying again."*

### Respecting Concurrency Limits

To avoid the 3-call concurrency ceiling, the test harness in [`run_report_matrix.py`](https://github.com/anthropics/claude-plugins-community/blob/main/run_report_matrix.py) executes calls synchronously by default. When parallel execution is required, developers must inspect the **`X-MCP-Concurrent-Calls`** header returned by previous responses and queue additional calls until the count drops below 3.

## Configuration and Protocol Details

Rate limiting parameters are defined in the plugin configuration and reference documentation.

The [[`tres-finance-plugin/.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/.mcp.json)](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/.mcp.json) file contains the MCP endpoint configuration and comments indicating that the server imposes rate-limit headers. Meanwhile, [[`quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md`](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md)](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md) provides the architectural specification, stating that clients must include the **`MCP-Protocol-Version`** header and must not exceed the 5 req/s sustained throughput limit.

## Summary

- **Throughput**: Maximum 5 requests per second (burst up to 20), enforced at the MCP gateway.
- **Quota**: 1,000 requests per hour per organization; exceeding this returns HTTP 429.
- **Concurrency**: Hard limit of 3 simultaneous GraphQL calls per token; monitor `X-MCP-Concurrent-Calls` header.
- **Error Handling**: Watch for `error_type: "RATE_LIMIT_EXCEEDED"` and the `retryAfter` field (or `Retry-After` header).
- **Retry Logic**: Implement exponential backoff with 0–0.5s jitter, maximum 5 retries, as demonstrated in [`run_report_matrix.py`](https://github.com/anthropics/claude-plugins-community/blob/main/run_report_matrix.py).
- **Protocol**: Always send `MCP-Protocol-Version` header; serialize calls unless explicitly managing the 3-call concurrency window.

## Frequently Asked Questions

### What happens if I exceed the 5 requests per second limit?

The MCP server immediately returns an **HTTP 429** response with a JSON error payload containing `error_type: "RATE_LIMIT_EXCEEDED"` and a `retryAfter` integer specifying the minimum wait time in seconds. The client must halt execution and backoff for the specified duration before retrying.

### How long should I wait after receiving a 429 error?

Respect the **`Retry-After`** header or the **`retryAfter`** field in the error body, which specify the exact seconds to wait. If these directives are missing, implement exponential backoff starting at 1 second, doubling with each attempt (up to 5 retries), and add random jitter between 0 and 0.5 seconds to avoid synchronized retry storms.

### Can I make multiple MCP calls in parallel?

You may execute up to **3 concurrent GraphQL calls** per user token. Attempting more than 3 simultaneous executions triggers a 429 error. The server returns the current concurrency count in the **`X-MCP-Concurrent-Calls`** header, allowing you to implement client-side throttling or semaphores to stay within the limit.

### Where are the rate limits enforced in the codebase?

While the MCP gateway enforces limits at the infrastructure level, the client-side handling is implemented in [[`tres-finance-plugin/skills/tres-report-create/tests/run_report_matrix.py`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/tests/run_report_matrix.py)](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/tests/run_report_matrix.py) through the `McpClient` class. Configuration details reside in [[`tres-finance-plugin/.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/.mcp.json)](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/.mcp.json), and protocol specifications are documented in [[`quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md`](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md)](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/skills/quickdesign/references/connecting-claude-ai-via-mcp.md).