mcp-gateway
Click on "Deploy 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-gatewaywhat tools are available from all my connected servers?"
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-gateway-poc
A local MCP Gateway that aggregates multiple MCP backend servers behind a single HTTP/SSE endpoint. One client connection, all tools and resources from every backend visible under a single namespace.
Why
Most MCP clients only connect to one endpoint. With many MCP servers (GitHub,
Jira, custom internal tools), you end up with N separate client configurations
and no unified observability. mcp-gateway solves this by acting as a local
proxy:
Client ──HTTP/SSE──▶ mcp-gateway ──┬─ stdio subprocess ─▶ Backend A
└─ HTTP/SSE ─▶ Backend BEach backend's tools/resources are exposed with a <backend>. prefix so
callers always know which backend is answering.
Related MCP server: MCP Proxy Server
Features (PoC scope)
HTTP/SSE frontend on
127.0.0.1(default port 8765)Backend transports: stdio subprocess and HTTP/SSE
Aggregated tool and resource catalogs
<backend>.<tool>and<backend>://<resource>namespaceYAML configuration with
${env:VAR}interpolationHot reload on config edit (add/remove/restart diffed, others unaffected)
Structured JSON logging with
request_idpropagationGET /healthfor per-backend statusStructured lifecycle logs (
startup,backend_connected,reload_applied, …)
Out of scope for the PoC: authentication, prompts/sampling, persistent state, multi-tenant quotas.
Install
Requires Python 3.13 and uv.
uv venv
uv pip install -e ".[dev]"Quick start (two commands)
Terminal 1 — start the gateway with the example config:
export PYTHON="$(pwd)/.venv/bin/python" # so the stdio mock can import `mcp`
mcp-gateway --config examples/mcp-gateway.yamlTerminal 2 — query the gateway:
curl http://127.0.0.1:8765/health
# JSON-RPC initialize
curl -X POST http://127.0.0.1:8765/messages \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
# List tools (prefixed with backend name)
curl -X POST http://127.0.0.1:8765/messages \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
# Call a tool (note the "mock." prefix)
curl -X POST http://127.0.0.1:8765/messages \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"mock.add","arguments":{"a":2,"b":3}}}'Open the SSE stream:
curl -N http://127.0.0.1:8765/sseThe first event is event: endpoint with the absolute URL to POST to.
Configuration
gateway:
host: 127.0.0.1
port: 8765
log_level: info
reload:
enabled: true
debounce_ms: 500
backends:
- name: github # unique, used as tool prefix
transport: stdio
command: uvx
args: [mcp-server-github]
env:
GITHUB_TOKEN: "${env:GITHUB_TOKEN}"
- name: jira
transport: sse
url: http://127.0.0.1:9001/sse
headers:
Authorization: "Bearer ${env:JIRA_TOKEN}"Backend name must match ^[a-z0-9_-]+$. Edit the file while the gateway is
running — within the debounce window, the gateway will add / remove / restart
the affected backends and emit a reload_applied log line.
CLI flags
--config <path>: explicit config file (else:MCP_GATEWAY_CONFIGenv var,./mcp-gateway.yaml,~/.config/mcp-gateway/config.yaml)--host <host>: overridegateway.host--port <port>: overridegateway.port--log-level <level>: overridegateway.log_level
Tests
uv run pytest # 78 tests, all layers
uv run pytest --cov=src/mcp_gateway # with coverage reportCoverage targets for the PoC: ≥ 80% overall, ≥ 90% on src/mcp_gateway/core/.
Architecture
┌──────────────────────────────────────────────────────────────────────┐
│ MCP Gateway (PoC) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Frontend (FastAPI) │ │
│ │ GET /sse → SSE stream (MCP transport) │ │
│ │ POST /messages → JSON-RPC dispatcher │ │
│ │ GET /health → per-backend status │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Core │ │
│ │ Registry – in-memory catalog, tools/resources │ │
│ │ Router – dispatch tools/call, resources/read │ │
│ │ Manager – start/stop backends, hot-reload diff │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Backend adapters │ │
│ │ StdioBackend → mcp.client.stdio.stdio_client │ │
│ │ HttpSseBackend → mcp.client.sse.sse_client │ │
│ └─────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘Boundary rules:
Frontend only speaks MCP wire protocol — knows nothing about backends.
Registry / Router are transport-agnostic — they only see prefixed names.
Adapters are the only layer that imports the
mcpSDK — upgrades are local.
Spec / plan
This PoC was built against the OpenSpec change at
openspec/changes/mcp-gateway-poc/.
To inspect or re-validate:
openspec status --change mcp-gateway-poc
openspec validate mcp-gateway-poc
openspec show mcp-gateway-pocWhen the implementation is accepted, archive it with /opsx-archive to merge
the specs into openspec/specs/.
This server cannot be deployed
Maintenance
Related MCP Connectors
Host your MCP tool over streamable HTTP in one command.
Streamable HTTP MCP server exposing planner flows, tasks, and squads.
Remote MCP server exposing SMI Aware tools, resources, and skills over Streamable HTTP.
MCP server for Riveter's enrichment, scraping, and monitoring API
Related MCP Servers
- AlicenseBqualityCmaintenanceA flexible proxy server that aggregates multiple backend MCP servers into a single interface using STDIO or SSE transports. It supports dynamic server management via an HTTP API and utilizes namespacing to prevent tool conflicts across connected services.31MIT
- AlicenseNot gradedqualityCmaintenanceAggregates multiple backend MCP servers into a single unified interface with optional web management UI for tool control and configuration.60 npm193MIT
- AlicenseNot gradedqualityAmaintenanceAggregates multiple MCP servers into a single HTTP endpoint with tool namespacing, dashboard, and REST API for management.13 npmMIT
- AlicenseNot gradedqualityCmaintenanceAggregates multiple upstream MCP servers (stdio, streamable-http, sse, websocket) behind a single streamable-HTTP endpoint with declarative configuration, namespacing, filtering, and auto-reload.MIT