Shared MCP Gateway
Shared MCP Gateway
Unifies multiple shared MCP servers into a single HTTP gateway, providing a stable, observable, and reusable MCP access layer for clients such as Codex, OpenCode, Claude Code, and OpenClaw.
Problems Solved
In scenarios where multiple clients and multiple MCP servers are used in parallel, you typically encounter these issues:
Each client requires maintaining its own set of MCP configurations, leading to redundant work.
Inconsistent configurations for the same toolchain across different clients, often resulting in "it works in this client but not that one."
When a downstream MCP server fails, troubleshooting is difficult due to fragmented entry points, making unified logging, self-checks, and circuit breaking hard to implement.
Adding or replacing an MCP server requires updating multiple configuration files, resulting in high change costs.
shared-mcp-gateway aims to centralize these shared capabilities:
Single Registry Maintenance: Manage downstream MCPs centrally via
registry.toml/registry.compose.toml.Single Exposure Point: Aggregate multiple downstream services through a single HTTP MCP endpoint.
Single Governance Point: Unified health checks, structured logging, failure isolation, and circuit breaking.
Single Configuration Generation: Automatically generate access configuration snippets for Codex / OpenCode / OpenClaw.
Related MCP server: MCPHubs
Capabilities
The project currently supports:
Aggregating multiple stdio-based downstream MCP servers.
Exposing downstream tools uniformly using the
namespace.tool_nameformat.Automatically tagging requests with a
calleridentifier for different clients to facilitate log tracing.Providing a
/healthzhealth check interface to view connected services, failed services, and circuit breaker status.Providing structured
logfmtlogs for easy retrieval via systems like grep, CLS, or Loki.Implementing minimal isolation when downstream services fail, preventing a single MCP server crash from affecting the overall experience.
Generating client configuration files:
Codex:
generated/codex-mcp.tomlOpenCode:
generated/opencode-mcp.jsoncOpenClaw:
generated/openclaw-mcp.json
Connectivity, self-check tools, and critical capability probing via
scripts/self_check.py.
Use Cases
Suitable for the following scenarios:
The same set of MCP capabilities needs to be reused by multiple AI clients.
You want to govern "shared capabilities" and "host-specific local capabilities" in separate layers.
You want unified logging, self-checks, health checks, and fault isolation.
You want to update only one registry configuration when adding a new shared MCP.
Project Structure
shared-mcp-gateway/
├── Dockerfile # 网关镜像构建文件
├── docker-compose.yml # 当前本地落地用 Compose 编排
├── registry.toml # 宿主机直跑配置
├── registry.compose.toml # 容器内运行配置
├── requirements.txt # Python 依赖
├── docs/
│ └── mcp-topology.md # 哪些 MCP 进入网关、哪些保留本地特例
├── generated/ # 自动生成的客户端配置文件
├── templates/ # 可复制的配置模板
│ ├── docker-compose.template.yml # Compose 配置模板
│ ├── registry.compose.template.toml # 容器内注册表模板
│ └── registry.template.toml # 宿主机注册表模板
├── scripts/
│ ├── render_client_configs.py # 生成客户端配置片段
│ └── self_check.py # 健康检查与关键工具自检
├── shared_mcp_gateway/
│ ├── config.py # 注册表解析
│ ├── gateway.py # HTTP MCP 聚合网关主程序
│ ├── logging_utils.py # 结构化日志输出
│ ├── render.py # 客户端配置渲染
│ └── stdio_bridge.py # stdio 客户端到 HTTP MCP 的桥接Core Workflow
flowchart LR
A["Codex / OpenCode / OpenClaw"] --> B["stdio_bridge / HTTP Client"]
B --> C["Shared MCP Gateway"]
C --> D["mempalace"]
C --> E["mysql-db"]
C --> F["obsidian-kb"]
C --> G["tencent-cls"]Request Flow
Once an MCP request enters the shared gateway, the critical path is as follows:
The client accesses the shared gateway via
stdio_bridge.pyor directly via HTTP.RequestLoggingMiddlewareinjectscaller,request_id, and access log context.SharedMcpGatewaylocates the target downstream based on tool name / resource URI / prompt name.If the corresponding downstream is circuit-broken, the request is rejected immediately to prevent continuous hits to an unhealthy service.
If forwarding is allowed, the request enters
DownstreamConnectionand accesses the downstream MCP serially via a single session lock.After the call completes, metrics, failure streaks, and circuit breakers are updated and synchronized to heartbeat / healthz.
Core module responsibilities are understood as follows:
shared_mcp_gateway/config.py: Registry parsing and strongly-typed configuration objects.shared_mcp_gateway/gateway.py: Unified indexing, request forwarding, circuit breaking/isolation, health checks, and heartbeat logging.shared_mcp_gateway/stdio_bridge.py: Provides an HTTP gateway bridge layer for clients that only support stdio.shared_mcp_gateway/render.py: Renders the unified registry into access configurations for different clients.scripts/self_check.py: Performs connectivity self-checks from both health interface and real MCP call dimensions.
Request Sequence Diagram
The following diagram is better suited for building a mental model while reading the code:
sequenceDiagram
participant Client as "MCP Client"
participant Bridge as "stdio_bridge / HTTP Client"
participant Middleware as "RequestLoggingMiddleware"
participant Gateway as "SharedMcpGateway"
participant Breaker as "CircuitBreaker"
participant Downstream as "DownstreamConnection"
participant Server as "Downstream MCP Server"
Client->>Bridge: 发起 list_tools / call_tool / read_resource
Bridge->>Middleware: HTTP 请求进入网关
Middleware->>Gateway: 注入 caller / request_id 后转发
Gateway->>Breaker: 检查目标下游是否允许访问
alt breaker open
Breaker-->>Gateway: reject
Gateway-->>Client: 快速失败 / 返回熔断提示
else breaker closed
Gateway->>Downstream: 按 namespace 路由请求
Downstream->>Server: 串行发起 MCP 调用
Server-->>Downstream: 返回结果或异常
Downstream-->>Gateway: 返回标准 MCP 响应
Gateway->>Gateway: 更新 metrics / failure streak / breaker
Gateway-->>Client: 返回聚合后的 MCP 响应
endCode Reading Suggestions
To quickly understand the main path, it is recommended to read in this order:
shared_mcp_gateway/config.py: Understand the registry structure first.shared_mcp_gateway/render.py: Understand how client access configurations are generated.shared_mcp_gateway/stdio_bridge.py: Understand how stdio clients connect to the HTTP gateway.shared_mcp_gateway/gateway.py: Focus onSharedMcpGateway,DownstreamConnection, andRequestLoggingMiddleware.scripts/self_check.py: Understand how to verify "interface liveness" and "real capability availability" after deployment.
Quick Start
1. Install Dependencies
cd /path/to/shared-mcp-gateway
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt2. Prepare Configuration
You can refer directly to the template files:
templates/registry.template.tomltemplates/registry.compose.template.tomltemplates/docker-compose.template.yml
The most common approach is:
cp templates/registry.template.toml registry.local.toml
cp templates/registry.compose.template.toml registry.compose.local.toml
cp templates/docker-compose.template.yml docker-compose.local.ymlThen replace the paths, ports, and downstream service commands in the templates with your actual environment.
3. Start Locally
python3 shared_mcp_gateway/gateway.py --registry registry.toml --log-level INFOAfter starting, access by default:
MCP endpoint:
http://127.0.0.1:8787/mcpHealth check:
http://127.0.0.1:8787/healthz
4. Start with Docker Compose
docker compose up -d --build
docker compose ps
curl http://127.0.0.1:8787/healthzStop:
docker compose downHow to Configure: Core Configuration
The project's core configuration file is registry.toml, which mainly contains five parts:
1. Listener Configuration
[listen]
host = "127.0.0.1"
port = 8787
path = "/mcp"Meaning:
host: Gateway listening addressport: Gateway listening portpath: MCP HTTP path
2. Gateway Metadata
[gateway]
name = "shared-gateway"
namespace_separator = "."
description = "Shared MCP gateway for Codex, OpenCode and OpenClaw."Meaning:
name: Name of the gateway exposed externallynamespace_separator: Namespace separator, usually.by defaultdescription: Gateway description
3. Downstream MCP Server Configuration
[[servers]]
key = "mysql-db"
enabled = true
namespace = "mysql_db"
command = "/bin/bash"
args = ["-lc", "cd /opt/mcps/mysql-connector && ./.venv/bin/python server.py"]Meaning:
key: Unique identifier for the downstream serviceenabled: Whether it is enablednamespace: Tool name prefix namespacecommand: Startup commandargs: Startup argumentsenv: Optional, inject environment variables specifically for this service
4. Local Exception Notes
[local_exceptions.openclaw]
keep_local = ["openspace"]
reason = "OpenSpace 强依赖宿主上下文,保留本地直连。"
endpoint = "http://127.0.0.1:8081/mcp"Used to record which capabilities do not go through the shared gateway but remain as local direct connections.
5. Client Configuration Path Metadata (Optional)
[clients.codex]
config_path = "~/.codex/config.toml"Meaning:
clients.*is mainly used to record the location of target client configuration files.The current project does not automatically write back to these paths by default.
It is recommended to run
scripts/render_client_configs.pyfirst, then copy the generated results into the corresponding client configurations.
How to Configure: Examples
Example 1: Host-based Configuration
Below is a minimal example you can refer to directly:
[listen]
host = "127.0.0.1"
port = 8787
path = "/mcp"
[gateway]
name = "shared-gateway"
namespace_separator = "."
description = "Shared MCP gateway for local development."
[[servers]]
key = "mempalace"
enabled = true
namespace = "mempalace"
command = "/opt/mempalace/.venv/bin/python"
args = ["-m", "mempalace.mcp_server"]
env = { PYTHONPATH = "/opt/mempalace" }
[[servers]]
key = "mysql-db"
enabled = true
namespace = "mysql_db"
command = "/bin/bash"
args = ["-lc", "cd /opt/mcps/mysql-connector && ./.venv/bin/python server.py"]
[local_exceptions.shared_gateway]
managed = ["mempalace", "mysql_db"]
reason = "共享能力统一由 shared-gateway 纳管。"Example 2: Docker Compose Configuration Strategy
If you want to run the gateway uniformly within a container, you can refer to the following strategy:
services:
shared-mcp-gateway:
build:
context: .
dockerfile: Dockerfile
container_name: shared-mcp-gateway
restart: unless-stopped
ports:
- "127.0.0.1:8787:8787"
environment:
OBSIDIAN_VAULT_PATH: /workspace/openclaw-workspace
PYTHONPATH: /workspace/mempalace
volumes:
- /opt/mcps:/workspace/mcps:ro
- /opt/mempalace:/workspace/mempalace:ro
- /opt/openclaw-workspace:/workspace/openclaw-workspace:rw
- /opt/mempalace-data:/root/.mempalace:rwSuitable for:
Mounting multiple MCP runtime dependencies into the same container context.
Ensuring downstream code directories are stable via read-only mounts.
Using
registry.compose.tomlinside the container uniformly.
Configuration Template Files
To facilitate direct implementation, the project includes copyable template files:
1. Registry Template
File: templates/registry.template.toml
Purpose:
When initializing a new environment, copy and modify the paths.
Suitable as a starting configuration for running directly on the host.
Retains the complete structure of
listen,gateway,servers,clients, andlocal_exceptions.
Recommended usage:
cp templates/registry.template.toml registry.local.toml2. In-Container Registry Template
File: templates/registry.compose.template.toml
Purpose:
Provides a registry template with container-internal paths for Docker / Compose scenarios.
Avoids accidentally bringing host absolute paths into container configurations.
Suitable as a copyable starting point for
registry.compose.toml.
Recommended usage:
cp templates/registry.compose.template.toml registry.compose.local.toml3. Compose Template
File: templates/docker-compose.template.yml
Purpose:
Quickly prepare Compose orchestration for new machines or environments.
Avoids modifying
docker-compose.ymlfiles dedicated to production or current machines.Facilitates changing mount paths and environment variables to your team's standards.
Recommended usage:
cp templates/docker-compose.template.yml docker-compose.local.ymlClient Access Examples
Recommended access process:
Start the shared-gateway first and confirm
http://127.0.0.1:8787/healthzis normal.Execute
python3 scripts/render_client_configs.pyto generate client configuration snippets for the current environment.Prioritize copying the actual artifacts in the
generated/directory; do not hand-write environment-related paths.
Codex Access Example
It is recommended to use generated/codex-mcp.toml directly. Its structure is roughly as follows:
[mcp_servers.shared-gateway]
command = "/bin/bash"
args = ["-lc", "python3 /absolute/path/to/shared_mcp_gateway/stdio_bridge.py --url http://127.0.0.1:8787/mcp --caller codex"]
enabled = trueOpenCode Access Example
It is recommended to use generated/opencode-mcp.jsonc directly. Its structure is roughly as follows:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"shared-gateway": {
"type": "local",
"enabled": true,
"command": [
"/bin/bash",
"-lc",
"python3 /absolute/path/to/shared_mcp_gateway/stdio_bridge.py --url http://127.0.0.1:8787/mcp --caller opencode"
]
}
}
}OpenClaw Access Example
OpenClaw can use HTTP MCP directly; it is recommended to use generated/openclaw-mcp.json directly:
{
"mcpServers": {
"shared-gateway": {
"url": "http://127.0.0.1:8787/mcp",
"transport": "streamable-http",
"connectionTimeoutMs": 10000,
"disabled": false
}
}
}Claude Code Access Strategy
The current project supports injecting caller identifiers into claude-code via stdio_bridge.py. The core idea is to use the bridge as a local stdio MCP command:
python3 /absolute/path/to/shared_mcp_gateway/stdio_bridge.py --url http://127.0.0.1:8787/mcp --caller claude-codeIf your client configuration system allows custom stdio MCP commands, you can reuse this bridge command directly.
Configuration Implementation Suggestions
To reduce environmental issues, it is recommended to implement in the following order:
Copy template files first; do not modify existing examples in the project directly.
Ensure each downstream MCP server can start independently.
Write downstream services into
registry.tomlorregistry.compose.tomlone by one.After starting the gateway, check
/healthzfirst, then executescripts/self_check.py.Finally, execute
scripts/render_client_configs.pyto synchronize client access configurations.
It is recommended to distinguish between three types of files:
registry.toml: Host-based configurationregistry.compose.toml: In-container configurationtemplates/*.template.*: New environment initialization templates
Common Commands
Generate Client Configurations
python3 scripts/render_client_configs.pyThis script will:
Read
registry.tomlUniformly generate configuration snippets for Codex / OpenCode / OpenClaw
Avoid configuration drift when manually copying bridge startup commands
Generated results are located in:
generated/codex-mcp.tomlgenerated/opencode-mcp.jsoncgenerated/openclaw-mcp.json
Execute Health Checks
python3 scripts/self_check.py
python3 scripts/self_check.py --jsonBy default, two types of checks are performed:
healthz: Checks if the gateway is exposed normally, if downstream services are missing, and if the circuit breaker is open.gateway_tools: Connects to the gateway as an MCP client, checks if critical tools exist, and performs side-effect-free probing.
View Logs
docker compose logs -f shared-mcp-gatewayCurrently Connected Shared MCPs
mempalacemysql-dbobsidian-kbtencent-cls
See /path/to/shared-mcp-gateway/docs/mcp-topology.md for topology details.
Future Suggestions
If you want to continue expanding this project, it is recommended to proceed in the following order:
Add a new
[[servers]]inregistry.toml.Verify locally if the MCP can start independently.
Check
/healthzafter starting the gateway.Run
scripts/self_check.pyto see if critical capabilities are normal.Re-execute
scripts/render_client_configs.pyto synchronize client configurations.
If you are currently adding documentation, templates, or default configurations to this project, prioritize maintaining:
README.mdtemplates/registry.template.tomltemplates/registry.compose.template.tomltemplates/docker-compose.template.ymldocs/mcp-topology.md
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
- AlicenseNot gradedqualityNot gradedmaintenanceA unified gateway and dashboard that aggregates multiple MCP servers into a single endpoint for streamlined management by AI clients. It features a centralized YAML configuration, a web-based monitoring dashboard, and hot-reload support for managing filesystem, GitHub, and database tools.
- AlicenseNot gradedqualityCmaintenanceA unified gateway and web dashboard that aggregates multiple MCP servers into a single Streamable HTTP endpoint. It supports stdio, SSE, and HTTP protocols, featuring optimized tool exposure modes to reduce token consumption for AI clients.5MIT
- AlicenseNot gradedqualityDmaintenanceMCPGate aggregates multiple MCP servers into a single unified endpoint, enabling centralized tool management with granular filtering, automatic namespacing, and observability. Features a real-time web dashboard and optional PostgreSQL-backed audit trails for monitoring and controlling AI tool access across local and remote deployments.17Apache 2.0
- AlicenseNot gradedqualityCmaintenanceA universal MCP server that acts as a unified gateway for dynamically connecting and managing multiple MCP servers via a single HTTP endpoint.106MIT
Related MCP Connectors
MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration
Hosted MCP server for LLM cost estimation, model comparison, and budget-aware routing.
Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.
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/xfn-jjw/shared-mcp-gateway'
If you have feedback or need assistance with the MCP directory API, please join our Discord server