Model or dataset
sparfenyuk/mcp-proxy avatar
sparfenyuk/mcp-proxy

mcp-proxy: bridging stdio, SSE and Streamable HTTP MCP transports

A bridge between Streamable HTTP and stdio MCP transports

2,753 stars262 forksPythonMIT

At a glance

What is it?
sparfenyuk/mcp-proxy is a Python bridge that lets an MCP client speak one transport while the server speaks another. It is useful when a client such as Claude Desktop cannot reach a remote server directly, but it is not a general-purpose API gateway.
Who is it for?
Adopt mcp-proxy if you need Claude Desktop or another stdio-only MCP client to reach a remote SSE or Streamable HTTP server, or if you need to expose a local stdio server over SSE. Do not adopt it as a general API gateway or as a substitute for authentication and network controls you have not configured.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 57 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The transport mismatch mcp-proxy exists to fix

MCP servers can expose themselves over stdio, SSE or Streamable HTTP. Clients do not all support the same set. Claude Desktop, for example, speaks stdio natively, so a remote MCP server that only offers SSE is unreachable without a shim. The README states this directly: the stdio-to-SSE mode allows clients like Claude Desktop to communicate to a remote server over SSE even though it is not supported natively. The reverse case also exists. A local stdio server may need to be reachable by a remote LLM client, and mcp-proxy can open a port and forward SSE requests into the spawned stdio process. The project is therefore aimed at people wiring MCP servers into clients, not at people building MCP servers from scratch. If both ends already speak the same transport, the proxy adds a process without adding capability.

Two modes, two different data flows

The repository documents two distinct topologies. In stdio-to-SSE/StreamableHTTP mode, the client starts mcp-proxy as its stdio server. mcp-proxy then connects out to a remote SSE endpoint. The README's diagram shows Claude Desktop talking stdio to mcp-proxy, and mcp-proxy talking SSE to an external MCP server. In SSE-to-stdio mode the direction reverses: mcp-proxy listens on a port for SSE requests, spawns a local stdio server, and relays MCP requests into that child process. The README describes this as opening a port to listen for SSE requests and spawning a local stdio server that handles MCP requests. The two modes are configured differently, use different arguments, and should not be confused. One is an outbound client-side bridge; the other is an inbound server-side bridge.

Configuration keys that decide behaviour

In stdio-to-SSE mode the first positional argument is command_or_url, the remote SSE endpoint, for example http://example.io/sse. The --transport flag selects sse or streamablehttp; the README warns that if the server uses Streamable HTTP transport, you must enforce it on the mcp-proxy side by passing --transport=streamablehttp. Authentication can be supplied through --headers, for example Authorization 'Bearer my-secret-access-token', or through the API_ACCESS_TOKEN environment variable, which the README says can be used instead of the header form. OAuth2 is also supported through --client-id, --client-secret and --token-url. In SSE-to-stdio mode the first positional argument is the command to spawn, such as uvx mcp-server-fetch. The --port and --host arguments control the listening socket; the README notes that --host defaults to 127.0.0.1 and that a random available port is used if --port is omitted. Extra environment variables go through --env, which can be repeated, and --cwd sets the working directory of the spawned process. Arguments for the local stdio server must come after the -- separator.

Getting it running: PyPI, GitHub and container installs

The README lists three installation routes: PyPI, the GitHub repository for the latest code, and a container image. It also includes a Docker Compose setup section and a troubleshooting section. A minimal Claude Desktop entry from the README looks like this: the mcpServers key contains mcp-proxy, whose command is mcp-proxy, args is an array holding the remote URL, and env carries API_ACCESS_TOKEN. That is the whole client-side configuration for the simplest authenticated case. For the reverse mode, the proxy is started with a command to spawn, a port, and a separator before the child server's own arguments. The README does not spell out every flag in the excerpt available here; the command line arguments section is the place to confirm the full set before writing a production config.

Named servers and multi-server setups

The README has a Named Servers section, which implies that a single proxy process can expose more than one named MCP server rather than a single endpoint. The excerpt provided here does not include the body of that section, so the exact syntax for naming servers cannot be confirmed from the supplied material. What can be said is that the feature exists in the documentation and that it matters for anyone running several MCP servers behind one client. If you need that topology, read the Named Servers section in the repository before assuming the single-server examples generalise.

Where mcp-proxy is the wrong tool

The project is a transport bridge, not an authorisation layer or a policy engine. It forwards headers and tokens; it does not decide which tools a client may call. If you need per-tool access control, request inspection or audit logging, mcp-proxy is not that product. The SSE-to-stdio mode is also a genuine exposure risk if misconfigured: the README notes that --host defaults to 127.0.0.1, and setting it to 0.0.0.0 opens the spawned local stdio server to the network. The README's own example shows 0.0.0.0 as a possible value, so the choice is deliberate, but it should be deliberate. Finally, the proxy adds a process and a hop. For a client and server that already share a transport, it is pure overhead.

How it compares with writing your own bridge

The obvious alternative is a small custom script using the MCP SDKs to read stdio messages and re-emit them over HTTP, or the reverse. That approach gives you full control over framing, retries and logging, and it avoids a dependency. The difference is that mcp-proxy already handles both directions, both SSE and Streamable HTTP, OAuth2 client credentials, header injection and environment-variable token passing. A hand-rolled bridge would need to reimplement those pieces and keep them aligned with MCP transport changes. The trade-off is the opposite of flexibility: you inherit the project's argument surface and its release cadence. The repository shows a steady release history, with v0.10.0 in October 2025, v0.11.0 in January 2026 and v0.12.0 in May 2026, so the tool is being maintained rather than abandoned. The latest push recorded is July 2026.

Licence, maintenance and what to verify first

The project is MIT licensed, which permits commercial and private use with the usual attribution and warranty disclaimer. That is a permissive licence, but it is not legal advice; check your own obligations. Maintenance cost is mostly upgrade cost: the tool is a single Python package with a container image, and the release notes are the place to check for argument changes between versions. The main thing to verify before adopting is which mode you actually need, because the two modes have different arguments and different security properties. Then confirm the remote server's transport and set --transport accordingly. Then decide how credentials reach the proxy, whether through API_ACCESS_TOKEN, --headers or the OAuth2 flags. If your client already speaks the server's transport, the correct decision is to skip mcp-proxy entirely.

Editorial conclusion

Adopt mcp-proxy if you need Claude Desktop or another stdio-only MCP client to reach a remote SSE or Streamable HTTP server, or if you need to expose a local stdio server over SSE. Do not adopt it as a general API gateway or as a substitute for authentication and network controls you have not configured. Before deploying, verify which mode you need, confirm the transport flag (--transport=streamablehttp or sse) matches your remote server, and check whether the OAuth2 or API_ACCESS_TOKEN options fit your auth model.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sparfenyuk/mcp-proxy on GitHub
Community notes

Community notes