Shared MCP Gateway
Shared MCP Gateway
Unifica múltiples servidores MCP compartidos en una única puerta de enlace HTTP, proporcionando una capa de acceso MCP estable, observable y reutilizable para que clientes como Codex, OpenCode, Claude Code, OpenClaw, etc., puedan utilizarla conjuntamente.
¿Qué problemas resuelve este proyecto?
En escenarios donde se utilizan múltiples clientes y múltiples servidores MCP en paralelo, suelen surgir estos problemas:
Cada cliente debe mantener por separado un conjunto de configuraciones MCP, lo que genera trabajo repetitivo.
La configuración de la misma cadena de herramientas es inconsistente entre diferentes clientes, lo que facilita que ocurran situaciones donde "este cliente funciona, pero aquel no".
Una vez que un servidor MCP descendente presenta una anomalía, los puntos de entrada para la resolución de problemas están dispersos, lo que dificulta la unificación de registros, la autocomprobación y el manejo de disyuntores.
Al añadir o reemplazar un servidor MCP, es necesario modificar múltiples configuraciones, lo que conlleva un alto costo de cambio.
El objetivo de shared-mcp-gateway es gestionar de forma unificada estas capacidades compartidas:
Un solo lugar para mantener el registro: Mantenimiento unificado de los MCP descendentes a través de
registry.toml/registry.compose.toml.Un solo lugar para exponer capacidades: Agregación de múltiples servicios descendentes a través de un único punto final HTTP MCP.
Un solo lugar para la gobernanza operativa: Comprobaciones de estado unificadas, registros estructurados, aislamiento de fallos y disyuntores mínimos.
Un solo lugar para generar configuraciones de cliente: Producción automática de fragmentos de configuración de acceso para Codex / OpenCode / OpenClaw.
Related MCP server: MCPHubs
¿Qué puede hacer este proyecto?
El proyecto actual ya admite:
Agregación de múltiples servidores MCP descendentes basados en stdio.
Exposición unificada de herramientas descendentes mediante
namespace.tool_name.Etiquetado automático de
callerpara diferentes clientes, facilitando el seguimiento de registros.Interfaz de comprobación de estado
/healthzpara ver servicios conectados, servicios fallidos y estado del disyuntor.Registros estructurados en formato
logfmt, facilitando la búsqueda en sistemas como grep, CLS, Loki, etc.Aislamiento mínimo cuando un servidor descendente presenta anomalías, evitando que la caída de un solo servidor MCP afecte la experiencia general.
Generación de archivos de configuración de cliente:
Codex:
generated/codex-mcp.tomlOpenCode:
generated/opencode-mcp.jsoncOpenClaw:
generated/openclaw-mcp.json
Verificación de conectividad, herramientas de autocomprobación y sondeo de capacidades clave a través de
scripts/self_check.py.
Escenarios de aplicación
Adecuado para su uso directo en los siguientes escenarios:
La misma capacidad MCP necesita ser reutilizada por múltiples clientes de IA.
Se desea una gobernanza estratificada entre "capacidades compartidas" y "capacidades locales específicas del host".
Se desea unificar registros, autocomprobaciones, comprobaciones de estado y aislamiento de fallos.
Se desea modificar solo una configuración de registro al añadir un nuevo MCP compartido.
Estructura del proyecto
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 的桥接Modo de trabajo principal
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"]Explicación del flujo de ejecución
Una vez que una solicitud MCP ingresa a la puerta de enlace compartida, la ruta crítica es la siguiente:
El cliente accede a la puerta de enlace compartida a través de
stdio_bridge.pyo directamente mediante HTTP.RequestLoggingMiddlewareinyectacaller,request_idy el contexto de registro de acceso.SharedMcpGatewaylocaliza el destino descendente basándose en el nombre de la herramienta / URI del recurso / nombre del prompt.Si el destino correspondiente ha sido bloqueado por el disyuntor, la solicitud será rechazada rápidamente para evitar seguir impactando al servicio anómalo.
Si se permite el reenvío, la solicitud ingresa a
DownstreamConnection, accediendo al MCP descendente de forma serializada a través de un bloqueo de sesión única.Una vez completada la llamada, se actualizan las métricas, la racha de fallos y el disyuntor, sincronizándose con heartbeat / healthz.
Se sugiere entender las responsabilidades de los módulos principales de la siguiente manera:
shared_mcp_gateway/config.py: Análisis del registro y objeto de configuración fuertemente tipado.shared_mcp_gateway/gateway.py: Indexación unificada, reenvío de solicitudes, aislamiento por disyuntor, comprobación de estado, registros de latido.shared_mcp_gateway/stdio_bridge.py: Proporciona una capa de puente de puerta de enlace HTTP para clientes que solo admiten stdio.shared_mcp_gateway/render.py: Renderiza el registro unificado en configuraciones de acceso para diferentes clientes.scripts/self_check.py: Realiza autocomprobaciones de conectividad desde las dimensiones de la interfaz de estado y la llamada real al MCP.
Diagrama de secuencia de solicitudes
El siguiente diagrama es más adecuado para establecer un modelo mental general al leer el código:
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 响应
endSugerencias para la lectura del código
Si desea entender rápidamente la ruta principal, se recomienda leer en este orden:
shared_mcp_gateway/config.py: Primero entienda la estructura del registro.shared_mcp_gateway/render.py: Entienda cómo se genera la configuración de acceso del cliente.shared_mcp_gateway/stdio_bridge.py: Entienda cómo los clientes stdio se conectan a la puerta de enlace HTTP.shared_mcp_gateway/gateway.py: Concéntrese enSharedMcpGateway,DownstreamConnection,RequestLoggingMiddleware.scripts/self_check.py: Entienda cómo verificar que "la interfaz está viva" y "la capacidad real está disponible" después de la puesta en línea.
Inicio rápido
1. Instalar dependencias
cd /path/to/shared-mcp-gateway
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt2. Preparar la configuración
Puede consultar directamente los archivos de plantilla:
templates/registry.template.tomltemplates/registry.compose.template.tomltemplates/docker-compose.template.yml
La práctica más común es:
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.ymlLuego, reemplace las rutas, puertos y comandos de servicio descendentes en la plantilla con su entorno real.
3. Iniciar localmente
python3 shared_mcp_gateway/gateway.py --registry registry.toml --log-level INFODespués de iniciar, acceda por defecto a:
Punto final MCP:
http://127.0.0.1:8787/mcpComprobación de estado:
http://127.0.0.1:8787/healthz
4. Iniciar con Docker Compose
docker compose up -d --build
docker compose ps
curl http://127.0.0.1:8787/healthzDetener:
docker compose downCómo configurar: Descripción de la configuración principal
El archivo de configuración principal del proyecto es registry.toml, que contiene principalmente cinco partes:
1. Configuración de escucha
[listen]
host = "127.0.0.1"
port = 8787
path = "/mcp"Significado:
host: Dirección de escucha de la puerta de enlaceport: Puerto de escucha de la puerta de enlacepath: Ruta HTTP de MCP
2. Metainformación de la puerta de enlace
[gateway]
name = "shared-gateway"
namespace_separator = "."
description = "Shared MCP gateway for Codex, OpenCode and OpenClaw."Significado:
name: Nombre de la puerta de enlace expuesta externamentenamespace_separator: Separador de espacio de nombres, por defecto suele ser.description: Información de descripción de la puerta de enlace
3. Configuración del servidor MCP descendente
[[servers]]
key = "mysql-db"
enabled = true
namespace = "mysql_db"
command = "/bin/bash"
args = ["-lc", "cd /opt/mcps/mysql-connector && ./.venv/bin/python server.py"]Significado:
key: Identificador único del servicio descendenteenabled: Si está habilitadonamespace: Espacio de nombres del prefijo del nombre de la herramientacommand: Comando de inicioargs: Argumentos de inicioenv: Opcional, inyecta variables de entorno por separado para este servicio
4. Descripción de excepciones locales
[local_exceptions.openclaw]
keep_local = ["openspace"]
reason = "OpenSpace 强依赖宿主上下文,保留本地直连。"
endpoint = "http://127.0.0.1:8081/mcp"Se utiliza para registrar qué capacidades no pasan por la puerta de enlace compartida, sino que se mantienen como conexión directa local.
5. Metainformación de la ruta de configuración del cliente (opcional)
[clients.codex]
config_path = "~/.codex/config.toml"Significado:
clients.*se utiliza principalmente para registrar la ubicación del archivo de configuración del cliente de destino.El proyecto actual no reescribirá automáticamente estas rutas por defecto.
Se recomienda ejecutar primero
scripts/render_client_configs.pyy luego copiar el resultado generado en la configuración del cliente correspondiente.
Cómo configurar: Casos
Caso 1: Configuración de ejecución directa en el host
A continuación se muestra un ejemplo mínimo que puede consultar directamente:
[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 纳管。"Caso 2: Ideas de configuración de Docker Compose
Si desea ejecutar la puerta de enlace de forma unificada dentro de un contenedor, puede consultar las siguientes ideas:
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:rwAdecuado para:
Montar dependencias de tiempo de ejecución de múltiples MCP en el mismo contexto de contenedor.
Garantizar la estabilidad del directorio de código descendente mediante montajes de solo lectura.
Usar de forma unificada
registry.compose.tomldentro del contenedor.
Archivos de plantilla de configuración
Para facilitar la implementación directa, el proyecto ha añadido archivos de plantilla que se pueden copiar:
1. Plantilla de registro
Archivo: templates/registry.template.toml
Uso:
Al inicializar un nuevo entorno, simplemente copie y modifique la ruta.
Adecuado como configuración de inicio para ejecución directa en el host.
Conserva la estructura completa de
listen,gateway,servers,clients,local_exceptions.
Forma de uso sugerida:
cp templates/registry.template.toml registry.local.toml2. Plantilla de registro dentro del contenedor
Archivo: templates/registry.compose.template.toml
Uso:
Proporciona una plantilla de registro con rutas dentro del contenedor para escenarios de Docker / Compose.
Evita llevar rutas absolutas del host a la configuración del contenedor por error.
Adecuado como punto de partida para copiar
registry.compose.toml.
Forma de uso sugerida:
cp templates/registry.compose.template.toml registry.compose.local.toml3. Plantilla de Compose
Archivo: templates/docker-compose.template.yml
Uso:
Preparación rápida de la orquestación de Compose para nuevas máquinas o entornos.
Evita modificar directamente el
docker-compose.ymldedicado a la red actual o a la máquina actual.Facilita la adaptación de rutas de montaje y variables de entorno a las normas del equipo.
Forma de uso sugerida:
cp templates/docker-compose.template.yml docker-compose.local.ymlEjemplos de acceso del cliente
Proceso de acceso recomendado:
Inicie primero shared-gateway y confirme que
http://127.0.0.1:8787/healthzfunciona correctamente.Ejecute
python3 scripts/render_client_configs.pypara generar fragmentos de configuración del cliente para el entorno actual.Priorice la copia de los productos reales en el directorio
generated/, no escriba manualmente rutas relacionadas con el entorno.
Ejemplo de acceso a Codex
Se recomienda utilizar directamente generated/codex-mcp.toml. Su estructura es aproximadamente la siguiente:
[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 = trueEjemplo de acceso a OpenCode
Se recomienda utilizar directamente generated/opencode-mcp.jsonc. Su estructura es aproximadamente la siguiente:
{
"$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"
]
}
}
}Ejemplo de acceso a OpenClaw
OpenClaw puede utilizar directamente HTTP MCP, se recomienda utilizar directamente generated/openclaw-mcp.json:
{
"mcpServers": {
"shared-gateway": {
"url": "http://127.0.0.1:8787/mcp",
"transport": "streamable-http",
"connectionTimeoutMs": 10000,
"disabled": false
}
}
}Ideas de acceso a Claude Code
El proyecto actual ya admite la inyección de identificadores de llamador para claude-code a través de stdio_bridge.py. La idea central es utilizar el puente como un comando MCP stdio local:
python3 /absolute/path/to/shared_mcp_gateway/stdio_bridge.py --url http://127.0.0.1:8787/mcp --caller claude-codeSi el sistema de configuración de su cliente permite comandos MCP stdio personalizados, simplemente reutilice este comando de puente.
Sugerencias para la implementación de la configuración
Para reducir problemas de entorno, se recomienda implementar en el siguiente orden:
Primero copie los archivos de plantilla, no modifique directamente los ejemplos existentes en el proyecto.
Asegúrese primero de que cada servidor MCP descendente pueda iniciarse por separado.
Luego escriba los servicios descendentes uno por uno en
registry.tomloregistry.compose.toml.Después de iniciar la puerta de enlace, verifique primero
/healthzy luego ejecutescripts/self_check.py.Finalmente, ejecute
scripts/render_client_configs.pypara sincronizar la configuración de acceso del cliente.
Se recomienda distinguir tres tipos de archivos:
registry.toml: Configuración de ejecución directa en el hostregistry.compose.toml: Configuración de ejecución dentro del contenedortemplates/*.template.*: Plantillas de inicialización de nuevo entorno
Comandos comunes
Generar configuración del cliente
python3 scripts/render_client_configs.pyEste script hará lo siguiente:
Leer
registry.tomlGenerar de forma unificada fragmentos de configuración para Codex / OpenCode / OpenClaw
Evitar la deriva de configuración al copiar manualmente los comandos de inicio del puente
Los resultados generados se encuentran en:
generated/codex-mcp.tomlgenerated/opencode-mcp.jsoncgenerated/openclaw-mcp.json
Ejecutar comprobación de estado
python3 scripts/self_check.py
python3 scripts/self_check.py --jsonPor defecto, se realizarán dos tipos de comprobaciones:
healthz: Comprueba si la puerta de enlace está expuesta correctamente, si faltan descendentes y si el disyuntor está abierto.gateway_tools: Se conecta a la puerta de enlace como un cliente MCP, comprueba si existen herramientas clave y realiza sondeos sin efectos secundarios.
Ver registros
docker compose logs -f shared-mcp-gatewayMCP compartidos conectados actualmente
mempalacemysql-dbobsidian-kbtencent-cls
Consulte la explicación de la topología en: /path/to/shared-mcp-gateway/docs/mcp-topology.md
Sugerencias posteriores
Si desea seguir ampliando este proyecto, se recomienda avanzar en el siguiente orden:
Añada primero un nuevo
[[servers]]enregistry.toml.Verifique localmente si este MCP puede iniciarse de forma independiente.
Compruebe
/healthzdespués de iniciar la puerta de enlace.Ejecute
scripts/self_check.pypara ver si las capacidades clave funcionan normalmente.Vuelva a ejecutar
scripts/render_client_configs.pypara sincronizar la configuración del cliente.
Si actualmente desea seguir añadiendo documentación, plantillas o configuraciones predeterminadas en este proyecto, priorice el mantenimiento de:
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