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.ipynbfilecell_idx: Zero-based index of the target cellcell_language: Enum value (python,markdown,javascript, etc.)is_new_cell: Boolean flag for insertion versus replacementold_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 notebookor shell scripts - Deterministic edits: The
old_stringrequirement ensures exact-match replacement, preventing unintended modifications - Controlled execution: Kernel runs happen through the
run_notebook_cellabstraction, 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.jsonandVSCode Agent/gpt-5.txt, not through shell commands. - The
edit_notebooktool requires precise parameters includingold_stringfor deterministic cell replacement and supports multiple languages via thecell_languageenum. - Execution isolation ensures the LLM never directly accesses the Jupyter kernel; instead, the assistant calls
run_notebook_celland 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →