Skip to main content

Convert REST API specifications (OpenAPI 3.x, Swagger 2.x, OpenAPI Actions) into MCP tools for AI agents. Supports JSON and YAML formats.

Project description

REST-to-MCP Adapter

A Python library for converting REST API specifications into MCP (Model Context Protocol) tools for AI agents.

Transform any REST API specification into tools that Claude, GPT, and other LLM-powered agents can use.

Supported Formats:

  • OpenAPI 3.x (JSON, YAML)
  • Swagger 2.x (JSON, YAML)
  • OpenAPI Actions format (JSON)

Python 3.11+ License: MIT PyPI version

โš ๏ธ Beta Status: This library is currently in beta (v0.1.0). The core functionality is stable and production-ready, but the API may evolve based on community feedback. We welcome early adopters and contributors!


๐Ÿš€ Quick Start

Simple Approach (Recommended for Most Users)

from adapter import ToolRegistry, MCPServer, APIExecutor, BearerAuth

# Create registry from OpenAPI spec (includes endpoints)
registry = ToolRegistry.create_from_openapi(
    "https://api.example.com/openapi.json"
)

# Set up executor
executor = APIExecutor(
    base_url="https://api.example.com",
    auth=BearerAuth(token="your-token")
)

# Create server - endpoints are in the registry!
server = MCPServer(
    name="My API Server",
    version="1.0.0",
    tool_registry=registry,
    executor=executor
    # No endpoints parameter needed!
)
server.run()

For advanced usage and individual step control, see Detailed Usage below.


๐Ÿ“ฆ Installation

Stable Release

pip install rest-to-mcp-adapter

Beta Release (Latest Features)

To install the latest beta version with cutting-edge features:

pip install --pre rest-to-mcp-adapter

Or install a specific beta version:

pip install rest-to-mcp-adapter==0.2.0b1

From Source (For Development)

git clone https://github.com/pawneetdev/rest-to-mcp-adapter.git
cd rest-to-mcp-adapter
pip install -e .

Dependencies

Core dependencies (automatically installed):

  • pydantic>=2.0.0 - Data validation and modeling
  • pyyaml>=6.0 - YAML parsing
  • requests>=2.31.0 - HTTP client

Optional dependencies:

  • langchain-community>=0.0.20 - Enhanced OpenAPI validation (install with: pip install rest-to-mcp-adapter[langchain])

โœจ Key Features

๐Ÿ”„ Specification Ingestion

  • Multiple formats: OpenAPI 3.x, Swagger 2.x, OpenAPI Actions
  • JSON & YAML: Full support for both formats
  • Load from anywhere: URL, file path, or raw content
  • Auto-detection: Automatically determines input type and format
  • $ref dereferencing: Resolves all JSON pointer references

๐Ÿ› ๏ธ MCP Tool Generation

  • Automatic conversion: OpenAPI endpoints โ†’ MCP tools
  • Smart naming: 64-character limit with intelligent truncation
  • Auth filtering: Automatically hides auth parameters from users
  • Hybrid approach: Defaults + auto-detection + custom overrides

๐Ÿ” Authentication Support

  • Built-in handlers: API Key, Bearer, Basic, OAuth2
  • Custom handlers: Easy to implement your own
  • Automatic parameter filtering: Auth params hidden from tool schemas
  • Conditional auth: Only applies to endpoints that require it

โšก Runtime Execution

  • Direct API calls: Execute REST requests from canonical endpoints
  • Retry logic: Exponential backoff for failed requests
  • Error handling: Comprehensive error types and messages
  • Response processing: JSON, text, and binary support

๐Ÿค– MCP Server

  • Full MCP protocol: JSON-RPC 2.0 over stdio
  • Claude integration: Ready for Claude Desktop
  • Tool discovery: tools/list endpoint
  • Tool execution: tools/call endpoint

๐Ÿ“– Detailed Usage

๐Ÿ’ก Looking for advanced features? See LIBRARY_USAGE.md for:

  • Advanced tool generation patterns
  • Registry operations (search, filter, export/import)
  • Batch API calls
  • Integration patterns and best practices
  • Troubleshooting guide
  • Important limitations (64-char tool name limit, etc.)

1. Loading API Specifications

The library supports multiple specification formats with automatic detection:

from adapter import OpenAPILoader

loader = OpenAPILoader()

# OpenAPI 3.x (JSON)
spec = loader.load("https://api.example.com/openapi.json")

# OpenAPI 3.x (YAML)
spec = loader.load("./specs/openapi.yaml")

# Swagger 2.x (JSON)
spec = loader.load("./specs/swagger.json")

# Swagger 2.x (YAML)
spec = loader.load("https://api.example.com/swagger.yaml")

# OpenAPI Actions format
spec = loader.load("./specs/actions.json")

# From raw YAML content
yaml_content = """
openapi: 3.0.0
info:
  title: My API
  version: 1.0.0
paths:
  /users:
    get:
      summary: List users
"""
spec = loader.load(yaml_content)

# From raw JSON content
json_content = '{"openapi": "3.0.0", "info": {"title": "My API"}}'
spec = loader.load(json_content)

# Auto-detection works for all methods
# Automatically detects: URL vs file vs content, JSON vs YAML, OpenAPI vs Swagger
spec = loader.load(source)

2. Normalizing to Canonical Format

from adapter import Normalizer

normalizer = Normalizer()
endpoints = normalizer.normalize_openapi(spec)

# Inspect normalized endpoints
for endpoint in endpoints:
    print(f"{endpoint.method} {endpoint.path}")
    print(f"  Name: {endpoint.name}")
    print(f"  Parameters: {len(endpoint.parameters)}")
    print(f"  Requires auth: {bool(endpoint.security)}")

3. Generating MCP Tools

Basic Usage

from adapter import ToolGenerator

generator = ToolGenerator(api_name="myapi")
tools = generator.generate_tools(endpoints)

# Tools are ready to use!
for tool in tools:
    print(f"Tool: {tool.name}")
    print(f"Description: {tool.description}")
    print(f"Parameters: {tool.inputSchema}")

With Auto-Detected Auth Filtering

from adapter import OpenAPILoader, ToolGenerator

# Load spec
loader = OpenAPILoader()
spec = loader.load("api.yaml")

# Auto-detect auth parameters from security schemes
auto_detected = loader.extract_auth_parameters(spec)
print(f"Auto-detected: {auto_detected}")
# Output: {'x-api-key', 'signature', ...}

# Generate tools with hybrid filtering (defaults + auto-detected)
generator = ToolGenerator(
    api_name="myapi",
    auto_detected_auth_params=auto_detected
)
tools = generator.generate_tools(endpoints)

# Auth parameters are automatically hidden!
# Users only see business parameters

With Custom Auth Parameters

# Override defaults completely
generator = ToolGenerator(
    api_name="myapi",
    auth_params={'my_signature', 'my_timestamp', 'my_nonce'}
)
tools = generator.generate_tools(endpoints)

4. Working with Tool Registry

from adapter import ToolRegistry

# Create registry
registry = ToolRegistry(name="My API")
registry.add_tools(tools)

# Query tools
print(f"Total tools: {registry.count()}")
print(f"Tool names: {registry.get_tool_names()}")

# Filter tools
product_tools = registry.get_tools_by_tag("products")
get_tools = registry.get_tools_by_method("GET")
search_results = registry.search_tools("user")

# Get specific tool
user_tool = registry.get_tool("myapi_get_users")

# Export/Import
registry.export_json("tools.json")
registry2 = ToolRegistry.import_json("tools.json")

5. Authentication Handlers

Built-in Handlers

from adapter import APIExecutor, BearerAuth, APIKeyAuth, BasicAuth

# Bearer Token
executor = APIExecutor(
    base_url="https://api.example.com",
    auth=BearerAuth(token="your-bearer-token")
)

# API Key (in header)
executor = APIExecutor(
    base_url="https://api.example.com",
    auth=APIKeyAuth(api_key="your-api-key", header_name="X-API-Key")
)

# API Key (in query)
executor = APIExecutor(
    base_url="https://api.example.com",
    auth=APIKeyAuth(api_key="your-api-key", location="query", param_name="apikey")
)

# Basic Auth
executor = APIExecutor(
    base_url="https://api.example.com",
    auth=BasicAuth(username="user", password="pass")
)

Custom Auth Handler

from adapter.runtime import AuthHandler

class CustomAuth(AuthHandler):
    def __init__(self, api_key: str, api_secret: str):
        self.api_key = api_key
        self.api_secret = api_secret

    def apply(self, headers: dict, params: dict) -> None:
        # Add custom authentication logic
        import time
        import hmac
        import hashlib

        timestamp = int(time.time() * 1000)
        params["timestamp"] = str(timestamp)

        # Create signature
        query_string = "&".join(f"{k}={v}" for k, v in sorted(params.items()))
        signature = hmac.new(
            self.api_secret.encode(),
            query_string.encode(),
            hashlib.sha256
        ).hexdigest()

        params["signature"] = signature
        headers["X-API-KEY"] = self.api_key

# Use custom auth
executor = APIExecutor(
    base_url="https://api.example.com",
    auth=CustomAuth(api_key="key", api_secret="secret")
)

Real-World Example: The Binance MCP implements a production-grade version of this pattern with additional features:

  • Server time synchronization for timestamp accuracy
  • Query string canonicalization (sorted parameter ordering)
  • Optional recvWindow parameter for clock skew tolerance
  • Comprehensive error messages for auth failures

Refer to its auth.py module for a complete implementation you can adapt for similar signature-based APIs.

6. Executing API Calls Directly

from adapter import APIExecutor, NoAuth

# Create executor
executor = APIExecutor(
    base_url="https://api.example.com",
    auth=NoAuth(),  # Public endpoints
    timeout=30,
    max_retries=3
)

# Find an endpoint
endpoint = next(ep for ep in endpoints if ep.name == "get_users")

# Execute call
result = executor.execute(endpoint, arguments={"limit": 10})

if result.success:
    print(f"Status: {result.status_code}")
    print(f"Data: {result.response.data}")
else:
    print(f"Error: {result.error}")

7. Running an MCP Server

from adapter import MCPServer

# Option 1: With create_from_openapi (recommended)
registry = ToolRegistry.create_from_openapi("https://api.example.com/openapi.json")
executor = APIExecutor(base_url="https://api.example.com", auth=BearerAuth(token="token"))

server = MCPServer(
    name="My API Server",
    version="1.0.0",
    tool_registry=registry,  # Endpoints included automatically
    executor=executor
)

# Option 2: Manual with explicit endpoints (backward compatible)
server = MCPServer(
    name="My API Server",
    version="1.0.0",
    tool_registry=registry,
    executor=executor,
    endpoints=endpoints  # Optional if registry has endpoints
)

# Run server (stdio transport for Claude Desktop)
server.run()

Configure in Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "myapi": {
      "command": "python",
      "args": ["/path/to/your/server.py"]
    }
  }
}

๐Ÿ” Authentication Parameter Filtering

One of the most powerful features is automatic authentication parameter filtering. This ensures users never see or need to provide auth-related parameters.

How It Works

The library uses a hybrid approach combining:

  1. Default common parameters: signature, timestamp, api_key, authorization, etc.
  2. Auto-detected from OpenAPI: Extracts from securitySchemes
  3. Custom overrides: You can specify your own

Default Auth Parameters

DEFAULT_AUTH_PARAMS = {
    'signature', 'timestamp', 'recvwindow', 'recv_window',
    'api_key', 'apikey', 'api_secret', 'apisecret',
    'access_token', 'accesstoken', 'token',
    'authorization', 'auth',
    'nonce', 'sign',
}

Auto-Detection Example

loader = OpenAPILoader()
spec = loader.load("api.yaml")

# Extract auth params from securitySchemes
auth_params = loader.extract_auth_parameters(spec)
# Returns: {'x-api-key', 'signature', ...}

# Use in tool generation
generator = ToolGenerator(
    api_name="myapi",
    auto_detected_auth_params=auth_params
)

Supported Security Schemes

Type Auto-Detected Parameters
apiKey Parameter name from spec
http (bearer/basic) authorization
oauth2 authorization, access_token, token
openIdConnect authorization

Example: Before vs After

Without filtering (โŒ Bad):

# User sees auth parameters
tool.inputSchema = {
    "properties": {
        "symbol": {"type": "string"},
        "timestamp": {"type": "integer"},  # โŒ Exposed
        "signature": {"type": "string"}     # โŒ Exposed
    }
}

# User has to provide them (confusing!)
client.call_tool("get_price", {
    "symbol": "BTCUSDT",
    "timestamp": 1234567890,      # โŒ User shouldn't know this
    "signature": "abc123..."       # โŒ User shouldn't know this
})

With filtering (โœ… Good):

# User only sees business parameters
tool.inputSchema = {
    "properties": {
        "symbol": {"type": "string"}  # โœ… Only what matters
    }
}

# Clean API!
client.call_tool("get_price", {
    "symbol": "BTCUSDT"  # โœ… Simple and clear
})
# Auth handler adds timestamp and signature automatically

๐Ÿ—๏ธ Architecture Overview

OpenAPI Spec (URL/file/content)
    โ†“
OpenAPILoader โ†’ Parses and dereferences $refs
    โ†“
Normalizer โ†’ Converts to CanonicalEndpoint models
    โ†“
ToolGenerator โ†’ Creates MCP tool definitions
    โ†“
ToolRegistry โ†’ Stores tools and endpoints
    โ†“
MCPServer โ†’ Exposes tools via JSON-RPC (stdio)
    โ†“
Claude/GPT โ†’ Calls tools
    โ†“
APIExecutor โ†’ Executes actual REST API calls
    โ†“
Response โ†’ Returns to agent

For detailed architecture documentation, see ARCHITECTURE.md.


๐ŸŒ Real-World Integrations

The REST-to-MCP Adapter powers production MCP servers for real APIs. These example repositories demonstrate complete implementations with different authentication patterns and specification formats.

DataForSEO MCP

Repository: https://github.com/pawneetdev/dataforseo-mcp/

Production MCP server for the DataForSEO API demonstrating:

  • Authentication: HTTP Basic Authentication
  • Spec Format: OpenAPI Actions/JSON format
  • Use Case: SEO data retrieval and analysis
  • What You'll Learn:
    • Loading OpenAPI JSON specifications
    • Implementing standard HTTP Basic auth
    • Organizing tools by API categories
    • Handling paginated responses

Quick Start:

git clone https://github.com/pawneetdev/dataforseo-mcp.git
cd dataforseo-mcp
pip install -e .

See the repository README for complete setup instructions and Claude Desktop integration.


Binance MCP

Repository: https://github.com/pawneetdev/binance-mcp

Production MCP server for the Binance Spot Trading API demonstrating:

  • Authentication: Custom HMAC-SHA256 signature-based authentication
  • Spec Format: Swagger/OpenAPI YAML format
  • Use Case: Cryptocurrency trading and market data
  • What You'll Learn:
    • Loading Swagger YAML specifications
    • Implementing custom AuthHandler with cryptographic signatures
    • Query string signing with HMAC-SHA256
    • Automatic timestamp and nonce injection
    • Advanced parameter filtering for signature-based endpoints
    • Handling large APIs (100+ endpoints)

Authentication Pattern: The Binance MCP extends the AuthHandler base class to implement Binance's specific requirements:

  • API key in headers (X-MBX-APIKEY)
  • Timestamp query parameter (synchronized with server time)
  • HMAC-SHA256 signature of query string
  • Optional recvWindow for timing flexibility

This pattern can be adapted for other APIs with signature-based authentication (AWS, Kraken, etc.).

Quick Start:

git clone https://github.com/pawneetdev/binance-mcp.git
cd binance-mcp
pip install -e .

See the repository README for API key setup, credential management, and Claude Desktop integration.


Learning Path

  1. Start with DataForSEO: Straightforward authentication, standard OpenAPI patterns
  2. Progress to Binance: Advanced custom authentication, complex parameter handling
  3. Build Your Own: Apply these patterns to your target API

Both repositories include:

  • Complete source code and project structure
  • Production-grade error handling
  • Retry logic and timeout management
  • Claude Desktop configuration examples
  • Deployment documentation

๐Ÿงช Testing

# Run all tests
pytest

# With coverage
pytest --cov=adapter

# Run specific test
pytest tests/test_tool_generator.py

๐Ÿ›ฃ๏ธ Roadmap

  • โœ… OpenAPI ingestion and normalization
  • โœ… MCP tool generation
  • โœ… Runtime execution engine
  • โœ… MCP server implementation
  • ๐Ÿ”„ Additional loaders (Postman, GraphQL)
  • ๐Ÿ“‹ WebSocket transport, enhanced caching

๐Ÿค Contributing

We welcome contributions from the community! Whether you're fixing bugs, adding features, or improving documentation, your help is appreciated.

How to Contribute

  1. Fork the repository on GitHub
  2. Clone your fork locally:
    git clone https://github.com/your-username/rest-to-mcp-adapter.git
    cd rest-to-mcp-adapter
    
  3. Create a branch for your changes:
    git checkout -b feature/your-feature-name
    
  4. Install development dependencies:
    pip install -e .
    pip install pytest pytest-cov black ruff
    
  5. Make your changes and ensure tests pass:
    pytest
    
  6. Format your code:
    black .
    ruff check .
    
  7. Commit and push your changes:
    git add .
    git commit -m "Description of your changes"
    git push origin feature/your-feature-name
    
  8. Open a Pull Request on GitHub

Areas We're Looking For Help

  • Additional authentication methods (OAuth2 flows, custom schemes)
  • Performance optimizations (caching, parallel processing)
  • More loaders (Postman collections, GraphQL schemas, API Blueprint)
  • Documentation improvements (tutorials, examples, API docs)
  • Real-world usage examples (new MCP server implementations)
  • Testing (edge cases, integration tests, CI/CD improvements)

Development Guidelines

  • Follow existing code style and patterns
  • Add tests for new features
  • Update documentation as needed
  • Keep changes focused and atomic
  • Write clear commit messages

Reporting Issues

Found a bug or have a feature request? Please open an issue with:

  • Clear description of the problem/feature
  • Steps to reproduce (for bugs)
  • Expected vs actual behavior
  • Relevant code snippets or examples

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Copyright (c) 2025 Pawneet Singh


๐Ÿ™‹ Support


๐Ÿ™ Acknowledgments

This library was developed with significant assistance from Claude (Anthropic), an AI assistant that helped with:

  • Architecture design and implementation
  • Code review and optimization
  • Documentation and examples
  • Testing and debugging

Special thanks to the AI agent and MCP communities for inspiration and feedback.


Built with โค๏ธ for the AI agent ecosystem

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rest_to_mcp_adapter-0.2.0b1.tar.gz (56.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rest_to_mcp_adapter-0.2.0b1-py3-none-any.whl (55.7 kB view details)

Uploaded Python 3

File details

Details for the file rest_to_mcp_adapter-0.2.0b1.tar.gz.

File metadata

  • Download URL: rest_to_mcp_adapter-0.2.0b1.tar.gz
  • Upload date:
  • Size: 56.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for rest_to_mcp_adapter-0.2.0b1.tar.gz
Algorithm Hash digest
SHA256 14327ee10ac166dd92560c1e884c6ac8c81c6241b88eec7c148f57172370d9a7
MD5 f3ee3862156b76538febf2ce9697af3a
BLAKE2b-256 535766c058493d413c833c88652aa8e28bb32652143a64f7ee0d4a17967ea9e1

See more details on using hashes here.

File details

Details for the file rest_to_mcp_adapter-0.2.0b1-py3-none-any.whl.

File metadata

File hashes

Hashes for rest_to_mcp_adapter-0.2.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 cba110cb4cac875fc993fb2f14973a0ef909fab6ae283b9e236b756cdacfa55a
MD5 bcad27a221af3557b06f11eaa378e720
BLAKE2b-256 ea49457c8a451cd1064eb1c9f0a565d2ca5368577f74d218d644e22c6da300cd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page