Skip to main content

Merge multiple instances of the same MCP server across environments into a single endpoint with a unified env parameter.

Project description

mcp-env-mux

Merge multiple instances of the same MCP server across environments into a single endpoint with a unified env parameter.

Problem

When you connect the same MCP server (e.g., Coralogix, Datadog) from multiple environments (prod, staging, dev), each instance exposes identical tool definitions. Your MCP client sees every tool duplicated per environment, wasting context window tokens and creating a confusing tool list.

Solution

mcp-env-mux sits in front of your MCP backends as a proxy. It discovers tools from each backend, merges identical definitions into a single tool with an injected env parameter, and routes calls to the correct backend based on the caller's env selection. One tool instead of N copies.

Quick Start

# Install
pip install -e .

# Set your API keys as environment variables
export BACKEND_PROD_API_KEY="your-prod-key"
export BACKEND_STAGING_API_KEY="your-staging-key"

# Create a config file (see Configuration below)

# Validate your config and check for schema mismatches
mcp-env-mux --config config.json --test-schema

# Start the proxy
mcp-env-mux --config config.json

Configuration

The config file is JSON with a single environments object. Each key is an environment name, and each value specifies the backend URL, a description, and optional HTTP headers.

Header values support $VAR substitution -- any value matching $SOME_NAME is resolved from the OS environment at startup.

{
  "environments": {
    "Prod": {
      "description": "Production environment",
      "url": "https://api.example.com/mcp",
      "headers": {
        "Authorization": "$PROD_API_KEY"
      }
    },
    "Staging": {
      "description": "Staging environment",
      "url": "https://api-staging.example.com/mcp",
      "headers": {
        "Authorization": "$STAGING_API_KEY"
      }
    }
  }
}

Fields:

  • url (required) -- The MCP backend's HTTP endpoint.
  • description (required) -- Human-readable label shown in the merged tool's env parameter description.
  • headers (optional) -- HTTP headers sent to this backend. Use $ENV_VAR for secrets.

How It Works

  1. Discovery -- Connects to each backend and calls list_tools() to collect tool definitions.
  2. Merge -- Groups tools by name across environments. For each group:
    • Descriptions must match across environments (mismatch is an error).
    • Parameter types must match (mismatch is an error).
    • Tools available in only a subset of environments get a constrained env enum.
    • Extra parameters present in some environments but not others are included as optional, with warnings.
  3. Proxy -- Builds a FastMCP server with one handler per merged tool. Each handler extracts the env argument, strips parameters not supported by the target backend, and forwards the call.

CLI Reference

mcp-env-mux [OPTIONS]
Flag Default Description
--config PATH (required) Path to the JSON configuration file.
--host HOST 0.0.0.0 Host to bind the proxy server to.
--port PORT 8080 Port to bind the proxy server to.
--test-schema off Validate config and tool schemas, print diagnostics, then exit.

Schema Validation (CI Mode)

Use --test-schema to check for configuration errors and tool schema mismatches without starting the server. This connects to all backends, runs the merge, and reports errors and warnings to stdout.

mcp-env-mux --config config.json --test-schema

Exit code 0 means all tools merged cleanly. Exit code 1 means there are merge errors (description or type mismatches). Integrate this into your CI pipeline to catch schema drift between environments.

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run all tests
pytest tests/ -v --timeout=120

# Run unit tests only
pytest tests/ -v --ignore=tests/test_e2e.py

# Run E2E tests only (starts real backends and proxy subprocesses)
pytest tests/test_e2e.py -v --timeout=120

Requires Python >= 3.11.

Architecture

The package is organized into five modules under src/mcp_env_mux/: cli, config, discovery, merge, and proxy. The data flow is linear: CLI parses args, config is loaded, backends are discovered, schemas are merged, and the proxy server is built and started.

For detailed module documentation, see src/mcp_env_mux/mcp_env_mux_docs.md. For test documentation and coverage mapping, see tests/tests_docs.md.

Project Structure

mcp-env-mux/
  pyproject.toml                       -- Package metadata, dependencies, CLI entrypoint
  config.json                          -- Example configuration file
  src/mcp_env_mux/
    __init__.py                        -- Package init
    cli.py                             -- CLI entrypoint and startup orchestration
    config.py                          -- Config loading, validation, env var resolution
    discovery.py                       -- Backend connection and tool discovery
    merge.py                           -- Schema diffing and tool merging
    proxy.py                           -- FastMCP server construction and call routing
    mcp_env_mux_docs.md               -- Detailed package documentation
  tests/
    conftest.py                        -- Shared fixtures: mock backends, proxy lifecycle
    test_config.py                     -- Unit tests for config loading and env var substitution
    test_merge.py                      -- Unit tests for schema merging logic
    test_proxy.py                      -- Unit tests for call routing and parameter stripping
    test_e2e.py                        -- End-to-end tests with real backends and proxy
    tests_docs.md                      -- Test suite documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_env_mux-0.2.0.tar.gz (120.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_env_mux-0.2.0-py3-none-any.whl (28.0 kB view details)

Uploaded Python 3

File details

Details for the file mcp_env_mux-0.2.0.tar.gz.

File metadata

  • Download URL: mcp_env_mux-0.2.0.tar.gz
  • Upload date:
  • Size: 120.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mcp_env_mux-0.2.0.tar.gz
Algorithm Hash digest
SHA256 dfeec8f26455c5cb7dc358bd6d275343d966a89904f1e3c31fe501c8e514f54c
MD5 bbe12cfafbee786472f861ebe5328bc4
BLAKE2b-256 b0404fbdf69c970208099305234946657f547551cdc118b70ddd707bf07ca2a8

See more details on using hashes here.

File details

Details for the file mcp_env_mux-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mcp_env_mux-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 28.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.8 {"installer":{"name":"uv","version":"0.10.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mcp_env_mux-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56d35c6cf4386cb7059af63054bdb80653229d7b9e4ae5ff596c3ef50b9b5e6a
MD5 59d609abc3a2e9d62c7bb5531c96d34b
BLAKE2b-256 66e97ff267b2c850b14a2a8082135c88ceedab43df3186fc8a08271d5fea841a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page