Skip to main content
Glama
amrsa1

Swagger MCP Server

execute_api_request

Execute API requests to specific endpoints using HTTP methods, paths, parameters, headers, and body data for testing and exploration.

Instructions

Execute an API request to a specific endpoint

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
methodYesHTTP method (GET, POST, PUT, DELETE, etc.)
pathYesThe endpoint path (e.g., '/users/123')
paramsNoQuery parameters as key-value pairs
bodyNoRequest body as a JSON object (for POST/PUT/PATCH)
headersNoCustom headers as key-value pairs

Implementation Reference

  • The core handler function that performs the actual API request using fetch. It builds the URL, sets headers including auth, handles request body, logs details, manages token refresh on 401, and processes the response.
    async function executeApiRequest(method, path, params = {}, body = null, headers = {}) {
      try {
        const url = buildUrl(path, params);
        const requestOptions = {
          method: method.toUpperCase(),
          headers: {
            'Accept': 'application/json',
            ...headers
          }
        };
        
        if (['POST', 'PUT', 'PATCH'].includes(method.toUpperCase()) && body) {
          requestOptions.headers['Content-Type'] = 'application/json';
          requestOptions.body = JSON.stringify(body);
        }
        
        const isAuthEndpoint = isAuthenticationEndpoint(path);
        
        if (isAuthEndpoint) {
          log.info(`Auth endpoint detected: ${path}. Not adding Authorization header.`);
          
          if (!body && ['POST', 'PUT'].includes(method.toUpperCase()) && API_USERNAME && API_PASSWORD) {
            const isSignUp = isSignUpEndpoint(path);
            
            if (!isSignUp) {
              requestOptions.headers['Content-Type'] = 'application/json';
              requestOptions.body = JSON.stringify({
                username: API_USERNAME,
                password: API_PASSWORD
              });
              log.info(`Auto-injecting default credentials for authentication endpoint`);
            } else {
              log.warning(`Sign-up/register endpoint detected: ${path}. Skipping auto-injection of default credentials. Use unique credentials for registration.`);
            }
          }
        } else {
          if (!headers.Authorization) {
            if (authTokens.apiAccess) {
              requestOptions.headers['Authorization'] = `Bearer ${authTokens.apiAccess}`;
              log.info(`Using stored API token for authorization`);
            } 
            else if (API_KEY) {
              requestOptions.headers['Authorization'] = `Bearer ${API_KEY}`;
              log.info(`Using configured API key for authorization`);
            }
          }
        }
        
        log.api(method.toUpperCase(), url);
        
        log.debug(`Request headers: ${JSON.stringify(maskSensitiveHeaders(requestOptions.headers))}`);
        if (requestOptions.body) {
          const logBody = JSON.parse(requestOptions.body);
          const sensitiveFields = ['password', 'secret', 'token', 'key', 'apiKey', 'api_key'];
          for (const field of sensitiveFields) {
            if (field in logBody) {
              logBody[field] = '********';
            }
          }
          log.debug(`Request body: ${JSON.stringify(logBody, null, 2)}`);
        }
        
        const response = await fetch(url, requestOptions);
        
        if (response.status === 401 && !isAuthEndpoint) {
          log.warning(`Received 401 Unauthorized. Attempting to refresh token...`);
          
          if (swaggerDoc) {
            const authEndpoint = findAuthEndpoint();
            
            if (authEndpoint) {
              log.info(`Found auth endpoint: ${authEndpoint.method} ${authEndpoint.path}`);
              
              const authResponse = await executeApiRequest(
                authEndpoint.method,
                authEndpoint.path,
                {},
                { username: API_USERNAME, password: API_PASSWORD },
                {}
              );
              
              if (authResponse.status >= 200 && authResponse.status < 300) {
                log.success(`Successfully refreshed token`);
                
                if (authTokens.apiAccess) {
                  requestOptions.headers['Authorization'] = `Bearer ${authTokens.apiAccess}`;
                  log.info(`Retrying request with new token`);
                  
                  const retryResponse = await fetch(url, requestOptions);
                  return await processApiResponse(retryResponse, path, url, method);
                }
              }
            } else {
              log.warning(`Could not find suitable auth endpoint to refresh token`);
            }
          }
        }
        
        return await processApiResponse(response, path, url, method);
      } catch (error) {
        log.error(`Error executing API request: ${error.message}`);
        throw new Error(`API request failed: ${error.message}`);
      }
    }
  • The tool definition including name, description, and input schema for validating parameters to the execute_api_request tool.
    {
      name: "execute_api_request",
      description: "Execute an API request to a specific endpoint",
      inputSchema: {
        type: "object",
        properties: {
          method: { 
            type: "string", 
            description: "HTTP method (GET, POST, PUT, DELETE, etc.)" 
          },
          path: { 
            type: "string", 
            description: "The endpoint path (e.g., '/users/123')" 
          },
          params: { 
            type: "object", 
            description: "Query parameters as key-value pairs"
          },
          body: { 
            type: "object", 
            description: "Request body as a JSON object (for POST/PUT/PATCH)"
          },
          headers: { 
            type: "object", 
            description: "Custom headers as key-value pairs"
          }
        },
        required: ["method", "path"],
      },
    },
  • The registration handler within the CallToolRequestSchema switch statement that extracts arguments and calls the executeApiRequest function.
    case "execute_api_request": {
      const method = request.params.arguments?.method;
      const path = request.params.arguments?.path;
      const params = request.params.arguments?.params || {};
      const body = request.params.arguments?.body || null;
      const headers = request.params.arguments?.headers || {};
      
      if (!method || !path) {
        throw new Error("Method and path are required");
      }
    
      try {
        const result = await executeApiRequest(method, path, params, body, headers);
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify(result)
          }],
          isError: false,
        };
      } catch (error) {
        throw new Error(`Failed to execute API request: ${error.message}`);
      }
    }
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions executing an API request but doesn't disclose critical traits like authentication requirements, rate limits, error handling, or whether it's read-only or destructive. For a tool that likely interacts with external systems, this lack of information is a significant gap.

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

Conciseness5/5

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

The description is a single, efficient sentence: 'Execute an API request to a specific endpoint'. It is front-loaded and wastes no words, making it easy to parse quickly. Every part of the sentence contributes to the core purpose without redundancy.

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

Completeness2/5

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

Given the tool's complexity (5 parameters, no output schema, no annotations), the description is incomplete. It doesn't explain return values, error cases, or behavioral nuances, leaving the agent with insufficient context for effective use. For a general-purpose API tool, more detail is needed to ensure correct invocation.

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

Parameters3/5

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

The input schema has 100% description coverage, with clear documentation for all 5 parameters (e.g., method, path, params). The description adds no additional meaning beyond what the schema provides, such as examples or constraints. Since the schema does the heavy lifting, the baseline score of 3 is appropriate, but the description doesn't compensate or enhance parameter understanding.

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

Purpose3/5

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

The description states the tool's purpose as 'Execute an API request to a specific endpoint', which is clear but vague. It specifies the verb ('execute') and resource ('API request'), but doesn't distinguish it from sibling tools like 'fetch_swagger_info' or 'get_endpoint_details', which might also involve API interactions. The purpose is understandable but lacks specificity about what makes this tool unique.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'fetch_swagger_info' for documentation or 'validate_api_response' for validation, nor does it specify prerequisites or contexts for usage. This leaves the agent without clear direction on tool selection.

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

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/amrsa1/swagger-mcp'

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