mcp-repl is an MCP server that gives an agent a persistent Python or R
session, kept alive across tool calls. The agent can load data once,
inspect objects, try ideas, read help, make plots, and keep iterating —
the way a person would in a REPL.
A shell tool running Rscript -e or python -c keeps forcing the agent
to rebuild context. mcp-repl keeps the session open instead:
variables, loaded packages, plots, and other state stay available until
you or the model reset.
- Sandboxed by default. The backend runs in a sandbox enforced by OS primitives at the process level — not command-specific runtime rules. Network is disabled; writes are constrained to workspace roots and the temp paths the active session needs. On Unix, a memory guardrail kills the worker if it exceeds threshold.
- Curated output. Smart echo (omitted when safe, elided for large multi-expression blocks) and in-band help pages. Plots are returned as inline images through MCP for vision-capable models, so the agent sees the plot directly; non-vision models still get the saved file path. When replies get too large, the tool response stays short and the full output is saved as a structured bundle (transcript + plot files) the model can explore on demand.
- No polling. R and Python run embedded in the worker, not behind a
stdio pipe driven by prompt-string heuristics. The server knows
precisely when the interpreter is idle and has settled, so each
replcall returns the moment the work is done — no fixed waits, no guessing whether more output is on the way. - Explicit session control. Interrupts and resets are first-class.
Install via cargo (needs the Rust toolchain):
cargo install --git https://github.com/posit-dev/mcp-repl --locked
# pin a version with: --tag v0.1.0Or use a prebuilt binary. Linux/macOS:
curl -fsSL https://raw.githubusercontent.com/posit-dev/mcp-repl/main/scripts/install.sh | shWindows PowerShell:
irm https://raw.githubusercontent.com/posit-dev/mcp-repl/main/scripts/install.ps1 | iex
Install-McpReplAppend --dev (or -Dev) for the rolling dev prerelease. Direct
downloads live on the latest release page. Linux x86_64 builds require glibc 2.35+; the glibc build produced on
Ubuntu 22.04 supports Ubuntu 22.04+.
Latest release binaries:
- Linux x86_64: https://github.com/posit-dev/mcp-repl/releases/latest/download/mcp-repl-x86_64-unknown-linux-gnu.tar.gz
- macOS arm64: https://github.com/posit-dev/mcp-repl/releases/latest/download/mcp-repl-aarch64-apple-darwin.tar.gz
- Windows x86_64: https://github.com/posit-dev/mcp-repl/releases/latest/download/mcp-repl-x86_64-pc-windows-msvc.zip
Download prebuilt dev binaries:
- Linux x86_64: https://github.com/posit-dev/mcp-repl/releases/download/dev/mcp-repl-x86_64-unknown-linux-gnu.tar.gz
- macOS arm64: https://github.com/posit-dev/mcp-repl/releases/download/dev/mcp-repl-aarch64-apple-darwin.tar.gz
- Windows x86_64: https://github.com/posit-dev/mcp-repl/releases/download/dev/mcp-repl-x86_64-pc-windows-msvc.zip
Prebuilt binaries do not bundle R or Python; install those separately.
Auto-install into agent config files:
mcp-repl install # all supported clients/interpreters
mcp-repl install --client codex # only Codex
mcp-repl install --client claude # only Claude (~/.claude.json)
mcp-repl install --client codex --interpreter r # limit to one interpreterBy default this writes entries for both r and python.
install --client codex writes
--sandbox inherit --oversized-output files — inherit tells
mcp-repl to take sandbox policy from Codex's per-call metadata (it
fails closed if the metadata is missing or malformed).
install --client claude writes an explicit --sandbox workspace-write
because Claude doesn't propagate that metadata. Bare mcp-repl (no
install) defaults to --oversized-output pager.
Manual Codex entry:
[mcp_servers.r]
command = "/Users/alice/.cargo/bin/mcp-repl"
tool_timeout_sec = 1800 # outer guard; mcp-repl handles the primary timeout
args = ["--sandbox", "inherit", "--oversized-output", "files", "--interpreter", "r"]Swap --interpreter r for --interpreter python (and rename the
section) for the Python entry.
Manual Claude entry in ~/.claude.json:
{
"mcpServers": {
"r": {
"command": "/Users/alice/.cargo/bin/mcp-repl",
"args": [
"--sandbox", "workspace-write",
"--oversized-output", "files",
"--interpreter", "r"
]
}
}
}Resolution order: --interpreter <r|python> → MCP_REPL_INTERPRETER →
r.
R. Set R_HOME to force a specific installation; otherwise it's
discovered from R on PATH (via R RHOME). Verify with R.home() in
the session.
Python. The interpreter resolves in this order:
- nearest
.venv/bin/pythonwalking upward from cwd - nearest
.venv/bin/python3walking upward from cwd - first
python3onPATH - first
pythononPATH - fallback literal
python3
.venv search stops at $HOME (inclusive), otherwise at the filesystem
root. The selected Python must expose a loadable CPython library via its
sysconfig metadata. Runtime-owned stdout/stderr is routed through
worker IPC; raw fd writes and child-process output are still captured
from the worker's stdout/stderr pipes.
- macOS: supported.
- Linux: supported. Dev binaries are glibc builds produced on Ubuntu 22.04.
- Windows: experimental for R. Python is not part of the stable Windows surface yet.
Default policy: workspace-write with network disabled. Write access
covers the working area plus worker-required temp paths (exact roots
vary by OS/policy). On Windows, the experimental R sandbox uses
parent-prepared workspace ACLs plus launch-scoped session-temp ACLs;
some environments reject the restricted-token setup.
See docs/sandbox.md for precise behavior.
repl→{ "input": "1+1\n", "timeout_ms": 10000 }repl_reset→{}
The exact repl tool description depends on the interpreter and
--oversized-output mode. Per-tool guides live in
docs/tool-descriptions/.
- Interrupt: prefix
replinput with\u0003(SIGINT, best-effort). Session continues. - Reset: call
repl_reset, or prefix input with\u0004(Ctrl-D); any remaining input runs in the fresh session. Reset attempts graceful shutdown, escalates to forceful termination, and on Unix falls back to scanning descendant processes if process-group signaling is unavailable. - In-band exits:
EOF,quit(), etc. also work — output is returned and the next request runs in a fresh worker.
Enable JSONL logs per startup:
- CLI:
--debug-dir /path/to/debug-root - Env:
MCP_REPL_DEBUG_DIR=/path/to/debug-root
Each startup writes a session directory with events.jsonl, startup
logs, and sandbox-state logs. See docs/debugging.md for the full guide, including the external
wire-trace proxy.
- Engineering map:
docs/index.md - Sandbox:
docs/sandbox.md - Worker sideband protocol:
docs/worker_sideband_protocol.md - Tool guides:
docs/tool-descriptions/
Apache-2.0. See LICENSE.