# 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**