mcpField
O
OpenAPI to MCP Server Converter

OpenAPI to MCP Server Converter

Local
github.com/zxypro1Developer Tools4Updated 16w ago

About OpenAPI to MCP Server Converter

A Node.js and TypeScript utility that converts OpenAPI specifications into MCP servers. It is intended for developers who want APIs exposed as MCP tools, with request-parameter mapping and several server transport examples.

Key features

  1. 01Parses OpenAPI 3.0 specifications
  2. 02Maps tool-call parameters to requests
  3. 03TypeScript type validation
  4. 04Examples for stdio, SSE, and Streamable HTTP

Use cases

  1. 01Expose an OpenAPI-described API to MCP clients
  2. 02Create an MCP server from an API specification

MCP support

Converts OpenAPI specifications into MCP server instances. The README demonstrates stdio, SSE, and Streamable HTTP transports for connecting MCP clients.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

OpenAPI to MCP Server Converter

Node.js Version TypeScript Version License: MIT

A tool for automatically converting OpenAPI specifications into Model Context Protocol (MCP) server instance

Features

  • 🚀 Automated Conversion: Auto-parses OpenAPI 3.0 specifications
  • 🛠 Type Safety: TypeScript-based strong type validation
  • 🔄 Request Proxy: Automatically handles tool call parameter mapping

Quick Start

Prerequisites
  • Node.js 18+
  • TypeScript 5.x
Basic Usage

Install the package:

npm install openapi-mcp-converter

Create a server instance:

import fs from 'fs';
import { OpenApiMCPSeverConverter } from '../index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import path from 'path';
import { fileURLToPath } from 'url';

const openApiDoc = JSON.parse(fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), 'openapi.json'), 'utf8'));

const converter = new OpenApiMCPSeverConverter(openApiDoc, { timeout: 100000, security: { apiKey: 'my-api-key' } });
const server = converter.getServer();

Run a local stdio MCP server:

async function runServer() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.log("GitHub MCP Server running on stdio");
}

runServer().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});

Run a local SSE Server:

const app = express();
let transport = null;

app.get("/sse", async (req, res) => {
  console.log("SSE connection opened");
  console.log("Request Headers:", req?.headers);
  console.log("Request Query:", req?.query);
  server.onclose = async () => {
    await server.close();
  };
  transport = new SSEServerTransport("/messages", res);
  await server.connect(transport);
  return;
});

app.post("/messages", async (req, res) => {
  const sessionId = req.query.sessionId as string;
  if (!sessionId) {
      throw new Error("sessionId query parameter is required");
  }
  await transport.handlePostMessage(req, res);
  return;
});

app.listen(8080, () => {
  console.log('MCP Server running on port 8080');
});

Run a local Streamable HTTP Server:

const app = express();
app.use(express.json());

const transports: { [sessionId: string]: StreamableHTTPServerTransport } = {};

app.post('/mcp', async (req, res) => {
  const sessionId = req.headers['mcp-session-id'] as string | undefined;
  let transport: StreamableHTTPServerTransport;

  if (sessionId && transports[sessionId]) {
    transport = transports[sessionId];
  } else if (!sessionId && isInitializeRequest(req.body)) {
    transport = new StreamableHTTPServerTransport({
      sessionIdGenerator: () => randomUUID(),
      onsessioninitialized: (sessionId) => {
        transports[sessionId] = transport;
      }
    });
    transport.onclose = () => {
      if (transport.sessionId) {
        delete transports[transport.sessionId];
      }
    };
    await server.connect(transport);
  } else {
    res.status(400).json({
      jsonrpc: '2.0',
      error: {
        code: -32000,
        message: 'Bad Request: No valid session ID provided',
      },
      id: null,
    });
    return;
  }

  await transport.handleRequest(req, res, req.body);
});

const handleSessionRequest = async (req: express.Request, res: express.Response) => {
  const sessionId = req.headers['mcp-session-id'] as string | undefined;
  if (!sessionId || !transports[sessionId]) {
    res.status(400).send('Invalid or missing session ID');
    return;
  }
  
  const transport = transports[sessionId];
  await transport.handleRequest(req, res);
};

app.get('/mcp', handleSessionRequest);

app.delete('/mcp', handleSessionRequest);

app.listen(3000);
Run Examples
npm run test  # Execute sample test cases

The example folder also includes xquik-openapi.json, a compact OpenAPI 3.1 sample that covers header API key auth, bearer auth, path parameters, query parameters, and cursor pagination.

Development Guide

Project Structure
/openapi-to-mcp
├── dist/            # Compiled output
├── src/             # Source code
│   ├── example/     # Example configurations
│   └── index.ts     # Core implementation
├── package.json
└── tsconfig.json
Build Commands
npm run build    # Production build
npm run watch    # Development mode watch

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.