- Python 98.8%
- PowerShell 1.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
- Teach `scripts/setup.py` to prompt for `.[matlab]` installation and MATLAB kernelspec registration when `-IncludeMatlab` is used - Detect MATLAB kernels by kernelspec name, display name, or language, and warn when service restart may be needed after MATLAB setup changes - Document rerunning setup after moving the repo or recreating `.venv` - Tests: `68 passed` |
||
| scripts | ||
| src/persistent_repl_mcp | ||
| tests | ||
| .gitignore | ||
| persistent-repl-mcp-spec.md | ||
| pyproject.toml | ||
| README.md | ||
| TODO.md | ||
Persistent REPL Session Manager MCP
MCP server that provides named, persistent interpreter sessions backed by Jupyter kernels.
Use it when you want agents to keep runtime state (variables, imports, loaded data) across multiple tool calls. The MCP process is now a thin wrapper that forwards tool calls to a shared local service process, so multiple MCP wrappers can share the same session set.
Features
- Named persistent sessions
- Sync and async code execution
- Per-session FIFO queueing
- Register and reuse named Python environments
- Interrupt, restart, and destroy controls
- Execution history queries
- Structured tool results with stable error codes
Requirements
- Python 3.11+ (current package setting)
- Jupyter kernels installed for languages you want to run (for example
python3)
Install
pip install -e .
Recommended on a new machine (Windows PowerShell):
py -3.12 -m venv .venv
.\.venv\Scripts\python -m pip install --upgrade pip
.\.venv\Scripts\python -m pip install -e ".[dev]"
Or run the guided setup script:
powershell -ExecutionPolicy Bypass -File .\scripts\setup.ps1
The setup script bootstraps .venv, repairs the editable install, registers the python3
kernelspec, checks the shared service, and can add or update the Codex MCP config after
showing a line-numbered snippet of the proposed change. If you move the repo or recreate
.venv, run the setup script again because editable installs and --sys-prefix
kernelspecs are tied to the environment path. Useful switches:
.\scripts\setup.ps1 -CheckOnly
.\scripts\setup.ps1 -Venv
.\scripts\setup.ps1 -CodexConfig
.\scripts\setup.ps1 -Service
.\scripts\setup.ps1 -IncludeMatlab
.\scripts\setup.ps1 -Yes
If one or more area switches such as -Venv, -CodexConfig, or -Service are passed,
only those areas run. With no area switches, all standard checks run.
-IncludeMatlab adds optional MATLAB repair checks: it can prompt to install .[matlab],
run install-matlab-kernelspec, and warn when licensing environment variables may need to
be set before the shared service starts.
Important:
- Do not copy/sync
.venvbetween devices or Python versions. - Always recreate
.venvper machine/interpreter. - Keep only source files under version control/sync.
KernelSpec Setup
This MCP server can use any Jupyter kernel that is installed and visible to the same Python environment used to run persistent-repl-mcp.
List installed kernels:
python -m jupyter kernelspec list
Install/register a Python kernel in the active environment:
python -m pip install -e ".[python]"
python -m ipykernel install --sys-prefix --name python3 --display-name "Python 3 (ipykernel)"
Install/register MATLAB kernel support:
python -m pip install -e ".[matlab]"
install-matlab-kernelspec
The guided setup script can also perform those MATLAB steps with prompts:
.\scripts\setup.ps1 -IncludeMatlab
After installing kernelspecs, restart the MCP client and confirm kernels are visible using this server's list_available_kernels tool.
Run
persistent-repl-mcp
Behavior:
persistent-repl-mcpauto-connects to a shared local service on127.0.0.1:8765.- If the service is not running, the wrapper auto-starts it.
- You can also start the service directly:
- default behavior on Windows is detached/background
- use
--foregroundfor debugging in a visible console
persistent-repl-service
Minimal User Console
Users can inject single-line commands into an existing session with:
persistent-repl-tui
From a repo checkout before reinstalling the package, run it as a module:
python -m persistent_repl_mcp.tui
If using the project virtual environment on Windows:
.\.venv\Scripts\python.exe -m persistent_repl_mcp.tui
To install or refresh the console script:
python -m pip install -e .
Run the editable install command again after adding or changing console scripts in pyproject.toml.
Until the package is reinstalled, new .venv\Scripts entry points such as persistent-repl.exe
or persistent-repl-exec.exe may not exist yet.
Behavior:
- Lists existing sessions and prompts for a session number or name.
- Sends every non-empty input line to the selected session as code.
- Prints
stdout,stderr,result, anderrorfields from the execution. - Exits on Ctrl+C, EOF, or closing the terminal window.
- If Ctrl+C is pressed while an execution is queued or running, the console best-effort cancels that execution before exiting.
Non-Interactive Automation CLI
Automation scripts can use the non-interactive CLI to call the same shared service used by MCP and the TUI:
persistent-repl exec --session matlab_zed --code "disp('hello')"
persistent-repl exec --session matlab_zed --file "C:\path\script.m"
persistent-repl exec --session matlab_zed --stdin
The shorter persistent-repl-exec entry point is equivalent to persistent-repl exec:
persistent-repl-exec --session matlab_zed --code "disp('hello')"
Behavior:
- Auto-connects to the shared local service on
127.0.0.1:8765. - Auto-starts the service if needed, using the same
ServiceClientpath as MCP and the TUI. - Executes in a named existing session by default.
- Creates a missing session only when
--createis passed. - Reads code from exactly one of
--code,--file, or--stdin. --filereads the file contents and submits those contents to the kernel. It does not call MATLABrun('path\file.m')by path, so MATLAB script identity, relative path behavior, andrun()semantics may differ.- Writes execution stdout and result text to process stdout.
- Writes execution stderr, errors, and tracebacks to process stderr.
- Exits
0only when execution status isfinished; errors, timeouts, and cancellations exit nonzero. - Use
--jsonfor structured tool-friendly payloads. - Use
--quietto suppress successful text output; execution failures still print diagnostics to stderr. --jsonand--quietmay be placed before the command or on the final command, for examplepersistent-repl --json session listorpersistent-repl session list --json.
Create a MATLAB session on demand and execute code:
persistent-repl-exec `
--session matlab_zed `
--create `
--language matlab `
--kernel jupyter_matlab_kernel `
--cwd "C:\path\project" `
--no-expire `
--timeout 30 `
--code "disp('hello')"
For MATLAB, the first Jupyter execution after startup may be much slower than warmed executions. If automation is latency-sensitive, run an explicit warmup command with a longer timeout before timing the real workload.
MATLAB Licensing And Service Environment
MATLAB kernels may need licensing-related environment variables such as:
$env:MWI_USE_EXISTING_LICENSE = "True"
$env:MLM_LICENSE_FILE = "27000@license-server.example.com"
The shared persistent-repl service inherits its environment when the service process starts. If the service is already running, setting MATLAB-related variables in a later shell usually does not affect that existing service or any kernels it starts. Set the variables before the first MCP, TUI, or CLI call that auto-starts the shared service.
If you change MATLAB licensing variables after the service has started, stop the existing service process and let the next command restart it with the new environment. There is not currently an in-band service-stop CLI command; the practical sequence is to destroy sessions you no longer need, then stop the process listening on the service port:
# Optional: destroy sessions you no longer need.
persistent-repl session destroy --session matlab_zed
# Stop the shared service process listening on 127.0.0.1:8765.
$conn = Get-NetTCPConnection -LocalAddress 127.0.0.1 -LocalPort 8765 -State Listen -ErrorAction SilentlyContinue
if ($conn) { Stop-Process -Id $conn.OwningProcess }
# Set MATLAB licensing variables before the next command starts the service again.
$env:MWI_USE_EXISTING_LICENSE = "True"
# or:
# $env:MLM_LICENSE_FILE = "27000@license-server.example.com"
persistent-repl-exec `
--session matlab_zed `
--create `
--language matlab `
--kernel jupyter_matlab_kernel `
--cwd "C:\path\project" `
--no-expire `
--startup-timeout 60 `
--timeout 120 `
--code "disp('matlab warmup ok')"
Recommended MATLAB automation flow:
- Set any required MATLAB licensing environment variables.
- Ensure the shared service is not already running with stale environment variables.
- Create or renew the MATLAB session with
--create,--language matlab, and--kernel jupyter_matlab_kernel. - Run a simple warmup command such as
disp('matlab warmup ok')with a longer timeout. - Run latency-sensitive commands after the warmup execution has succeeded.
Other service-backed commands are available through subcommands:
persistent-repl session list
persistent-repl session create --session py1 --language python --kernel python3
persistent-repl session get --session py1
persistent-repl session interrupt --session py1
persistent-repl session restart --session py1
persistent-repl session renew --session py1 --no-expire
persistent-repl session destroy --session py1
persistent-repl enqueue --session py1 --code "print('queued')"
persistent-repl execution get --session py1 --exec-id 1
persistent-repl execution latest --session py1
persistent-repl execution history --session py1 --latest-n 10
persistent-repl execution cancel --session py1 --exec-id 2
persistent-repl queue clear --session py1
persistent-repl kernel list
persistent-repl env list
persistent-repl env register --environment py312 --python "C:\path\python.exe"
persistent-repl env get --environment py312
persistent-repl env validate --environment py312
persistent-repl env remove --environment py312
Codex config.toml Setup
Add this MCP server entry to your Codex config (typically %USERPROFILE%\\.codex\\config.toml on Windows).
Recommended (project venv):
[mcp_servers.persistent_repl]
command = "C:\\Path\\To\\The\\Repo\\Kernel Sessions MCP\\.venv\\Scripts\\python.exe"
args = ["-m", "persistent_repl_mcp.cli"]
cwd = "C:\\Path\\To\\The\\Repo\\Kernel Sessions MCP"
Alternative (if persistent-repl-mcp is on PATH):
[mcp_servers.persistent_repl]
command = "persistent-repl-mcp"
cwd = "C:\\Users\\Curt\\Dropbox\\Private\\Kernel Sessions MCP"
Restart your MCP client after updating config.toml.
Quick Start (Tool Flow)
create_sessionexecuteorexecute_enqueueget_execution/get_session_historyinterrupt_session/cancel_execution/clear_session_queue/restart_sessionas neededdestroy_sessionwhen done
Available Tools
create_sessionregister_python_environmentlist_python_environmentsget_python_environmentremove_python_environmentvalidate_python_environment(optional)list_sessionsget_sessionexecuteexecute_enqueueget_executionget_latest_executionget_session_historyinterrupt_sessioncancel_executionclear_session_queuerestart_sessionrenew_sessiondestroy_sessionlist_available_kernels
Tool descriptions are defined directly in src/persistent_repl_mcp/mcp_server.py docstrings so MCP clients/agents can discover what each tool does and how to use key arguments.
Python environment registry behavior:
- Registrations are stored at
~/.persistent-repl-mcp/python-environments.json. - Registration validates that the executable runs and captures metadata (
python_version,has_ipykernel). environment_namecan be used bycreate_sessionwhenlanguage="python"to create sessions from that interpreter.- Removing a registered environment does not terminate active sessions; it only prevents future sessions from using that name.
Runtime Behavior (v1)
create_sessionblocks until ready; sessions are not listed before ready.- Sessions use idle expiration by default (3 days). Set
expires_after_seconds=0to disable for a session. - Timeout applies to execution runtime only (not queue wait).
executereturns top-levelexec_idand fullexecutionpayload.- History selectors are mutually exclusive:
latest_n,exec_id,start_exec_id,end_exec_id. - If no history selector is provided, latest 50 entries are returned.
- Output truncation limits:
stdout64 KBstderr64 KBresult_text32 KBerror.traceback64 KB- total payload cap 256 KB
Error Codes
Tool-level failures return:
error_codemessage- optional
details
Supported error_code values:
SESSION_NOT_FOUNDSESSION_ALREADY_EXISTSSESSION_NOT_READYSESSION_DEADSESSION_EXPIREDSESSION_BUSYINVALID_ARGUMENTENVIRONMENT_ALREADY_EXISTSENVIRONMENT_NOT_FOUNDINVALID_HISTORY_QUERYEXECUTION_NOT_FOUNDQUEUE_FULLINTERNAL_ERROR
Development
Run tests:
pip install -e .[test]
PYTHONPATH=src pytest -q
If Jupyter integration tests fail with a pyzmq import error on Windows, rebuild pyzmq for the active interpreter:
.\.venv\Scripts\python -m pip install --force-reinstall --no-cache-dir --only-binary=:all: pyzmq
The test suite includes:
- Unit tests for session/queue/history logic using a fake backend
- Integration tests for Jupyter backend (auto-skipped if unavailable)