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

> Easily create MCP servers from OpenAPI specifications with the MCP Server Builder tool. Generate production-ready Python or TypeScript code and a tool manifest automatically. Get started today!

- Repository: [Alireza Rezvani/claude-skills](https://github.com/alirezarezvani/claude-skills)
- Tags: how-to-guide
- Published: 2026-03-09

---

**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`](https://github.com/alirezarezvani/claude-skills/blob/main/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`](https://github.com/alirezarezvani/claude-skills/blob/main/openapi_to_mcp.py))

The entry point [`engineering/mcp-server-builder/scripts/openapi_to_mcp.py`](https://github.com/alirezarezvani/claude-skills/blob/main/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`](https://github.com/alirezarezvani/claude-skills/blob/main/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`](https://github.com/alirezarezvani/claude-skills/blob/main/mcp_validator.py))

The [`engineering/mcp-server-builder/scripts/mcp_validator.py`](https://github.com/alirezarezvani/claude-skills/blob/main/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:

```bash

# 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`](https://github.com/alirezarezvani/claude-skills/blob/main/tool_manifest.json) — the canonical tool description required by MCP clients
- [`server.py`](https://github.com/alirezarezvani/claude-skills/blob/main/server.py) (or [`server.ts`](https://github.com/alirezarezvani/claude-skills/blob/main/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:

```python
#!/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:

```typescript
// 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

- **[`engineering/mcp-server-builder/scripts/openapi_to_mcp.py`](https://github.com/alirezarezvani/claude-skills/blob/main/engineering/mcp-server-builder/scripts/openapi_to_mcp.py)** — Core generator that transforms OpenAPI definitions into MCP manifests and scaffold code
- **[`engineering/mcp-server-builder/scripts/mcp_validator.py`](https://github.com/alirezarezvani/claude-skills/blob/main/engineering/mcp-server-builder/scripts/mcp_validator.py)** — Structural linting and quality checks for generated manifests
- **[`engineering/mcp-server-builder/references/python-server-template.md`](https://github.com/alirezarezvani/claude-skills/blob/main/engineering/mcp-server-builder/references/python-server-template.md)** — Reference template for Python scaffold generation
- **[`engineering/mcp-server-builder/references/typescript-server-template.md`](https://github.com/alirezarezvani/claude-skills/blob/main/engineering/mcp-server-builder/references/typescript-server-template.md)** — Reference template for TypeScript scaffold generation
- **[`engineering/mcp-server-builder/references/openapi-extraction-guide.md`](https://github.com/alirezarezvani/claude-skills/blob/main/engineering/mcp-server-builder/references/openapi-extraction-guide.md)** — Design patterns for mapping OpenAPI operations to MCP tools
- **[`engineering/mcp-server-builder/references/validation-checklist.md`](https://github.com/alirezarezvani/claude-skills/blob/main/engineering/mcp-server-builder/references/validation-checklist.md)** — Quality gates enforced by the validator

## Summary

- The **MCP Server Builder** converts OpenAPI specifications into fully functional MCP servers through a deterministic CLI pipeline
- **[`openapi_to_mcp.py`](https://github.com/alirezarezvani/claude-skills/blob/main/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`](https://github.com/alirezarezvani/claude-skills/blob/main/tool_manifest.json) and runnable server code in either Python (`FastMCP`) or TypeScript
- **[`mcp_validator.py`](https://github.com/alirezarezvani/claude-skills/blob/main/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`](https://github.com/alirezarezvani/claude-skills/blob/main/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`](https://github.com/alirezarezvani/claude-skills/blob/main/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.