Skip to content

Repository files navigation

autonomous-notebooks

Pre-release — APIs may change without notice.

A stdio MCP server that lets agents read, edit, and execute Jupyter notebooks headlessly. No Jupyter server, no browser, no VS Code required. Produces standard .ipynb files that open natively in VS Code.

Why

Agents are effective at research, analysis, and prototyping — but their interface with notebooks has been awkward. This package exposes notebook operations as MCP tools so Claude Code (or any MCP client) can drive notebooks without shell-escaping multi-line source, without managing kernel lifecycles, and without a persistent daemon.

How it works

  • Read/edit are kernel-free — pure nbformat operations against the given .ipynb path.
  • Exec auto-starts an in-process ipykernel subprocess the first time you execute in a notebook. The kernel is keyed by the notebook's absolute path — one kernel per notebook, many notebooks concurrently.
  • Kernels live for the lifetime of the MCP server, which Claude Code owns. When Claude Code exits, every kernel dies with it.

Install and register

Add to your project as a dev dependency:

uv add --dev git+ssh://git@github.com/treebeardtech/autonomous-notebooks

Then tell Claude Code about the server. Either add to your project's .mcp.json:

{
  "mcpServers": {
    "nb": { "command": "uv", "args": ["run", "nb", "mcp"] }
  }
}

…or register globally:

claude mcp add nb -- uv run nb mcp

Open a Claude Code session in the project and the nb tools appear in the MCP tool list.

Hello, notebook

Ask Claude:

Use the nb MCP server to create hello.ipynb and run a cell that prints the first ten Fibonacci numbers.

Then open hello.ipynb in VS Code. The cell is already run, outputs already captured.

Tools

All tools take notebook_path (absolute or relative, created if missing).

Tool Purpose
list_cells Compact one-line-per-cell summary.
read_cell(index?, cell_id?) Full source + outputs for one cell.
insert_cell(index, source, markdown=False) Insert at index; shifts existing cells down.
set_cell(source, index?, cell_id?, markdown=False) Overwrite a cell's source.
delete_cell(index?, cell_id?) Delete a cell.
clear_outputs(index?) Clear outputs from one cell or all code cells.
exec_cell(index?, cell_id?) Execute a cell; outputs written back to the file.
exec_status Progress of the notebook's active or latest job (incl. scratch output).
exec_range(start, end) Execute cells [start, end); stops on first error.
exec_all Execute every code cell in order; stops on first error.
run_scratch(code) Execute arbitrary code without writing it to the notebook; output returned inline or via exec_status.
insert_and_exec(index, source) Insert a code cell and execute it in one step.
interrupt Send SIGINT to the notebook's kernel.
shutdown_kernel Stop the notebook's kernel. Next exec starts a fresh one.

Execution never holds the agent hostage: every exec tool waits at most a short grace period (NB_MCP_BLOCK_FOR_SEC, default 5s) for the job to finish. Short cells come back inline; longer ones keep running in the background and the response tells the agent how to follow them — exec_status, or the ready-made Monitor(command='uv run nb watch --job …') line.

Admin CLI

nb mcp                 # run the stdio MCP server (Claude Code invokes this)
nb cleanup             # kill stray ipykernel processes and remove leftover .nb/
nb status              # recent jobs from the log + live ipykernel processes
nb watch --job <id>    # tail the log for one job; exits when it ends (for Monitor)

Contributing

See CONTRIBUTING.md for the component map and dev loop.

About

No description, website, or topics provided.

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages