Skip to main content
Glama
nufelroknidev

Jupiter Controller MCP

Jupiter Controller MCP (jkb-mcp)

CI Python 3.11+ Platform: Windows

Connects Claude Code to local Jupyter kernels as a set of native tools: start/restart/shutdown kernels, run code against a live kernel (including one backing a VS Code notebook), get stdout, results, errors and plots back, and execute whole notebooks with outputs saved into the .ipynb. The client never needs to know the kernel's connection details.

Built and tested with Claude Code on Windows. It is a standard MCP server over stdio, so other MCP clients should work too, but they are untested.

Security warning: this tool executes arbitrary code inside your live Jupyter kernel process, with that process's full OS privileges, exactly as if you typed it into the notebook yourself. Execution ships disabled by default; see "Enabling execution" below.

The realistic threat is not just a misbehaving client. It is untrusted data flowing through a trusted client (prompt injection): a notebook, CSV, or web page containing adversarial text can steer the model into running exfiltration or destructive code. Mitigations built in: the tool-based opt-in is session-scoped (dies with the server process; persistent enablement requires you to edit the config file yourself), and a disable_execution tool can always turn it off. Still: be deliberate about which files and data you let the model read while execution is enabled.

Requirements

  • Windows

  • Python 3.11+

  • Optional: VS Code with an active Jupyter kernel, if you want to attach to an existing notebook session. start_kernel can otherwise run everything standalone.

Related MCP server: JupyterMCP

Install

pip install git+https://github.com/nufelroknidev/jupyter-kernel-bridge-mcp.git

Or from a local clone:

git clone https://github.com/nufelroknidev/jupyter-kernel-bridge-mcp.git
pip install ./jupyter-kernel-bridge-mcp

Verify it installed correctly:

jkb-mcp --help

If jkb-mcp isn't found, your Python Scripts directory isn't on PATH. Use the full path shown by pip show -f jkb-mcp, or activate the venv you installed into.

Enabling execution

The server ships with code execution off. list_kernels and get_config always work; every tool that executes code or mutates kernel state refuses until you opt in, one of two ways:

  1. Via the client (session-scoped): call the enable_execution tool with confirm="I understand the risk". This enables execution only until the MCP server process restarts. It is deliberately never persisted, so the model (or injected instructions in data it read) can't quietly enable execution forever.

  2. Manually (persistent): edit %APPDATA%\jkb-mcp\config.json and set "execution_enabled": true, then restart the MCP server (config is cached at startup).

disable_execution turns it off again at any time. It clears the session flag and the config-file flag.

Register with Claude Code

claude mcp add jkb-mcp -- jkb-mcp

Add -s user to make it available in every project on this machine, not just the current one:

claude mcp add jkb-mcp -s user -- jkb-mcp

No absolute paths are involved; jkb-mcp resolves through whatever Python environment you installed the package into.

Teaching Claude Code about this server

The server ships its own usage guide as MCP server instructions (the recommended workflow, kernel-addressing semantics, and security rules), which Claude Code surfaces to the model automatically, so no context-file setup is required. If you want the model to reach for these tools more proactively, add a note like this to your project's CLAUDE.md:

All Jupyter-notebook work goes through the jkb-mcp MCP server: enable execution once per session (enable_execution), start or attach to a kernel (start_kernel / list_kernels), iterate with run_python, and persist results into the .ipynb with execute_notebook. Do not run notebook code through plain python subprocesses.

The "Tool reference" table below covers every tool and its parameters.

Tool reference

Tool

Gated?

Description

list_kernels()

No

Lists detected kernel connection files with age and status: alive, busy (executing), or dead (stale file).

get_config()

No

Shows current settings (execution enabled?, output limits, retention).

enable_execution(confirm)

-

Enables execution for this session only (resets on server restart). Requires confirm="I understand the risk".

disable_execution()

-

Disables execution: clears the session opt-in and the config-file flag.

run_python(code, kernel=0, timeout=60)

Yes

Executes code in a live kernel; returns text output and inline images.

run_file(path, kernel=0, timeout=60)

Yes

Reads a local .py file and executes it the same way.

interrupt_kernel(kernel=0, force=False)

Yes

Stops a stuck/runaway cell and confirms whether the interrupt landed. force=True hard-restarts a server-owned kernel if it doesn't (blocking C calls ignore Windows interrupts); state is lost.

start_kernel(kernel_name="python3", cwd="")

Yes

Starts a fresh kernel owned by this server, no VS Code needed. Supports real restart/shutdown.

restart_kernel(kernel=0)

Yes

Real process restart for server-owned kernels; best-effort protocol restart request for external (VS Code) kernels.

shutdown_kernel(kernel=0)

Yes

Shuts down a server-owned kernel. Refuses kernels owned by other apps.

execute_notebook(path, kernel=0, timeout_per_cell=120, stop_on_error=True, cells=None)

Yes

Runs a .ipynb's code cells and saves outputs (incl. embedded plot images) into the file, like nbconvert --execute; VS Code shows them on reload.

list_variables(kernel=0)

Yes

Lists user variables in the kernel namespace with type, shape/length, size.

get_variable(name, kernel=0, max_chars=4000)

Yes

Deep preview of one variable: type, shape/dtypes, DataFrame columns + head(), capped repr.

list_kernelspecs()

No

Lists installed kernelspecs usable with start_kernel(kernel_name=...).

list_notebook_cells(path)

No

Shows cell indices/types/first lines + saved-output status for execute_notebook(cells=[...]).

kernel parameter: 0 (the default) auto-selects the most recent kernel that responds to a health check, silently falling back to the next-most-recent if it's unresponsive. Any other explicit index is honored exactly: it fails with a clear message rather than silently substituting a different kernel. Because indices are positions in the newest-first list, they shift when new kernels appear; to target a specific kernel reliably across calls, pass its connection-file name (or a unique substring of it) from list_kernels instead, e.g. kernel="kernel-jkb-1a2b3c.json".

Troubleshooting

Message

Cause

Fix

"No Jupyter kernel connection files found..."

No .ipynb has ever run a cell

Open a notebook in VS Code and run a cell.

"Found N kernel connection file(s) but none responded..."

The kernel process(es) behind those files are closed

Restart the notebook's kernel (run a cell again).

"Kernel index N ... did not respond to a health check"

You asked for a specific kernel index and it's dead

Use list_kernels to find a live index, or omit kernel to auto-select.

"Kernel N is currently busy running another request..."

Two calls hit the same kernel at once

Wait for the first to finish, or use a different kernel index.

"... is malformed or incomplete..."

A connection file was partially written or corrupted

It's skipped automatically; this is informational, not fatal.

"Execution exceeded the timeout..."

Your cell ran past the timeout you passed

Partial output (if any) is included. The kernel was interrupted; on Windows this can take a few seconds to land.

"Code execution is disabled..."

The safety gate is off (the default)

See "Enabling execution" above.

Data locations

What

Where

Config (execution gate, limits)

%APPDATA%\jkb-mcp\config.json

Logs

%LOCALAPPDATA%\jkb-mcp\logs\server.log (rotates at 5MB, 5 backups)

Captured images

%LOCALAPPDATA%\jkb-mcp\outputs\ (auto-cleaned: 7-day retention, 500MB cap by default, both configurable in config.json)

Nothing is ever logged above DEBUG level for the actual code/output content, since kernel output can contain secrets. Only short previews and outcomes are logged at INFO.

Uninstall

pip uninstall jkb-mcp
claude mcp remove jkb-mcp

Optionally also delete %APPDATA%\jkb-mcp and %LOCALAPPDATA%\jkb-mcp.

License

PolyForm Noncommercial 1.0.0: free for personal, research, educational, and other noncommercial use. Commercial use requires a separate paid license from the copyright holder: nufel.rokni.dev@gmail.com. See LICENSE for full terms.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

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/nufelroknidev/Jupyter-kernel-bridge-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server