MCP Proxy Server
by sparfenyuk
# mcp-proxy



[](https://codecov.io/gh/sparfenyuk/mcp-proxy)
[](https://smithery.ai/server/mcp-proxy)
- [mcp-proxy](#mcp-proxy)
- [About](#about)
- [1. stdio to SSE](#1-stdio-to-sse)
- [1.1 Configuration](#11-configuration)
- [1.2 Example usage](#12-example-usage)
- [2. SSE to stdio](#2-sse-to-stdio)
- [2.1 Configuration](#21-configuration)
- [2.2 Example usage](#22-example-usage)
- [Installation](#installation)
- [Installing via Smithery](#installing-via-smithery)
- [Installing via PyPI](#installing-via-pypi)
- [Installing via Github repository (latest)](#installing-via-github-repository-latest)
- [Installing as container](#installing-as-container)
- [Extending the container image](#extending-the-container-image)
- [Docker Compose Setup](#docker-compose-setup)
- [Command line arguments](#command-line-arguments)
- [Testing](#testing)
## About
The `mcp-proxy` is a tool that lets you switch between server transports. There are two supported modes:
1. stdio to SSE
2. SSE to stdio
## 1. stdio to SSE
Run a proxy server from stdio that connects to a remote SSE server.
This mode allows clients like Claude Desktop to communicate to a remote server over SSE even though it is not supported natively.
```mermaid
graph LR
A["Claude Desktop"] <--> |stdio| B["mcp-proxy"]
B <--> |SSE| C["External MCP Server"]
style A fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px
style B fill:#e6e6ff,stroke:#333,color:black,stroke-width:2px
style C fill:#e6ffe6,stroke:#333,color:black,stroke-width:2px
```
### 1.1 Configuration
This mode requires passing the URL to the MCP Server SSE endpoint as the first argument to the program.
Arguments
| Name | Required | Description | Example |
| ---------------- | -------- | ------------------------------------------------ | --------------------------------------------- |
| `command_or_url` | Yes | The MCP server SSE endpoint to connect to | http://example.io/sse |
| `--headers` | No | Headers to use for the MCP server SSE connection | Authorization 'Bearer my-secret-access-token' |
Environment Variables
| Name | Required | Description | Example |
| ------------------ | -------- | ---------------------------------------------------------------------------- | ---------- |
| `API_ACCESS_TOKEN` | No | Can be used instead of `--headers Authorization 'Bearer <API_ACCESS_TOKEN>'` | YOUR_TOKEN |
### 1.2 Example usage
`mcp-proxy` is supposed to be started by the MCP Client, so the configuration must be done accordingly.
For Claude Desktop, the configuration entry can look like this:
```json
{
"mcpServers": {
"mcp-proxy": {
"command": "mcp-proxy",
"args": ["http://example.io/sse"],
"env": {
"API_ACCESS_TOKEN": "access-token"
}
}
}
}
```
## 2. SSE to stdio
Run a proxy server exposing a SSE server that connects to a local stdio server.
This allows remote connections to the local stdio server. The `mcp-proxy` opens a port to listen for SSE requests, spawns a local stdio server that handles MCP requests.
```mermaid
graph LR
A["LLM Client"] <-->|SSE| B["mcp-proxy"]
B <-->|stdio| C["Local MCP Server"]
style A fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px
style B fill:#e6e6ff,stroke:#333,color:black,stroke-width:2px
style C fill:#e6ffe6,stroke:#333,color:black,stroke-width:2px
```
### 2.1 Configuration
This mode requires the `--sse-port` argument to be set. The `--sse-host` argument can be set to specify the host IP address that the SSE server will listen on. Additional environment variables can be passed to the local stdio server using the `--env` argument. The command line arguments for the local stdio server must be passed after the `--` separator.
Arguments
| Name | Required | Description | Example |
| -------------------- | -------------------------- | ---------------------------------------------------------------- | --------------------- |
| `command_or_url` | Yes | The command to spawn the MCP stdio server | uvx mcp-server-fetch |
| `--sse-port` | No, random available | The SSE server port to listen on | 8080 |
| `--sse-host` | No, `127.0.0.1` by default | The host IP address that the SSE server will listen on | 0.0.0.0 |
| `--env` | No | Additional environment variables to pass to the MCP stdio server | FOO=BAR |
| `--pass-environment` | No | Pass through all environment variables when spawning the server | --no-pass-environment |
| `--allow-origin` | No | Pass through all environment variables when spawning the server | --allow-cors "\*" |
### 2.2 Example usage
To start the `mcp-proxy` server that listens on port 8080 and connects to the local MCP server:
```bash
# Start the MCP server behind the proxy
mcp-proxy uvx mcp-server-fetch
# Start the MCP server behind the proxy with a custom port
mcp-proxy --sse-port=8080 uvx mcp-server-fetch
# Start the MCP server behind the proxy with a custom host and port
mcp-proxy --sse-host=0.0.0.0 --sse-port=8080 uvx mcp-server-fetch
# Start the MCP server behind the proxy with a custom user agent
# Note that the `--` separator is used to separate the `mcp-proxy` arguments from the `mcp-server-fetch` arguments
mcp-proxy --sse-port=8080 -- uvx mcp-server-fetch --user-agent=YourUserAgent
```
This will start an MCP server that can be connected to at `http://127.0.0.1:8080/sse`
## Installation
### Installing via Smithery
To install MCP Proxy for Claude Desktop automatically via [Smithery](https://smithery.ai/server/mcp-proxy):
```bash
npx -y @smithery/cli install mcp-proxy --client claude
```
### Installing via PyPI
The stable version of the package is available on the PyPI repository. You can install it using the following command:
```bash
# Option 1: With uv (recommended)
uv tool install mcp-proxy
# Option 2: With pipx (alternative)
pipx install mcp-proxy
```
Once installed, you can run the server using the `mcp-proxy` command. See configuration options for each mode above.
### Installing via Github repository (latest)
The latest version of the package can be installed from the git repository using the following command:
```bash
uv tool install git+https://github.com/sparfenyuk/mcp-proxy
```
> [!NOTE]
> If you have already installed the server, you can update it using `uv tool upgrade --reinstall` command.
> [!NOTE]
> If you want to delete the server, use the `uv tool uninstall mcp-proxy` command.
### Installing as container
Starting from version 0.3.2, it's possible to pull and run the corresponding container image:
```bash
docker run -t ghcr.io/sparfenyuk/mcp-proxy:v0.3.2-alpine --help
```
## Extending the container image
You can extend the `mcp-proxy` container image to include additional executables. For instance, `uv` is not included by default, but you can create a custom image with it:
```Dockerfile
# file: mcp-proxy.Dockerfile
FROM ghcr.io/sparfenyuk/mcp-proxy:latest
# Install the 'uv' package
RUN python3 -m ensurepip && pip install --no-cache-dir uv
ENV PATH="/usr/local/bin:$PATH" \
UV_PYTHON_PREFERENCE=only-system
ENTRYPOINT [ "mcp-proxy" ]
```
## Docker Compose Setup
With the custom Dockerfile, you can define a service in your Docker Compose file:
```yaml
services:
mcp-proxy-custom:
build:
context: .
dockerfile: mcp-proxy.Dockerfile
network_mode: host
restart: unless-stopped
ports:
- 8096:8096
command: "--pass-environment --sse-port=8096 --sse-host 0.0.0.0 uvx mcp-server-fetch"
```
> [!NOTE]
> Don't forget to set `--pass-environment` argument, otherwise you'll end up with the error "No interpreter found in managed installations or search path"
## Command line arguments
```bash
usage: mcp-proxy [-h] [-H KEY VALUE] [-e KEY VALUE] [--pass-environment | --no-pass-environment] [--sse-port SSE_PORT] [--sse-host SSE_HOST]
[--allow-origin ALLOW_ORIGIN [ALLOW_ORIGIN ...]]
[command_or_url] [args ...]
Start the MCP proxy in one of two possible modes: as an SSE or stdio client.
positional arguments:
command_or_url Command or URL to connect to. When a URL, will run an SSE client, otherwise will run the given command and connect as a stdio client. See corresponding options for more details.
options:
-h, --help show this help message and exit
SSE client options:
-H KEY VALUE, --headers KEY VALUE
Headers to pass to the SSE server. Can be used multiple times.
stdio client options:
args Any extra arguments to the command to spawn the server
-e KEY VALUE, --env KEY VALUE
Environment variables used when spawning the server. Can be used multiple times.
--pass-environment, --no-pass-environment
Pass through all environment variables when spawning the server.
SSE server options:
--sse-port SSE_PORT Port to expose an SSE server on. Default is a random port
--sse-host SSE_HOST Host to expose an SSE server on. Default is 127.0.0.1
--allow-origin ALLOW_ORIGIN [ALLOW_ORIGIN ...]
Allowed origins for the SSE server. Can be used multiple times. Default is no CORS allowed.
Examples:
mcp-proxy http://localhost:8080/sse
mcp-proxy --headers Authorization 'Bearer YOUR_TOKEN' http://localhost:8080/sse
mcp-proxy --sse-port 8080 -- your-command --arg1 value1 --arg2 value2
mcp-proxy your-command --sse-port 8080 -e KEY VALUE -e ANOTHER_KEY ANOTHER_VALUE
mcp-proxy your-command --sse-port 8080 --allow-origin='*'
```
## Testing
Check the `mcp-proxy` server by running it with the `mcp-server-fetch` server. You can use the [inspector tool](https://modelcontextprotocol.io/docs/tools/inspector) to test the target server.
```bash
# Run the stdio server called mcp-server-fetch behind the proxy over SSE
mcp-proxy --sse-port=8080 uvx mcp-server-fetch &
# Connect to the SSE proxy server spawned above using another instance of mcp-proxy given the URL of the SSE server
mcp-proxy http://127.0.0.1:8080/sse
# Send CTRL+C to stop the second server
# Bring the first server to the foreground
fg
# Send CTRL+C to stop the first server
```