docs: update readme and --help output (#13)

* Refine CLI and reflect the change in the documentation
* Update README.md with concise examples
* Bump version

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
This commit is contained in:
Sergey Parfenyuk
2025-01-02 21:22:59 +01:00
committed by GitHub
parent 1b9880bc56
commit 874ae38087
4 changed files with 170 additions and 97 deletions

230
README.md
View File

@@ -2,52 +2,140 @@
- [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)
- [Configuration](#configuration)
- [Claude Desktop Configuration](#claude-desktop-configuration)
- [Advanced Configuration](#advanced-configuration)
- [Environment Variables](#environment-variables)
- [Command line arguments](#command-line-arguments)
- [Testing](#testing)
## About
Connect to MCP servers that run on SSE transport, or expose stdio servers as an SSE server using the MCP Proxy server.
The `mcp-proxy` is a tool that lets you switch between server transports. There are two supported modes:
## stdio to SSE
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"] <--> B["mcp-proxy"]
B <--> C["External MCP Server"]
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
```
> [!TIP]
> As of now, Claude Desktop does not support MCP servers that run on SSE transport. This server is a workaround to enable the support.
### 1.1 Configuration
## SSE to stdio
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 |
| `--api-access-token` | No | Will be sent as a `Bearer` access token in the `Authorization` header | YOUR_TOKEN |
Environment Variables
| Name | Required | Description | Example |
| ------------------ | -------- | ------------------------------------------- | ---------- |
| `API_ACCESS_TOKEN` | No | Can be used instead of `--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"] <--> B["mcp-proxy"]
B <--> C["Local MCP Server"]
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 |
### 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
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.
The latest version of the package can be installed from the git repository using the following command:
```bash
@@ -60,84 +148,54 @@ uv tool install git+https://github.com/sparfenyuk/mcp-proxy
> [!NOTE]
> If you want to delete the server, use the `uv tool uninstall mcp-proxy` command.
## Configuration
### Claude Desktop Configuration
Configure Claude Desktop to recognize the MCP server.
1. Open the Claude Desktop configuration file:
- in MacOS, the configuration file is located at `~/Library/Application Support/Claude/claude_desktop_config.json`
- in Windows, the configuration file is located at `%APPDATA%\Claude\claude_desktop_config.json`
> __Note:__
> You can also find claude_desktop_config.json inside the settings of Claude Desktop app
2. Add the server configuration
```json
{
"mcpServers": {
"mcp-proxy": {
"command": "mcp-proxy",
"env": {
"SSE_URL": "http://example.io/sse"
}
}
}
}
```
## Detailed Configuration
The MCP Proxy server can support two different approaches for proxying:
- stdio to SSE: To allow clients like Claude Desktop to run this proxy directly. The proxy is started by the LLM Client as a server that proxies to a remote server over SSE.
- SSE to stdio: To allow a client that supports remote SSE servers to access a local stdio server. This proxy opens
a port to listen for SSE requests, then spawns a local stdio server that handles MCP requests.
### stdio to SSE
Run a proxy server from stdio that connects to a remote SSE server.
Arguments
| Name | Description |
| ------------------ | ---------------------------------------------------------------------------------- |
| `--sse-url` | Required. The MCP server SSE endpoint to connect to e.g. http://example.io/sse same as environment variable `SSE_URL` |
Environment Variables
| Name | Description |
| ---------------- | ---------------------------------------------------------------------------------- |
| `SSE_URL` | The MCP server SSE endpoint to connect to e.g. http://example.io/sse same as `--sse-url` |
| `API_ACCESS_TOKEN` | Added in the `Authorization` header of the HTTP request as a `Bearer` access token |
Example usage:
## Command line arguments
```bash
uv run mcp-proxy --sse-url=http://example.io/sse
usage: mcp-proxy [-h] [--api-access-token API_ACCESS_TOKEN] [-e KEY VALUE] [--sse-port SSE_PORT] [--sse-host SSE_HOST] [command_or_url] [args ...]
Start the MCP proxy in one of two possible modes: as a SSE or stdio client.
positional arguments:
command_or_url Command or URL to connect to. When a URL, will run a 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:
--api-access-token API_ACCESS_TOKEN
Access token Authorization header passed by the client to the SSE server. Can also be set as environment variable API_ACCESS_TOKEN.
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.
SSE server options:
--sse-port SSE_PORT Port to expose a SSE server on. Default is a random port
--sse-host SSE_HOST Host to expose a SSE server on. Default is 127.0.0.1
Examples:
mcp-proxy http://localhost:8080/sse
mcp-proxy --api-access-token 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
```
## Testing
### SSE to stdio
Run a proxy server exposing an SSE server that connects to a local stdio server. This allows remote connections to the stdio server.
Arguments
| Name | Description |
| ------------------ | ---------------------------------------------------------------------------------- |
| `--sse-port` | Required. The SSE server port to listen to e.g. `8080` |
| `--sse-host` | Optional. The host IP address that the SSE server will listen on e.g. `0.0.0.0`. By default only listens on localhost. |
| command | Required. The path for the MCP stdio server command line. |
| arg1 arg2 ... | Optional. Additional arguments to the MCP stdio server command line program. |
Example usage:
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
uv run mcp-proxy --sse-port=8080 -e FOO=BAR -- /path/to/command arg1 arg2
```
# Run the stdio server called mcp-server-fetch behind the proxy over SSE
mcp-proxy --sse-port=8080 uvx mcp-server-fetch &
This will start an MCP server that can be connected to at `http://127.0.0.1:8080/sse`
# Connect to the SSE proxy server spawned above using another instance of mcp-proxy given the URL of the SSE server
mcp-proxy http://localhost: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
```

View File

@@ -24,7 +24,7 @@ classifiers = [
"Topic :: Utilities",
"Typing :: Typed",
]
version = "0.2.2"
version = "0.3.0"
requires-python = ">=3.11"
dependencies = ["mcp", "uvicorn>=0.34.0"]

View File

@@ -19,19 +19,34 @@ from .sse_client import run_sse_client
from .sse_server import SseServerSettings, run_sse_server
logging.basicConfig(level=logging.DEBUG)
SSE_URL: t.Final[str | None] = os.getenv("SSE_URL", None)
SSE_URL: t.Final[str | None] = os.getenv(
"SSE_URL",
None,
) # Left for backwards compatibility. Will be removed in future.
API_ACCESS_TOKEN: t.Final[str | None] = os.getenv("API_ACCESS_TOKEN", None)
def main() -> None:
"""Start the client using asyncio."""
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(
description=(
"Start the MCP proxy in one of two possible modes: as an SSE or stdio client."
),
epilog=(
"Examples:\n"
" mcp-proxy http://localhost:8080/sse\n"
" mcp-proxy --api-access-token YOUR_TOKEN http://localhost:8080/sse\n"
" mcp-proxy --sse-port 8080 -- your-command --arg1 value1 --arg2 value2\n"
" mcp-proxy your-command --sse-port 8080 -e KEY VALUE -e ANOTHER_KEY ANOTHER_VALUE\n"
),
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
"command_or_url",
help=(
"Command or URL to connect to. When a URL, will run an SSE client "
"to connect to the server, otherwise will run the command and "
"connect as a stdio client. Can also be set as environment variable SSE_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."
),
nargs="?", # Required below to allow for coming form env var
default=SSE_URL,
@@ -51,7 +66,7 @@ def main() -> None:
stdio_client_options.add_argument(
"args",
nargs="*",
help="Arguments to the command to run to spawn the server",
help="Any extra arguments to the command to spawn the server",
)
stdio_client_options.add_argument(
"-e",
@@ -67,13 +82,13 @@ def main() -> None:
sse_server_group.add_argument(
"--sse-port",
type=int,
default=None,
help="Port to expose an SSE server on",
default=0,
help="Port to expose an SSE server on. Default is a random port",
)
sse_server_group.add_argument(
"--sse-host",
default="127.0.0.1",
help="Host to expose an SSE server on",
help="Host to expose an SSE server on. Default is 127.0.0.1",
)
args = parser.parse_args()

2
uv.lock generated
View File

@@ -185,7 +185,7 @@ wheels = [
[[package]]
name = "mcp-proxy"
version = "0.2.2"
version = "0.3.0"
source = { editable = "." }
dependencies = [
{ name = "mcp" },