ScavioScavio
ProductPricingDocs
Sign InGet Started
  1. Home
  2. Tutorials
  3. How to Generate an MCP Server from an OpenAPI Spec
Tutorial

How to Generate an MCP Server from an OpenAPI Spec

Auto-generate an MCP server from any OpenAPI spec. Give AI agents typed tool access to REST APIs in minutes, not days.

Get Free API KeyAPI Docs

Generating an MCP server from an OpenAPI spec converts any documented REST API into a set of typed tools that AI agents can call directly, eliminating manual tool definition. Instead of writing MCP tool handlers by hand for each endpoint, you parse the OpenAPI JSON/YAML, extract operations, parameters, and response schemas, and generate a standards-compliant MCP server that Claude Code, Cursor, or any MCP client can consume. This tutorial builds a generator in Python that takes an OpenAPI 3.x spec and outputs a working MCP server.

Prerequisites

  • Python 3.10+
  • fastmcp library installed (pip install fastmcp)
  • An OpenAPI 3.x spec (JSON or YAML)
  • Scavio API key for testing with a real spec

Walkthrough

Step 1: Parse the OpenAPI spec

Load and parse an OpenAPI 3.x spec file, extracting all operations with their paths, methods, parameters, and request bodies.

Python
import json, yaml
from pathlib import Path

def parse_openapi(spec_path):
    content = Path(spec_path).read_text()
    spec = yaml.safe_load(content) if spec_path.endswith(('.yml', '.yaml')) else json.loads(content)
    operations = []
    for path, methods in spec.get('paths', {}).items():
        for method, details in methods.items():
            if method in ('get', 'post', 'put', 'patch', 'delete'):
                op = {
                    'operation_id': details.get('operationId', f'{method}_{path}'.replace('/', '_')),
                    'summary': details.get('summary', ''),
                    'method': method.upper(),
                    'path': path,
                    'parameters': details.get('parameters', []),
                    'request_body': details.get('requestBody', {}),
                }
                operations.append(op)
    print(f'Parsed {len(operations)} operations from {spec_path}')
    return spec, operations

spec, ops = parse_openapi('openapi.json')

Step 2: Generate MCP tool definitions

Convert each OpenAPI operation into an MCP tool with typed parameters and descriptions.

Python
def openapi_type_to_python(schema):
    type_map = {'string': 'str', 'integer': 'int', 'number': 'float',
                'boolean': 'bool', 'array': 'list', 'object': 'dict'}
    return type_map.get(schema.get('type', 'string'), 'str')

def generate_tool_code(op, base_url):
    params = []
    for p in op['parameters']:
        ptype = openapi_type_to_python(p.get('schema', {}))
        default = f' = None' if not p.get('required') else ''
        params.append(f"{p['name']}: {ptype}{default}")

    body_params = []
    if op['request_body']:
        content = op['request_body'].get('content', {})
        json_schema = content.get('application/json', {}).get('schema', {})
        for prop, schema in json_schema.get('properties', {}).items():
            ptype = openapi_type_to_python(schema)
            required = prop in json_schema.get('required', [])
            default = '' if required else ' = None'
            body_params.append(f"{prop}: {ptype}{default}")

    all_params = ', '.join(params + body_params)
    name = op['operation_id'].replace('-', '_').replace('.', '_')
    return name, all_params, op['summary']

Step 3: Build the MCP server file

Generate a complete MCP server Python file that registers all tools and handles HTTP requests to the underlying API.

Python
def generate_mcp_server(spec, operations, base_url, output_path='generated_mcp.py'):
    lines = [
        'import httpx',
        'from fastmcp import FastMCP',
        '',
        f'mcp = FastMCP("Generated API")',
        f'BASE_URL = "{base_url}"',
        '',
    ]
    for op in operations:
        name, params, summary = generate_tool_code(op, base_url)
        lines.append(f'@mcp.tool(description="{summary}")')
        lines.append(f'async def {name}({params}) -> dict:')
        lines.append(f'    async with httpx.AsyncClient() as client:')
        if op['method'] == 'GET':
            lines.append(f'        resp = await client.get(f"{{BASE_URL}}{op["path"]}")')
        else:
            lines.append(f'        resp = await client.{op["method"].lower()}(f"{{BASE_URL}}{op["path"]}", json=locals())')
        lines.append(f'        return resp.json()')
        lines.append('')

    Path(output_path).write_text('\n'.join(lines))
    print(f'Generated MCP server with {len(operations)} tools at {output_path}')

generate_mcp_server(spec, ops, 'https://api.example.com')

Step 4: Test with the Scavio OpenAPI spec

Fetch the Scavio API spec using search and generate an MCP server from it as a working example.

Python
import requests, os

# Use Scavio search to find OpenAPI specs for testing
H = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}
data = requests.post('https://api.scavio.dev/api/v1/search',
    headers=H, json={'query': 'petstore openapi 3.0 json spec', 'country_code': 'us'}).json()

print('Found specs to test with:')
for r in data.get('organic_results', [])[:3]:
    print(f"  {r.get('title', '')}: {r.get('link', '')}")

# Example: generate from the classic Petstore spec
# spec, ops = parse_openapi('petstore.json')
# generate_mcp_server(spec, ops, 'https://petstore3.swagger.io/api/v3')

Python Example

Python
import json, yaml, httpx, os, requests
from pathlib import Path

def parse_openapi(spec_path):
    content = Path(spec_path).read_text()
    spec = yaml.safe_load(content) if spec_path.endswith(('.yml', '.yaml')) else json.loads(content)
    ops = []
    for path, methods in spec.get('paths', {}).items():
        for method, details in methods.items():
            if method in ('get', 'post', 'put', 'patch', 'delete'):
                ops.append({
                    'id': details.get('operationId', f'{method}_{path}'.replace('/', '_')),
                    'summary': details.get('summary', ''),
                    'method': method.upper(), 'path': path,
                    'parameters': details.get('parameters', []),
                    'body': details.get('requestBody', {}),
                })
    return spec, ops

def generate_server(spec, ops, base_url, out='generated_mcp.py'):
    type_map = {'string': 'str', 'integer': 'int', 'number': 'float', 'boolean': 'bool'}
    lines = ['import httpx', 'from fastmcp import FastMCP', '',
             'mcp = FastMCP("Generated API")', f'BASE = "{base_url}"', '']
    for op in ops:
        name = op['id'].replace('-', '_').replace('.', '_')
        params = []
        for p in op['parameters']:
            pt = type_map.get(p.get('schema', {}).get('type', 'string'), 'str')
            params.append(f"{p['name']}: {pt}")
        sig = ', '.join(params)
        lines.extend([
            f'@mcp.tool(description="{op["summary"]}")',
            f'async def {name}({sig}) -> dict:',
            f'    async with httpx.AsyncClient() as c:',
            f'        r = await c.request("{op["method"]}", f"{{BASE}}{op["path"]}")',
            f'        return r.json()', ''
        ])
    Path(out).write_text('\n'.join(lines))
    print(f'Generated {len(ops)} MCP tools to {out}')

# Example usage
# spec, ops = parse_openapi('openapi.json')
# generate_server(spec, ops, 'https://api.example.com')
print('MCP generator ready. Pass any OpenAPI 3.x spec.')

JavaScript Example

JavaScript
const fs = require('fs');

function parseOpenAPI(specPath) {
  const spec = JSON.parse(fs.readFileSync(specPath, 'utf-8'));
  const ops = [];
  for (const [path, methods] of Object.entries(spec.paths || {})) {
    for (const [method, details] of Object.entries(methods)) {
      if (['get', 'post', 'put', 'patch', 'delete'].includes(method)) {
        ops.push({
          id: details.operationId || \`\${method}_\${path.replace(/\//g, '_')}\`,
          summary: details.summary || '',
          method: method.toUpperCase(), path,
          parameters: details.parameters || [],
        });
      }
    }
  }
  return {spec, ops};
}

function generateServer(spec, ops, baseUrl, out = 'generated_mcp.mjs') {
  let code = \`import {FastMCP} from 'fastmcp';\nconst mcp = new FastMCP('Generated API');\nconst BASE = '\${baseUrl}';\n\n\`;
  for (const op of ops) {
    const name = op.id.replace(/[-. ]/g, '_');
    const params = op.parameters.map(p => \`\${p.name}: {type: 'string'}\`).join(', ');
    code += \`mcp.addTool({name: '\${name}', description: '\${op.summary}',\n  parameters: {\${params}},\n  execute: async (args) => {\n    const r = await fetch(\\\`\\\${BASE}\${op.path}\\\`, {method: '\${op.method}'});\n    return JSON.stringify(await r.json());\n  }\n});\n\n\`;
  }
  fs.writeFileSync(out, code);
  console.log(\`Generated \${ops.length} MCP tools to \${out}\`);
}

// const {spec, ops} = parseOpenAPI('openapi.json');
// generateServer(spec, ops, 'https://api.example.com');
console.log('MCP generator ready');

Expected Output

JSON
Parsed 12 operations from openapi.json
Generated MCP server with 12 tools at generated_mcp.py
Tools: get_users, post_users, get_users_by_id, put_users_by_id, ...

Related Tutorials

  • How to Add MCP Search to Claude Code
  • How to Set Up an MCP Pre-Coding Search Routine
  • How to Build Curated Search for AI Agents

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.10+. fastmcp library installed (pip install fastmcp). An OpenAPI 3.x spec (JSON or YAML). Scavio API key for testing with a real spec. A Scavio API key gives you 50 free credits on signup.

Yes. The free tier includes 50 credits on signup, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Related Resources

Solution

Generate MCP Servers from OpenAPI Specs with Search-Verified Schemas

Read more
Best Of

Best OpenAPI to MCP Generator Tools in 2026

Read more
Glossary

MCP Swagger Auto Server Generation

Read more
Best Of

Best MCP Server Management and Optimization Tools in May 2026

Read more
Glossary

MCP Server OpenAPI Generation

Read more
Use Case

OpenAPI to MCP Server Integration

Read more

Start Building

Auto-generate an MCP server from any OpenAPI spec. Give AI agents typed tool access to REST APIs in minutes, not days.

Get Free API KeyRead the Docs
ScavioScavio

Real-time search API for AI agents. Search every platform, not just Google.

Product

  • Features
  • Pricing
  • Dashboard
  • Affiliates

Developers

  • Documentation
  • API Reference
  • Quickstart
  • MCP Integration
  • Python SDK

Alternatives

  • Tavily Alternative
  • SerpAPI Alternative
  • Firecrawl Alternative
  • Exa Alternative

Tools

  • JSON Formatter
  • cURL to Code
  • Token Counter
  • All Tools

© 2026 Scavio. All rights reserved.

Featured on TAAFT
Terms of ServicePrivacy Policy