mcp-database-server

""" Template for MCP server definitions. This template provides a standardized structure for creating MCP server modules. Each module should follow this pattern to ensure consistency across the codebase. Module Structure: 1. Imports and Configuration 2. Global Constants 3. Registration Variables 4. Endpoint Sections (one per endpoint): - Pydantic Models (Input/Output) - Data Fetching Function - Handler Function - Tool Registration Usage: Copy this template and replace the placeholders with actual implementation. """ # 1. Standard Imports Section import logging from typing import Any, List, Optional, Sequence import httpx import mcp.types as types from pydantic import BaseModel, Field # Initialize logging log = logging.getLogger(__name__) # 2. Constants Section BASE_URL = "https://api.example.com/v1" # 3. Registration Variables RESOURCES: List[Any] = [] # resources that will be registered by each endpoints RESOURCES_HANDLERS: dict[ str, Any ] = {} # resources handlers that will be registered by each endpoints TOOLS: List[types.Tool] = [] # tools that will be registered by each endpoints TOOLS_HANDLERS: dict[ str, Any ] = {} # tools handlers that will be registered by each endpoints ################### # [Endpoint Name] ################### # 1. Input/Output Models class EndpointParams(BaseModel): """Input parameters for the endpoint.""" param1: str = Field(..., description="Description of param1") param2: Optional[int] = Field(None, description="Description of param2") class EndpointResult(BaseModel): """Single result item from the endpoint.""" field1: str = Field(..., description="Description of field1") field2: int = Field(..., description="Description of field2") class EndpointResponse(BaseModel): """Complete response from the endpoint.""" results: List[EndpointResult] = Field(..., description="List of results") # 2. Data Fetching Function def fetch_endpoint_data(params: EndpointParams) -> EndpointResponse: """ Fetch data from the endpoint. Args: params: EndpointParams object containing all query parameters Returns: EndpointResponse object containing the results Raises: httpx.HTTPError: If the API request fails """ endpoint = f"{BASE_URL}/endpoint" response = httpx.get(endpoint, params=params.model_dump(exclude_none=True)) response.raise_for_status() return EndpointResponse(**response.json()) # 3. Handler Function async def handle_endpoint( arguments: dict[str, Any] | None = None, ) -> Sequence[types.TextContent | types.ImageContent | types.EmbeddedResource]: """ Handle the tool execution for this endpoint. Args: arguments: Dictionary of tool arguments Returns: Sequence of content objects Raises: Exception: If the handling fails """ try: response = fetch_endpoint_data(EndpointParams(**(arguments or {}))) return [types.TextContent(type="text", text=str(response))] except Exception as e: log.error(f"Error handling endpoint: {e}") raise # 4. Tool Registration TOOLS.append( types.Tool( name="endpoint-name", description="Description of what this endpoint does", inputSchema=EndpointParams.model_json_schema(), ) ) TOOLS_HANDLERS["endpoint-name"] = handle_endpoint ################### # [Another Endpoint Name] ################### ... # Server initialization (if module is run directly) if __name__ == "__main__": import anyio from odmcp.utils import run_server anyio.run( run_server, "service.name", RESOURCES, RESOURCES_HANDLERS, TOOLS, TOOLS_HANDLERS )