https://github.com/pawneetdev/rest-to-mcp-adapter
A Python library for converting REST API specifications into MCP (Model Context Protocol) tools for AI agents.
https://github.com/pawneetdev/rest-to-mcp-adapter
ai chatgpt claude mcp mcp-server mcp-servers python python3 rest-api rest-to-mcp
Last synced: 5 months ago
JSON representation
A Python library for converting REST API specifications into MCP (Model Context Protocol) tools for AI agents.
- Host: GitHub
- URL: https://github.com/pawneetdev/rest-to-mcp-adapter
- Owner: pawneetdev
- License: mit
- Created: 2025-11-19T16:55:07.000Z (7 months ago)
- Default Branch: master
- Last Pushed: 2025-11-27T15:36:10.000Z (7 months ago)
- Last Synced: 2025-11-30T08:11:19.828Z (7 months ago)
- Topics: ai, chatgpt, claude, mcp, mcp-server, mcp-servers, python, python3, rest-api, rest-to-mcp
- Language: Python
- Homepage: https://pypi.org/project/rest-to-mcp-adapter
- Size: 306 KB
- Stars: 4
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 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)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
[](https://pypi.org/project/rest-to-mcp-adapter/)
> **โ ๏ธ 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)
```python
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](#-detailed-usage) below.
---
## ๐ฆ Installation
### Stable Release
```bash
pip install rest-to-mcp-adapter
```
### Beta Release (Latest Features)
To install the latest beta version with cutting-edge features:
```bash
pip install --pre rest-to-mcp-adapter
```
Or install a specific beta version:
```bash
pip install rest-to-mcp-adapter==0.2.0b1
```
### From Source (For Development)
```bash
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](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:
```python
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
```python
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
```python
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
```python
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
```python
# 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
```python
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
```python
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
```python
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](https://github.com/pawneetdev/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
```python
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
```python
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`:
```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
```python
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
```python
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):
```python
# 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):
```python
# 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](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**:
```bash
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**:
```bash
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
```bash
# 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:
```bash
git clone https://github.com/your-username/rest-to-mcp-adapter.git
cd rest-to-mcp-adapter
```
3. **Create a branch** for your changes:
```bash
git checkout -b feature/your-feature-name
```
4. **Install development dependencies**:
```bash
pip install -e .
pip install pytest pytest-cov black ruff
```
5. **Make your changes** and ensure tests pass:
```bash
pytest
```
6. **Format your code**:
```bash
black .
ruff check .
```
7. **Commit and push** your changes:
```bash
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](https://github.com/pawneetdev/rest-to-mcp-adapter/issues) 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](LICENSE) file for details.
Copyright (c) 2025 Pawneet Singh
---
## ๐ Support
- **Issues**: [GitHub Issues](https://github.com/pawneetdev/rest-to-mcp-adapter/issues)
- **PyPI Package**: [rest-to-mcp-adapter](https://pypi.org/project/rest-to-mcp-adapter/)
---
## ๐ 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**