A stdio-to-HTTP proxy for MCP (Model Context Protocol) servers. It lets stdio-based MCP clients like Claude Code connect to remote MCP servers over HTTP or SSE, with support for custom headers, TLS options, and authentication.
go-mcp-proxy
A stdio-to-HTTP proxy for MCP (Model Context Protocol) servers. It lets stdio-based MCP clients like Claude Code connect to remote MCP servers over HTTP or SSE, with support for custom headers, TLS options, and authentication.
Build
Requires Go 1.23+.
go build -o go-mcp-proxy ./cmd/go-mcp-proxy/
Usage
go-mcp-proxy [flags] [server-url]
Flags:
-config string path to JSON config file
-server string server name from config (default: first/only server)
-insecure skip TLS certificate verification
-type string transport: http, sse, auto (default "auto")
-header value custom header key=value (repeatable)
Basic
./go-mcp-proxy https://mcp.example.com/mcp
With authentication and custom headers
./go-mcp-proxy \
-header "Authorization=Bearer my-token" \
-header "X-Api-Key=abc123" \
https://mcp.example.com/mcp
Self-signed / mismatched TLS certificates
./go-mcp-proxy -insecure https://10.0.0.5:8443/mcp
Using a config file
Create a JSON config:
{
"mcpServers": {
"my-server": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer my-token"
},
"insecure": false,
"type": "auto"
}
}
}
./go-mcp-proxy -config servers.json -server my-server
Environment Variables
Environment variables are the lowest priority — CLI flags and config file values take precedence.
| Variable | Description |
|---|---|
| MCP_SERVER_URL | Server URL (also accepts legacy MCP_SSE_URL) |
| MCP_AUTH_TOKEN | Sets Authorization: Bearer <token> header |
| MCP_HEADERS | Comma-separated headers: Key1=Value1,Key2=Value2 |
| MCP_INSECURE | Skip TLS verification (true or 1) |
| MCP_TRANSPORT | Transport type: http or sse |
Examples:
# URL + bearer token via env
export MCP_SERVER_URL=https://mcp.example.com/mcp
export MCP_AUTH_TOKEN=my-secret-token
./go-mcp-proxy
# Multiple headers via env
export MCP_HEADERS="Authorization=Bearer tok123,X-Api-Key=key456"
./go-mcp-proxy https://mcp.example.com/mcp
# Skip TLS via env
MCP_INSECURE=true ./go-mcp-proxy https://10.0.0.5:8443/mcp
Configuration Priority
Settings are resolved in this order (first wins):
- CLI flags (
-header,-insecure, positional URL,-type) - Config file (
-config) - Environment variables (
MCP_SERVER_URL,MCP_AUTH_TOKEN, etc.)
Transport Modes
The proxy supports two MCP transport protocols:
- Streamable HTTP — current MCP standard. Uses
POSTfor messages, optionalGETSSE for server-initiated notifications, session management viaMcp-Session-Id. - Legacy SSE — older protocol. Opens a persistent
GETSSE connection for receiving,POSTfor sending.
By default (-type auto), the proxy tries Streamable HTTP first and falls back to Legacy SSE if the server doesn't support it.
Claude Code Integration
Add the proxy to .mcp.json in your project directory or globally at ~/.claude/.mcp.json.
Simple — direct URL
{
"mcpServers": {
"my-server": {
"command": "/path/to/go-mcp-proxy",
"args": ["https://mcp.example.com/sse"]
}
}
}
With authentication
{
"mcpServers": {
"my-server": {
"command": "/path/to/go-mcp-proxy",
"args": [
"-header", "Authorization=Bearer my-token",
"https://mcp.example.com/mcp"
]
}
}
}
With env variables (keeps secrets out of config)
{
"mcpServers": {
"my-server": {
"command": "/path/to/go-mcp-proxy",
"args": ["https://mcp.example.com/mcp"],
"env": {
"MCP_AUTH_TOKEN": "my-secret-token"
}
}
}
}
Self-signed TLS + auth header
{
"mcpServers": {
"internal-server": {
"command": "/path/to/go-mcp-proxy",
"args": [
"-insecure",
"-header", "Authorization=whm root:YOUR_API_TOKEN",
"https://10.0.0.5:2087/mcp"
]
}
}
}
Using a config file
{
"mcpServers": {
"my-server": {
"command": "/path/to/go-mcp-proxy",
"args": [
"-config", "/path/to/servers.json",
"-server", "my-server"
]
}
}
}
Multiple headers via env
{
"mcpServers": {
"my-server": {
"command": "/path/to/go-mcp-proxy",
"args": [],
"env": {
"MCP_SERVER_URL": "https://mcp.example.com/mcp",
"MCP_HEADERS": "Authorization=Bearer tok123,X-Tenant-Id=acme",
"MCP_INSECURE": "true"
}
}
}
}
Windows
{
"mcpServers": {
"my-server": {
"command": "C:\\tools\\go-mcp-proxy.exe",
"args": ["https://mcp.example.com/sse"]
}
}
}
How It Works
MCP Client (e.g. Claude Code)
│ stdin (JSON-RPC 2.0)
▼
┌──────────────┐
│ go-mcp-proxy │ ← flags / config / env vars
└──────────────┘
│ HTTPS POST + custom headers
▼
Remote MCP Server
│ JSON response or SSE stream
▼
┌──────────────┐
│ go-mcp-proxy │
└──────────────┘
│ stdout (JSON-RPC 2.0)
▼
MCP Client
The proxy reads JSON-RPC messages from stdin, forwards them as HTTP POST requests to the remote server, and writes responses back to stdout. All logging goes to stderr so it doesn't interfere with the protocol.
Project Structure
cmd/go-mcp-proxy/main.go CLI entrypoint
internal/proxy/ Proxy library
config.go Config file + header flag parsing
jsonrpc.go JSON-RPC types and stdin/stdout I/O
transport.go HTTP client and header helpers
sse.go SSE parser and URL resolution
legacy_sse.go Legacy SSE transport
streamable.go Streamable HTTP transport
License
See LICENSE file.