Coding agents write entire scripts in one shot, then debug from the top when something breaks. That works sometimes, but you might not always want to do it that way -- try a small piece, check the output, build up from there. Notebooks exist for exactly this reason.
hamelnb gives your coding agent a live Jupyter notebook kernel. Instead of generating a 200-line script and hoping it works, the agent can explore an API interactively, check return values, fix one thing at a time, and build up working code cell by cell -- the same way you would.

It works with Claude Code and Codex. In Claude Code, the standalone entrypoint is /hamelnb. If you load the repo as a Claude plugin, the plugin entrypoint is /hamelnb:live-kernel.
The agent connects to your local Jupyter server, finds running notebook sessions, and sends code to the live kernel. Think of it as giving the agent the same notebook workflow you already use:
The agent reads the saved .ipynb file and executes code against the running kernel. It can edit cells, inspect Python variables, and restart the kernel when you ask for a fresh run.
By default, cell outputs are saved back to the notebook file so you see results in JupyterLab as the agent works. If you only care about the result of the computation and not about updating the notebook — for example, when quickly checking a value or running a throwaway calculation — tell the agent you don't need the notebook updated. It will skip writing outputs back, which is faster.
In the Codex app, use the Skills UI to add or manage this skill.
For a direct local install:
git clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
ln -s ~/.agent-skills/hamelnb/skills/jupyter-live-kernel "${CODEX_HOME:-$HOME/.codex}/skills/hamelnb"
Then restart Codex.
If you prefer the bundled installer helper:
python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/skill-installer/scripts/install-skill-from-github.py" \
--repo hamelsmu/hamelnb \
--path skills/jupyter-live-kernel \
--name hamelnb
Clone the repo and point Claude Code at it:
git clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb
claude --add-dir ~/.agent-skills/hamelnb
Already in a session? Run /add-dir ~/.agent-skills/hamelnb.
To make the skill available in every project without --add-dir:
git clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb
mkdir -p ~/.claude/skills
ln -s ~/.agent-skills/hamelnb/.claude/skills/hamelnb ~/.claude/skills/hamelnb
If you want to use the repo as an actual Claude plugin instead of a standalone skill:
claude --plugin-dir ~/.agent-skills/hamelnb
See the Claude Code skills docs for more on how skills work.
Use the standalone skill directly:
/hamelnb use notebooks/demo.ipynb and change price from 10 to 12, rerunning only dependent cells
After the first target is clear, keep follow-up turns conversational.
If you load the repo as a Claude plugin, use:
/hamelnb:live-kernel use notebooks/demo.ipynb and change price from 10 to 12, rerunning only dependent cells
Mention hamelnb directly in your prompt:
Use hamelnb on notebooks/demo.ipynb and change price from 10 to 12, rerunning only dependent cells.
If more than one live notebook or session matches, the agent should ask you to choose instead of guessing.
Fast/default suite:
uv run --group dev pytest tests/test_jupyter_live_kernel.py -v
Full suite (includes slow live-kernel verification scenarios):
JLK_RUN_SLOW_INTEGRATION=1 uv run --group dev pytest tests/test_jupyter_live_kernel.py -v
Browser collaboration smoke test:
uv run --group dev --group browser playwright install chromium
JLK_RUN_BROWSER_INTEGRATION=1 uv run --group dev --group browser pytest tests/test_jupyter_collaboration_refresh.py -v
Manual collaborative JupyterLab launch for browser-refresh debugging:
mkdir -p /tmp/jupyter-live-kernel-collab
uv run --with jupyterlab --with jupyter-collaboration jupyter lab \
--no-browser \
--collaborative \
--LabApp.extension_manager=readonly \
--IdentityProvider.token=testtoken \
--ServerApp.password= \
--ServerApp.port=8899 \
--ServerApp.port_retries=0 \
--ServerApp.root_dir=/tmp/jupyter-live-kernel-collab
To keep before/after screenshots from the Playwright run:
JLK_BROWSER_ARTIFACT_DIR=/tmp/jlk-browser-artifacts \
JLK_RUN_BROWSER_INTEGRATION=1 \
uv run --group dev --group browser pytest tests/test_jupyter_collaboration_refresh.py -v
31 commits
Python
70.7%
Jupyter Notebook
29.3%
Coding agents write entire scripts in one shot, then debug from the top when something breaks. That works sometimes, but you might not always want to do it that way -- try a small piece, check the output, build up from there. Notebooks exist for exactly this reason.
hamelnb gives your coding agent a live Jupyter notebook kernel. Instead of generating a 200-line script and hoping it works, the agent can explore an API interactively, check return values, fix one thing at a time, and build up working code cell by cell -- the same way you would.

It works with Claude Code and Codex. In Claude Code, the standalone entrypoint is /hamelnb. If you load the repo as a Claude plugin, the plugin entrypoint is /hamelnb:live-kernel.
The agent connects to your local Jupyter server, finds running notebook sessions, and sends code to the live kernel. Think of it as giving the agent the same notebook workflow you already use:
The agent reads the saved .ipynb file and executes code against the running kernel. It can edit cells, inspect Python variables, and restart the kernel when you ask for a fresh run.
By default, cell outputs are saved back to the notebook file so you see results in JupyterLab as the agent works. If you only care about the result of the computation and not about updating the notebook — for example, when quickly checking a value or running a throwaway calculation — tell the agent you don't need the notebook updated. It will skip writing outputs back, which is faster.
In the Codex app, use the Skills UI to add or manage this skill.
For a direct local install:
git clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb
mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
ln -s ~/.agent-skills/hamelnb/skills/jupyter-live-kernel "${CODEX_HOME:-$HOME/.codex}/skills/hamelnb"
Then restart Codex.
If you prefer the bundled installer helper:
python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/skill-installer/scripts/install-skill-from-github.py" \
--repo hamelsmu/hamelnb \
--path skills/jupyter-live-kernel \
--name hamelnb
Clone the repo and point Claude Code at it:
git clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb
claude --add-dir ~/.agent-skills/hamelnb
Already in a session? Run /add-dir ~/.agent-skills/hamelnb.
To make the skill available in every project without --add-dir:
git clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb
mkdir -p ~/.claude/skills
ln -s ~/.agent-skills/hamelnb/.claude/skills/hamelnb ~/.claude/skills/hamelnb
If you want to use the repo as an actual Claude plugin instead of a standalone skill:
claude --plugin-dir ~/.agent-skills/hamelnb
See the Claude Code skills docs for more on how skills work.
Use the standalone skill directly:
/hamelnb use notebooks/demo.ipynb and change price from 10 to 12, rerunning only dependent cells
After the first target is clear, keep follow-up turns conversational.
If you load the repo as a Claude plugin, use:
/hamelnb:live-kernel use notebooks/demo.ipynb and change price from 10 to 12, rerunning only dependent cells
Mention hamelnb directly in your prompt:
Use hamelnb on notebooks/demo.ipynb and change price from 10 to 12, rerunning only dependent cells.
If more than one live notebook or session matches, the agent should ask you to choose instead of guessing.
Fast/default suite:
uv run --group dev pytest tests/test_jupyter_live_kernel.py -v
Full suite (includes slow live-kernel verification scenarios):
JLK_RUN_SLOW_INTEGRATION=1 uv run --group dev pytest tests/test_jupyter_live_kernel.py -v
Browser collaboration smoke test:
uv run --group dev --group browser playwright install chromium
JLK_RUN_BROWSER_INTEGRATION=1 uv run --group dev --group browser pytest tests/test_jupyter_collaboration_refresh.py -v
Manual collaborative JupyterLab launch for browser-refresh debugging:
mkdir -p /tmp/jupyter-live-kernel-collab
uv run --with jupyterlab --with jupyter-collaboration jupyter lab \
--no-browser \
--collaborative \
--LabApp.extension_manager=readonly \
--IdentityProvider.token=testtoken \
--ServerApp.password= \
--ServerApp.port=8899 \
--ServerApp.port_retries=0 \
--ServerApp.root_dir=/tmp/jupyter-live-kernel-collab
To keep before/after screenshots from the Playwright run:
JLK_BROWSER_ARTIFACT_DIR=/tmp/jlk-browser-artifacts \
JLK_RUN_BROWSER_INTEGRATION=1 \
uv run --group dev --group browser pytest tests/test_jupyter_collaboration_refresh.py -v
31 commits
Python
70.7%
Jupyter Notebook
29.3%