An open API service indexing awesome lists of open source software.

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.

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)

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PyPI version](https://badge.fury.io/py/rest-to-mcp-adapter.svg)](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**