TUI, CLI, and MCP server for named persistent Jupyter-backed REPL sessions
  • Python 98.8%
  • PowerShell 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
UserCurt 80195e7358 Repair MATLAB setup flow
- 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`
2026-07-02 14:57:54 -04:00
scripts Repair MATLAB setup flow 2026-07-02 14:57:54 -04:00
src/persistent_repl_mcp feat(tui): Add direct session attachment 2026-06-04 10:29:00 -04:00
tests Repair MATLAB setup flow 2026-07-02 14:57:54 -04:00
.gitignore feat(cli): Add non-interactive automation CLI 2026-06-03 14:14:28 -04:00
persistent-repl-mcp-spec.md chore: Initialize repository 2026-06-03 10:58:09 -04:00
pyproject.toml Add guided setup for Codex persistent REPL configuration 2026-07-02 11:01:40 -04:00
README.md Repair MATLAB setup flow 2026-07-02 14:57:54 -04:00
TODO.md docs: Add MCP server management TODO 2026-06-21 12:15:33 -04:00

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 .venv between devices or Python versions.
  • Always recreate .venv per 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-mcp auto-connects to a shared local service on 127.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 --foreground for 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, and error fields 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 ServiceClient path as MCP and the TUI.
  • Executes in a named existing session by default.
  • Creates a missing session only when --create is passed.
  • Reads code from exactly one of --code, --file, or --stdin.
  • --file reads the file contents and submits those contents to the kernel. It does not call MATLAB run('path\file.m') by path, so MATLAB script identity, relative path behavior, and run() semantics may differ.
  • Writes execution stdout and result text to process stdout.
  • Writes execution stderr, errors, and tracebacks to process stderr.
  • Exits 0 only when execution status is finished; errors, timeouts, and cancellations exit nonzero.
  • Use --json for structured tool-friendly payloads.
  • Use --quiet to suppress successful text output; execution failures still print diagnostics to stderr.
  • --json and --quiet may be placed before the command or on the final command, for example persistent-repl --json session list or persistent-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:

  1. Set any required MATLAB licensing environment variables.
  2. Ensure the shared service is not already running with stale environment variables.
  3. Create or renew the MATLAB session with --create, --language matlab, and --kernel jupyter_matlab_kernel.
  4. Run a simple warmup command such as disp('matlab warmup ok') with a longer timeout.
  5. 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)

  1. create_session
  2. execute or execute_enqueue
  3. get_execution / get_session_history
  4. interrupt_session / cancel_execution / clear_session_queue / restart_session as needed
  5. destroy_session when done

Available Tools

  • create_session
  • register_python_environment
  • list_python_environments
  • get_python_environment
  • remove_python_environment
  • validate_python_environment (optional)
  • list_sessions
  • get_session
  • execute
  • execute_enqueue
  • get_execution
  • get_latest_execution
  • get_session_history
  • interrupt_session
  • cancel_execution
  • clear_session_queue
  • restart_session
  • renew_session
  • destroy_session
  • list_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_name can be used by create_session when language="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_session blocks until ready; sessions are not listed before ready.
  • Sessions use idle expiration by default (3 days). Set expires_after_seconds=0 to disable for a session.
  • Timeout applies to execution runtime only (not queue wait).
  • execute returns top-level exec_id and full execution payload.
  • 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:
    • stdout 64 KB
    • stderr 64 KB
    • result_text 32 KB
    • error.traceback 64 KB
    • total payload cap 256 KB

Error Codes

Tool-level failures return:

  • error_code
  • message
  • optional details

Supported error_code values:

  • SESSION_NOT_FOUND
  • SESSION_ALREADY_EXISTS
  • SESSION_NOT_READY
  • SESSION_DEAD
  • SESSION_EXPIRED
  • SESSION_BUSY
  • INVALID_ARGUMENT
  • ENVIRONMENT_ALREADY_EXISTS
  • ENVIRONMENT_NOT_FOUND
  • INVALID_HISTORY_QUERY
  • EXECUTION_NOT_FOUND
  • QUEUE_FULL
  • INTERNAL_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)