How AI Coding Assistants Execute and Edit Code in Jupyter Notebooks: The `edit_notebook` Tool Architecture

AI coding assistants use structured tool-calling APIs like edit_notebook and run_notebook_cell to manipulate Jupyter notebooks without spawning shell commands or Jupyter servers, isolating the LLM from direct execution environments.

When working with Jupyter notebooks, modern AI assistants such as GitHub Copilot, Claude, and Gemini do not invoke terminal commands like jupyter notebook. Instead, according to the x1xhlol/system-prompts-and-models-of-ai-tools repository, these systems rely on a structured tool-calling architecture defined in agent prompts. This approach enables precise cell editing and execution through JSON-based tool schemas while maintaining security boundaries between the language model and the runtime environment.

The Four-Step Tool-Based Workflow

AI assistants follow a standardized workflow when interacting with .ipynb files. This process is defined across multiple prompt files in the repository, specifically within VSCode Agent/gpt-5.txt and tool schema definitions.

1. Notebook Discovery with copilot_getNotebookSummary

Before editing, the assistant retrieves a structured overview of the notebook. In VSCode Agent/gpt-5.txt (lines 30-38), the prompts mandate calling copilot_getNotebookSummary to obtain cell lists, types, languages, and execution states. This prevents blind edits and ensures the LLM understands the notebook structure.

{
  "notebook_path": "analysis.ipynb"
}

2. Precise Cell Editing via edit_notebook

The core manipulation tool is edit_notebook, defined in Cursor Prompts/Agent Tools v1.0.json (lines 286-326). This tool accepts a JSON payload specifying the target notebook, cell index, language, and content replacement parameters.

Key parameters include:

  • target_notebook: File path to the .ipynb file
  • cell_idx: Zero-based index of the target cell
  • cell_language: Enum value (python, markdown, javascript, etc.)
  • is_new_cell: Boolean flag for insertion versus replacement
  • old_string: Exact existing content (required for deterministic replacement)
  • new_string: Updated cell content
{
  "name": "edit_notebook",
  "description": "Use this tool to edit a jupyter notebook cell. Use ONLY this tool to edit notebooks.",
  "parameters": {
    "type": "object",
    "properties": {
      "target_notebook": { "type": "string" },
      "cell_idx": { "type": "number" },
      "cell_language": { "type": "string", "enum": ["python","markdown","javascript","typescript","r","sql","shell","raw","other"] },
      "is_new_cell": { "type": "boolean" },
      "old_string": { "type": "string" },
      "new_string": { "type": "string" }
    },
    "required": ["target_notebook","cell_idx","cell_language","is_new_cell","old_string","new_string"]
  }
}

3. Code Execution with run_notebook_cell

After editing, the assistant invokes run_notebook_cell to execute the updated cell. As specified in VSCode Agent/gpt-5.txt (line 34), this tool runs the cell through the Jupyter kernel managed by the host environment, not the LLM itself.

{
  "notebook_path": "analysis.ipynb",
  "cell_idx": 5
}

4. State Verification and Reporting

The workflow concludes with a second call to copilot_getNotebookSummary to capture the updated execution state, followed by a markdown-formatted response presenting outputs, errors, or cell numbers to the user (lines 40-45 in VSCode Agent/gpt-5.txt).

Practical Example: Adding a Matplotlib Plot

When a user requests "Add a plot of y = x² to my notebook," the LLM constructs the following tool call:

{
  "target_notebook": "analysis.ipynb",
  "cell_idx": 5,
  "cell_language": "python",
  "is_new_cell": true,
  "old_string": "",
  "new_string": "import matplotlib.pyplot as plt\nx = range(0, 10)\ny = [i**2 for i in x]\nplt.plot(x, y)\nplt.show()"
}

The assistant emits this as a structured XML-style invocation (as per the tool format specifications):


<invoke name="edit_notebook">
<parameter name="target_notebook">analysis.ipynb</parameter>
<parameter name="cell_idx">5</parameter>
<parameter name="cell_language">python</parameter>
<parameter name="is_new_cell">true</parameter>
<parameter name="old_string"></parameter>
<parameter name="new_string">import matplotlib.pyplot as plt
x = range(0, 10)
y = [i**2 for i in x]
plt.plot(x, y)
plt.show()</parameter>
</invoke>

Security Architecture: Isolating the LLM from Execution

The repository's prompt files explicitly prohibit terminal-based Jupyter commands. This architectural decision creates a safety boundary where the LLM only emits structured JSON payloads while the host IDE (VS Code, Cursor, etc.) performs actual file I/O and kernel management.

Key security benefits:

  • No arbitrary process spawning: The LLM cannot execute jupyter notebook or shell scripts
  • Deterministic edits: The old_string requirement ensures exact-match replacement, preventing unintended modifications
  • Controlled execution: Kernel runs happen through the run_notebook_cell abstraction, allowing the host to manage timeouts, resource limits, and environment isolation

Summary

  • AI coding assistants manipulate Jupyter notebooks through structured tool APIs defined in Cursor Prompts/Agent Tools v1.0.json and VSCode Agent/gpt-5.txt, not through shell commands.
  • The edit_notebook tool requires precise parameters including old_string for deterministic cell replacement and supports multiple languages via the cell_language enum.
  • Execution isolation ensures the LLM never directly accesses the Jupyter kernel; instead, the assistant calls run_notebook_cell and the host environment manages runtime safety.
  • The workflow follows a strict sequence: discovery (copilot_getNotebookSummary), editing (edit_notebook), execution (run_notebook_cell), and verification.

Frequently Asked Questions

How does the edit_notebook tool prevent editing the wrong cell content?

The tool requires an old_string parameter containing the exact existing cell content. As implemented in Cursor Prompts/Agent Tools v1.0.json (lines 286-326), this enforces deterministic replacement—if the content does not match, the edit fails, preventing accidental overwrites when notebook state changes between the assistant's read and write operations.

Can AI assistants create new notebook cells or only modify existing ones?

Yes, assistants can insert new cells by setting is_new_cell to true and providing an empty old_string. The JSON schema in Cursor Prompts/Agent Tools v1.0.json includes this boolean flag specifically to distinguish between insertion and replacement operations at the specified cell_idx.

Why don't AI coding assistants just run jupyter notebook commands in the terminal?

According to VSCode Agent/gpt-5.txt (line 34), the prompts explicitly prohibit terminal-based Jupyter commands to maintain security isolation. Running shell commands would give the LLM arbitrary process execution capabilities, whereas the edit_notebook and run_notebook_cell tools provide a restricted, auditable interface for notebook manipulation.

What programming languages does the edit_notebook tool support?

The cell_language parameter accepts an enum of values including python, markdown, javascript, typescript, r, sql, shell, raw, and other, as defined in the tool schema at Cursor Prompts/Agent Tools v1.0.json (lines 286-326). This covers the primary languages used in data science and development workflows.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →