MCP Proxy
A Python-based MCP proxy server (Model Context Protocol) that facilitates communication between MCP clients and various backend MCP servers (stdio, SSE, or streamable HTTP). It supports two primary modes: proxying a local stdio server to SSE/StreamableHTTP, or proxying an external SSE/StreamableHTTP server to stdio. The library is actively maintained, with version 0.11.0 released in January 2026, and typically sees frequent updates.
Common errors
-
No interpreter found in managed installations or search path
cause When `mcp-proxy` executes a command like `uvx` or `npx` for a local STDIO server, the child process does not inherit the necessary environment variables (e.g., PATH, Python interpreter location) by default.fixAdd the `--pass-environment` argument to your `mcp-proxy` command: `mcp-proxy --pass-environment <other_args> <command_for_stdio_server>`. -
mcp-proxy: error: unrecognized arguments: --sse-port
cause You are using the deprecated `--sse-port` argument (or `--sse-host`). These arguments were replaced with a more generic naming convention.fixReplace `--sse-port` with `--port` and `--sse-host` with `--host`. -
401 Unauthorized
cause The `mcp-proxy` is configured to require authentication (e.g., an API key or client credentials), but the incoming client request is missing the required `Authorization` header or `API_ACCESS_TOKEN`.fixEnsure the client making requests to `mcp-proxy` provides the correct authentication credentials, typically via an `Authorization: Bearer <token>` header or `X-API-Key: <key>`, or by setting the `API_ACCESS_TOKEN` environment variable if configured this way. Alternatively, review `mcp-proxy` configuration to disable authentication if it's not needed for your environment. -
Connection refused when client tries to connect to mcp-proxy
cause The `mcp-proxy` server is either not running, listening on a different IP address or port than the client expects, or a firewall is blocking the connection to the specified host and port.fixVerify that `mcp-proxy` is running (`ps aux | grep mcp-proxy`), check the `--host` and `--port` arguments used when starting the proxy, and confirm that no firewall rules (e.g., `ufw`, `iptables`, security groups) are preventing inbound connections to the `mcp-proxy`'s listening address and port.
Warnings
- breaking Version 0.11.0 introduced client credentials authentication for SSE and streamable HTTP connections. Existing unauthenticated or differently authenticated clients may break and require updates to provide the necessary credentials.
- deprecated The command-line arguments `--sse-port` and `--sse-host` are deprecated. They have been replaced by the more generic `--port` and `--host` arguments for specifying the listening address.
- gotcha When `mcp-proxy` starts a local STDIO server (e.g., via `uvx` or `npx`), the environment variables of the `mcp-proxy` process are not automatically passed to the child process. This can lead to 'No interpreter found' or similar errors if the child process relies on specific environment settings.
- breaking Version 0.8.0 introduced a significant feature for 'Named servers', allowing a single `mcp-proxy` instance to manage multiple STDIO servers. This changed the configuration paradigm for handling multiple backend servers, potentially breaking existing deployments that might have relied on workarounds or different configurations for such scenarios.
Install
-
pip install mcp-proxy
Quickstart
import os
# Example 1: Proxy a local stdio MCP server to expose it via SSE/HTTP
# This command starts mcp-proxy listening on port 8080 and proxies
# an 'mcp-server-fetch' stdio server, also enabling a named server 'my_server'.
# Note: 'uvx' should be installed and in PATH, or specify full path.
print("Starting mcp-proxy to expose a local stdio server via SSE/HTTP...")
os.system("mcp-proxy --port 8080 --named-server my_server 'uvx mcp-server-fetch'")
# Example 2: Proxy an external SSE/HTTP MCP server to stdio
# This command connects mcp-proxy to a remote SSE server at http://example.io/sse
# and exposes it as a local stdio server (for clients like Claude Desktop).
# Use a dummy token for demonstration; in real use, use os.environ.get('API_ACCESS_TOKEN', '')
# to load from environment or a secure secret management system.
print("\nStarting mcp-proxy to proxy a remote SSE server to stdio...")
api_token = os.environ.get('API_ACCESS_TOKEN', 'YOUR_DUMMY_TOKEN_HERE')
print(f"Using API_ACCESS_TOKEN: {api_token[:5]}...")
os.system(f"mcp-proxy http://example.io/sse --api-access-token {api_token}")