mcp-mux
Allows routing to a GitHub CLI MCP server for GitHub integration and repository management.
Allows routing to a web search MCP server providing Google Search and content extraction tools.
Allows routing to a Hugging Face MCP server providing model search, hub browsing, and model download capabilities.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-muxSearch the web for 'MCP server orchestration'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
๐ MCP Mux
Dynamic Multi-Endpoint Python Model Context Protocol (MCP) Router & Orchestrator
mcp-mux is a dynamic MCP server orchestrator and multiplexer. It acts as a central proxy to multiple remote and local sub-MCP servers, monitoring a config.yaml file to hot-reload endpoints live without server restarts. It supports Server-Sent Events (SSE) and Streamable HTTP backend transports, including a local SSE bridge for clients that need an SSE endpoint while the upstream server speaks Streamable HTTP. It also provides a lightweight /summary endpoint to minimize context token flooding for AI agents.
๐ Key Features
๐ Dynamic Hot-Reloading: Reloads endpoint configuration in place and uses one shared filesystem observer to invalidate only managed backends whose watched source trees changed.
๐ Flexible Sub-Server Modes:
Remote: Seamless proxying to external HTTP MCP endpoints.
Managed CLI: Native spawning of command-line tools (e.g., via
npxoruvx).
๐งฉ Configurable Request Headers: Adds endpoint-specific upstream headers, including tokens loaded from environment variables.
๐ Optional Local SSE-to-Streamable-HTTP Bridge: Streamable HTTP endpoints are proxied as Streamable HTTP by default. Endpoints can opt into a legacy SSE compatibility bridge when traditional SSE clients need a local
event: endpointflow.โก Automatic Transport Auto-Detection: Dynamically detects the backend transport mode (
streamable-httpvssse) based on URL paths. Sub-servers with/mcpor/mcp/in their URL automatically default tostreamable-http.๐ก๏ธ Session Propagation & Isolation: For opt-in legacy bridge sessions, tracks local sessions per endpoint, maps upstream
Mcp-Session-Idvalues to the correct local session, and rejects cross-endpoint session reuse.๐ค Streamable HTTP Client Compatibility: Normalizes upstream
Acceptheaders for Streamable HTTP POST/DELETE requests and fills in missing JSON-RPC"jsonrpc": "2.0"fields for request bodies that otherwise look like JSON-RPC messages.๐งผ Decoded Response Header Safety: Strips stale
Content-Encodingand upstreamContent-Lengthheaders when the router reads and rebuilds JSON responses.๐ Token-Saving Metadata Endpoint: Registers a custom
/summaryroute returning only namespaces and descriptions, shielding AI clients from schema bloat.๐งน Clean Subprocess Lifecycle: The manager isolates background subprocesses inside unique Unix process groups (
os.setsid) to guarantee no zombie processes are left behind on teardown.
Related MCP server: MCP Hub
๐ Architecture
graph TD
A[main.py - Uvicorn/Starlette Server] --> B[config_loader.py - ConfigWatcher]
B -->|Watches & Parses| C[config.yaml]
A --> J[source_watcher.py - Shared Observer]
J -->|Debounce and invalidate| E
A --> D[process_manager.py - ProcessManager]
D -->|Spawns / Cleans up| E[Managed Subprocesses: uvx / npx]
A --> F[server.py - MCPRouter]
F -->|Proxy SSE| G[Remote SSE Servers]
F -->|Proxy Streamable HTTP & map sessions| H[Streamable HTTP Servers]
A --> I[summary route]โ๏ธ Configuration (config.yaml)
Define your endpoints in mcp_router/config.yaml. Here is an example layout:
endpoints:
- path: "web-search"
mode: "remote"
url: "https://mcp.garion.us/mcp"
summary: "Google Search and content extraction tool"
# transport: "streamable-http" (Automatically detected due to /mcp path suffix)
allowed_tools:
- "google_search"
- "batch_extract_urls"
- path: "firecrawl"
mode: "managed_cli"
command: "export NVM_DIR=$HOME/.config/nvm && [ -s $NVM_DIR/nvm.sh ] && . $NVM_DIR/nvm.sh && HTTP_STREAMABLE_SERVER=true PORT=3033 HOST=localhost FIRECRAWL_API_URL=http://garion.us:3002 npx --yes firecrawl-mcp"
url: "http://localhost:3033/mcp"
summary: "Firecrawl Web Content Extraction Tool"
timeout: 300 # Automatically shuts down after 300 seconds of inactivity
watch:
paths:
- "/absolute/path/to/firecrawl-mcp/src"
debounce_ms: 400
allowed_tools:
- "firecrawl_search"
- "firecrawl_scrape"
- path: "huggingface"
mode: "remote"
url: "https://huggingface.co/mcp"
summary: "HuggingFace MCP Server โ model search, hub browsing, model download"
headers:
Authorization: "Bearer ${HF_TOKEN:-}"Environment Variable Expansion
Configuration values support shell-style environment references before validation:
${NAME}expands to the required environment variableNAMEand fails config loading if it is missing.${NAME:-fallback}expands toNAMEwhen set, otherwise tofallback.Empty
Authorization: "Bearer ${HF_TOKEN:-}"values are omitted, allowing endpoints such as Hugging Face to fall back to anonymous access.If
HF_TOKENis accidentally set toBearer hf_..., the loader normalizesBearer Bearer hf_...toBearer hf_....
Configuration Parameters
Parameter | Type | Required | Description |
| String | Yes | Unique namespace/route for the sub-server. |
| String | Yes | Spawning mode. |
| String | Yes (for remote/managed) | Target endpoint URL. |
| String | Yes (for managed) | Command string to spawn the local server process. |
| String | Yes | Brief description of the sub-server, returned by |
| Integer | No | Inactivity timeout in seconds for CLI mode (defaults to 300). |
| String | No | Transport mode ( |
| Boolean | No | For |
| Mapping | No | Extra request headers forwarded upstream after environment expansion. |
| List of Strings | No | Allowlist of tool names. Only these tools are exposed. |
| List of Strings | No | Denylist of tool names. These tools are excluded. (Ignored if |
| List of Strings | No | Absolute, existing source directories that invalidate this managed endpoint when files change. Managed CLI endpoints only. |
| Integer | No | Per-endpoint change coalescing window from 50 through 60,000 milliseconds. Defaults to 400. |
| List of Strings | No | Filename or relative-path glob patterns ignored by the watcher. Defaults to Python bytecode, editor swap/temporary files, and backup files. |
Managed Backend Source Invalidation
watch provides selective development-time reload behavior without restarting the
mux or unrelated backends:
endpoints:
- path: "gh"
mode: "managed_cli"
command: >-
cd /workspace/mcp_servers/gh_mcp &&
MCP_GH_TRANSPORT=streamable-http
MCP_GH_HTTP_PORT=8768
uv run mcp-gh
url: "http://localhost:8768/mcp"
summary: "GitHub CLI MCP server"
timeout: 300
transport: "streamable-http"
watch:
paths:
- "/workspace/mcp_servers/gh_mcp/src"
debounce_ms: 400The mux creates one watchdog Observer for all configured endpoints and schedules
each unique source directory only once. A file create, delete, modification, or
atomic move is mapped back to every endpoint that watches that path. Changes under
version-control metadata, virtual environments, dependency directories, and common
tool caches are always ignored. ignore_patterns provides additional
endpoint-specific exclusions.
Events are transferred from watchdog's thread to the mux event loop and coalesced per endpoint. When the debounce window expires, the mux:
acquires the endpoint's existing startup lock;
verifies that the current configuration still watches the endpoint;
discards its local bridge sessions and inactivity timestamp;
terminates its complete managed process group; and
leaves the endpoint stopped.
The next request follows the normal on-demand activation path and starts the backend from its revised source. An endpoint that was already stopped is not started merely because a file changed. Shared source directories may invalidate multiple explicitly configured endpoints, while unrelated managed and remote endpoints remain untouched.
Watch paths must be absolute, existing directories. Filesystem roots are rejected to
prevent accidentally monitoring an entire host. To include dependency manifests or
other files outside src, watch a suitably narrow common directory and add
ignore_patterns for generated content. Do not watch .venv, node_modules, build
output, logs, or other high-churn trees.
Invalidation intentionally interrupts active calls to the affected backend. Clients must retry or reinitialize according to the backend transport; stateless Streamable HTTP backends provide the cleanest behavior. This mechanism reloads backend code but does not force external clients such as ChatGPT to rediscover a cached MCP tool schema.
Streamable HTTP Bridge Behavior
For streamable-http endpoints, the mux preserves the original transport by default:
POST /<path>forwards JSON-RPC messages to the upstream MCP endpoint.GET /<path>withAccept: text/event-streamforwards to the upstream MCP endpoint and preserves the upstream response status and stream.
To expose the legacy local SSE bridge, set legacy_sse_bridge: true on that endpoint. SSE clients can then connect with:
curl -N -H 'Accept: text/event-stream' http://127.0.0.1:8012/huggingfaceThe first SSE event contains a local POST endpoint such as:
event: endpoint
data: /huggingface?session_id=<local-session-id>Client POSTs to that local URL are forwarded upstream. If the upstream returns Mcp-Session-Id, the router stores it on the local bridge session and forwards it on later POSTs for the same endpoint. Sessions are removed when the local SSE stream closes or when their endpoint is removed or changed during config reload.
๐ Getting Started
Prerequisites
Make sure you have uv installed.
1. Installation & Setup
Clone the repository and install all dependencies:
# Activate virtual environment
source .venv/bin/activate
# Install & sync dependencies
uv sync2. Running the Orchestrator
Start the main router server (default port is 8012):
export HF_TOKEN=hf_xxx # optional; omit for anonymous Hugging Face access
uv run python main.py --port 80123. Querying Endpoint Summary
You can check active routes and summaries by visiting:
curl http://127.0.0.1:8012/summary๐งช Testing
The project is fully tested using pytest and pytest-asyncio. To execute unit tests:
uv run pytestCurrent verification state: 35 passed.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceA powerful orchestration layer for Model Context Protocol (MCP) servers that enables AI assistants to dynamically discover, inspect, and interact with multiple MCP servers through a unified interface.Last updatedMIT
- Flicense-quality-maintenanceMCP Hub aggregates and proxies multiple Model Context Protocol servers into a unified Streamable HTTP interface. It allows users to combine diverse stdio, SSE, and HTTP-based servers while providing tool namespacing, health monitoring, and secure authentication.Last updated748
- Alicense-qualityCmaintenanceAn MCP server that functions as an intelligent gateway for multiple LLM backends including OpenAI, Claude, and Ollama. It supports automatic provider fallback, streaming responses via Server-Sent Events, and real-time monitoring for robust AI integration.Last updatedMIT
- Flicense-qualityDmaintenanceAn MCP server that routes LLM requests across multiple providers and orchestrates other MCP servers, with a focus on local privacy for embeddings and memory.Last updated3
Related MCP Connectors
Hosted MCP server for LLM cost estimation, model comparison, and budget-aware routing.
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Real-time chat hub for AI agents โ Claude Code, Cursor, Cline, Codex over MCP or REST.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/fvanevski/mcp-mux'
If you have feedback or need assistance with the MCP directory API, please join our Discord server