host-mcp-gateway

command module
v0.0.0-...-a3370a0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2026 License: MIT Imports: 28 Imported by: 0

README

Host MCP Gateway

Host MCP Gateway is a small Go daemon that runs local MCP servers on the host and exposes them through authenticated HTTP endpoints. It is intended for MCP servers that need host-only capabilities, such as macOS frameworks, while the MCP client runs somewhere else.


Features

  • Runs configured MCP server processes over stdio.
  • Routes JSON-RPC requests to a target MCP server by server_id.
  • Supports wrapper requests through POST /rpc.
  • Supports direct raw JSON-RPC requests through /{server_id}/rpc.
  • Exposes health and server-status endpoints.
  • Enforces bearer-token authentication on every endpoint.
  • Restricts clients by explicit IP address or CIDR allowlist.
  • Restarts crashed MCP server processes according to per-server policy.
  • Emits structured JSON logs and OTLP traces and metrics.

Requirements

  • Go 1.22 or newer.
  • One or more MCP server commands installed on the host.
  • macOS when running MCP servers that depend on macOS APIs.

Set OTEL_EXPORTER_OTLP_ENDPOINT only when you want OTLP metrics and traces exported. If the variable is unset, the gateway still runs and uses no-op observability providers.


Install

Build a local binary:

go build -o host-mcp-gateway ./...

Install into your Go binary directory:

go install ./...

For a published module, the install command should use the repository module path:

go install github.com/replace-me/host-mcp-gateway@latest

The current go.mod uses the same placeholder path. Replace github.com/replace-me/host-mcp-gateway with the final repository path before publishing a release.


Configuration

By default, the gateway reads:

~/.config/host-mcp-gateway/config.json

Create a config from the sample:

mkdir -p ~/.config/host-mcp-gateway
cp config/host-mcp-gateway.sample.json ~/.config/host-mcp-gateway/config.json

Generate a bearer token for auth_token:

openssl rand -hex 32

The config file is JSON:

{
  "bind_host": "127.0.0.1",
  "bind_port": 7411,
  "request_timeout_ms": 30000,
  "restart_backoff_ms": 2000,
  "auth_token": "replace-me-generate-a-token",
  "allowed_clients": [
    "127.0.0.1/32",
    "::1/128"
  ],
  "servers": [
    {
      "server_id": "host-service",
      "command": "/usr/local/bin/replace-me-mcp-server",
      "args": [],
      "working_dir": "",
      "env": {},
      "autostart": true,
      "restart_policy": "on-failure",
      "startup_timeout_ms": 30000
    }
  ]
}

Config fields:

Field Required Default Description
bind_host No 127.0.0.1 Interface for the HTTP server.
bind_port No 7411 Port for the HTTP server.
request_timeout_ms No 30000 Timeout for MCP request/response calls.
restart_backoff_ms No 2000 Delay before restarting a crashed MCP process.
auth_token Yes None Bearer token required by all endpoints.
allowed_clients Yes None IP addresses, CIDRs, or localhost.
servers Yes None MCP server process definitions.

Server fields:

Field Required Default Description
server_id Yes None Unique routing key for the MCP server.
command Yes None Executable path or command name.
args No [] Command arguments.
working_dir No "" Working directory for the child process.
env No {} Additional environment variables.
autostart No false Starts the process when the gateway starts.
restart_policy No on-failure One of always, on-failure, or never.
startup_timeout_ms No 0 Reserved by config; process startup is currently marked ready after spawn.

Run

Run with the default config path:

./host-mcp-gateway

Run with an explicit config:

./host-mcp-gateway -config ~/.config/host-mcp-gateway/config.json

Enable OTLP export:

OTEL_EXPORTER_OTLP_ENDPOINT=localhost:4317 \
  ./host-mcp-gateway -config ~/.config/host-mcp-gateway/config.json

The gateway is designed to run on the host that owns the MCP server capabilities. Host-only services should be launched where their APIs, permissions, and local resources are actually available.


HTTP API

Every request must include:

Authorization: Bearer <auth_token>

GET /health returns gateway uptime, version, aggregate status, and configured server statuses.

GET /servers returns configured server statuses.

POST /rpc accepts a wrapper request and returns a wrapper response:

{
  "server_id": "host-service",
  "payload": {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }
}

POST /{server_id}/rpc sends a raw MCP JSON-RPC request body to the named server and returns the raw MCP JSON-RPC response body.

GET /{server_id}/rpc opens a server-sent event stream and returns MCP-Session-Id when a session ID exists or is created.

Error responses use this shape:

{
  "error": {
    "error_code": "server_not_found",
    "message": "unknown server_id",
    "server_id": "host-service",
    "request_id": "1"
  }
}

LaunchAgent

A sample macOS LaunchAgent is provided at launchd/host-mcp-gateway.plist.sample.

Copy and edit the sample:

cp launchd/host-mcp-gateway.plist.sample \
  ~/Library/LaunchAgents/host-mcp-gateway.plist

Replace replace-me paths with your macOS username and confirm the binary path. Add OTEL_EXPORTER_OTLP_ENDPOINT only when you want OTLP export enabled.

Load the LaunchAgent:

launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/host-mcp-gateway.plist

Unload the LaunchAgent:

launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/host-mcp-gateway.plist

Development

Run tests:

go test ./...

Run the configured linter when golangci-lint is installed:

golangci-lint run

This repository uses the MIT license. See LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL