HTTP bridge for any stdio MCP server.
One process = one upstream stdio MCP server.
Multiple servers → multiple instances via the mcp-http@<name>.service systemd template.
HTTP client ──POST /──► mcp-http ──stdio──► any MCP server
◄─JSON─── ◄────────
mcp-http connects to the upstream server at startup, discovers all tools via
list_tools, and proxies call_tool requests over HTTP.
Returns server status and list of available tools.
{"ok": true, "cmd": "dav-mcp", "tools": ["read_file", "write_file"]}Call a tool on the upstream MCP server.
{"tool": "read_file", "arguments": {"path": "/etc/hosts"}}Returns the MCP CallToolResult as JSON.
If MCP_HTTP_TOKENS_FILE is set, the request must include:
Authorization: Bearer <token>
All configuration is via environment variables (see example.env):
| Variable | Required | Default | Description |
|---|---|---|---|
MCP_HTTP_CMD |
✓ | — | Command to launch the upstream MCP server |
MCP_HTTP_ADDR |
127.0.0.1:8770 |
Listen address (host:port) |
|
MCP_HTTP_TOKENS_FILE |
— | Path to Bearer tokens file (one per line) | |
MCP_HTTP_ALLOWED_HOSTS |
— | Comma-separated allowed Host headers | |
MCP_HTTP_TOOL_TIMEOUT |
30s |
Per-call timeout (Go duration) |
go install github.com/nikita-popov/mcp-http@latestOr build from source:
git clone https://github.com/nikita-popov/mcp-http
cd mcp-http
go build -o mcp-http .
sudo mv mcp-http /usr/local/bin/Copy the template unit:
sudo cp example@.service /etc/systemd/system/mcp-http@.service
sudo systemctl daemon-reloadCreate a config for each instance:
# /etc/mcp-http/dav-mcp.env
MCP_HTTP_CMD=dav-mcp
MCP_HTTP_ADDR=127.0.0.1:8771
MCP_HTTP_TOKENS_FILE=/etc/mcp-http/dav-mcp.tokensEnable and start:
sudo systemctl enable --now mcp-http@dav-mcp
sudo systemctl enable --now mcp-http@mempalace
sudo journalctl -u mcp-http@dav-mcp -fSee example.nginx.conf for a reverse proxy configuration.
MIT