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")
      );
    }
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Tool has no description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness1/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Tool has no description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Tool has no description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Tool has no description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose1/5

Does the description clearly state what the tool does and how it differs from similar tools?

Tool has no description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Tool has no description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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