← Back to Blog

Claude Code NotebookEdit: Jupyter Guide (2026)

How Claude Code's NotebookEdit tool edits Jupyter notebooks cell-by-cell: insert, replace, delete without breaking execution order or JSON structure.


Editing a Jupyter notebook by hand-writing JSON is a bad time. A .ipynb file isn't source code — it's a JSON document with a cells array, each cell carrying its own cell_type, source lines, outputs, and execution metadata. Ask a generic text-editing tool to "add a cell after the imports" and it either has to reconstruct that whole structure from scratch or risks corrupting the file. That's the gap NotebookEdit closes: it lets Claude Code edit notebooks at the cell level, the same unit a human works in, instead of the raw-bytes level a normal file edit works in.

If you do any data science, ML experimentation, or exploratory analysis inside notebooks, this is the tool that keeps an agent from turning a five-line change into a broken kernel state.

Why Notebooks Need Their Own Tool

A source file is a flat sequence of text. A notebook is a tree of cells, and each cell has state that matters beyond its text: whether it's code or markdown, what it printed or plotted last time it ran, and an execution count that tracks run order. A plain text edit tool sees none of that structure — it would have to serialize and deserialize the whole JSON blob correctly on every change, and one misplaced comma turns a working notebook into one that won't even open in Jupyter.

NotebookEdit sidesteps all of that by operating on cells as the unit of change: insert a cell, replace a cell's contents, delete a cell. The tool understands the notebook's shape, so the agent never has to think about brackets, commas, or where the outputs array starts.

The Three Operations

NotebookEdit supports a small, deliberate set of actions rather than arbitrary JSON surgery:

  • Insert. Add a new cell at a specific position — before or after an existing cell — as either code or markdown.
  • Replace. Overwrite the source of an existing cell, identified by its position or ID, without touching the cells around it.
  • Delete. Remove a cell entirely, collapsing the notebook around the gap.

That's deliberately narrower than what a general-purpose edit tool offers. Notebooks don't need arbitrary diff-based patching the way source files do — almost every real edit is "change what this cell does," "add a cell here," or "this cell shouldn't exist anymore." Constraining the tool to those three operations makes every edit unambiguous and easy to verify.

Cell Boundaries Are the Point

The reason cell-level editing matters isn't just convenience — it's correctness. A notebook's execution order is part of its meaning. A cell that defines a dataframe in cell 3 and gets used in cell 7 depends on cell 3 having actually run first. If an agent edits by treating the whole notebook as one big text blob, it's trivially easy to introduce an edit that looks fine in the diff but breaks the dependency chain between cells — a variable renamed in one cell but not the three cells downstream that reference it.

Editing cell-by-cell keeps that dependency chain visible. Each change is scoped to exactly one cell, so it's obvious which cell changed and which downstream cells might need a second look — the same discipline you'd use editing the notebook by hand.

Outputs and Execution State Aren't Yours to Touch

A notebook's outputs — printed text, plot images, error tracebacks — are the record of what happened the last time that cell ran, not something an edit tool should be fabricating. NotebookEdit changes source, not outputs. Outputs get regenerated by actually re-running the cell in a kernel, not by an agent guessing what the output "should" look like and writing it into the JSON. That distinction matters: a notebook with hand-written fake outputs is actively misleading — it claims a result was produced when it wasn't.

The practical implication: after using NotebookEdit to change a cell's code, the change isn't "done" until the notebook is actually re-executed. Editing the source and re-running are two separate steps, and skipping the second one leaves a notebook whose displayed outputs no longer match its actual code.

Markdown Cells Matter Too

Notebooks mix code and prose by design — a markdown cell explaining what the next three code cells are about is part of the notebook's actual documentation, not an afterthought. NotebookEdit treats markdown cells as first-class citizens alongside code cells: insert one to explain a new section, replace one when the analysis it describes changes, delete one that's gone stale. An agent that only ever touches code cells and leaves the surrounding prose stale produces a notebook that documents what used to be true.

When to Reach for NotebookEdit vs. Edit

The rule is simple: if the file ends in .ipynb, use NotebookEdit. Every other source file — .py, .js, config files, scripts — uses the regular text-editing tool. Mixing them up doesn't work: a plain text edit applied to a notebook's raw JSON is exactly the fragile approach NotebookEdit exists to avoid, and it's easy to end up with a file that's syntactically broken JSON even when the intended change was tiny.

This also means an agent working across a mixed project — a .py module imported by a notebook, say — needs to track which tool applies to which file as it moves between them. Get the module wrong and you've broken the import; get the notebook wrong and you've broken the analysis built on top of it.

Practical Patterns

A few patterns show up constantly in notebook-heavy work:

  • Exploratory data analysis. Insert new cells to test a hypothesis without disturbing the cells that already produced a validated result above it.
  • Refactoring a pipeline. Replace a cell's source when a preprocessing step changes, but leave the cells that consume its output alone unless they also need to change.
  • Cleaning up before sharing. Delete scratch cells — the ones used to sanity-check an intermediate value — once the notebook is ready to hand off, so the final version reads as a coherent narrative instead of a debugging log.
  • Documenting as you go. Insert a markdown cell above a new code section explaining what it does and why, keeping the notebook readable for the next person (including a future instance of the same agent).

The Takeaway

NotebookEdit exists because notebooks aren't flat text files — they're structured documents where cell boundaries, execution order, and the separation between source and output all carry meaning. Insert, replace, and delete at the cell level instead of touching raw JSON, treat outputs as something the kernel produces rather than something to fabricate, and keep markdown cells as up to date as the code they describe. Get that right and an agent can work in notebooks with the same care a human analyst would.


Free: Claude custom instructions template pack

Eight copy-paste templates — developer, writer, analyst, CLAUDE.md starter, and more. Plus new guides in your inbox. No spam, unsubscribe anytime.

Or grab the templates directly — no email needed

Keep learning — for free

50+ AI courses. 590+ lessons. No paywall for starters.

Need help building this?

We build MCP servers, Claude workflows, and AI agents for teams. Strategy calls start at $150/hr.