OpenAPI to MCP Server Code Generator

Turn any OpenAPI 3.0/3.1 or Swagger API specification into a fully functional Model Context Protocol (MCP) server in TypeScript or Python.

  • Free
  • No sign-in
  • Runs in your browser

1 Your API spec

Samples:
openapi.json
3 operations
Authentication
Parsed tools (3)
  • findpetsbystatusGET/pet/findByStatus

    Finds Pets by status

    status*: string

  • getpetbyidGET/pet/{petId}

    Find pet by ID

    petId*: integer

  • deletepetDELETE/pet/{petId}

    Deletes a pet

    petId*: integer

2 Generated server

Installnpm install @modelcontextprotocol/sdk zod
mcp-server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";

const BASE_URL = process.env.API_BASE_URL || "https://petstore.swagger.io/v2";

const server = new Server(
  { name: "mcp-api-server", version: "1.0.0" },
  { capabilities: { tools: {} } }
);

// --- Expose MCP Tools ---
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "findpetsbystatus",
      description: "Finds Pets by status",
      inputSchema: {
        type: "object",
        properties: {
          "status": { type: "string", description: "Status values that need to be considered for filter" },
        },
        required: ["status"],
      },
    },
    {
      name: "getpetbyid",
      description: "Find pet by ID",
      inputSchema: {
        type: "object",
        properties: {
          "petId": { type: "number", description: "ID of pet to return" },
        },
        required: ["petId"],
      },
    },
    {
      name: "deletepet",
      description: "Deletes a pet",
      inputSchema: {
        type: "object",
        properties: {
          "petId": { type: "number", description: "Pet id to delete" },
        },
        required: ["petId"],
      },
    },
  ],
}));

// --- Tool Execution Handlers ---
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args = {} } = request.params;

  const headers: Record<string, string> = {
    "Content-Type": "application/json",
    "User-Agent": "MCP-OpenAPI-Client/1.0",
  };

  switch (name) {
    case "findpetsbystatus": {
      let targetPath = `/pet/findByStatus`;
      const queryParams = new URLSearchParams();
      if (args.status !== undefined) queryParams.append("status", String(args.status));
      if (queryParams.toString()) targetPath += "?" + queryParams.toString();
      const response = await fetch(`${BASE_URL}${targetPath}`, { method: "GET", headers });
      const responseText = await response.text();
      return {
        content: [
          { type: "text", text: `HTTP Status: ${response.status}\n${responseText}` }
        ],
        isError: !response.ok,
      };
    }
    case "getpetbyid": {
      let targetPath = `/pet/${encodeURIComponent(String(args.petId ?? ""))}`;
      const response = await fetch(`${BASE_URL}${targetPath}`, { method: "GET", headers });
      const responseText = await response.text();
      return {
        content: [
          { type: "text", text: `HTTP Status: ${response.status}\n${responseText}` }
        ],
        isError: !response.ok,
      };
    }
    case "deletepet": {
      let targetPath = `/pet/${encodeURIComponent(String(args.petId ?? ""))}`;
      const response = await fetch(`${BASE_URL}${targetPath}`, { method: "DELETE", headers });
      const responseText = await response.text();
      return {
        content: [
          { type: "text", text: `HTTP Status: ${response.status}\n${responseText}` }
        ],
        isError: !response.ok,
      };
    }
    default:
      throw new Error(`Unknown tool: ${name}`);
  }
});

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP OpenAPI Server listening over stdio...");
}

main().catch((err) => {
  console.error("Server error:", err);
  process.exit(1);
});

How OpenAPI to MCP conversion works

Exposing existing Web APIs to AI assistants like Claude Desktop, Cursor, and Windsurf allows models to fetch real-time data, query databases, and trigger workflows on your behalf. However, manually writing Zod schemas and HTTP execution handlers for dozens of REST endpoints is slow and error-prone.

This generator parses your paths, HTTP methods (GET, POST, PUT, DELETE), path/query parameters, and JSON request bodies, outputting clean boilerplates that adhere to the official Model Context Protocol JSON-RPC specification.

Frequently asked questions

Paste your OpenAPI 3.0 or 3.1 JSON spec into the generator above, enter your target API base URL, select an auth mode (Bearer Token or API Key), and pick either TypeScript or Python. Copy or download the generated file, install the SDK dependencies, and add the command to your client config.

Yes! You can toggle between official TypeScript SDK (@modelcontextprotocol/sdk) code using native fetch and Zod input schemas, or Python code using the official FastMCP framework and httpx.

You can configure Bearer Token authentication or custom API Key headers. The generated server reads credentials securely from environment variables (e.g. process.env.API_TOKEN or os.environ.get("API_TOKEN")), ensuring API keys are never hardcoded in client configurations.

An OpenAPI spec defines HTTP REST endpoints (paths, methods, request bodies, status codes) for human developers or API gateways. An MCP tool schema packages those capabilities into standardized JSON-RPC 2.0 primitives so LLMs can call functions directly without custom integration glue code.