mcp-async-repl
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-async-replrun Python code: x=5; print(x*2)"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-async-repl
Async Python REPL + Shell execution for MCP. Persistent state, background jobs, and interactive input() bridging — in a single server.
The only MCP server that combines a crash-isolated persistent Python worker, true async shell execution, stdin interaction, and job lifecycle management in one package.
What makes this different
Every other Python REPL MCP server runs exec() in the server process and blocks on long-running code. This one doesn't.
Crash-isolated Python worker — runs in a separate subprocess with a JSON protocol over stdin/stdout. If your code segfaults, the MCP server stays alive.
True async from the start — both shell and Python execution return job IDs immediately if they take >2s. Poll with status tools. Never blocks the server.
input()bridging — user code can callinput("prompt")and the server surfaces awaiting_inputstatus. Feed text viasend_python_input()to unblock it. No other REPL MCP has this.Persistent state — variables survive across
execute_python()calls until you restart the worker.Shell + REPL in one server — async shell commands with stdin support alongside the persistent Python worker. No need for two separate MCP servers.
Auto venv via uv — creates and manages a
.venvautomatically. No Docker required.
Related MCP server: MCP Code Mode
Install
# Run directly with uvx (no install needed)
uvx mcp-async-repl
# Or install from PyPI
pip install mcp-async-replConfiguration
Add to your MCP client config:
{
"mcpServers": {
"async-repl": {
"command": "uvx",
"args": ["mcp-async-repl"]
}
}
}With a custom venv path:
{
"mcpServers": {
"async-repl": {
"command": "uvx",
"args": ["mcp-async-repl"],
"env": {
"REPL_VENV_DIR": "/path/to/your/venv"
}
}
}
}Claude Desktop
Add to claude_desktop_config.json:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Claude Code
claude mcp add async-repl uvx mcp-async-replCursor
Add to .cursor/mcp.json or ~/.cursor/mcp.json.
Tools (9 total)
Python REPL
Tool | Description |
| Execute code in a persistent worker. Returns immediately if >2s. Supports |
| Feed text to a pending |
| Poll status, stdout, stderr, and input prompts for the current job. |
| Inspect all variables in the persistent session. |
| Kill and restart the worker. Clears all state. |
Async Shell
Tool | Description |
| Run any shell command in the background. Returns a job ID. |
| Send stdin text to a running shell job (e.g. |
| Poll status and output of a background shell job. |
Package Management
Tool | Description |
| Install a pip package via |
Example session
Full 8-step test run, executed by an LLM agent via Mux-Swarm:
> Test the Python REPL MCP by running these steps in order:
>
> 1. Execute: x = 42; print(f"x is {x}")
> 2. Execute: y = x * 2; print(f"y is {y}")
> 3. List variables
> 4. Execute: name = input("Enter your name: ")
> 5. Send python input: Jonathan
> 6. Execute: print(f"Hello {name}, x={x}")
> 7. Execute: import time; [print(f"tick {i}") for i in range(5) if not time.sleep(1)]
> 8. Restart the python worker, then list variables
── MuxAgent ────────────────────────────────────────────────────────────
## Step 1: Execute initial code with state and stdout
✅ Step 1 passed — State persisted, stdout captured: `x is 42`
## Step 2: Verify x persisted from step 1
✅ Step 2 passed — `x` persisted correctly: `y is 84`
## Step 3: List variables
✅ Step 3 passed — Variables `x` and `y` are present
## Step 4: Execute code with input() — should return waiting_input status
✅ Step 4 passed — Correctly returned `waiting_input` status with prompt: `'Enter your name: '`
## Step 5: Send python input to unblock
✅ Step 5 passed — Input delivered, status changed to `completed`
## Step 6: Verify name persisted alongside x and y
✅ Step 6 passed — All variables persisted: `Hello Jonathan, x=42`
## Step 7: Execute long-running code — should timeout to background
✅ Step 7a passed — Timed out to background as expected.
✅ Step 7b passed — Background job completed with all ticks: `tick 0` through `tick 4`
## Step 8: Restart python worker, then list variables
✅ Step 8 passed — Worker restarted, variables cleared (empty list returned)
───────────────────────────────────────────────────────────────────────
Summary: All Tests Passed ✅
| Step | Test | Result |
|------|-------------------------------------------|-----------------------------------|
| 1 | State persistence + stdout capture | ✅ `x is 42` |
| 2 | Variable persistence across calls | ✅ `y is 84` (x=42 persisted) |
| 3 | List variables | ✅ `x`, `y` found |
| 4 | input() returns waiting_input | ✅ Status: `waiting_input` |
| 5 | Send input unblocks | ✅ Status: `completed` |
| 6 | All variables persist together | ✅ `Hello Jonathan, x=42` |
| 7 | Long-running → background + status check | ✅ All ticks captured |
| 8 | Restart clears state | ✅ Empty variable list |Architecture
┌─────────────────────────────────────────────────────┐
│ MCP Server │
│ (mcp-async-repl) │
│ │
│ ┌─────────────────┐ ┌────────────────────────┐ │
│ │ Shell Jobs │ │ Python Worker Manager │ │
│ │ │ │ │ │
│ │ execute_command │ │ ┌──────────────────┐ │ │
│ │ send_input │ │ │ Worker Subprocess│ │ │
│ │ check_status │ │ │ │ │ │
│ │ │ │ │ Main Thread: │ │ │
│ │ Each command │ │ │ stdin loop │ │ │
│ │ runs as an │ │ │ (never blocks) │ │ │
│ │ async subprocess│ │ │ │ │ │
│ │ with job ID │ │ │ Exec Thread: │ │ │
│ │ │ │ │ runs exec() │ │ │
│ │ │ │ │ in daemon │ │ │
│ │ │ │ │ thread │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ Input Queue: │ │ │
│ │ │ │ │ bridges input()│ │ │
│ │ │ │ │ calls to host │ │ │
│ └─────────────────┘ │ └──────────────────┘ │ │
│ └────────────────────────┘ │
└─────────────────────────────────────────────────────┘The Python worker runs in a separate subprocess communicating via JSON over stdin/stdout. Inside the worker:
Main thread reads commands from stdin and dispatches them. Never blocks.
Exec thread runs
exec()in a daemon thread soinput()calls don't starve the command loop.Input queue bridges
send_python_input()from the host tobuiltins.input()inside user code. When code callsinput("prompt"), the worker emits aninput_requestmessage and blocks on the queue. The host pushes text onto the queue to unblock it.
This means:
Long-running code doesn't block the MCP server
input()works without a PTYA crash in user code kills the worker, not the server
The worker can be restarted cleanly at any time
Environment variables
Variable | Default | Description |
|
| Path to the virtual environment. Created automatically via |
How it compares
Feature | mcp-async-repl | mcp-python (hdresearch) | mcp-python-repl (soufiane-aazizi) | mcp-background-job (dylan-gluck) |
Persistent Python state | ✅ | ✅ | ✅ | ❌ |
Async (non-blocking) execution | ✅ | ❌ | ❌ | ✅ |
Background job polling | ✅ | ❌ | ❌ | ✅ |
| ✅ | ❌ | ❌ | ❌ |
Shell command execution | ✅ | ❌ | ❌ | ✅ |
Shell stdin interaction | ✅ | ❌ | ❌ | ✅ |
Crash-isolated worker | ✅ | ❌ | ❌ | N/A |
Variable introspection | ✅ | ✅ | ✅ | ❌ |
Package install tool | ✅ | ✅ | ❌ | ❌ |
Auto venv (no Docker) | ✅ | ❌ | ✅ | ✅ |
Requirements
License
Apache License 2.0
Author
Jonathan Bankston (@jnotsknab)
Built for Mux-Swarm — a CLI-native multi-agent runtime.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jnotsknab/mcp-async-repl'
If you have feedback or need assistance with the MCP directory API, please join our Discord server