Skip to main content
Glama

call_endpoint

Execute API calls to the Swagger Petstore by specifying operation IDs and parameters, enabling interaction with endpoints discovered through list_endpoints.

Instructions

Call an endpoint in the Swagger Petstore - OpenAPI 3.0. Use list_endpoints first to discover available operationIds and their required parameters.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationIdYesThe operationId from list_endpoints, e.g. 'getPetById' or 'createUser'
parametersNoPath, query, and header parameters as key-value pairs
bodyNoRequest body for POST/PUT/PATCH requests (object or string)

Implementation Reference

  • The handler function for the `call_endpoint` tool. It validates the operationId, executes the request via `executeCall`, and formats the response.
    async ({ operationId, parameters, body }) => {
      const endpoint = findEndpoint(spec, operationId);
    
      if (!endpoint) {
        const available = getAllEndpoints(spec)
          .map((e) => e.operationId)
          .join(", ");
        return {
          content: [
            {
              type: "text" as const,
              text: `Unknown operationId: "${operationId}".\n\nAvailable operations: ${available}`,
            },
          ],
          isError: true,
        };
      }
    
      try {
        const result = await executeCall(spec, endpoint, parameters ?? {}, body);
        return {
          content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
        };
      } catch (err) {
        const message = err instanceof Error ? err.message : String(err);
        return {
          content: [{ type: "text" as const, text: `Error calling ${operationId}: ${message}` }],
          isError: true,
        };
      }
    }
  • src/index.ts:65-113 (registration)
    Tool registration for `call_endpoint` including input schema validation using Zod.
    server.tool(
      "call_endpoint",
      `Call an endpoint in the ${apiTitle}. ` +
        "Use list_endpoints first to discover available operationIds and their required parameters.",
      {
        operationId: z
          .string()
          .describe("The operationId from list_endpoints, e.g. 'getPetById' or 'createUser'"),
        parameters: z
          .record(z.union([z.string(), z.number(), z.boolean()]))
          .optional()
          .describe("Path, query, and header parameters as key-value pairs"),
        body: z
          .unknown()
          .optional()
          .describe("Request body for POST/PUT/PATCH requests (object or string)"),
      },
      async ({ operationId, parameters, body }) => {
        const endpoint = findEndpoint(spec, operationId);
    
        if (!endpoint) {
          const available = getAllEndpoints(spec)
            .map((e) => e.operationId)
            .join(", ");
          return {
            content: [
              {
                type: "text" as const,
                text: `Unknown operationId: "${operationId}".\n\nAvailable operations: ${available}`,
              },
            ],
            isError: true,
          };
        }
    
        try {
          const result = await executeCall(spec, endpoint, parameters ?? {}, body);
          return {
            content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
          };
        } catch (err) {
          const message = err instanceof Error ? err.message : String(err);
          return {
            content: [{ type: "text" as const, text: `Error calling ${operationId}: ${message}` }],
            isError: true,
          };
        }
      }
    );
  • The actual logic that prepares and executes the HTTP request for the API endpoint.
    export async function executeCall(
      spec: OpenAPIV3.Document,
      endpoint: EndpointInfo,
      parameters: Record<string, string | number | boolean>,
      body: unknown
    ): Promise<ApiResponse> {
      const baseUrl = getBaseUrl(spec);
      let urlPath = endpoint.path;
      const queryParams: Record<string, string> = {};
      const headers: Record<string, string> = {
        Accept: "application/json",
        ...buildAuthHeaders(),
      };
    
      const params = (endpoint.operation.parameters ?? []) as OpenAPIV3.ParameterObject[];
    
      for (const param of params) {
        const value = parameters[param.name];
        if (value === undefined || value === null) {
          if (param.required) {
            throw new Error(`Missing required parameter: ${param.name} (${param.in})`);
          }
          continue;
        }
    
        const strValue = String(value);
    
        switch (param.in) {
          case "path":
            urlPath = urlPath.replace(`{${param.name}}`, encodeURIComponent(strValue));
            break;
          case "query":
            queryParams[param.name] = strValue;
            break;
          case "header":
            headers[param.name] = strValue;
            break;
          // cookie params are uncommon — skip for now
        }
      }
    
      let fullUrl = baseUrl + urlPath;
      if (Object.keys(queryParams).length > 0) {
        fullUrl += "?" + new URLSearchParams(queryParams).toString();
      }
    
      const fetchOptions: RequestInit = {
        method: endpoint.method.toUpperCase(),
        headers,
      };
    
      const methodHasBody = ["post", "put", "patch"].includes(endpoint.method.toLowerCase());
      if (methodHasBody && body !== undefined && body !== null) {
        if (typeof body === "string") {
          fetchOptions.body = body;
          headers["Content-Type"] = "text/plain";
        } else {
          fetchOptions.body = JSON.stringify(body);
          headers["Content-Type"] = "application/json";
        }
      }
    
      const response = await fetch(fullUrl, fetchOptions);
      const responseText = await response.text();
    
      let responseBody: unknown;
      const contentType = response.headers.get("content-type") ?? "";
      if (contentType.includes("application/json") || contentType.includes("+json")) {
        try {
          responseBody = JSON.parse(responseText);
        } catch {
          responseBody = responseText;
        }
      } else {
        responseBody = responseText;
      }
    
      const responseHeaders: Record<string, string> = {};
      response.headers.forEach((value, key) => {
        responseHeaders[key] = value;
      });
    
      return {
        status: response.status,
        statusText: response.statusText,
        headers: responseHeaders,
        body: responseBody,
      };
    }
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/saurav61091/mcp-openapi'

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