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
Markdown
# 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)