API-to-MCP-Generator


NameAPI-to-MCP-Generator JSON
Version 0.1.4 PyPI version JSON
download
home_pagehttps://github.com/itssri5/openapi-to-mcp
SummaryA Python library to automatically convert any OpenAPI v2/v3 specification into a Model Context Protocol (MCP) server, with integrations for popular frameworks like FastAPI.
upload_time2025-07-27 01:33:07
maintainerNone
docs_urlNone
authorSriram Krishna
requires_python<4.0,>=3.8
licenseMPL-2.0
keywords openapi mcp fastapi api converter generator
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # API-to-MCP Generator

A Python library to automatically generate MCP (Model Context Protocol) servers from any OpenAPI v2/v3 specification.

This library allows you to expose any API with an OpenAPI spec as an MCP-compliant server, making it easy to integrate with AI agents and other MCP-enabled tools.

## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Configuration Options](#configuration-options)
- [Usage Examples](#usage-examples)
  - [Option 1: Standalone MCP Gateway](#option-1-standalone-mcp-gateway)
  - [Option 2: Integration with Existing FastAPI App](#option-2-integration-with-existing-fastapi-app)
- [Dynamic Configuration (Query Parameters)](#dynamic-configuration-query-parameters)
- [Security: SSRF Protection](#security-ssrf-protection)
- [Advanced Examples](#advanced-examples)
- [Development and Testing](#development-and-testing)
- [Troubleshooting](#troubleshooting)

## Features

- **Dynamic Conversion**: Generate MCP servers from any public OpenAPI v2/v3 specification URL or local file
- **Path Filtering**: Selectively expose a subset of API endpoints using path prefixes
- **Dynamic Upstream URL**: Forward requests to a different base URL than the one specified in the OpenAPI spec
- **Authentication Forwarding**: Pass authentication headers from MCP requests to the upstream API
- **`$ref` Resolution**: Automatically resolves JSON references (`$ref`) in OpenAPI specs for complete schema definitions
- **Local File Support**: Load OpenAPI specifications from local file paths in addition to URLs
- **Security**: Built-in SSRF protection with configurable domain whitelisting
- **Framework Integration**: Plug-and-play integration with FastAPI
- **Multiple Formats**: Supports both JSON and YAML OpenAPI specifications

## Installation

```bash
pip install API-to-MCP-Generator
```

## Quick Start

Here's the fastest way to get started with a dynamic MCP gateway:

```python
from fastapi import FastAPI
from api_to_mcp_generator.integrations.fastapi import add_mcp_route
import uvicorn

app = FastAPI(title="MCP Gateway")

# Add the MCP route with minimal configuration
add_mcp_route(
    app,
    allowed_domains=["petstore.swagger.io", "api.example.com"]
)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
```

**Test it:**
```bash
# Run the server
uvicorn main:app --reload

# Test with Petstore API
curl "http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json"
```

## Configuration Options

The `add_mcp_route()` function accepts the following parameters:

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `app` | `FastAPI` | Required | The FastAPI application instance |
| `prefix` | `str` | `"/mcp"` | The URL prefix for the MCP endpoint |
| `openapi_url` | `str` | `None` | Default OpenAPI spec URL (can be overridden by `s` parameter) |
| `openapi_file` | `str` | `None` | Path to a default local OpenAPI spec file |
| `allowed_domains` | `List[str]` | Required | List of allowed domains for SSRF protection |

**Important Notes:**
- You must provide either `openapi_url` OR `openapi_file`, or neither (for dynamic-only usage)
- You cannot provide both `openapi_url` and `openapi_file` simultaneously
- `allowed_domains` is mandatory for security (use empty list `[]` only for local files)

## Usage Examples

### Option 1: Standalone MCP Gateway

Create a dedicated server that can convert any OpenAPI spec to MCP on demand.

#### 1.1 Dynamic Gateway (Recommended)

```python
from fastapi import FastAPI
from api_to_mcp_generator.integrations.fastapi import add_mcp_route

app = FastAPI(
    title="Universal MCP Gateway",
    description="Convert any OpenAPI spec to MCP on the fly"
)

add_mcp_route(
    app,
    prefix="/mcp",
    allowed_domains=[
        "petstore.swagger.io",
        "petstore3.swagger.io", 
        "api.github.com",
        "api.stripe.com"
    ]
)

# Run with: uvicorn server:app --reload
```

**Usage:**
```bash
# GitHub API
curl "http://localhost:8000/mcp?s=https://api.github.com/openapi.json"

# Petstore with filtering
curl "http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&f=/pet"
```

#### 1.2 Gateway with Default Spec

```python
add_mcp_route(
    app,
    openapi_url="https://petstore.swagger.io/v2/swagger.json",  # Default spec
    allowed_domains=["petstore.swagger.io", "api.example.com"]
)

# This works without query parameters:
# curl "http://localhost:8000/mcp"

# And can be overridden:
# curl "http://localhost:8000/mcp?s=https://api.example.com/openapi.json"
```

#### 1.3 Gateway with Local File

```python
add_mcp_route(
    app,
    openapi_file="./specs/my-api.json",  # Local file
    allowed_domains=[]  # Empty for local files
)
```

### Option 2: Integration with Existing FastAPI App

Add MCP capabilities to your existing application.

```python
from fastapi import FastAPI
from api_to_mcp_generator.integrations.fastapi import add_mcp_route

# Your existing app
app = FastAPI(title="My Existing API")

# Your existing routes
@app.get("/health")
def health_check():
    return {"status": "healthy"}

@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"user_id": user_id, "name": f"User {user_id}"}

# Add MCP gateway functionality
add_mcp_route(
    app,
    prefix="/mcp",  # MCP available at /mcp endpoint
    allowed_domains=["api.third-party.com"]
)

# Now your app serves both:
# - Your API: /health, /users/{user_id}
# - MCP Gateway: /mcp?s=https://api.third-party.com/openapi.json
```

## Dynamic Configuration (Query Parameters)

The MCP endpoint supports dynamic configuration through URL query parameters. This allows a single deployed gateway to serve multiple APIs.

| Parameter | Required | Description | Example Value |
|-----------|----------|-------------|---------------|
| `s` | Conditional* | OpenAPI specification URL | `https://petstore.swagger.io/v2/swagger.json` |
| `u` | No | Upstream API base URL (overrides spec) | `https://api.production.example.com` |
| `f` | No | Comma-separated path filters | `/users,/products,/orders` |
| `h` | No | Authentication header name to forward | `Authorization` or `X-API-Key` |

**\* Required if no default `openapi_url` or `openapi_file` is configured.**

### Complete Examples

```bash
# Basic usage
http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json

# With upstream override (useful for dev/staging/prod environments)
http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&u=https://staging.petstore.com

# With path filtering (only expose pet-related endpoints)
http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&f=/pet

# With authentication forwarding
http://localhost:8000/mcp?s=https://api.example.com/openapi.json&h=Authorization

# Combined - all parameters
http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&u=https://prod.petstore.com&f=/pet,/store&h=X-API-Key
```

### Path Filtering Details

The `f` parameter accepts comma-separated path prefixes:

```bash
# Single prefix
?f=/users

# Multiple prefixes  
?f=/users,/products,/orders

# Nested paths
?f=/api/v1/users,/api/v1/products
```

**Example:** If your OpenAPI spec has these paths:
- `/users` ✅ (matches `/users`)
- `/users/{id}` ✅ (matches `/users`)  
- `/products` ✅ (matches `/products`)
- `/orders` ❌ (not in filter)
- `/health` ❌ (not in filter)

Only the ✅ paths will be exposed in the MCP server.

## Security: SSRF Protection

**Server-Side Request Forgery (SSRF) protection is mandatory and built-in.**

### Domain Whitelist

The `allowed_domains` parameter prevents malicious requests:

```python
add_mcp_route(
    app,
    allowed_domains=[
        "api.trusteddomain.com",
        "petstore.swagger.io",
        "api.github.com"
    ]
)
```

**✅ Allowed:**
- `?s=https://api.trusteddomain.com/openapi.json`  
- `?s=https://petstore.swagger.io/v2/swagger.json`

**❌ Blocked:**
- `?s=https://malicious.com/steal-secrets`
- `?s=http://localhost:22/ssh-config`
- `?s=https://internal.company.com/secrets`

### Best Practices

```python
# ✅ GOOD: Specific domains
allowed_domains=["api.partner.com", "docs.vendor.io"]

# ❌ DANGEROUS: Empty list with URLs (allows all domains)  
allowed_domains=[]  # Only use for local files!

# ✅ GOOD: Empty list for local files only
add_mcp_route(app, openapi_file="local.json", allowed_domains=[])
```

## Advanced Examples

### Multi-Environment Setup

```python
import os
from fastapi import FastAPI
from api_to_mcp_generator.integrations.fastapi import add_mcp_route

app = FastAPI()

# Environment-specific configuration
ENVIRONMENT = os.getenv("ENVIRONMENT", "development")

if ENVIRONMENT == "production":
    allowed_domains = ["api.prod.example.com"]
    default_url = "https://api.prod.example.com/openapi.json"
elif ENVIRONMENT == "staging":
    allowed_domains = ["api.staging.example.com", "api.prod.example.com"]  
    default_url = "https://api.staging.example.com/openapi.json"
else:
    allowed_domains = ["localhost:3000", "api.dev.example.com"]
    default_url = None

add_mcp_route(
    app,
    openapi_url=default_url,
    allowed_domains=allowed_domains
)
```

### Multiple MCP Endpoints

```python
# Serve different APIs on different endpoints
add_mcp_route(
    app, 
    prefix="/mcp/github",
    openapi_url="https://api.github.com/openapi.json",
    allowed_domains=["api.github.com"]
)

add_mcp_route(
    app,
    prefix="/mcp/stripe", 
    openapi_url="https://api.stripe.com/openapi.json",
    allowed_domains=["api.stripe.com"]
)

# Usage:
# curl "http://localhost:8000/mcp/github"
# curl "http://localhost:8000/mcp/stripe"
```

## Development and Testing

### 1. Install Dependencies

```bash
# Install the package and development dependencies
poetry install

# Or with pip
pip install -e .
pip install pytest black
```

### 2. Running Tests

```bash
# Run all tests
poetry run pytest

# Run with coverage
poetry run pytest --cov=api_to_mcp_generator

# Run specific test file
poetry run pytest tests/test_security.py -v
```

### 3. Code Formatting

```bash
# Format code
poetry run black .

# Check formatting
poetry run black --check .
```

## Troubleshooting

### Common Issues

**1. `ModuleNotFoundError: No module named 'api_to_mcp_generator'`**
```bash
# Make sure you installed the package
pip install API-to-MCP-Generator

# Or install in development mode
pip install -e .
```

**2. `HTTP 404 Not Found` when accessing `/mcp`**
```python
# Check your endpoint prefix
add_mcp_route(app, prefix="/mcp")  # Accessible at /mcp
add_mcp_route(app, prefix="/api/mcp")  # Accessible at /api/mcp
```

**3. `HTTP 400: Missing OpenAPI spec`**
```bash
# Provide spec URL via 's' parameter
curl "http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json"

# Or configure a default
add_mcp_route(app, openapi_url="https://default.com/spec.json", ...)
```

**4. `ConnectionError: URL domain 'example.com' is not an allowed domain`**
```python
# Add the domain to allowed_domains
add_mcp_route(app, allowed_domains=["example.com"])
```

**5. `HTTP 500: Failed to parse OpenAPI spec`**
- Verify the OpenAPI spec URL returns valid JSON/YAML
- Check if the spec follows OpenAPI 2.0/3.x standards
- Test the URL directly in your browser

### Debug Mode

```python
import logging
logging.basicConfig(level=logging.DEBUG)

# This will show detailed error messages and request logs
```

### Testing Your Setup

```python
# test_example.py
from fastapi.testclient import TestClient
from your_app import app

client = TestClient(app)

def test_mcp_endpoint():
    response = client.get("/mcp?s=https://petstore.swagger.io/v2/swagger.json")
    assert response.status_code == 200
    assert "paths" in response.json()
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/itssri5/openapi-to-mcp",
    "name": "API-to-MCP-Generator",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.8",
    "maintainer_email": null,
    "keywords": "openapi, mcp, fastapi, api, converter, generator",
    "author": "Sriram Krishna",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/a6/23/a601e061b66255de6f69fdec58196a35a9c401117a325083d69f50aba710/api_to_mcp_generator-0.1.4.tar.gz",
    "platform": null,
    "description": "# API-to-MCP Generator\n\nA Python library to automatically generate MCP (Model Context Protocol) servers from any OpenAPI v2/v3 specification.\n\nThis library allows you to expose any API with an OpenAPI spec as an MCP-compliant server, making it easy to integrate with AI agents and other MCP-enabled tools.\n\n## Table of Contents\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Configuration Options](#configuration-options)\n- [Usage Examples](#usage-examples)\n  - [Option 1: Standalone MCP Gateway](#option-1-standalone-mcp-gateway)\n  - [Option 2: Integration with Existing FastAPI App](#option-2-integration-with-existing-fastapi-app)\n- [Dynamic Configuration (Query Parameters)](#dynamic-configuration-query-parameters)\n- [Security: SSRF Protection](#security-ssrf-protection)\n- [Advanced Examples](#advanced-examples)\n- [Development and Testing](#development-and-testing)\n- [Troubleshooting](#troubleshooting)\n\n## Features\n\n- **Dynamic Conversion**: Generate MCP servers from any public OpenAPI v2/v3 specification URL or local file\n- **Path Filtering**: Selectively expose a subset of API endpoints using path prefixes\n- **Dynamic Upstream URL**: Forward requests to a different base URL than the one specified in the OpenAPI spec\n- **Authentication Forwarding**: Pass authentication headers from MCP requests to the upstream API\n- **`$ref` Resolution**: Automatically resolves JSON references (`$ref`) in OpenAPI specs for complete schema definitions\n- **Local File Support**: Load OpenAPI specifications from local file paths in addition to URLs\n- **Security**: Built-in SSRF protection with configurable domain whitelisting\n- **Framework Integration**: Plug-and-play integration with FastAPI\n- **Multiple Formats**: Supports both JSON and YAML OpenAPI specifications\n\n## Installation\n\n```bash\npip install API-to-MCP-Generator\n```\n\n## Quick Start\n\nHere's the fastest way to get started with a dynamic MCP gateway:\n\n```python\nfrom fastapi import FastAPI\nfrom api_to_mcp_generator.integrations.fastapi import add_mcp_route\nimport uvicorn\n\napp = FastAPI(title=\"MCP Gateway\")\n\n# Add the MCP route with minimal configuration\nadd_mcp_route(\n    app,\n    allowed_domains=[\"petstore.swagger.io\", \"api.example.com\"]\n)\n\nif __name__ == \"__main__\":\n    uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n**Test it:**\n```bash\n# Run the server\nuvicorn main:app --reload\n\n# Test with Petstore API\ncurl \"http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json\"\n```\n\n## Configuration Options\n\nThe `add_mcp_route()` function accepts the following parameters:\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `app` | `FastAPI` | Required | The FastAPI application instance |\n| `prefix` | `str` | `\"/mcp\"` | The URL prefix for the MCP endpoint |\n| `openapi_url` | `str` | `None` | Default OpenAPI spec URL (can be overridden by `s` parameter) |\n| `openapi_file` | `str` | `None` | Path to a default local OpenAPI spec file |\n| `allowed_domains` | `List[str]` | Required | List of allowed domains for SSRF protection |\n\n**Important Notes:**\n- You must provide either `openapi_url` OR `openapi_file`, or neither (for dynamic-only usage)\n- You cannot provide both `openapi_url` and `openapi_file` simultaneously\n- `allowed_domains` is mandatory for security (use empty list `[]` only for local files)\n\n## Usage Examples\n\n### Option 1: Standalone MCP Gateway\n\nCreate a dedicated server that can convert any OpenAPI spec to MCP on demand.\n\n#### 1.1 Dynamic Gateway (Recommended)\n\n```python\nfrom fastapi import FastAPI\nfrom api_to_mcp_generator.integrations.fastapi import add_mcp_route\n\napp = FastAPI(\n    title=\"Universal MCP Gateway\",\n    description=\"Convert any OpenAPI spec to MCP on the fly\"\n)\n\nadd_mcp_route(\n    app,\n    prefix=\"/mcp\",\n    allowed_domains=[\n        \"petstore.swagger.io\",\n        \"petstore3.swagger.io\", \n        \"api.github.com\",\n        \"api.stripe.com\"\n    ]\n)\n\n# Run with: uvicorn server:app --reload\n```\n\n**Usage:**\n```bash\n# GitHub API\ncurl \"http://localhost:8000/mcp?s=https://api.github.com/openapi.json\"\n\n# Petstore with filtering\ncurl \"http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&f=/pet\"\n```\n\n#### 1.2 Gateway with Default Spec\n\n```python\nadd_mcp_route(\n    app,\n    openapi_url=\"https://petstore.swagger.io/v2/swagger.json\",  # Default spec\n    allowed_domains=[\"petstore.swagger.io\", \"api.example.com\"]\n)\n\n# This works without query parameters:\n# curl \"http://localhost:8000/mcp\"\n\n# And can be overridden:\n# curl \"http://localhost:8000/mcp?s=https://api.example.com/openapi.json\"\n```\n\n#### 1.3 Gateway with Local File\n\n```python\nadd_mcp_route(\n    app,\n    openapi_file=\"./specs/my-api.json\",  # Local file\n    allowed_domains=[]  # Empty for local files\n)\n```\n\n### Option 2: Integration with Existing FastAPI App\n\nAdd MCP capabilities to your existing application.\n\n```python\nfrom fastapi import FastAPI\nfrom api_to_mcp_generator.integrations.fastapi import add_mcp_route\n\n# Your existing app\napp = FastAPI(title=\"My Existing API\")\n\n# Your existing routes\n@app.get(\"/health\")\ndef health_check():\n    return {\"status\": \"healthy\"}\n\n@app.get(\"/users/{user_id}\")\ndef get_user(user_id: int):\n    return {\"user_id\": user_id, \"name\": f\"User {user_id}\"}\n\n# Add MCP gateway functionality\nadd_mcp_route(\n    app,\n    prefix=\"/mcp\",  # MCP available at /mcp endpoint\n    allowed_domains=[\"api.third-party.com\"]\n)\n\n# Now your app serves both:\n# - Your API: /health, /users/{user_id}\n# - MCP Gateway: /mcp?s=https://api.third-party.com/openapi.json\n```\n\n## Dynamic Configuration (Query Parameters)\n\nThe MCP endpoint supports dynamic configuration through URL query parameters. This allows a single deployed gateway to serve multiple APIs.\n\n| Parameter | Required | Description | Example Value |\n|-----------|----------|-------------|---------------|\n| `s` | Conditional* | OpenAPI specification URL | `https://petstore.swagger.io/v2/swagger.json` |\n| `u` | No | Upstream API base URL (overrides spec) | `https://api.production.example.com` |\n| `f` | No | Comma-separated path filters | `/users,/products,/orders` |\n| `h` | No | Authentication header name to forward | `Authorization` or `X-API-Key` |\n\n**\\* Required if no default `openapi_url` or `openapi_file` is configured.**\n\n### Complete Examples\n\n```bash\n# Basic usage\nhttp://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json\n\n# With upstream override (useful for dev/staging/prod environments)\nhttp://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&u=https://staging.petstore.com\n\n# With path filtering (only expose pet-related endpoints)\nhttp://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&f=/pet\n\n# With authentication forwarding\nhttp://localhost:8000/mcp?s=https://api.example.com/openapi.json&h=Authorization\n\n# Combined - all parameters\nhttp://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json&u=https://prod.petstore.com&f=/pet,/store&h=X-API-Key\n```\n\n### Path Filtering Details\n\nThe `f` parameter accepts comma-separated path prefixes:\n\n```bash\n# Single prefix\n?f=/users\n\n# Multiple prefixes  \n?f=/users,/products,/orders\n\n# Nested paths\n?f=/api/v1/users,/api/v1/products\n```\n\n**Example:** If your OpenAPI spec has these paths:\n- `/users` \u2705 (matches `/users`)\n- `/users/{id}` \u2705 (matches `/users`)  \n- `/products` \u2705 (matches `/products`)\n- `/orders` \u274c (not in filter)\n- `/health` \u274c (not in filter)\n\nOnly the \u2705 paths will be exposed in the MCP server.\n\n## Security: SSRF Protection\n\n**Server-Side Request Forgery (SSRF) protection is mandatory and built-in.**\n\n### Domain Whitelist\n\nThe `allowed_domains` parameter prevents malicious requests:\n\n```python\nadd_mcp_route(\n    app,\n    allowed_domains=[\n        \"api.trusteddomain.com\",\n        \"petstore.swagger.io\",\n        \"api.github.com\"\n    ]\n)\n```\n\n**\u2705 Allowed:**\n- `?s=https://api.trusteddomain.com/openapi.json`  \n- `?s=https://petstore.swagger.io/v2/swagger.json`\n\n**\u274c Blocked:**\n- `?s=https://malicious.com/steal-secrets`\n- `?s=http://localhost:22/ssh-config`\n- `?s=https://internal.company.com/secrets`\n\n### Best Practices\n\n```python\n# \u2705 GOOD: Specific domains\nallowed_domains=[\"api.partner.com\", \"docs.vendor.io\"]\n\n# \u274c DANGEROUS: Empty list with URLs (allows all domains)  \nallowed_domains=[]  # Only use for local files!\n\n# \u2705 GOOD: Empty list for local files only\nadd_mcp_route(app, openapi_file=\"local.json\", allowed_domains=[])\n```\n\n## Advanced Examples\n\n### Multi-Environment Setup\n\n```python\nimport os\nfrom fastapi import FastAPI\nfrom api_to_mcp_generator.integrations.fastapi import add_mcp_route\n\napp = FastAPI()\n\n# Environment-specific configuration\nENVIRONMENT = os.getenv(\"ENVIRONMENT\", \"development\")\n\nif ENVIRONMENT == \"production\":\n    allowed_domains = [\"api.prod.example.com\"]\n    default_url = \"https://api.prod.example.com/openapi.json\"\nelif ENVIRONMENT == \"staging\":\n    allowed_domains = [\"api.staging.example.com\", \"api.prod.example.com\"]  \n    default_url = \"https://api.staging.example.com/openapi.json\"\nelse:\n    allowed_domains = [\"localhost:3000\", \"api.dev.example.com\"]\n    default_url = None\n\nadd_mcp_route(\n    app,\n    openapi_url=default_url,\n    allowed_domains=allowed_domains\n)\n```\n\n### Multiple MCP Endpoints\n\n```python\n# Serve different APIs on different endpoints\nadd_mcp_route(\n    app, \n    prefix=\"/mcp/github\",\n    openapi_url=\"https://api.github.com/openapi.json\",\n    allowed_domains=[\"api.github.com\"]\n)\n\nadd_mcp_route(\n    app,\n    prefix=\"/mcp/stripe\", \n    openapi_url=\"https://api.stripe.com/openapi.json\",\n    allowed_domains=[\"api.stripe.com\"]\n)\n\n# Usage:\n# curl \"http://localhost:8000/mcp/github\"\n# curl \"http://localhost:8000/mcp/stripe\"\n```\n\n## Development and Testing\n\n### 1. Install Dependencies\n\n```bash\n# Install the package and development dependencies\npoetry install\n\n# Or with pip\npip install -e .\npip install pytest black\n```\n\n### 2. Running Tests\n\n```bash\n# Run all tests\npoetry run pytest\n\n# Run with coverage\npoetry run pytest --cov=api_to_mcp_generator\n\n# Run specific test file\npoetry run pytest tests/test_security.py -v\n```\n\n### 3. Code Formatting\n\n```bash\n# Format code\npoetry run black .\n\n# Check formatting\npoetry run black --check .\n```\n\n## Troubleshooting\n\n### Common Issues\n\n**1. `ModuleNotFoundError: No module named 'api_to_mcp_generator'`**\n```bash\n# Make sure you installed the package\npip install API-to-MCP-Generator\n\n# Or install in development mode\npip install -e .\n```\n\n**2. `HTTP 404 Not Found` when accessing `/mcp`**\n```python\n# Check your endpoint prefix\nadd_mcp_route(app, prefix=\"/mcp\")  # Accessible at /mcp\nadd_mcp_route(app, prefix=\"/api/mcp\")  # Accessible at /api/mcp\n```\n\n**3. `HTTP 400: Missing OpenAPI spec`**\n```bash\n# Provide spec URL via 's' parameter\ncurl \"http://localhost:8000/mcp?s=https://petstore.swagger.io/v2/swagger.json\"\n\n# Or configure a default\nadd_mcp_route(app, openapi_url=\"https://default.com/spec.json\", ...)\n```\n\n**4. `ConnectionError: URL domain 'example.com' is not an allowed domain`**\n```python\n# Add the domain to allowed_domains\nadd_mcp_route(app, allowed_domains=[\"example.com\"])\n```\n\n**5. `HTTP 500: Failed to parse OpenAPI spec`**\n- Verify the OpenAPI spec URL returns valid JSON/YAML\n- Check if the spec follows OpenAPI 2.0/3.x standards\n- Test the URL directly in your browser\n\n### Debug Mode\n\n```python\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\n\n# This will show detailed error messages and request logs\n```\n\n### Testing Your Setup\n\n```python\n# test_example.py\nfrom fastapi.testclient import TestClient\nfrom your_app import app\n\nclient = TestClient(app)\n\ndef test_mcp_endpoint():\n    response = client.get(\"/mcp?s=https://petstore.swagger.io/v2/swagger.json\")\n    assert response.status_code == 200\n    assert \"paths\" in response.json()\n```\n",
    "bugtrack_url": null,
    "license": "MPL-2.0",
    "summary": "A Python library to automatically convert any OpenAPI v2/v3 specification into a Model Context Protocol (MCP) server, with integrations for popular frameworks like FastAPI.",
    "version": "0.1.4",
    "project_urls": {
        "Homepage": "https://github.com/itssri5/openapi-to-mcp",
        "Repository": "https://github.com/itssri5/openapi-to-mcp"
    },
    "split_keywords": [
        "openapi",
        " mcp",
        " fastapi",
        " api",
        " converter",
        " generator"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a7702e24efe17981668fc46c5db438fe30d6bba2aaafc26872a65eb6c9d9afb8",
                "md5": "c36232c67f2073355b3c678eb1bd251d",
                "sha256": "d6d0f4a03057ebd818a1aee9206a2c955dae8588a891194d30cf8dc5ee22f250"
            },
            "downloads": -1,
            "filename": "api_to_mcp_generator-0.1.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c36232c67f2073355b3c678eb1bd251d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8",
            "size": 16392,
            "upload_time": "2025-07-27T01:33:06",
            "upload_time_iso_8601": "2025-07-27T01:33:06.248966Z",
            "url": "https://files.pythonhosted.org/packages/a7/70/2e24efe17981668fc46c5db438fe30d6bba2aaafc26872a65eb6c9d9afb8/api_to_mcp_generator-0.1.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a623a601e061b66255de6f69fdec58196a35a9c401117a325083d69f50aba710",
                "md5": "a7089973e5e8ccc318eeb97537f4ecaf",
                "sha256": "db9cfe3af6b1fffca633a1cb4ad993c4e4f93319a8728204df136454b22d7099"
            },
            "downloads": -1,
            "filename": "api_to_mcp_generator-0.1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "a7089973e5e8ccc318eeb97537f4ecaf",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8",
            "size": 16934,
            "upload_time": "2025-07-27T01:33:07",
            "upload_time_iso_8601": "2025-07-27T01:33:07.837479Z",
            "url": "https://files.pythonhosted.org/packages/a6/23/a601e061b66255de6f69fdec58196a35a9c401117a325083d69f50aba710/api_to_mcp_generator-0.1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-27 01:33:07",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "itssri5",
    "github_project": "openapi-to-mcp",
    "github_not_found": true,
    "lcname": "api-to-mcp-generator"
}
        
Elapsed time: 1.79509s