/ Directory / Playground / mcp-proxy
● Community sparfenyuk ⚡ Instant

mcp-proxy

by sparfenyuk · sparfenyuk/mcp-proxy

Bridge stdio MCPs to SSE/Streamable HTTP and vice versa — one tiny Python tool that makes transports interoperate.

sparfenyuk/mcp-proxy is a transport bridge. Two modes: (1) stdio client connecting to a remote SSE/HTTP MCP — lets Claude Desktop talk to a remote server; (2) SSE server wrapping a local stdio MCP — exposes it over HTTP with CORS, auth, multiple named servers.

Why use it

Key features

Live Demo

What it looks like in practice

proxy.replay ▶ ready
0/0

Install

Pick your client

~/Library/Application Support/Claude/claude_desktop_config.json  · Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "proxy": {
      "command": "uvx",
      "args": [
        "mcp-proxy"
      ],
      "_inferred": true
    }
  }
}

Open Claude Desktop → Settings → Developer → Edit Config. Restart after saving.

~/.cursor/mcp.json · .cursor/mcp.json
{
  "mcpServers": {
    "proxy": {
      "command": "uvx",
      "args": [
        "mcp-proxy"
      ],
      "_inferred": true
    }
  }
}

Cursor uses the same mcpServers schema as Claude Desktop. Project config wins over global.

VS Code → Cline → MCP Servers → Edit
{
  "mcpServers": {
    "proxy": {
      "command": "uvx",
      "args": [
        "mcp-proxy"
      ],
      "_inferred": true
    }
  }
}

Click the MCP Servers icon in the Cline sidebar, then "Edit Configuration".

~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "proxy": {
      "command": "uvx",
      "args": [
        "mcp-proxy"
      ],
      "_inferred": true
    }
  }
}

Same shape as Claude Desktop. Restart Windsurf to pick up changes.

~/.continue/config.json
{
  "mcpServers": [
    {
      "name": "proxy",
      "command": "uvx",
      "args": [
        "mcp-proxy"
      ]
    }
  ]
}

Continue uses an array of server objects rather than a map.

~/.config/zed/settings.json
{
  "context_servers": {
    "proxy": {
      "command": {
        "path": "uvx",
        "args": [
          "mcp-proxy"
        ]
      }
    }
  }
}

Add to context_servers. Zed hot-reloads on save.

claude mcp add proxy -- uvx mcp-proxy

One-liner. Verify with claude mcp list. Remove with claude mcp remove.

Use Cases

Real-world ways to use mcp-proxy

How to use a remote SSE MCP server inside Claude Desktop

👤 Devs with a team-hosted MCP gateway ⏱ ~10 min beginner

When to use: Your team runs a gateway at https://mcp.team.internal but Claude Desktop only speaks stdio.

Prerequisites
  • uv or pipx — brew install uv
Flow
  1. Install mcp-proxy
    Run: uv tool install mcp-proxy✓ Copied
    → mcp-proxy on PATH
  2. Configure Claude Desktop
    Add an MCP entry: command=mcp-proxy, args=['--headers','Authorization','Bearer $TOKEN','https://mcp.team.internal/sse'].✓ Copied
    → Claude Desktop connects on restart
  3. Verify
    In Claude, ask: what tools do you have?✓ Copied
    → Remote tools listed

Outcome: Remote server usable from stdio-only clients.

Pitfalls
  • Auth header not picked up — Use --headers syntax exactly; some clients mangle env var interpolation — expand the token yourself
Combine with: mcphub

How to expose a local stdio MCP over HTTP for remote teammates

👤 Devs sharing a local tool temporarily ⏱ ~15 min intermediate

When to use: You built a custom stdio MCP and a remote colleague wants to try it.

Flow
  1. Run proxy in inbound mode
    mcp-proxy --sse-host 0.0.0.0 --sse-port 3333 --named-server my-tool 'uvx my-tool-mcp'✓ Copied
    → SSE endpoint at :3333/my-tool/sse
  2. Tunnel it
    Use ngrok or cloudflared to expose 3333 on a public URL.✓ Copied
    → Shareable URL
  3. Teammate connects
    They add the URL to their client (via mcp-proxy or directly if their client supports SSE).✓ Copied
    → Shared session working

Outcome: Ad-hoc sharing of local tools.

Pitfalls
  • No auth by default — Use --bearer-token or put it behind Caddy basic auth

How to serve multiple local MCPs from one proxy port

👤 Homelab tinkerers ⏱ ~15 min intermediate

When to use: You want one gateway serving github, filesystem, and postgres MCPs.

Flow
  1. Start with multiple --named-server args
    mcp-proxy --sse-port 3333 --named-server gh 'uvx mcp-server-github' --named-server fs 'uvx mcp-server-filesystem ~/src'✓ Copied
    → Endpoints /gh/sse and /fs/sse
  2. Connect each in your client
    Add each as a separate server in your MCP client.✓ Copied
    → Tools from both appear

Outcome: One process, many MCPs.

Pitfalls
  • Named servers share the proxy's resource budget — Don't put heavyweight MCPs in the same proxy as lightweight ones
Combine with: mcphub

Combinations

Pair with other MCPs for X10 leverage

proxy + mcphub

Use mcp-proxy to expose stdio MCPs that MCPHub can then aggregate over HTTP

Bridge my local github stdio MCP to HTTP with mcp-proxy, then register it in MCPHub's 'dev' group.✓ Copied
proxy + unla

Use Unla's public-facing gateway on top of mcp-proxy's last-mile stdio bridge

Bridge stdio MCPs with mcp-proxy and put Unla in front for OAuth + multi-tenancy.✓ Copied

Tools

What this MCP exposes

ToolInputsWhen to callCost
(proxy) stdio-to-sse remote_url, headers?, bearer? Connect stdio client to remote SSE server free
(proxy) sse-to-stdio named_server spec Expose a stdio MCP over HTTP free

Cost & Limits

What this costs to run

API quota
None
Tokens per call
No measurable overhead
Monetary
Free (MIT)
Tip
Skip proxy when your client natively supports the other transport — fewer moving parts.

Security

Permissions, secrets, blast radius

Minimum scopes: Network egress to the remote URL (outbound mode) Inbound port binding (inbound mode)
Credential storage: Headers/tokens passed via CLI args or env
Data egress: Whatever the bridged MCP does; proxy itself is transparent
Never grant: Don't expose inbound mode on 0.0.0.0 without auth Don't log tokens in shell history — use env vars

Troubleshooting

Common errors and fixes

Connection closed immediately

The remote URL path is wrong — SSE endpoints typically end in /sse.

Verify: curl -N <url>
CORS error in browser client

Start mcp-proxy with --allow-origin or put it behind a reverse proxy with CORS headers.

401 even with --bearer-token

The remote expects the token on a different header (e.g., X-API-Key). Use --headers to customize.

SSE drops after 60s

Load balancer idle timeout. Raise it or use Streamable HTTP.

Alternatives

mcp-proxy vs others

AlternativeWhen to use it insteadTradeoff
MCPHubYou need multi-server aggregation + routing, not just a bridgeHeavier — UI, DB, OAuth all bundled
UnlaYou want REST-to-MCP conversion + gatewayDifferent problem space
supergatewayYou prefer a JavaScript stdio-to-SSE bridgeNode dependency

More

Resources

📖 Read the official README on GitHub

🐙 Browse open issues

🔍 Browse all 400+ MCP servers and Skills