Minimal MCP STDIO to Remote SSE proxy in Python.
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
messageevents) - Send path: remote provides an
endpointSSE 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-18vs strict servers on2025-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).
chmod +x ./*.sh
./install-global-uv.sh
Windows (CMD):
install-global-uv.cmd
Uninstall:
./uninstall-global-uv.sh
Windows (CMD):
uninstall-global-uv.cmd
If your shell can’t find the command, ensure ~/.local/bin is on your PATH.
Option B — Dev install (editable)
python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e .
Run
mcp-remote-py http://127.0.0.1:8080/mcp
Transport strategy (Node mcp-remote와 유사):
# 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:
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:
[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:
command = "/Users/<you>/.local/bin/mcp-remote-py"
Claude Desktop (`claude_desktop_config.json`)
{
"mcpServers": {
"ida-remote": {
"command": "mcp-remote-py",
"args": ["http://127.0.0.1:8080/mcp"]
}
}
}
Cursor (`~/.cursor/mcp.json`)
{
"mcpServers": {
"ida-remote": {
"command": "mcp-remote-py",
"args": ["http://127.0.0.1:8080/mcp"]
}
}
}
Windsurf (`~/.codeium/windsurf/mcp_config.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
messageevent. Non-protocol events are ignored. - Don’t see the command: add
~/.local/bintoPATH(macOS zsh:~/.zprofileis a good default). - Logs: all logs go to stderr by design; stdout is reserved for MCP protocol.
Configuration
{"mcpServers": {"ida-remote": {"command": "mcp-remote-py", "args": ["http://127.0.0.1:8080/mcp"]}}}