mcp-gw
Integrates with Home Assistant's MCP server to provide tools for controlling Home Assistant entities such as turning devices on/off, setting volumes, and more.
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-gwlist all registered backends"
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-gw
An aggregating MCP (Model Context Protocol) gateway that runs as a Docker container. Claude Code connects to one endpoint and gets tools from all registered backend MCP servers combined.
Architecture
Claude Code
│ HTTP MCP (localhost:3000/mcp)
▼
┌─────────────────────────────┐
│ mcp-gateway │ ← Alpine Docker container
│ ┌─────────┐ ┌──────────┐ │
│ │ MCP srv │ │Dashboard │ │
│ └────┬────┘ └──────────┘ │
│ │ mcp-gw-net │
└───────┼─────────────────────┘
│
├── backend-a:8080 ← Docker container on mcp-gw-net
├── backend-b:8080 ← Docker container on mcp-gw-net
└── 10.10.7.22:8123 ← External host (e.g. Home Assistant)Tools from all backends are aggregated and namespaced as backend__tool_name so Claude Code sees them in a single tool list.
Related MCP server: MCP Proxy Server
Quick Start
git clone https://github.com/gpimthong/mcp-gw
cd mcp-gw
docker compose up -dThe gateway starts on port 3000.
Dashboard: http://localhost:3000
MCP endpoint: http://localhost:3000/mcp
Health: http://localhost:3000/api/health
Connect Claude Code
Add to ~/.mcp.json:
{
"mcpServers": {
"gateway": {
"type": "http",
"url": "http://localhost:3000/mcp"
}
}
}Restart Claude Code to pick up the change.
Homelab Deployment
First-time setup on a new machine
config/backends.json is gitignored (to prevent credentials from leaking). You must create it manually on every fresh clone:
mkdir -p config
cat > config/backends.json << 'EOF'
{
"backends": []
}
EOFThen start the gateway and register your backends via the dashboard or API.
Persistent config across restarts
The config/ directory is bind-mounted into the container (see docker-compose.yml). Any backends you register via the dashboard or API are written to config/backends.json on the host and survive container restarts automatically.
Network topology
The gateway runs on a dedicated bridge network mcp-gw-net (172.22.0.0/16). Backend containers must be on this network. External hosts (like Home Assistant on your LAN) are reachable directly by IP — no network joining needed for those.
Adding Backend MCP Servers
Docker container backends
The container must be on the mcp-gw-net network:
# Attach an existing container
docker network connect mcp-gw-net <container-name>
# Or start a new backend directly on the network
docker run -d --name my-mcp --network mcp-gw-net my-mcp-imageThen register it:
curl -X POST http://localhost:3000/api/backends \
-H 'Content-Type: application/json' \
-d '{"name":"my-mcp","url":"http://my-mcp:8080/mcp","transport":"http","enabled":true}'External host backends
Backends that run outside Docker (on a LAN IP, VM, or another machine) are registered by IP. No network setup needed — the gateway container reaches them over the host network.
curl -X POST http://localhost:3000/api/backends \
-H 'Content-Type: application/json' \
-d '{"name":"my-service","url":"http://192.168.1.50:8080/mcp","transport":"http","enabled":true}'Authenticated backends (Bearer token / custom headers)
Pass a headers object to send arbitrary HTTP headers on every request to a backend. This is how you authenticate against services like Home Assistant:
curl -X POST http://localhost:3000/api/backends \
-H 'Content-Type: application/json' \
-d '{
"name": "my-service",
"url": "http://192.168.1.50:8080/mcp",
"transport": "sse",
"enabled": true,
"headers": {
"Authorization": "Bearer <your-token-here>"
}
}'The headers field is optional. Without it, requests are sent unauthenticated.
Home Assistant Setup
Home Assistant's built-in MCP server is exposed at /mcp_server/sse and uses SSE transport. It requires a long-lived access token.
Get a long-lived access token
Open Home Assistant → Profile (bottom-left avatar)
Scroll to Long-Lived Access Tokens → Create Token
Give it a name (e.g.
mcp-gateway) and copy the token
Register Home Assistant as a backend
curl -X POST http://localhost:3000/api/backends \
-H 'Content-Type: application/json' \
-d '{
"name": "homeassistant",
"url": "http://<HA_IP>:8123/mcp_server/sse",
"transport": "sse",
"enabled": true,
"headers": {
"Authorization": "Bearer <your-long-lived-token>"
}
}'Replace <HA_IP> with your Home Assistant host IP (e.g. 10.10.7.22) and <your-long-lived-token> with the token from the previous step.
Resulting tools in Claude Code
Once connected, Home Assistant tools appear namespaced as homeassistant__<tool>, for example:
homeassistant__HassTurnOnhomeassistant__HassTurnOffhomeassistant__HassSetVolume
Dashboard
The dashboard at http://localhost:3000 shows:
Backend cards — connection status, tool count, latency, last ping
Live request log — real-time stream of every tool call with duration and status
Tool catalog — all tools from all backends, expandable by backend
Use the + Add Backend button to register new backends, or click Remove / Reconnect on each card.
REST API
Method | Path | Description |
|
| Status, version, uptime, tool count |
|
| List all backends with state |
|
| Add / reconnect a backend |
|
| Remove a backend |
|
| Force reconnect |
|
| Last 200 log entries |
|
| SSE live log stream |
Tool Namespacing
Backend memory with tool search_notes → exposed to Claude Code as memory__search_notes.
The double-underscore separator avoids collisions between backends. The gateway parses the prefix at call time to route to the right backend client.
Transport Support
Backend transport | Config value |
MCP Streamable HTTP |
|
MCP SSE (legacy) |
|
Home Assistant uses SSE. Most modern MCP servers use Streamable HTTP.
config/backends.json
This file is gitignored because it typically contains auth tokens. It is created and maintained at runtime by the gateway — every dashboard or API action writes through to this file.
Template for a fresh deployment:
{
"backends": []
}Start from the empty template and re-register your backends after cloning. The config/ directory is bind-mounted so the file persists across docker compose down / up cycles.
Development
Requires Node.js 22+.
npm install
npm run dev # tsx hot-reload
npm run build # compile TypeScript → dist/Config is read from ./config/backends.json in dev mode (set CONFIG_PATH env var to override).
Versioning
Version is set in package.json. The gateway advertises it in the MCP initialize handshake and at /api/health. Git tags follow v<semver> (e.g. v0.1.0).
Project Structure
src/
index.ts — entry point
version.ts — reads version from package.json
types.ts — shared interfaces
logger.ts — circular log buffer + SSE emitter
config.ts — load/save backends.json
backend-registry.ts — MCP client connections + heartbeat
tool-aggregator.ts — namespace + route tool calls
mcp-server.ts — MCP HTTP server (session management)
dashboard.ts — Express app (REST API + SSE)
public/
index.html — dashboard SPA (no build step)
config/
backends.json — persisted backend definitions (gitignored)This server cannot be deployed
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Unified gateway exposing 150+ tools across all NexGenData MCP servers via one endpoint.
Host your MCP tool over streamable HTTP in one command.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceAggregates multiple MCP servers behind a single, secure endpoint with unified tool/resource discovery, OAuth authentication, and resilient request routing. Enables users to manage and interact with multiple MCP backends through one centralized interface with load balancing and circuit breakers.2-
- AlicenseNot gradedqualityCmaintenanceAggregates multiple backend MCP servers into a single unified interface with optional web management UI for tool control and configuration.60 npm193MIT
- AlicenseNot gradedqualityCmaintenanceAuthenticating reverse proxy for MCP servers providing credential isolation, OAuth2 token management, and composite tool aggregation.BSD Zero Clause
- FlicenseNot gradedqualityCmaintenanceAggregates multiple MCP servers into a single unified endpoint with hot-plugging, multi-protocol support, and management via web and CLI.8 npm-