Skip to content

Support dynamic environment variable injection in mcpgateway.translate for STDIO MCP servers #964

@crivetimihai

Description

@crivetimihai

Header Passthrough for STDIO MCP Servers

Research Summary

Current State

mcpgateway.translate supports OAuth2 Bearer tokens for outbound connections (when acting as a client), but does not support dynamic environment variable injection from incoming request headers when exposing STDIO MCP servers.

Key Findings

  1. Existing OAuth2 Support: mcpgateway.translate already accepts --oauth2Bearer for outbound client connections
  2. STDIO Process Creation: All subprocess creation uses asyncio.create_subprocess_exec() without custom environment variables
  3. Header Passthrough Infrastructure: Exists in main gateway but not integrated with translate module
  4. No Dynamic Environment Injection: STDIO processes inherit the parent process environment only

Architecture Gap

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│ Client Request  │───▶│ mcpgateway       │───▶│ STDIO MCP       │
│ Authorization:  │    │ .translate       │    │ Server          │
│ Bearer <token>  │    │                  │    │ (needs env var) │
└─────────────────┘    └──────────────────┘    └─────────────────┘
                              │
                              ▼
                    ❌ Headers NOT converted
                       to environment variables

Code Locations

  • STDIO Process Creation: mcpgateway/translate.py:369-374, 1037-1042, 1245-1250, 1439-1444
  • Header Handling: Only for outbound client connections (oauth2_bearer parameter)
  • Environment Variables: Not supported - all use shlex.split(cmd) without env parameter

Proposed Solution

Feature Request: Dynamic Environment Variable Injection

Title: Support dynamic environment variable injection in mcpgateway.translate for STDIO MCP servers

Description:
Enable mcpgateway.translate to extract headers from incoming HTTP requests and inject them as environment variables when starting STDIO MCP processes. This would allow secure token passthrough for services like GitHub Enterprise MCP servers.

Use Case: GitHub Enterprise MCP

Scenario:

  • Self-hosted GitHub Enterprise with MCP server requiring Personal Access Token (PAT)
  • Multiple users with different PATs
  • Need to pass user's PAT from request header to MCP server environment

Current Limitation:

# This works for static tokens only
export GITHUB_TOKEN=static-token
python3 -m mcpgateway.translate --stdio "uvx mcp-server-github" --port 9000

Desired Functionality:

# Dynamic token injection from request headers
python3 -m mcpgateway.translate \
  --stdio "uvx mcp-server-github" \
  --port 9000 \
  --header-to-env "Authorization=GITHUB_TOKEN" \
  --header-to-env "X-GitHub-Enterprise-Host=GITHUB_HOST"

Implementation Requirements

  1. New CLI Arguments:

    • --header-to-env HEADER=ENV_VAR: Map request header to environment variable
    • --enable-dynamic-env: Safety flag to enable the feature
  2. Modified STDIO Process Creation:

    • Extract headers from incoming requests
    • Build custom environment with mapped variables
    • Pass to asyncio.create_subprocess_exec(env=custom_env)
  3. Security Considerations:

    • Whitelist allowed headers (no arbitrary header injection)
    • Sanitize header values (prevent injection attacks)
    • Log security events
  4. Integration Points:

    • Modify StdIOEndpoint.start() to accept environment variables
    • Update FastAPI endpoints to extract and forward headers
    • Integrate with existing OAuth2 bearer token support

Code Changes Required

  1. StdIOEndpoint Class (mcpgateway/translate.py:298-460):

    async def start(self, env_vars: Optional[Dict[str, str]] = None) -> None:
        env = os.environ.copy()
        if env_vars:
            env.update(env_vars)
        
        self._proc = await asyncio.create_subprocess_exec(
            *shlex.split(self._cmd),
            stdin=asyncio.subprocess.PIPE,
            stdout=asyncio.subprocess.PIPE, 
            stderr=sys.stderr,
            env=env  # 🔑 Add environment variable support
        )
  2. FastAPI Request Handlers:

    • Extract configured headers from requests
    • Pass to STDIO endpoint as environment variables
    • Log header extraction for debugging
  3. CLI Argument Parsing (mcpgateway/translate.py:740-906):

    • Add --header-to-env and --enable-dynamic-env options
    • Validate header-to-environment mappings

Benefits

  1. Multi-tenant Support: Different users can use different tokens
  2. Security: Tokens don't need to be stored in process environment
  3. Flexibility: Works with any STDIO MCP server requiring environment variables
  4. Integration: Seamless with existing gateway passthrough headers

Priority: Medium-High

This enables important enterprise use cases and improves the multi-tenant capabilities of the MCP Gateway ecosystem.


Labels: enhancement, translate, stdio, security, enterprise
Milestone: Next minor release

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions