MCP Proxy Server

# mcp-proxy ![GitHub License](https://img.shields.io/github/license/sparfenyuk/mcp-proxy) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mcp-proxy) ![PyPI - Downloads](https://img.shields.io/pypi/dm/mcp-proxy) [![codecov](https://codecov.io/gh/sparfenyuk/mcp-proxy/graph/badge.svg?token=31VV9L7AZQ)](https://codecov.io/gh/sparfenyuk/mcp-proxy) [![smithery badge](https://smithery.ai/badge/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 ```