Skip to main content
Glama
xfn-jjw

Shared MCP Gateway

by xfn-jjw

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_name format.

  • Automatically tagging requests with a caller identifier for different clients to facilitate log tracing.

  • Providing a /healthz health check interface to view connected services, failed services, and circuit breaker status.

  • Providing structured logfmt logs 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.toml

    • OpenCode: generated/opencode-mcp.jsonc

    • OpenClaw: 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:

  1. The client accesses the shared gateway via stdio_bridge.py or directly via HTTP.

  2. RequestLoggingMiddleware injects caller, request_id, and access log context.

  3. SharedMcpGateway locates the target downstream based on tool name / resource URI / prompt name.

  4. If the corresponding downstream is circuit-broken, the request is rejected immediately to prevent continuous hits to an unhealthy service.

  5. If forwarding is allowed, the request enters DownstreamConnection and accesses the downstream MCP serially via a single session lock.

  6. 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 响应
    end

Code Reading Suggestions

To quickly understand the main path, it is recommended to read in this order:

  1. shared_mcp_gateway/config.py: Understand the registry structure first.

  2. shared_mcp_gateway/render.py: Understand how client access configurations are generated.

  3. shared_mcp_gateway/stdio_bridge.py: Understand how stdio clients connect to the HTTP gateway.

  4. shared_mcp_gateway/gateway.py: Focus on SharedMcpGateway, DownstreamConnection, and RequestLoggingMiddleware.

  5. 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.txt

2. Prepare Configuration

You can refer directly to the template files:

  • templates/registry.template.toml

  • templates/registry.compose.template.toml

  • templates/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.yml

Then 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 INFO

After starting, access by default:

  • MCP endpoint: http://127.0.0.1:8787/mcp

  • Health 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/healthz

Stop:

docker compose down

How 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 address

  • port: Gateway listening port

  • path: 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 externally

  • namespace_separator: Namespace separator, usually . by default

  • description: 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 service

  • enabled: Whether it is enabled

  • namespace: Tool name prefix namespace

  • command: Startup command

  • args: Startup arguments

  • env: 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.py first, 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:rw

Suitable for:

  • Mounting multiple MCP runtime dependencies into the same container context.

  • Ensuring downstream code directories are stable via read-only mounts.

  • Using registry.compose.toml inside 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, and local_exceptions.

Recommended usage:

cp templates/registry.template.toml registry.local.toml

2. 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.toml

3. Compose Template

File: templates/docker-compose.template.yml

Purpose:

  • Quickly prepare Compose orchestration for new machines or environments.

  • Avoids modifying docker-compose.yml files 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.yml

Client Access Examples

Recommended access process:

  1. Start the shared-gateway first and confirm http://127.0.0.1:8787/healthz is normal.

  2. Execute python3 scripts/render_client_configs.py to generate client configuration snippets for the current environment.

  3. 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 = true

OpenCode 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-code

If 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:

  1. Copy template files first; do not modify existing examples in the project directly.

  2. Ensure each downstream MCP server can start independently.

  3. Write downstream services into registry.toml or registry.compose.toml one by one.

  4. After starting the gateway, check /healthz first, then execute scripts/self_check.py.

  5. Finally, execute scripts/render_client_configs.py to synchronize client access configurations.

It is recommended to distinguish between three types of files:

  • registry.toml: Host-based configuration

  • registry.compose.toml: In-container configuration

  • templates/*.template.*: New environment initialization templates

Common Commands

Generate Client Configurations

python3 scripts/render_client_configs.py

This script will:

  • Read registry.toml

  • Uniformly generate configuration snippets for Codex / OpenCode / OpenClaw

  • Avoid configuration drift when manually copying bridge startup commands

Generated results are located in:

  • generated/codex-mcp.toml

  • generated/opencode-mcp.jsonc

  • generated/openclaw-mcp.json

Execute Health Checks

python3 scripts/self_check.py
python3 scripts/self_check.py --json

By 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-gateway

Currently Connected Shared MCPs

  • mempalace

  • mysql-db

  • obsidian-kb

  • tencent-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:

  1. Add a new [[servers]] in registry.toml.

  2. Verify locally if the MCP can start independently.

  3. Check /healthz after starting the gateway.

  4. Run scripts/self_check.py to see if critical capabilities are normal.

  5. Re-execute scripts/render_client_configs.py to synchronize client configurations.


If you are currently adding documentation, templates, or default configurations to this project, prioritize maintaining:

  • README.md

  • templates/registry.template.toml

  • templates/registry.compose.template.toml

  • templates/docker-compose.template.yml

  • docs/mcp-topology.md

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    A 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.
  • A
    license
    Not graded
    quality
    C
    maintenance
    A 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.
    5
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCPGate 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.
    17
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    A universal MCP server that acts as a unified gateway for dynamically connecting and managing multiple MCP servers via a single HTTP endpoint.
    10
    6
    MIT

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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