How to Create MCP Servers from OpenAPI Specifications: A Complete Guide

The MCP Server Builder tool in the alirezarezvani/claude-skills repository automatically converts OpenAPI contracts into production-ready Model Context Protocol (MCP) servers, generating a canonical tool_manifest.json and runnable scaffold code in Python or TypeScript.

The alirezarezvani/claude-skills repository provides a comprehensive skillset for bridging REST APIs and AI assistants. By using the MCP Server Builder, you can create MCP servers from OpenAPI specifications through a streamlined CLI pipeline that handles parsing, code generation, and validation. This article explores the architecture, workflow, and implementation details of this conversion process.

Architecture of the MCP Server Builder

The conversion pipeline consists of three tightly integrated components that transform an OpenAPI document into a functional MCP server.

CLI Driver (openapi_to_mcp.py)

The entry point engineering/mcp-server-builder/scripts/openapi_to_mcp.py orchestrates the entire conversion through four sequential operations:

  • load_raw_input reads the OpenAPI specification from a local file or standard input (lines 51–64)
  • parse_openapi attempts JSON parsing first, then falls back to PyYAML for YAML support (lines 67–81)
  • extract_tools iterates over the OpenAPI paths object, filters valid HTTP methods, and constructs MCP-compatible tool definitions using sanitize_tool_name to generate deterministic identifiers (lines 103–165)
  • write_outputs persists the tool_manifest.json and language-specific server scaffold based on the --language flag (lines 26–48)

Scaffold Generators

Two template generators produce immediately executable server code:

  • python_scaffold creates a FastMCP instance with stub functions for each tool. Each generated function echoes received input, providing a clear insertion point for business logic (lines 69–92)
  • typescript_scaffold generates equivalent TypeScript code using the FastMCP class, registering each tool via server.tool() with async handler stubs (lines 97–120)

Manifest Validator (mcp_validator.py)

The engineering/mcp-server-builder/scripts/mcp_validator.py utility enforces structural integrity:

  • load_manifest ingests the generated JSON from file or stdin (lines 46–62)
  • validate_manifest checks for unique snake_case names matching TOOL_NAME_RE, non-trivial descriptions, and valid inputSchema structures, delegating property validation to validate_schema (lines 24–45 and 69–102)
  • The --strict flag forces non-zero exit codes when validation errors occur (lines 66–78)

End-to-End Workflow

Execute the complete pipeline in three steps:


# 1. Generate the MCP scaffold from an OpenAPI contract

python3 engineering/mcp-server-builder/scripts/openapi_to_mcp.py \
  --input openapi.json \
  --server-name my-mcp \
  --language python \
  --output-dir ./generated \
  --format text

# 2. Inspect the generated manifest

cat ./generated/tool_manifest.json | jq .

# 3. Validate structural compliance

python3 engineering/mcp-server-builder/scripts/mcp_validator.py \
  --input ./generated/tool_manifest.json \
  --strict \
  --format text

This produces three artifacts in ./generated:

  • tool_manifest.json — the canonical tool description required by MCP clients
  • server.py (or server.ts) — a runnable scaffold launchable with python server.py
  • A textual summary of the conversion results

Generated Code Examples

The Python scaffold utilizes the fastmcp library to expose tools:

#!/usr/bin/env python3
"""Generated MCP server scaffold."""

from fastmcp import FastMCP

mcp = FastMCP(name='my-mcp')

@mcp.tool()
def get_user(input: dict) -> dict:
    """Retrieve a user by ID."""
    return {"tool": "get_user", "status": "todo", "input": input}


if __name__ == '__main__':
    mcp.run()

The TypeScript equivalent uses the same FastMCP class with async tool registration:

// Generated MCP server scaffold
import { FastMCP } from 'fastmcp';

const server = new FastMCP({ name: 'my-mcp' });

server.tool(
  'create_order',
  'Create a new order',
  async (input) => ({
    content: [{ type: 'text', text: JSON.stringify({ tool: 'create_order', status: 'todo', input }) }],
  })
);

server.run();

Key Source Files

Summary

  • The MCP Server Builder converts OpenAPI specifications into fully functional MCP servers through a deterministic CLI pipeline
  • openapi_to_mcp.py handles parsing, tool extraction, and multi-language scaffold generation using extract_tools and sanitize_tool_name
  • Generated artifacts include a canonical tool_manifest.json and runnable server code in either Python (FastMCP) or TypeScript
  • mcp_validator.py enforces naming conventions (snake_case via TOOL_NAME_RE), schema validity, and description quality before deployment
  • The --strict validation mode ensures CI/CD pipelines fail on manifest defects

Frequently Asked Questions

What input formats does the MCP Server Builder support?

The tool accepts both JSON and YAML OpenAPI specifications. The parse_openapi function in openapi_to_mcp.py attempts JSON parsing first, then automatically falls back to PyYAML if JSON parsing fails, allowing seamless processing of either format from file or stdin.

How are tool names generated from OpenAPI operations?

The extract_tools function uses sanitize_tool_name to convert OpenAPI path and operation combinations into deterministic, snake_case identifiers. The validator enforces these names against the TOOL_NAME_RE pattern (3–64 characters, lowercase alphanumeric and underscores), ensuring compatibility with MCP client expectations.

Can I customize the generated server logic?

Yes. Both python_scaffold and typescript_scaffold generate stub functions that simply echo input parameters. Developers replace the return statements with actual API integration logic—such as HTTP client calls to the original REST endpoints—while preserving the MCP tool interface and inputSchema contract.

What does the validator check in strict mode?

In strict mode (--strict), mcp_validator.py exits with a non-zero status if any structural errors exist. It validates that all tools have unique names matching the snake_case regex, descriptions exceeding minimum length thresholds, and valid JSON Schema structures in their inputSchema fields, preventing deployment of malformed MCP servers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →