Documentation Index
Fetch the complete documentation index at: https://redop.useagents.site/docs/llms.txt
Use this file to discover all available pages before exploring further.
Use Unkey Ratelimit when you want a hosted global rate-limit service without provisioning Redis yourself.
This guide adapts @unkey/ratelimit to a Redop server.
Install
Add the Unkey package to your Redop app:
Prerequisites
You need:
- an Unkey account
- a root key with ratelimit permissions
UNKEY_ROOT_KEY in your environment
Create the limiter
Create the limiter once at module scope and use a namespace that clearly matches the part of your app you are protecting.
import { Ratelimit } from "@unkey/ratelimit";
const ratelimit = new Ratelimit({
rootKey: process.env.UNKEY_ROOT_KEY!,
namespace: "redop-api",
limit: 10,
duration: "60s",
});
Add it as Redop middleware
import { McpError, McpErrorCode, Redop } from "@redopjs/redop";
new Redop({
serverInfo: {
name: "unkey-demo",
version: "0.1.0",
},
})
.middleware(async ({ request, next }) => {
const identifier =
request.headers["x-user-id"] ??
request.headers["x-forwarded-for"] ??
request.ip ??
"anonymous";
const { limit, remaining, reset, success } =
await ratelimit.limit(identifier);
if (!success) {
throw new McpError(
McpErrorCode.InvalidRequest,
`Rate limit exceeded. Limit ${limit}, remaining ${remaining}, reset at ${new Date(
reset
).toISOString()}.`
);
}
return next();
})
.tool("ping", {
handler: () => ({ ok: true }),
});
Add timeout and fallback behavior
Unkey’s docs note that the SDK rejects by default if it does not get a response within 5 seconds. Configure timeout and onError if you want fail-open or custom handling.
const fallback = () => ({
success: true,
limit: 0,
remaining: 0,
reset: 0,
});
const ratelimit = new Ratelimit({
rootKey: process.env.UNKEY_ROOT_KEY!,
namespace: "redop-api",
limit: 10,
duration: "60s",
timeout: {
ms: 3000,
fallback,
},
onError: (_error, _identifier) => fallback(),
});
Use different namespaces for different surfaces
Create separate limiters when different routes or tool families need different policies.
const authLimiter = new Ratelimit({
rootKey: process.env.UNKEY_ROOT_KEY!,
namespace: "auth-tools",
limit: 5,
duration: "60s",
});
const apiLimiter = new Ratelimit({
rootKey: process.env.UNKEY_ROOT_KEY!,
namespace: "api-tools",
limit: 100,
duration: "60s",
});
Use the stricter limiter for login, token minting, or verification flows, and the broader limiter for normal API traffic.
When to choose Unkey
Unkey is a strong fit when you want global hosted rate limiting with simple namespaces and per-identifier checks, especially if you already use Unkey for API auth or key management.
See also