OptionalData ScienceVersion 1.0.0

Jupyter Notebook (hamelnb) Skill for Hermes Agent: Iterative Python REPL

Iterative Python via live Jupyter kernel (hamelnb).

Written by Neura Market from the official Hermes Agent documentation for Jupyter Notebook. Commands, paths, and version numbers are reproduced from the source unchanged.

Read the official documentation

The Jupyter Notebook skill (hamelnb) gives Hermes Agent a stateful Python REPL backed by a live Jupyter kernel. Variables, imports, and objects persist across executions, making it the right choice when you need to explore an API, inspect a DataFrame, or iterate on complex code step by step. Reach for this when a one-shot script won't cut it and you want the interactive feel of a notebook.

What it does

This skill lets the agent run Python code inside a real Jupyter notebook kernel, keep state between calls, inspect live variables, and edit notebook cells programmatically. All interactions go through the Jupyter REST API, so the agent can create, read, update, and delete cells, restart the kernel, and verify the notebook runs cleanly from top to bottom. The result is a persistent Python session that the agent can treat like a scratchpad for data science, machine learning, or any iterative task.

Before you start

Three prerequisites must be met before the skill can function.

  1. uv must be installed. Run which uv to confirm it is on your PATH.
  2. JupyterLab must be installed via uv: uv tool install jupyterlab.
  3. A Jupyter server must be running. See the Setup section below.

The skill is optional and installed on demand. It works on Linux, macOS, and Windows.

Setup

The hamelnb script lives at a fixed path. If the repository is not yet cloned, clone it first.

SCRIPT="$HOME/.agent-skills/hamelnb/skills/jupyter-live-kernel/scripts/jupyter_live_kernel.py"
git clone https://github.com/hamelsmu/hamelnb.git ~/.agent-skills/hamelnb

Starting JupyterLab

Check whether a server is already running.

uv run "$SCRIPT" servers

If no servers are found, start one. The command below disables authentication for local agent access and runs the server headless.

jupyter-lab --no-browser --port=8888 --notebook-dir=$HOME/notebooks \
  --IdentityProvider.token='' --ServerApp.password='' > /tmp/jupyter.log 2>&1 &
sleep 3

Creating a Notebook for REPL Use

If you only need a REPL and do not have an existing notebook, create a minimal notebook file and start a kernel session via the Jupyter REST API.

mkdir -p ~/notebooks
curl -s -X POST http://127.0.0.1:8888/api/sessions \
  -H "Content-Type: application/json" \
  -d '{"path":"scratch.ipynb","type":"notebook","name":"scratch.ipynb","kernel":{"name":"python3"}}'

Core Workflow

All commands return structured JSON. Always use --compact to save tokens.

1. Discover servers and notebooks

uv run "$SCRIPT" servers --compact
uv run "$SCRIPT" notebooks --compact

2. Execute code (primary operation)

uv run "$SCRIPT" execute --path <notebook.ipynb> --code '<python code>' --compact

State persists across execute calls. Variables, imports, and objects all survive.

Multi-line code works with $'...' quoting:

uv run "$SCRIPT" execute --path scratch.ipynb --code $'import os\nfiles = os.listdir(".")\nprint(f"Found {len(files)} files")' --compact

3. Inspect live variables

uv run "$SCRIPT" variables --path <notebook.ipynb> list --compact
uv run "$SCRIPT" variables --path <notebook.ipynb> preview --name <varname> --compact

4. Edit notebook cells

# View current cells
uv run "$SCRIPT" contents --path <notebook.ipynb> --compact

# Insert a new cell
uv run "$SCRIPT" edit --path <notebook.ipynb> insert \
  --at-index <N> --cell-type code --source '<code>' --compact

# Replace cell source (use cell-id from contents output)
uv run "$SCRIPT" edit --path <notebook.ipynb> replace-source \
  --cell-id <id> --source '<new code>' --compact

# Delete a cell
uv run "$SCRIPT" edit --path <notebook.ipynb> delete --cell-id <id> --compact

5. Verification (restart + run all)

Only use when the user asks for a clean verification or you need to confirm the notebook runs top-to-bottom.

uv run "$SCRIPT" restart-run-all --path <notebook.ipynb> --save-outputs --compact

Practical Tips from Experience

  1. First execution after server start may timeout, the kernel needs a moment to initialize. If you get a timeout, just retry.
  2. The kernel Python is JupyterLab's Python, packages must be installed in that environment. If you need additional packages, install them into the JupyterLab tool environment first.
  3. --compact flag saves significant tokens, always use it. JSON output can be very verbose without it.
  4. For pure REPL use, create a scratch.ipynb and don't bother with cell editing. Just use execute repeatedly.
  5. Argument order matters, subcommand flags like --path go BEFORE the sub-subcommand. E.g.: variables --path nb.ipynb list not variables list --path nb.ipynb.
  6. If a session doesn't exist yet, you need to start one via the REST API (see Setup section). The tool can't execute without a live kernel session.
  7. Errors are returned as JSON with traceback, read the ename and evalue fields to understand what went wrong.
  8. Occasional websocket timeouts, some operations may timeout on first try, especially after a kernel restart. Retry once before escalating.
  9. If websocket consistently times out on this host, force zmq transport: uv run "$SCRIPT" execute --transport zmq .... Symptom: every execute returns "Websocket execution may already have reached the kernel, so auto fallback was skipped". The kernel actually ran fine (REST shows execution_state=idle and execution_count increments), only the websocket reply channel is broken. zmq transport uses jupyter_client directly and sidesteps the issue.
  10. When starting a fresh server for REST-only use, add --ServerApp.disable_check_xsrf=True, otherwise POST /api/sessions returns "'_xsrf' argument missing from POST" and kernel session creation fails.

Timeout Defaults

The script has a 30-second default timeout per execution. For long-running operations, pass --timeout 120. Use generous timeouts (60+) for initial setup or heavy computation.

When not to use it

Use execute_code for one-shot scripts that need Hermes tool access (web search, file operations) and do not require state between steps. Use terminal for shell commands, builds, installs, git, and process management. If you would not reach for a Jupyter notebook for the task, do not use this skill.

Limits and gotchas

  • The kernel Python is the same Python that runs JupyterLab. Packages you need must be installed in that environment, not in the agent's environment.
  • A live kernel session must exist before any execute call. The tool cannot create one on its own.
  • Websocket timeouts can occur, especially after a kernel restart. Retry once before assuming a deeper problem.
  • The --compact flag is essential for token efficiency. Without it, JSON output can be very verbose.
  • Argument order is strict: flags like --path must come before the sub-subcommand.

What pairs with this

This skill lives under the Data Science category in the optional-skills directory. It pairs naturally with other data science skills in the same category, such as data analysis or visualization tools that also benefit from a persistent Python state.