Skip to main content
Glama
aazizisoufiane

mcp-python-repl

README.md
# 🐍 mcp-python-repl

A **production-grade** MCP server providing a persistent Python REPL with multi-session support, sandboxing, and timeout protection.

Built for LLM agents that need to execute Python code across multiple turns with **variables that persist between calls**.

## ✨ Features

| Feature | Description |
|---|---|
| **Multi-session** | Isolated sessions with unique IDs β€” run parallel workflows |
| **Persistent namespace** | Variables survive across calls within a session |
| **Timeout protection** | Configurable execution timeout (SIGALRM on Unix) |
| **Sandboxing** | Optional mode blocks dangerous modules (`subprocess`, `socket`, etc.) |
| **Package install** | Install pip packages on-the-fly (prefers `uv` for speed) |
| **File execution** | Run `.py` files inside the persistent session |
| **Dual transport** | stdio (local) and streamable-http (remote) |
| **Full introspection** | List variables, get history, check server status |
| **Env-based config** | All settings via `REPL_*` environment variables |

## πŸš€ Quick Start

### With Claude Desktop / Cursor (stdio)

Add to your MCP config:

```json
{
  "mcpServers": {
    "python-repl": {
      "command": "uvx",
      "args": ["mcp-python-repl"]
    }
  }
}
```

### With uv (local dev)

```bash
# Clone and run
git clone https://github.com/soufiane-aazizi/mcp-python-repl.git
cd mcp-python-repl
uv run mcp-python-repl
```

### HTTP transport (remote / multi-client)

```bash
REPL_TRANSPORT=streamable-http REPL_PORT=8000 uv run mcp-python-repl
```

## πŸ› οΈ Tools

### Code Execution

| Tool | Description |
|---|---|
| `repl_run_code` | Execute Python code with persistent namespace |
| `repl_run_file` | Execute a `.py` file in the session |
| `repl_install_package` | Install a pip package (uses `uv` if available) |

### Namespace Management

| Tool | Description |
|---|---|
| `repl_list_namespace` | List all variables in a session |
| `repl_get_variable` | Get the full value of a variable |
| `repl_set_variable` | Inject a variable from JSON |
| `repl_delete_variable` | Delete a specific variable |
| `repl_clear_namespace` | Clear all variables in a session |

### Session Management

| Tool | Description |
|---|---|
| `repl_list_sessions` | List all active sessions |
| `repl_delete_session` | Delete a session and its data |

### Debugging

| Tool | Description |
|---|---|
| `repl_get_history` | Get execution history for a session |
| `repl_server_status` | Server config, Python version, session count |

## πŸ”„ How Persistence Works

```
Call 1:  repl_run_code(code="data = [1,2,3]; total = sum(data); result = total")
         β†’ returns: {"result": 6, "session_id": "a1b2c3d4e5f6", "new_variables": ["data", "total"]}

Call 2:  repl_run_code(code="doubled = [x*2 for x in data]; result = doubled", session_id="a1b2c3d4e5f6")
         β†’ returns: {"result": [2,4,6], "new_variables": ["doubled"]}
```

> **Important:** The `result` variable is for returning output to the caller. It does **NOT** persist. Use named variables instead.

## βš™οΈ Configuration

All settings are configurable via environment variables:

| Variable | Default | Description |
|---|---|---|
| `REPL_TIMEOUT` | `30` | Max execution time in seconds |
| `REPL_MAX_SESSIONS` | `50` | Maximum concurrent sessions |
| `REPL_SESSION_TTL` | `120` | Session expiry in minutes |
| `REPL_MAX_OUTPUT` | `1048576` | Max stdout/stderr capture (bytes) |
| `REPL_SANDBOX` | `false` | Enable sandboxing (`true`/`false`) |
| `REPL_TRANSPORT` | `stdio` | Transport: `stdio` or `streamable-http` |
| `REPL_HOST` | `127.0.0.1` | HTTP host (when using HTTP transport) |
| `REPL_PORT` | `8000` | HTTP port (when using HTTP transport) |
| `REPL_WORKDIR` | `cwd` | Working directory for executions |

### Sandbox Mode

When `REPL_SANDBOX=true`, the following modules are blocked:

`subprocess`, `shutil`, `ctypes`, `socket`, `http.server`, `xmlrpc`, `ftplib`, `smtplib`, `telnetlib`, `webbrowser`

And the following builtins are removed: `exec`, `eval`, `compile`, `__import__` (replaced with a restricted version).

## πŸ§ͺ Development

```bash
# Install dev dependencies
uv sync --extra dev

# Run tests
uv run pytest -v

# Lint
uv run ruff check src/ tests/

# Test with MCP Inspector
npx @modelcontextprotocol/inspector uv run mcp-python-repl
```

## πŸ“¦ Project Structure

```
mcp-python-repl/
β”œβ”€β”€ src/mcp_python_repl/
β”‚   β”œβ”€β”€ __init__.py       # Package metadata
β”‚   β”œβ”€β”€ config.py         # Env-based configuration
β”‚   β”œβ”€β”€ session.py        # Multi-session manager with TTL
β”‚   β”œβ”€β”€ executor.py       # Python code executor (timeout + sandbox)
β”‚   └── server.py         # MCP server with all tools
β”œβ”€β”€ tests/
β”‚   └── test_core.py      # Unit + integration tests
β”œβ”€β”€ pyproject.toml        # uv/hatch project config
β”œβ”€β”€ LICENSE               # MIT
└── README.md
```

## πŸ“„ License

MIT β€” See [LICENSE](LICENSE).

TDQS

A4/5.0

Scored across 12 tools

Disambiguation5/5

Each tool targets a distinct operation: running code vs. running files, managing variables (list/get/set/delete/clear), managing sessions (list/delete), plus package installation, history, and server status. There is no overlap between tools; even run_code vs. run_file is clearly separated by input type.

Naming Consistency4/5

All tools follow a 'repl_' prefix and mostly use verb_noun naming (run_code, list_namespace, get_variable, delete_session). The only deviation is 'repl_server_status', which uses noun_noun instead of verb_noun, but this is a minor inconsistency in an otherwise uniform pattern.

Tool Count5/5

With 12 tools, the server is well-scoped for a Python REPL session manager. Each tool addresses a distinct needβ€”execution, package management, namespace introspection, session lifecycle, history, and statusβ€”without redundancy or bloat, fitting comfortably in the ideal 3-15 range.

Completeness4/5

The tool surface covers core REPL workflows: running code, running files, installing packages, managing namespace variables, listing/deleting sessions, retrieving history, and server status. Minor gaps exist, such as no explicit 'create session' tool (though sessions appear to be implicit) and no batch execution or session renaming, but these are not critical for typical usage.

Maintenance

ActivityInactive
ResponsivenessNo issues