Skip to main content
Guard provides rate limiting, concurrency control, execution timeout, and IP filtering for your MCP server. It protects against abuse, ensures fair resource allocation, and prevents runaway requests.
Guard is powered by the @frontmcp/guard library and integrates directly into tool and agent flows. All guard checks run automatically before execution, with cleanup handled in finalize stages.

Why Guard?


Quick Start

Add rate limiting and a timeout to any tool with decorator options:

How Guard Integrates with Flows

Guard checks are implemented as flow stages that run automatically in the tool and agent execution pipelines:
  1. acquireQuota — Checks global and per-entity rate limits. Throws RateLimitError if exceeded.
  2. acquireSemaphore — Acquires a concurrency slot. Throws ConcurrencyLimitError if no slot available.
  3. execute — Wrapped with withTimeout if a timeout is configured. Throws ExecutionTimeoutError if exceeded.
  4. releaseSemaphore — Releases the concurrency slot back to the pool.
  5. releaseQuota — Cleans up rate limit state.

Rate Limiting

FrontMCP uses a sliding window algorithm for rate limiting. It provides smooth, accurate throttling with O(1) storage per key.

Per-Tool Rate Limiting

Global Rate Limiting

Set a server-wide rate limit in your app configuration:
The global rate limit is checked before per-entity limits. Both must pass for a request to proceed.

Partition Strategies

Partition keys determine how rate limits are bucketed: Custom partition key example:

Concurrency Control

Concurrency control uses a distributed semaphore to limit how many instances of a tool or agent can execute simultaneously.

Per-Tool Concurrency

Mutex Pattern

Set maxConcurrent: 1 to ensure only one execution at a time:

Queue Behavior

When queueTimeoutMs is set, requests that cannot acquire a slot immediately will wait in a queue:
  • queueTimeoutMs: 0 (default) — Immediately reject if no slot available. Throws ConcurrencyLimitError.
  • queueTimeoutMs: 5000 — Wait up to 5 seconds for a slot. Throws QueueTimeoutError if the wait expires.
The semaphore uses pub/sub notifications when available (Redis) for efficient slot release detection, falling back to polling with exponential backoff.

Execution Timeout

Timeout wraps the execute stage with a deadline. If execution exceeds the configured duration, it throws ExecutionTimeoutError.

Per-Tool Timeout

Default Timeout

Set a default timeout for all tools and agents at the app level:
Per-entity timeout takes precedence over the app default.

IP Filtering

IP filtering allows or blocks requests based on client IP address, supporting IPv4, IPv6, and CIDR ranges.

Filter Precedence

  1. Deny list is checked first. If matched, the request is blocked with IpBlockedError (403).
  2. Allow list is checked next. If matched, the request proceeds.
  3. Default action applies if neither list matches:
    • 'allow' (default) — Request proceeds.
    • 'deny' — Request is blocked with IpNotAllowedError (403).

Supported IP Formats

Proxy Configuration

When your server is behind a reverse proxy (Nginx, CloudFront, etc.), enable trustProxy to read the client IP from the X-Forwarded-For header:

App-Level Configuration

The throttle field in @FrontMcp configures all guard features at the app level:

Configuration Precedence


Storage Backends

Guard supports multiple storage backends for distributed deployments.

Memory (Development)

The default backend. Suitable for single-instance development. No configuration needed.
In-memory storage does not persist across restarts and does not work with multiple server instances. Use Redis for production.

Redis (Production)

For distributed rate limiting across multiple server instances:
Redis enables pub/sub-based semaphore notifications for more efficient concurrency slot release detection.

Vercel KV / Upstash

For serverless environments:

Error Handling

Guard throws specific error classes when limits are exceeded: These errors are automatically serialized to appropriate MCP error responses by the transport layer.

Agent Guard

Agents support the same guard options as tools:
The agent flow follows the same stage ordering: acquireQuotaacquireSemaphoreexecute (with timeout) → releaseSemaphorereleaseQuota.

Configuration Reference

RateLimitConfig

ConcurrencyConfig

TimeoutConfig

IpFilterConfig

GuardConfig (App-Level)