Skip to content

mikluko/mcp-proxy

Repository files navigation

mcp-proxy

A Go implementation of a proxy that connects MCP clients to remote MCP servers with OAuth support.

Features

  • Dual mode operation: Stdio (default) or HTTP/SSE server
  • OAuth 2.0: Full support with PKCE, dynamic client registration, and token refresh
  • Transport flexibility: HTTP and SSE with configurable fallback strategies
  • Tool filtering: Block specific tools from being exposed to clients

Installation

Homebrew (macOS/Linux)

brew install mikluko/tap/mcp-proxy

Go

go install github.com/mikluko/mcp-proxy/cmd/mcp-proxy@latest

Binary releases

Download from GitHub Releases.

Usage

Stdio Mode (Default)

Standard mode for MCP clients that communicate via stdio (Claude Code, Claude Desktop, Cursor, Windsurf).

Claude Code

claude mcp add remote-example mcp-proxy https://remote.mcp.server/sse

Claude Desktop, Cursor, Windsurf

{
  "mcpServers": {
    "remote-example": {
      "command": "mcp-proxy",
      "args": [
        "https://remote.mcp.server/sse"
      ]
    }
  }
}

HTTP/SSE Server Mode

Run as an HTTP server that accepts MCP client connections via SSE. Useful for:

  • Web-based MCP clients
  • Sharing a single upstream connection among multiple clients
  • Environments where stdio isn't available
# Listen on port 8080
mcp-proxy https://remote.mcp.server/sse --listen :8080

# Listen on specific interface
mcp-proxy https://remote.mcp.server/sse --listen localhost:8080

Clients connect via:

  • SSE endpoint: GET /sse - Establishes SSE stream for server→client messages
  • Message endpoint: POST /message - Sends client→server messages

Custom Headers

{
  "mcpServers": {
    "remote-example": {
      "command": "mcp-proxy",
      "args": [
        "https://remote.mcp.server/sse",
        "--header",
        "Authorization:Bearer ${AUTH_TOKEN}"
      ],
      "env": {
        "AUTH_TOKEN": "your-token"
      }
    }
  }
}

Flags

Flag Description Default
--listen, -l Listen address for HTTP mode (e.g., :8080) -
--header, -H Custom headers (KEY:VALUE) -
--transport Upstream transport strategy (http-first, sse-first, http-only, sse-only) http-first
--host OAuth callback hostname localhost
--allow-http Allow non-HTTPS connections false
--log-level Log level (debug, info, warn, error) info
--enable-proxy Use HTTP_PROXY/HTTPS_PROXY false
--ignore-tool Ignore tools matching pattern (wildcards) -
--auth-timeout OAuth callback timeout (seconds) 30
--resource OAuth resource parameter -
--static-oauth-client-metadata Static OAuth client metadata (JSON or @file) -
--static-oauth-client-info Static OAuth client info (JSON or @file) -

Transport Strategy

Controls how mcp-proxy connects to the upstream server:

  • http-first (default): Try HTTP, fall back to SSE on 404
  • sse-first: Try SSE, fall back to HTTP on 405
  • http-only/sse-only: No fallback

Multiple Instances

Use --resource to isolate OAuth sessions:

{
  "mcpServers": {
    "tenant1": {
      "command": "mcp-proxy",
      "args": [
        "https://mcp.example.com/sse",
        "--resource",
        "https://tenant1.example.com/"
      ]
    },
    "tenant2": {
      "command": "mcp-proxy",
      "args": [
        "https://mcp.example.com/sse",
        "--resource",
        "https://tenant2.example.com/"
      ]
    }
  }
}

Cache Location

OAuth tokens and client registration are stored in:

  • Linux: ~/.cache/mcp-proxy/
  • macOS: ~/Library/Caches/mcp-proxy/
  • Windows: %LocalAppData%\mcp-proxy\

To clear authentication state:

rm -rf ~/.cache/mcp-proxy # Linux
rm -rf ~/Library/Caches/mcp-proxy # macOS

Architecture

                     ┌─────────────────────────────────────────┐
                     │              mcp-proxy                  │
                     │                                         │
  ┌──────────┐       │  ┌────────────┐      ┌────────────────┐ │       ┌──────────┐
  │  Client  │──────▶│  │ Downstream │──────│     Proxy      │─│──────▶│ Upstream │
  │ (stdio   │       │  │ Transport  │      │   (filtering,  │ │       │  Server  │
  │  or SSE) │◀──────│  │            │◀─────│  modification) │◀│───────│          │
  └──────────┘       │  └────────────┘      └────────────────┘ │       └──────────┘
                     │     stdio or              HTTP or       │
                     │     HTTP/SSE                SSE         │
                     └─────────────────────────────────────────┘

Directory Structure

cmd/
└── mcp-proxy/          # Main CLI binary

internal/
├── auth/               # OAuth 2.0 implementation (PKCE, tokens, callback server)
├── config/             # Cross-platform cache directory management
├── proxy/              # Bidirectional JSON-RPC proxy with tool filtering
├── server/             # HTTP/SSE server for downstream client connections
├── stdio/              # Stdio transport for downstream client connections
└── transport/          # HTTP and SSE transports for upstream connections

pkg/
└── jsonrpc/            # JSON-RPC 2.0 message types

OAuth Flow

  1. auth.Provider.Initialize() loads existing tokens or prepares for auth
  2. On 401: start callback server, open browser to authorization URL
  3. Callback receives code, exchanges for tokens via PKCE
  4. Tokens persisted to cache dir, auto-refreshed on expiry

Release

Releases via goreleaser + GitHub Actions. Creates:

  • Multi-platform binaries (linux/darwin/windows × amd64/arm64)
  • Homebrew formula in mikluko/homebrew-tap

Prior Art

License

MIT

About

MCP proxy that connects stdio/HTTP clients to remote MCP servers with OAuth support

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages