Skip to main content
Glama

rate_limit_check

Test API rate limits by sending controlled request bursts to an endpoint, specifying method, delay, and auth headers. Identify vulnerabilities in backend systems with CyberMCP.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
auth_headerNoAuthentication header (if any)
endpointYesAPI endpoint to test
http_methodNoHTTP method to useGET
request_bodyNoRequest body (for POST/PUT requests)
request_countNoNumber of requests to send
request_delay_msNoDelay between requests in milliseconds

Implementation Reference

  • Executes the rate limiting check by sending multiple HTTP requests with configurable delays, detecting rate limits through status 429, rate-limit headers, and error messages in responses, then analyzes and formats a vulnerability report.
    async ({ endpoint, http_method, request_count, request_delay_ms, auth_header, request_body }) => { try { const results = []; let rateLimitDetected = false; let rateLimitThreshold = 0; let lastStatusCode = 0; // Make a sequence of requests to detect rate limiting for (let i = 0; i < request_count; i++) { // Make the request const response = await axios({ method: http_method.toLowerCase(), url: endpoint, data: request_body ? JSON.parse(request_body) : undefined, headers: auth_header ? { Authorization: auth_header } : undefined, validateStatus: () => true, // Accept any status code }); // Check for rate limiting response const isRateLimited = isRateLimitingResponse(response); const rateLimitHeaders = extractRateLimitHeaders(response.headers); results.push({ request_number: i + 1, status: response.status, rate_limited: isRateLimited, headers: rateLimitHeaders, }); // If we detect rate limiting, note when it happened if (isRateLimited && !rateLimitDetected) { rateLimitDetected = true; rateLimitThreshold = i + 1; } lastStatusCode = response.status; // If we've already been rate limited, we can stop testing if (rateLimitDetected && i >= rateLimitThreshold + 2) { break; } // Add delay between requests if (i < request_count - 1 && request_delay_ms > 0) { await new Promise(resolve => setTimeout(resolve, request_delay_ms)); } } // Analyze results const analysis = analyzeRateLimiting(results, rateLimitDetected, rateLimitThreshold); return { content: [ { type: "text", text: formatRateLimitResults(results, analysis, endpoint), }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error testing rate limiting: ${(error as Error).message}`, }, ], }; } }
  • Zod schema validating input parameters for the tool: endpoint URL, HTTP method, number of requests, delay, optional auth and body.
    { endpoint: z.string().url().describe("API endpoint to test"), http_method: z.enum(["GET", "POST", "PUT", "DELETE"]).default("GET").describe("HTTP method to use"), request_count: z.number().min(5).max(50).default(20).describe("Number of requests to send"), request_delay_ms: z.number().min(0).max(1000).default(100).describe("Delay between requests in milliseconds"), auth_header: z.string().optional().describe("Authentication header (if any)"), request_body: z.string().optional().describe("Request body (for POST/PUT requests)"), },
  • Registers the rate_limit_check tool on the MCP server, including schema and handler function.
    export function registerRateLimitingTools(server: McpServer) { // Rate limiting test server.tool( "rate_limit_check", { endpoint: z.string().url().describe("API endpoint to test"), http_method: z.enum(["GET", "POST", "PUT", "DELETE"]).default("GET").describe("HTTP method to use"), request_count: z.number().min(5).max(50).default(20).describe("Number of requests to send"), request_delay_ms: z.number().min(0).max(1000).default(100).describe("Delay between requests in milliseconds"), auth_header: z.string().optional().describe("Authentication header (if any)"), request_body: z.string().optional().describe("Request body (for POST/PUT requests)"), }, async ({ endpoint, http_method, request_count, request_delay_ms, auth_header, request_body }) => { try { const results = []; let rateLimitDetected = false; let rateLimitThreshold = 0; let lastStatusCode = 0; // Make a sequence of requests to detect rate limiting for (let i = 0; i < request_count; i++) { // Make the request const response = await axios({ method: http_method.toLowerCase(), url: endpoint, data: request_body ? JSON.parse(request_body) : undefined, headers: auth_header ? { Authorization: auth_header } : undefined, validateStatus: () => true, // Accept any status code }); // Check for rate limiting response const isRateLimited = isRateLimitingResponse(response); const rateLimitHeaders = extractRateLimitHeaders(response.headers); results.push({ request_number: i + 1, status: response.status, rate_limited: isRateLimited, headers: rateLimitHeaders, }); // If we detect rate limiting, note when it happened if (isRateLimited && !rateLimitDetected) { rateLimitDetected = true; rateLimitThreshold = i + 1; } lastStatusCode = response.status; // If we've already been rate limited, we can stop testing if (rateLimitDetected && i >= rateLimitThreshold + 2) { break; } // Add delay between requests if (i < request_count - 1 && request_delay_ms > 0) { await new Promise(resolve => setTimeout(resolve, request_delay_ms)); } } // Analyze results const analysis = analyzeRateLimiting(results, rateLimitDetected, rateLimitThreshold); return { content: [ { type: "text", text: formatRateLimitResults(results, analysis, endpoint), }, ], }; } catch (error) { return { content: [ { type: "text", text: `Error testing rate limiting: ${(error as Error).message}`, }, ], }; } } ); }
  • Imports and calls registerRateLimitingTools as part of overall security tools registration.
    import { registerRateLimitingTools } from "./rateLimiting.js"; import { registerSecurityHeadersTools } from "./securityHeaders.js"; /** * Register all security testing tools with the MCP server */ export function registerSecurityTools(server: McpServer) { registerAuthenticationTools(server); registerInjectionTools(server); registerDataLeakageTools(server); registerRateLimitingTools(server);
  • Helper function to detect if an HTTP response indicates rate limiting based on status code, headers, or body content.
    function isRateLimitingResponse(response: any): boolean { // Check status code (429 is the standard for rate limiting) if (response.status === 429) { return true; } // Check for common rate limit headers const headers = response.headers || {}; const headerKeys = Object.keys(headers).map(h => h.toLowerCase()); if ( headerKeys.some(h => h.includes("ratelimit") || h.includes("rate-limit") || h.includes("x-rate")) ) { return true; } // Check response body for rate limit messages const responseBody = typeof response.data === 'string' ? response.data.toLowerCase() : JSON.stringify(response.data || "").toLowerCase(); return ( responseBody.includes("rate limit") || responseBody.includes("ratelimit") || responseBody.includes("too many requests") || responseBody.includes("exceeded") || responseBody.includes("throttle") || responseBody.includes("slow down") ); }

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/ricauts/CyberMCP'

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