UNPKG

mcp-http-bridge

Version:

Generic bridge client for connecting MCP clients to remote MCP servers via HTTP supporting session based environment variables

281 lines (213 loc) 9.15 kB
# RFC: Configuration Headers Extension for MCP Streamable HTTP Transport **Status**: Draft **Author**: Jason Chen **Date**: 2025-06-10 **MCP Version**: 2025-03-26+ ## Abstract This RFC proposes a standardized extension to the MCP Streamable HTTP transport that enables client-specific configuration via HTTP headers. This addresses the configuration gap between stdio-based MCP clients (like Cursor, Claude Desktop) and remote HTTP-deployed MCP servers. ## Motivation ### Problem Statement The current MCP ecosystem has a configuration mismatch: 1. **MCP Clients** (Cursor, Claude Desktop) expect stdio transport with environment variables 2. **Remote MCP Servers** deployed via HTTP cannot access client-side environment variables 3. **No Standard Mechanism** exists for passing client-specific configuration to remote servers This forces developers to choose between: - Local stdio deployment (limited scalability) - Remote HTTP deployment (no client-specific configuration) ### Use Cases 1. **Database Connections**: Each client connects to their own database 2. **API Keys**: Client-specific API credentials for third-party services 3. **Multi-tenant Services**: Per-client configuration in shared deployments 4. **Development vs Production**: Different configurations per environment ## Proposal ### Configuration Headers Specification #### Header Format Clients MAY pass configuration to servers via HTTP headers using the pattern: ``` X-MCP-{VARIABLE_NAME}: {value} ``` Where: - `VARIABLE_NAME` is the environment variable name (case-insensitive) - Dashes in header names are converted to underscores in environment variables - Header names are case-insensitive per HTTP specification #### Examples ```http X-MCP-SQL-SERVER: mydb.example.com X-MCP-SQL-DATABASE: client_db X-MCP-API-KEY: abc123xyz X-MCP-CUSTOM-CONFIG: value ``` Server receives these as: ```bash SQL_SERVER=mydb.example.com SQL_DATABASE=client_db API_KEY=abc123xyz CUSTOM_CONFIG=value ``` #### Server Behavior 1. **Header Extraction**: Servers SHOULD extract `X-MCP-*` headers from requests 2. **Environment Application**: Apply header values as temporary environment variables 3. **Session Scope**: Configuration MUST be session-scoped, not global 4. **Cleanup**: Restore original environment after request processing #### Client Behavior 1. **Variable Filtering**: Clients SHOULD filter system variables (PATH, HOME, NODE_ENV, etc.) 2. **Security**: Clients MUST NOT expose sensitive system information 3. **Transport Agnostic**: Implementation should work with any HTTP transport ### Bridge Client Pattern To enable existing stdio-based MCP clients to use remote servers, implementations SHOULD provide a bridge client that: 1. **Stdio Interface**: Presents standard stdio interface to MCP clients 2. **HTTP Backend**: Communicates with remote servers via Streamable HTTP 3. **Automatic Conversion**: Converts environment variables to configuration headers 4. **Transparent Operation**: Requires no changes to existing MCP client code #### Bridge Architecture ``` [MCP Client] ←stdio→ [Bridge Client] ←HTTP+Headers→ [Remote MCP Server] ``` ## Detailed Design ### Server Implementation ```javascript // Extract configuration from headers function extractMCPConfig(req) { const config = {}; for (const [headerName, headerValue] of Object.entries(req.headers)) { if (headerName.startsWith('x-mcp-')) { const envVarName = headerName .substring(6) // Remove 'x-mcp-' prefix .replace(/-/g, '_') // Replace dashes with underscores .toUpperCase(); // Convert to uppercase config[envVarName] = headerValue; } } return config; } // Apply configuration temporarily function withMCPConfig(config, fn) { const originalEnv = {}; // Store original values and apply new ones for (const [key, value] of Object.entries(config)) { originalEnv[key] = process.env[key]; process.env[key] = value; } try { return fn(); } finally { // Restore original environment for (const [key, value] of Object.entries(originalEnv)) { if (value === undefined) { delete process.env[key]; } else { process.env[key] = value; } } } } ``` ### Bridge Client Implementation ```javascript // Convert MCP-configured environment variables to headers function envToHeaders() { const headers = {}; const configuredVars = getMCPConfiguredVariables(); for (const key of configuredVars) { const value = process.env[key]; if (value !== undefined) { headers[`X-MCP-${key.replace(/_/g, '-')}`] = value; } } return headers; } function getMCPConfiguredVariables() { const configuredVars = []; const systemVars = ['PATH', 'HOME', 'NODE_ENV', 'npm_', /* ... */]; const bridgeVars = ['MCP_SERVER_URL']; for (const [key, value] of Object.entries(process.env)) { // Skip system and bridge variables if (!systemVars.some(sysVar => key.startsWith(sysVar)) && !bridgeVars.includes(key)) { configuredVars.push(key); } } return configuredVars; } ``` ## Security Considerations ### Server-Side Security 1. **Input Validation**: Servers MUST validate and sanitize header values 2. **Configuration Scope**: Environment changes MUST be session-scoped 3. **Resource Limits**: Implement limits on number and size of configuration headers 4. **Audit Logging**: Log configuration changes for security monitoring ### Client-Side Security 1. **System Variable Filtering**: Clients MUST filter system and sensitive variables 2. **Credential Management**: Use secure credential storage, not hardcoded values 3. **Transport Security**: Use HTTPS for production deployments 4. **Access Control**: Implement proper authentication and authorization ### Threat Model - **Information Disclosure**: Malicious servers could log client configuration - **Configuration Injection**: Malicious clients could inject harmful configuration - **Resource Exhaustion**: Large numbers of headers could impact performance ## Backward Compatibility This extension is fully backward compatible: 1. **Optional Implementation**: Servers MAY implement configuration headers 2. **Graceful Degradation**: Clients work normally without header support 3. **No Breaking Changes**: Existing MCP implementations continue to work 4. **Progressive Enhancement**: Adds capability without changing core protocol ## Implementation Examples ### Cursor Configuration ```json { "mcpServers": { "remote-sql": { "command": "node", "args": ["mcp-bridge-client.js"], "env": { "MCP_SERVER_URL": "https://mcp-server.example.com/sql/mcp", "SQL_SERVER": "mydb.example.com", "SQL_DATABASE": "client_db", "SQL_USER": "client_user", "SQL_PASSWORD": "client_pass" } } } } ``` ### Server Deployment ```javascript app.post('/mcp', async (req, res) => { const config = extractMCPConfig(req); await withMCPConfig(config, async () => { // Server logic runs with client-specific configuration const transport = new StreamableHTTPServerTransport(options); await server.connect(transport); await transport.handleRequest(req, res, req.body); }); }); ``` ## Alternatives Considered 1. **Query Parameters**: Less secure, URL length limits 2. **Request Body**: Conflicts with MCP message format 3. **Custom Authentication**: More complex, not standardized 4. **WebSocket Subprotocols**: Limited to WebSocket transport ## Open Questions 1. Should there be a maximum number of configuration headers? 2. Should servers advertise configuration header support in capabilities? 3. Should there be a standard schema format for expected configuration? 4. How should configuration validation errors be reported? ## Implementation Status A reference implementation is available at: [GitHub Repository URL] The implementation includes: - Generic bridge client for stdio-to-HTTP conversion - Server-side header extraction and environment application - Security filtering and session isolation - Working examples with SQL and WebSearch MCP servers ## Conclusion Configuration headers provide a clean, standardized solution for client-specific configuration in remote MCP deployments. This extension: - Maintains backward compatibility - Enables flexible deployment patterns - Provides security through proper scoping - Offers a path for stdio clients to use remote servers We propose this as an optional extension to the MCP Streamable HTTP transport specification. --- ## References - [MCP Specification 2025-03-26](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports) - [HTTP Header Field Definitions (RFC 7231)](https://tools.ietf.org/html/rfc7231#section-5) - [Reference Implementation](https://github.com/your-repo/mcp-configuration-headers)