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)
๐ Quick Start
from adapter import (
OpenAPILoader,
Normalizer,
ToolGenerator,
ToolRegistry,
APIExecutor,
BearerAuth,
MCPServer
)
# 1. Load OpenAPI spec
loader = OpenAPILoader()
spec = loader.load("https://api.example.com/openapi.json")
# 2. Normalize to canonical format
normalizer = Normalizer()
endpoints = normalizer.normalize_openapi(spec)
# 3. Generate MCP tools (auth params auto-filtered!)
generator = ToolGenerator(api_name="myapi")
tools = generator.generate_tools(endpoints)
# 4. Create tool registry
registry = ToolRegistry(name="My API")
registry.add_tools(tools)
# 5. Set up API executor with authentication
executor = APIExecutor(
base_url="https://api.example.com",
auth=BearerAuth(token="your-token")
)
# 6. Start MCP server (for Claude Desktop, etc.)
server = MCPServer(
name="My API Server",
version="1.0.0",
tool_registry=registry,
executor=executor,
endpoints=endpoints
)
server.run() # Claude can now use your API!
๐ฆ Installation
From PyPI
pip install rest-to-mcp-adapter
From Source
git clone https://github.com/pawneetdev/rest-to-mcp-adapter.git
cd rest-to-mcp-adapter
pip install -e .
Development Installation
# Clone and install with development dependencies
git clone https://github.com/pawneetdev/rest-to-mcp-adapter.git
cd rest-to-mcp-adapter
pip install -e ".[dev]"
Dependencies
Core dependencies (automatically installed):
pydantic>=2.0.0- Data validation and modelingpyyaml>=6.0- YAML parsingrequests>=2.31.0- HTTP clientlangchain-community>=0.0.20- MCP protocol support
โจ 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/listendpoint - Tool execution:
tools/callendpoint
๐ 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
recvWindowparameter 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
# Create server (combines registry + executor + endpoints)
server = MCPServer(
name="My API Server",
version="1.0.0",
tool_registry=registry,
executor=executor,
endpoints=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:
- Default common parameters:
signature,timestamp,api_key,authorization, etc. - Auto-detected from OpenAPI: Extracts from
securitySchemes - 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 โ Organizes and manages tools
โ
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.
๐ Examples
For complete, production-ready MCP server implementations with full source code, see the Real-World Integrations section below.
๐ 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
AuthHandlerwith 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
recvWindowfor 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
- Start with DataForSEO: Straightforward authentication, standard OpenAPI patterns
- Progress to Binance: Advanced custom authentication, complex parameter handling
- 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
- โ Phase 1: OpenAPI ingestion and normalization
- โ Phase 2: MCP tool generation
- โ Phase 3: Runtime execution engine
- โ Phase 4: MCP server implementation
- ๐ Phase 5: Additional loaders (Postman, GraphQL)
- ๐ Future: WebSocket transport, enhanced caching
๐ค Contributing
Contributions welcome! The core library is complete, and we're looking for:
- Additional authentication methods
- Performance optimizations
- More loaders (Postman collections, GraphQL schemas)
- Documentation improvements
- Real-world usage examples
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright (c) 2025 Pawneet Singh
๐ Support
- Issues: GitHub Issues
Built with โค๏ธ for the AI agent ecosystem
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rest_to_mcp_adapter-0.1.0.tar.gz.
File metadata
- Download URL: rest_to_mcp_adapter-0.1.0.tar.gz
- Upload date:
- Size: 53.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e5ecab6aede619728357048853efbc2c73878319e30879836cc41159c32fb30
|
|
| MD5 |
f80532719353e804d1946391a821f856
|
|
| BLAKE2b-256 |
737f593fac231882dbb4d599a68c76425fa6878273b59defdaea03516f425b82
|
File details
Details for the file rest_to_mcp_adapter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rest_to_mcp_adapter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 53.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be249587c1623bf054367cf9134d1305f4415e349f52306d10e022c55c58864d
|
|
| MD5 |
229c6d2004ebeacb7bcb3f066c0c9f27
|
|
| BLAKE2b-256 |
a9315deaa30a2b799495f7217cfa241ae4eee27aa637b9779597dd7fb8312317
|