# mcp-proxy: A Python Tool for Bridging stdio and SSE Transports in MCP

> mcp-proxy is a Python bridge between Model Context Protocol transports. It runs in two modes: exposing a remote SSE-based MCP server to a local stdio client such as Claude Desktop, or exposing a local stdio-based MCP server as an SSE endpoint for remote clients. Version 0.12.0, Python 3.10+, MIT license.

**sparfenyuk/mcp-proxy** — A bridge between Streamable HTTP and stdio MCP transports

- Repository: https://github.com/sparfenyuk/mcp-proxy
- Stars: 2,767 · Forks: 265
- Language: Python
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/sparfenyuk-mcp-proxy

## What mcp-proxy Does and Why It Exists

The Model Context Protocol defines two transport mechanisms: stdio, where the client and server communicate through standard input and output of a spawned process, and HTTP-based transports (SSE and Streamable HTTP), where the server listens on a network port.

Not every client supports every transport. Claude Desktop, for example, communicates with MCP servers over stdio. If a server is deployed remotely and only exposes an SSE endpoint, Claude Desktop cannot connect to it directly. mcp-proxy solves this by sitting between the two: it speaks stdio to the client and SSE (or Streamable HTTP) to the server.

## Mode 1: Connecting a stdio Client to a Remote SSE Server

In this mode, mcp-proxy accepts a connection from a stdio-based MCP client and forwards requests to a remote SSE endpoint. The client, such as Claude Desktop, launches mcp-proxy as a subprocess and communicates with it over stdio. mcp-proxy then connects to the remote server over the network.

For Claude Desktop, the configuration entry in `mcpServers` looks like this:

```json
{
  "mcpServers": {
    "mcp-proxy": {
      "command": "mcp-proxy",
      "args": [
        "http://example.io/sse"
      ],
      "env": {
        "API_ACCESS_TOKEN": "access-token"
      }
    }
  }
}
```

The first argument is the remote server's SSE endpoint URL. If the server uses Streamable HTTP instead of SSE, pass `--transport=streamablehttp`. Authorization headers can be set with `--headers` or through the `API_ACCESS_TOKEN` environment variable, which mcp-proxy converts to a Bearer token header. OAuth2 is also supported through `--client-id`, `--client-secret`, and `--token-url` flags.

## Mode 2: Exposing a Local stdio Server Over SSE

In the reverse mode, mcp-proxy spawns a local stdio-based MCP server and listens for incoming SSE connections from remote clients. The `--sse-port` argument sets the port. By default, the server binds to `127.0.0.1`; setting `--host 0.0.0.0` makes it accessible on all interfaces.

The command to run the local server is passed after the `--` separator. For example, to expose a locally installed stdio server, the mcp-proxy command would be:

```bash
mcp-proxy --port 8080 --host 0.0.0.0 -- uvx mcp-server-fetch
```

Additional environment variables for the spawned server process are passed with `--env`. The `--cwd` flag sets the working directory for the spawned process. The `--pass-environment` flag forwards all current environment variables to the child process; `--no-pass-environment` blocks this.

This mode is useful for making a development tool or a locally installed server available to a remote LLM client without rewriting the server to support HTTP transports.

## Named Servers and Config File Format

mcp-proxy supports a JSON configuration file for defining named server configurations. Rather than passing all arguments on the command line each time, a config file entry defines the command, arguments, and environment variables for a named server.

The repository includes `config_example.json` at the root as a reference. The README documents the config file format under the command line arguments section. Using named configurations is useful when managing multiple server definitions from a single mcp-proxy instance.

## Installing and Running mcp-proxy

The standard installation path uses PyPI:

```bash
pip install mcp-proxy
```

Alternatively, using uv's tool runner avoids a permanent install:

```bash
uvx mcp-proxy http://example.io/sse
```

To install the latest unreleased version from the GitHub repository, install directly from the source.

A Docker image is provided. The Dockerfile uses a two-stage build: the first stage installs dependencies with uv on Alpine, and the second stage copies the virtual environment into a clean Python 3.13 Alpine image. The entrypoint wraps `mcp-proxy` with `catatonit` as an init process to handle signal forwarding and zombie reaping. To build and run:

```bash
docker build -t mcp-proxy .
docker run mcp-proxy http://example.io/sse
```

The pyproject.toml lists Python 3.10 through 3.14 as supported versions. The three runtime dependencies are `mcp>=1.27.1`, `httpx-auth>=0.23.1`, and `uvicorn>=0.47.0`.

## Docker Compose and Container Customization

The README describes a Docker Compose setup for running mcp-proxy alongside other services. Extending the container image is documented separately, covering cases where additional tools or dependencies need to be bundled with the proxy.

The Dockerfile uses uv for dependency installation rather than pip, with layer caching optimization: dependencies are installed in a separate layer from the project source. This means rebuilding the image after a source change does not re-download dependencies if the lockfile has not changed.

The image uses `catatonit` as a process supervisor. catatonit is a minimal init for containers that correctly handles SIGTERM forwarding and reaps zombie processes. This matters for mcp-proxy because it spawns child processes in Mode 2.

## Limitations and What mcp-proxy Is Not

mcp-proxy is a transport bridge, not a gateway. It does not route requests to multiple upstream servers, apply access control policies, or load-balance across server instances. Each mcp-proxy process connects to one server in Mode 1 or spawns one server in Mode 2.

The tool runs only on macOS, Linux, and other Unix-like systems. The pyproject.toml classifiers list `OS :: MacOS`, `OS :: POSIX :: Linux`, and `OS :: Unix`; Windows is not listed.

In Mode 1, if the remote SSE server goes down, the stdio client loses its connection. mcp-proxy does not implement reconnection logic beyond what the underlying MCP library (`mcp>=1.27.1`) provides.

The pyproject.toml classification is `Development Status :: 4 - Beta`.

## How mcp-proxy Differs from an MCP Gateway

A gateway in the MCP context typically provides a centralized entry point for multiple MCP servers, with features like authentication, routing by tool name or server ID, and a management API. mcp-proxy provides none of those features by design.

The difference is scope: mcp-proxy solves the transport mismatch problem for a single client-server pair. An MCP gateway solves multi-server management for multiple clients. The search data shows interest in both `mcp proxy vs gateway` and `mcp proxy vs mcp remote`, indicating that users choosing a transport bridging solution weigh these tools against each other. mcp-proxy's value is its simplicity: it requires no server-side changes and installs with a single pip command.

The repository was at version 0.12.0 as of the last release on 2026-05-14. The last push was on 2026-07-20. The license is MIT.

## Conclusion

mcp-proxy is the right tool when a client and a server speak different MCP transports and changing either is not practical. Claude Desktop supports stdio natively; mcp-proxy makes remote SSE-based servers accessible without modifying Claude Desktop's configuration format. The reverse mode lets any stdio server be accessed by remote clients without rewriting the server. The pyproject.toml classifies it as Beta. Engineers who need a gateway with request routing, access control, or load balancing across multiple MCP servers should evaluate a purpose-built gateway instead. Confirm the Docker image's Python version matches the server's requirements before deploying in production.

## FAQ

### What is mcp-proxy?

mcp-proxy is a Python tool that bridges stdio and SSE/StreamableHTTP MCP transports. It runs in two modes: connecting a local stdio MCP client to a remote SSE server, or exposing a local stdio MCP server as an SSE endpoint for remote clients.

### How do I install mcp-proxy?

Install via PyPI with `pip install mcp-proxy`, run without installing using `uvx mcp-proxy`, or pull the Docker image from the repository's container setup. Python 3.10 or later is required.

### How does mcp-proxy compare to an MCP gateway?

mcp-proxy bridges transport protocols for a single server connection. An MCP gateway typically handles routing, authentication, and multi-server management. mcp-proxy does not route requests to multiple upstream servers or apply access control policies.

## Sources

- [Issues](https://github.com/sparfenyuk/mcp-proxy/issues)
- [License: MIT](https://github.com/sparfenyuk/mcp-proxy/blob/main/LICENSE)
- [README](https://github.com/sparfenyuk/mcp-proxy/blob/main/README.md)
- [Releases](https://github.com/sparfenyuk/mcp-proxy/releases)
- [sparfenyuk/mcp-proxy on GitHub](https://github.com/sparfenyuk/mcp-proxy)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sparfenyuk-mcp-proxy
