Skip to main content
Glama
architecture.md9.96 kB
# Architecture Overview This document provides a technical overview of MCP Foxxy Bridge's architecture, design principles, and implementation details. ## System Architecture ```mermaid graph LR subgraph "MCP Clients" C1[Claude Desktop] C2[VS Code] C3[Custom Apps] end subgraph "MCP Foxxy Bridge" SSE[SSE Server<br/>Port 8080] BS[Bridge Server<br/>Aggregator] SM[Server Manager<br/>Connections] SSE --> BS BS --> SM end subgraph "MCP Servers" S1[GitHub Server] S2[Filesystem] S3[Fetch Server] S4[Brave Search] S5[Custom Servers] end C1 --> SSE C2 --> SSE C3 --> SSE SM --> S1 SM --> S2 SM --> S3 SM --> S4 SM --> S5 ``` ## Core Components ### 1. SSE Server (`mcp_server.py`) **Responsibility:** HTTP server providing SSE endpoints for MCP clients **Key Features:** - Starlette-based ASGI application - Server-Sent Events (SSE) transport for MCP protocol - StreamableHTTP support for advanced clients - Auto port-finding with increment fallback - Graceful shutdown handling **Endpoints:** - `GET /sse` - Main MCP client connection point - `GET /status` - Health and status monitoring - `POST /messages/` - MCP message handling ### 2. Bridge Server (`bridge_server.py`) **Responsibility:** MCP protocol implementation and tool aggregation **Key Features:** - Implements MCP Server SDK interface - Aggregates capabilities from multiple backend servers - Handles tool/resource/prompt routing - Manages namespacing and conflict resolution - Provides unified client interface **Core Methods:** - `list_tools()` - Aggregate tools from all servers - `call_tool()` - Route tool calls to appropriate server - `list_resources()` - Aggregate resources with namespacing - `read_resource()` - Route resource reads ### 3. Server Manager (`server_manager.py`) **Responsibility:** Backend MCP server lifecycle and connection management **Key Features:** - Manages multiple stdio MCP server connections - Health monitoring and automatic failover - Connection retry logic with exponential backoff - Graceful shutdown with context management - Server capability discovery and caching **Server States:** - `CONNECTING` - Initial connection attempt - `CONNECTED` - Active and healthy - `FAILED` - Connection failed or server unhealthy - `DISCONNECTED` - Cleanly disconnected - `DISABLED` - Administratively disabled ### 4. Config Loader (`config_loader.py`) **Responsibility:** Configuration parsing and validation **Key Features:** - JSON configuration file parsing - Environment variable expansion (`${VAR_NAME}`) - JSON Schema validation - Server configuration normalization - Bridge settings management **Environment Variable Syntax:** - `${VAR_NAME}` - Required variable - `${VAR_NAME:default}` - Variable with default value - Recursive expansion through nested structures ## Data Flow ### Tool Call Flow ```mermaid sequenceDiagram participant Client participant SSE as SSE Server participant Bridge as Bridge Server participant Manager as Server Manager participant MCP as MCP Server Client->>SSE: POST tool call request SSE->>Bridge: Forward MCP message Bridge->>Manager: Route to target server Manager->>MCP: Execute tool via stdio MCP->>Manager: Return result Manager->>Bridge: Forward result Bridge->>SSE: Send MCP response SSE->>Client: Return JSON result ``` ### Capability Discovery Flow ```mermaid flowchart TD A[Server Manager Start] --> B[Connect to All Configured Servers] B --> C{For Each Server} C --> D[Execute list_tools()] C --> E[Execute list_resources()] C --> F[Execute list_prompts()] D --> G[Apply Namespace Transformations] E --> G F --> G G --> H[Cache Capabilities Locally] H --> I{More Servers?} I -->|Yes| C I -->|No| J[Bridge Server: Aggregate All Capabilities] J --> K[Client Request: Return Unified Capability List] ``` ## Design Principles ### 1. Transparency The bridge acts as a transparent proxy, preserving MCP protocol semantics while adding aggregation capabilities. ### 2. Fault Tolerance - Individual server failures don't bring down the bridge - Automatic retry and recovery mechanisms - Health monitoring and failover support - Graceful degradation when servers are unavailable ### 3. Scalability - Asynchronous I/O throughout the stack - Connection pooling and reuse - Efficient tool routing with caching - Configurable resource limits ### 4. Extensibility - Plugin-like server configuration - Support for any stdio-based MCP server - Flexible namespacing and routing rules - Environment-based configuration ## Namespacing Strategy ### Tool Namespacing Tools are namespaced to prevent conflicts between servers: ```text Original: search_repositories Namespaced: github.search_repositories ``` **Resolution Order:** 1. Check explicit namespace configuration 2. Use server name as default namespace (if enabled) 3. Apply conflict resolution strategy ### Resource Namespacing Resources use URI-style namespacing: ```text Original: file.txt Namespaced: fs://file.txt ``` ### Conflict Resolution Strategies 1. **Namespace** (default): Add namespaces to prevent conflicts 2. **Priority**: Higher priority server wins 3. **First**: First server to register wins 4. **Error**: Throw error on conflicts ## Connection Management ### AsyncExitStack Pattern The bridge uses Python's `AsyncExitStack` to manage the lifecycle of async context managers: ```python async with contextlib.AsyncExitStack() as stack: # Enter stdio_client context read_stream, write_stream = await stack.enter_async_context(stdio_client(params)) # Enter ClientSession context session = await stack.enter_async_context(ClientSession(read_stream, write_stream)) # Both contexts remain active until stack exits ``` ### Health Monitoring Each server has continuous health monitoring: ```python async def health_check_loop(): while not shutdown: for server in active_servers: try: await server.session.list_tools() # Simple ping server.mark_healthy() except Exception: server.mark_unhealthy() await asyncio.sleep(health_check_interval) ``` ## Error Handling ### Error Propagation Errors are propagated with context preservation: 1. **Server Errors**: Forwarded to client with server identification 2. **Connection Errors**: Trigger retry logic and failover 3. **Protocol Errors**: Wrapped in standard MCP error format 4. **Configuration Errors**: Fail fast at startup ### Retry Logic Exponential backoff for connection failures: ```python for attempt in range(max_retries): try: await connect_to_server() break except Exception: await asyncio.sleep(base_delay * (2 ** attempt)) ``` ## Security Model ### Isolation - Each MCP server runs in its own process - No direct inter-server communication - Environment variable isolation per server ### Access Control - No built-in authentication (design choice) - Relies on network-level security - Environment variable based secrets ### Process Management - Child processes don't inherit parent signals - Graceful shutdown with timeout enforcement - Resource cleanup on exit ## Performance Characteristics ### Latency - **Tool calls**: ~10-50ms overhead (mostly I/O) - **Capability listing**: Cached, <1ms after warmup - **Connection setup**: ~100-500ms per server ### Memory Usage - **Base bridge**: ~20-30MB - **Per server**: ~5-10MB overhead - **Per connection**: ~1-2MB ### Concurrency - Fully asynchronous I/O - No global locks or bottlenecks - Scales with available file descriptors ## Configuration Schema ### Server Configuration ```typescript interface ServerConfig { // Connection enabled: boolean; command: string; args: string[]; env: Record<string, string>; timeout: number; // Reliability retryAttempts: number; retryDelay: number; healthCheck: HealthCheckConfig; // Routing toolNamespace?: string; resourceNamespace?: string; promptNamespace?: string; priority: number; // Metadata tags: string[]; } ``` ### Bridge Configuration ```typescript interface BridgeConfig { conflictResolution: ConflictStrategy; defaultNamespace: boolean; aggregation: { tools: boolean; resources: boolean; prompts: boolean; }; failover: { enabled: boolean; maxFailures: number; recoveryInterval: number; }; } ``` ## Extension Points ### Custom Server Types While currently stdio-only, the architecture supports extension: ```python class CustomServerManager: async def connect(self, config: ServerConfig) -> ClientSession: # Custom connection logic pass ``` ### Custom Routing Tool routing can be extended with custom logic: ```python class CustomBridgeServer: def route_tool_call(self, tool_name: str) -> ManagedServer: # Custom routing logic pass ``` ### Middleware Support The Starlette-based server supports standard ASGI middleware: ```python middleware = [ Middleware(AuthenticationMiddleware), Middleware(RateLimitingMiddleware), Middleware(LoggingMiddleware), ] ``` ## Future Architecture Considerations ### Multi-Protocol Support - WebSocket transport for low-latency clients - gRPC support for high-performance scenarios - HTTP/2 for multiplexed connections ### Distributed Deployment - Multiple bridge instances with load balancing - Shared state via Redis or similar - Cross-bridge server discovery ### Advanced Routing - Content-based routing (route by tool arguments) - Load-based routing (route to least loaded server) - Geographic routing (route to nearest server) ### Observability - OpenTelemetry integration - Structured logging with correlation IDs - Prometheus metrics export

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/billyjbryant/mcp-foxxy-bridge'

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