@upstash/ratelimit checks them before a tool runs—even when requests reach different server instances.
This recipe allows three generate_report calls per 30-second sliding window. The report is a local calculation, so you can try the integration with just an Upstash account. Use the same middleware around an expensive API call, export, or sandbox operation.
Try the live example
Select generate_report, enter[10, 20, 30] in values, and click Execute. Repeat the call to see a report followed by a rate-limit error. No chat model or API key is needed to use the demo.
Open the example in a new tab.
All visitors share this demo’s quota. You may hit the limit on your first call if someone else has used it. Wait about a minute and try again, or run your own copy below for an isolated demo.
Prerequisites
- A working mcp-use server.
- An Upstash Redis database and its REST URL and read/write REST token. The read-only token cannot update rate-limit counters.
Add the integration
Install the Redis client and rate limiter in your server project:.env. Use these prefixed names even though the Upstash console shows names without MCP_USE_:
.env
.env out of version control. Both values stay on the server.
Add the highlighted middleware to your existing server, or copy this complete example into src/index.ts. It checks only generate_report; other tools and tool discovery continue normally.
src/index.ts
isError: true when the quota is exhausted, so the caller receives an MCP tool error and the report callback does not run. Missing credentials, Redis failures, and quota-check timeouts also block execution. Upstash normally allows requests after its timeout; the explicit reason === "timeout" check makes this example reject them.
Try it
Start or restart your server so it loads.env:
Rate limit reached. Its retry time is approximate because the sliding window also accounts for calls in the previous window. After a full minute without calls, try again. Restarting the server does not clear the Redis counters.
Adapt the quota
- Change
Ratelimit.slidingWindow(3, "30 s")to choose the allowance and window. - Change
prefixto separate deployments that use the same Redis database. - Replace the constant
generate_reportkey with a verified user or tenant ID plus the tool name for customer-specific quotas. Do not trust an ID supplied in tool arguments or an arbitrary header.