Skip to main content
Glama
idea.md5.31 kB
# OpenAPI MCP Server - Technical Design Document ## Project Structure ``` openapi-mcp-server/ ├── src/ │ ├── main.py # MCP server entry point │ ├── openapi_loader.py # OpenAPI JSON fetcher/parser │ ├── request_executor.py # HTTP request handler │ ├── variable_manager.py # Variable storage/substitution │ └── tools.py # MCP tool definitions ├── config.json # Server configuration ├── pyproject.toml # Dependencies └── README.md ``` ## Configuration (config.json) ```json { "openapi_url": "http://localhost:8000/openapi.json", "refresh_interval": 300 } ``` ## Core Modules ### 1. openapi_loader.py **Purpose:** Fetch and parse OpenAPI spec **Class: `OpenAPILoader`** - `__init__(url: str)` - `load() -> dict` - Fetch JSON from URL - `get_endpoints() -> List[Endpoint]` - Extract all endpoints - `get_endpoint_schema(path: str, method: str) -> dict` - Get specific endpoint details - `search_endpoints(query: str) -> List[Endpoint]` - Search by path/description/tag **Endpoint dataclass:** ```python @dataclass class Endpoint: path: str method: str summary: str description: str tags: List[str] parameters: dict request_body: dict responses: dict ``` ### 2. variable_manager.py **Purpose:** Manage runtime variables and template substitution **Class: `VariableManager`** - `__init__()` - `set(key: str, value: str)` - Store variable - `get(key: str) -> str` - Retrieve variable - `get_all() -> dict` - List all variables - `substitute(text: str) -> str` - Replace `{{var}}` with values (regex-based) - `apply_to_request(headers: dict, body: any, path: str) -> tuple` - Apply substitution to all request parts **Storage:** Simple in-memory dict ### 3. request_executor.py **Purpose:** Execute HTTP requests **Class: `RequestExecutor`** - `__init__(variable_manager: VariableManager, base_url: str)` - `execute(path: str, method: str, headers: dict, query_params: dict, path_params: dict, body: any) -> Response` - Make HTTP call with variable substitution **Response dataclass:** ```python @dataclass class Response: status_code: int headers: dict body: any elapsed_ms: float ``` **Implementation:** Use `httpx.Client` for requests ### 4. tools.py **Purpose:** Define MCP tools **Tools:** 1. **list_endpoints** - Input: `{"method_filter": "GET", "path_prefix": "/api", "tag": "users"}` - Returns: List of matching endpoints with path, method, summary 2. **execute_request** - Input: `{"path": "/api/users/{id}", "method": "GET", "path_params": {"id": "123"}, "query_params": {}, "headers": {}, "body": null}` - Returns: Response object as JSON 3. **set_variable** - Input: `{"key": "auth_token", "value": "Bearer xyz..."}` - Returns: Success confirmation 4. **get_variables** - Input: `{}` - Returns: All stored variables 5. **search_schema** - Input: `{"query": "user login"}` - Returns: Matching endpoints **Each tool calls corresponding loader/executor/manager methods** ### 5. main.py **Purpose:** MCP server initialization ```python from mcp.server import Server from mcp.server.stdio import stdio_server # Initialize components loader = OpenAPILoader(config["openapi_url"]) loader.load() var_manager = VariableManager() executor = RequestExecutor(var_manager, base_url) # Create MCP server server = Server("openapi-mcp") # Register tools from tools.py register_tools(server, loader, executor, var_manager) # Run server async def main(): async with stdio_server() as streams: await server.run( streams[0], streams[1], server.create_initialization_options() ) ``` ## Dependencies (pyproject.toml) ```toml [project] name = "openapi-mcp-server" dependencies = [ "mcp>=0.9.0", "httpx>=0.27.0", "pydantic>=2.0.0" ] ``` ## Variable Substitution Logic - Scan strings for `{{variable_name}}` pattern - Replace with value from VariableManager - Apply to: headers, body (JSON stringified), query params, path params - Example: `Authorization: {{auth_token}}` → `Authorization: Bearer abc123` ## Error Handling - Wrap all HTTP calls in try/except - Return structured errors: `{"error": "message", "type": "NetworkError"}` - Validate endpoint exists before execution - Validate required parameters from OpenAPI schema ## Startup Flow 1. Load config.json 2. Fetch OpenAPI JSON from URL 3. Parse into Endpoint objects 4. Initialize MCP server with 5 tools 5. Ready to accept tool calls ## Example AI Workflow ``` AI: list_endpoints(method_filter="POST", tag="auth") → Returns login endpoint AI: execute_request(path="/api/auth/login", method="POST", body={"user":"admin","pass":"123"}) → Returns token AI: set_variable(key="token", value="Bearer xyz...") → Stored AI: execute_request(path="/api/users", method="GET", headers={"Authorization":"{{token}}"}) → Auto-substitutes token, returns users ``` ## Implementation Notes - Keep it synchronous for simplicity (async only for MCP server loop) - No caching initially - reload OpenAPI on each server start - Base URL extracted from OpenAPI `servers[0].url` or config - Use regex `r'\{\{(\w+)\}\}'` for variable substitution **Total LOC estimate: ~400-500 lines**

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fellowabhi/ControlAPI-openapi-to-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server