Skip to main content
Glama
elphinsnow

mcp-remote-py

by elphinsnow
README.md
# mcp-remote-py

Minimal **MCP STDIO ↔ Remote SSE** proxy in Python.

This project is a deliberately small reimplementation of the core idea from `mcp-remote`:

- Local side: MCP over **STDIO** (newline-delimited JSON / JSONL)
- Remote side: MCP over **SSE** (receives JSON-RPC via SSE `message` events)
- Send path: remote provides an `endpoint` SSE event; subsequent client→server messages are sent via **HTTP POST** to that endpoint.

## What this is / isn’t

**Included**

- Bidirectional proxying of MCP JSON-RPC messages
- No stdout contamination (logs go to stderr)
- Optional custom headers (`--header 'Name: value'`)
- **Stateful HTTP Support**: Handles FastMCP's "streamable-http" by persisting `mcp-session-id`.
- **Protocol Version Hijacking**: Transparently rewrites protocol versions (e.g., handles clients on `2025-06-18` vs strict servers on `2025-11-25`).

**Intentionally excluded** (keep it simple)

- OAuth / authorization flows
- Token storage / refresh
- Multi-instance coordination / lockfiles
- Automated HTTP↔SSE fallback (manual strategy selection via `--transport`)

## Install

### Option A — “Global” install with `uv` (recommended)

Installs a user-scoped executable into `~/.local/bin` (macOS/Linux) or `%USERPROFILE%\.local\bin` (Windows).

```bash
chmod +x ./*.sh
./install-global-uv.sh
```

Windows (CMD):

```bat
install-global-uv.cmd
```

Uninstall:

```bash
./uninstall-global-uv.sh
```

Windows (CMD):

```bat
uninstall-global-uv.cmd
```

If your shell can’t find the command, ensure `~/.local/bin` is on your `PATH`.

### Option B — Dev install (editable)

```bash
python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e .
```

## Run

```bash
mcp-remote-py http://127.0.0.1:8080/mcp
```

Transport strategy (Node `mcp-remote`와 유사):

```bash
# default: http-first
mcp-remote-py http://127.0.0.1:8080/mcp --transport http-first

# force SSE-only (서버가 HTTP transport를 지원하지 않을 때)
mcp-remote-py http://127.0.0.1:8080/mcp --transport sse-only
```

Custom headers:

```bash
mcp-remote-py http://127.0.0.1:8080/mcp \
	--header 'Authorization: Bearer TOKEN'
```

## MCP client configs (copy/paste)

### Codex (`~/.codex/config.toml`)

Codex expects TOML like this:

```toml
[mcp_servers.ida-remote]
command = "/Users/<you>/.local/bin/mcp-remote-py"
args = ["http://127.0.0.1:8080/mcp"]
```

If you installed via `uv` into `~/.local/bin`, `command` is typically:

```toml
command = "/Users/<you>/.local/bin/mcp-remote-py"
```

### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "ida-remote": {
      "command": "mcp-remote-py",
      "args": ["http://127.0.0.1:8080/mcp"]
    }
  }
}
```

### Cursor (`~/.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "ida-remote": {
      "command": "mcp-remote-py",
      "args": ["http://127.0.0.1:8080/mcp"]
    }
  }
}
```

### Windsurf (`~/.codeium/windsurf/mcp_config.json`)

```json
{
  "mcpServers": {
    "ida-remote": {
      "command": "mcp-remote-py",
      "args": ["http://127.0.0.1:8080/mcp"]
    }
  }
}
```

## Troubleshooting

- **Nothing works / random parse errors:** ensure the remote SSE server emits JSON-RPC only on the default `message` event. Non-protocol events are ignored.
- **Don’t see the command:** add `~/.local/bin` to `PATH` (macOS zsh: `~/.zprofile` is a good default).
- **Logs:** all logs go to stderr by design; stdout is reserved for MCP protocol.