Skip to main content
Glama
monuit
by monuit
tokenRateLimit.ts2.33 kB
import { Request, Response, NextFunction } from 'express'; import { auditLog, AuditEventType, getClientIP } from '../utils/audit.js'; /** * Per-token rate limiting * Tracks requests per AUTH_TOKEN to prevent abuse */ interface TokenRateLimit { count: number; resetAt: number; } // In-memory store for token rate limits // In production, use Redis or similar distributed store const tokenRateLimits = new Map<string, TokenRateLimit>(); // Configuration const WINDOW_MS = 15 * 60 * 1000; // 15 minutes const MAX_REQUESTS_PER_TOKEN = 500; // 500 requests per 15 minutes per token /** * Middleware to enforce per-token rate limiting */ export function tokenRateLimiter(req: Request, res: Response, next: NextFunction): void { const authHeader = req.headers.authorization; if (!authHeader) { // No auth header, skip token rate limiting (will be caught by auth middleware) next(); return; } const token = authHeader.split(' ')[1]; if (!token) { next(); return; } const now = Date.now(); const tokenLimit = tokenRateLimits.get(token); if (!tokenLimit || now > tokenLimit.resetAt) { // Create new rate limit window tokenRateLimits.set(token, { count: 1, resetAt: now + WINDOW_MS, }); next(); return; } if (tokenLimit.count >= MAX_REQUESTS_PER_TOKEN) { // Rate limit exceeded auditLog(AuditEventType.RATE_LIMIT_EXCEEDED, false, { ipAddress: getClientIP(req), userAgent: req.headers['user-agent'], metadata: { endpoint: req.path, method: req.method, }, }); res.status(429).json({ jsonrpc: '2.0', id: null, error: { code: -32001, message: 'Rate limit exceeded', data: { details: `Too many requests for this token. Limit: ${MAX_REQUESTS_PER_TOKEN} requests per ${WINDOW_MS / 60000} minutes.`, retryAfter: Math.ceil((tokenLimit.resetAt - now) / 1000), }, }, }); return; } // Increment count tokenLimit.count++; next(); } /** * Cleanup expired rate limit entries periodically */ setInterval(() => { const now = Date.now(); for (const [token, limit] of tokenRateLimits.entries()) { if (now > limit.resetAt) { tokenRateLimits.delete(token); } } }, 60000); // Cleanup every minute

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/monuit/oura-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server