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.
1 Your API spec
findpetsbystatusGET/pet/findByStatusFinds Pets by status
status*: stringgetpetbyidGET/pet/{petId}Find pet by ID
petId*: integerdeletepetDELETE/pet/{petId}Deletes a pet
petId*: integer
2 Generated server
npm install @modelcontextprotocol/sdk zodimport { 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
@modelcontextprotocol/sdk) code using native fetch and Zod input schemas, or Python code using the official FastMCP framework and httpx.process.env.API_TOKEN or os.environ.get("API_TOKEN")), ensuring API keys are never hardcoded in client configurations.