notebook-tools-mcp
Provides tools for reading, searching, and editing Jupyter notebook (.ipynb) files directly as JSON, enabling efficient navigation of cell contents, metadata, and outputs without requiring a Jupyter server or kernel.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@notebook-tools-mcpshow overview of notebook.ipynb"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
notebook-tools-mcp
MCP server for Jupyter notebook navigation and editing. Reads .ipynb files directly as JSON — no Jupyter server, no kernel, no overhead.
Problem
AI CLI agents (Claude Code, Gemini CLI, Codex) working inside VS Code Dev Containers don't have a good way of interacting with Jupyter notebooks. Notebooks are JSON files where 90%+ of the bytes are base64-encoded image outputs and execution metadata. Reading a 1MB notebook with a standard file-read tool wastes ~294K tokens on noise. Agents re-invent notebook parsing logic every session, burning tokens on the same problem repeatedly.
Related MCP server: jupyter-editor-mcp
Architecture
6 files, ~700 lines, zero dependencies beyond mcp>=1.10.1:
notebook_tools_mcp/
__init__.py (35L) FastMCP instance + server instructions
_helpers.py (182L) Shared utilities: load/save, cell formatting, parsing
read_tools.py (251L) 6 read tools
search_tools.py (126L) 2 search tools
write_tools.py (104L) 3 write tools
server.py (16L) Entry pointEach file < 260 lines. Single responsibility. Shared helpers avoid duplication. No circular imports.
Design decisions
No Jupyter server. Works in remote VS Code Dev Containers (Docker) over SSH. Adding a Jupyter server means extra memory, extra complexity, zero value when VS Code already renders notebooks natively.
No dependencies beyond mcp. Notebooks are JSON. Python's stdlib json module reads them perfectly. nbformat (and its 50+ transitive Jupyter ecosystem deps) is unnecessary weight.
No execution. Running code requires a kernel, which requires a server. That's the complexity this tool exists to avoid.
stdio transport only. Launched on demand by the MCP client, communicates via stdin/stdout, exits when done. No HTTP endpoints, no WebSocket connections, no persistent processes.
Consistent index-based addressing. All 11 tools use integer cell indices. nb_overview shows indices → nb_read_cell(15) reads → nb_write_cell(15, ...) edits. One addressing scheme throughout.
sort_keys=True on save. Matches Jupyter/nbformat convention for deterministic output. Prevents noisy git diffs from key reordering between load/save cycles.
Write tools vs NotebookEdit
Claude Code has a built-in NotebookEdit tool (addresses cells by cell_id or cell_number). This server also provides write tools. Both are kept intentionally:
MCP write tools | NotebookEdit (built-in) | |
Addressing | Integer index (matches |
|
Best for | Within the | When VS Code or another tool provides the cell_id |
Footprint | 102 lines | Built-in |
The MCP write tools exist for workflow cohesion — an agent using nb_overview to find a cell already has its index. Requiring a lookup to get the cell_id for NotebookEdit would add a pointless extra step.
Tools we deliberately did NOT build
These were considered and rejected because nb_search / nb_search_dir already cover them:
Rejected tool | Why |
|
|
|
|
|
|
| Agent calls |
Building AST-based dependency tracking would add ~200+ lines of fragile code that breaks across Python/R/Julia/bash cells. Not worth it when regex search + LLM reasoning achieves the same result.
How agents discover when to use these tools
Claude Code (and similar agents) decide which tool to use based on three channels, in order of priority:
MCP server
instructions— set viaFastMCP(instructions=...)in__init__.py. Injected into the system prompt of every conversation where the server is connected. This is where the "use nb_search INSTEAD OF Grep for .ipynb" guidance lives. Agents see this before any tool is called.Tool docstrings — the
"""..."""on each@mcp.tool()function. Shown when the agent discovers tools (e.g. via ToolSearch). Each docstring says what the tool does AND when to prefer it over alternatives.CLAUDE.md — project-level instructions always loaded into context. Contains a decision table mapping tasks to tools (e.g. "Read notebook → nb_overview, NOT Read tool").
All three channels reinforce the same message: use nb_* tools for .ipynb, never Read/Grep.
Install
# pip
pip install git+https://github.com/tony-zhelonkin/notebook-tools-mcp.git
# uv
uv pip install git+https://github.com/tony-zhelonkin/notebook-tools-mcp.gitFor development (editable install from a local clone):
git clone https://github.com/tony-zhelonkin/notebook-tools-mcp.git
pip install -e notebook-tools-mcp/Configure
Add to .mcp.json:
{
"mcpServers": {
"notebook-tools": {
"type": "stdio",
"command": "python",
"args": ["-m", "notebook_tools_mcp.server"]
}
}
}Or toggle via SciAgent-toolkit addon system:
./scripts/manage-addon.sh enable notebook-tools --project-dir /path/to/project
./scripts/manage-addon.sh disable notebook-tools --project-dir /path/to/projectTools
All tools take notebook_path (absolute path) as first parameter unless noted.
Read tools
Tool | Parameters | What it does |
|
| Kernel info, format version, cell counts, file size, output size |
|
| Cell index, type, line/char count, first-line preview, output sizes |
|
| Full source of one cell by index, optional truncated outputs |
|
| Batch read with range syntax, optional type filter |
|
| All cells from a markdown heading to the next same-or-higher-level heading |
|
| All markdown headings with cell indices and levels |
Search tools
Tool | Parameters | What it does |
|
| Regex search across cells with context, optional type filter |
|
| Search all |
Write tools
Tool | Parameters | What it does |
|
| Overwrite source content of an existing cell |
|
| Insert a new cell at position |
|
| Delete a cell |
Typical agent workflow
1. nb_metadata(path) → Is this notebook big? What kernel?
2. nb_overview(path) → See all cells at a glance (index, type, preview)
3. nb_headings(path) → Understand section structure
4. nb_search(path, "pattern") → Find cells containing a variable/function/import
5. nb_read_cell(path, 15) → Read the specific cell you need
6. nb_read_cells(path, "15-20") → Read a range of related cells
7. nb_read_section(path, "Results") → Read everything under a heading
8. nb_write_cell(path, 15, src) → Edit the cell in-placeThe key insight: start with nb_overview, then drill down. Never read the full notebook.
Token economics
Tested against real project notebooks:
Notebook | File size | Cells | Full |
|
|
|
NB00 (smallest) | 51 KB | 30 | ~13K tokens | ~500 tokens | ~50-200 tokens | ~100 tokens |
NB01 (biggest) | 1.15 MB | 41 | ~294K tokens | ~690 tokens | ~100-400 tokens | ~50-200 tokens |
For the 1.15 MB notebook, nb_overview achieves ~425x token reduction vs reading the full file. Individual cell reads achieve ~700-2900x reduction.
CLAUDE.md snippet
Add this to your project's CLAUDE.md to steer Claude Code toward using notebook-tools instead of built-in tools for .ipynb files. The server also ships its own instructions (injected into the system prompt automatically), but CLAUDE.md reinforcement ensures consistent behavior, especially when agents are choosing between several tools.
### Working with .ipynb files
**ALWAYS use `notebook-tools` MCP tools instead of built-in tools for `.ipynb` files:**
| Task | Use this | NOT this | Why |
|------|----------|----------|-----|
| Read notebook | `nb_overview` then `nb_read_cell` | `Read` tool | Read loads raw JSON with base64 images, wastes 100K+ tokens |
| Search notebook | `nb_search` / `nb_search_dir` | `Grep` tool | Grep sees JSON structure, nb_search sees cell source code |
| Edit notebook cell | `nb_write_cell` (by index from nb_overview) | — | Consistent index-based workflow |
| Edit notebook cell | `NotebookEdit` (by cell_id) | — | Use when cell_id is known from another source |
| Insert/delete cells | `nb_insert_cell` / `nb_delete_cell` | — | Index-based, consistent with nb_overview |
**Workflow:** `nb_overview` (get cell indices) → `nb_read_cell` or `nb_search` → `nb_write_cell`.
All 11 tools are in the `notebook-tools` MCP server. Start with `nb_overview` for any notebook interaction.When NotebookEdit is the better choice
The MCP write tools and Claude Code's built-in NotebookEdit solve the same problem (editing notebook cells) with different addressing:
MCP
nb_write_cell: addresses by integer index. Best when you're already in thenb_overview→nb_read_cell→ edit flow, because you already have the index.NotebookEdit: addresses by
cell_id(a string like"abc123") orcell_number(0-indexed integer). Best when something else gives you the cell_id — for example, VS Code's notebook renderer, or theidfield shown innb_read_celloutput.
In practice, MCP write tools are used more often because the typical agent workflow starts with nb_overview, which shows indices. NotebookEdit is better when the agent already has a cell_id from a non-MCP source, or when it needs NotebookEdit's edit_mode: "insert" semantics (insert after a specific cell_id rather than at an index position).
Both tools can coexist safely. The server's instructions field tells agents to prefer MCP write tools during the nb_overview workflow. There is no conflict as long as the agent doesn't use both on the same cell in the same turn.
Changelog
v0.3.0 (2026-02-25)
Fix: Added
sort_keys=Truetosave_notebookfor deterministic JSON output matching Jupyter/nbformat conventionAgent guidance: Added
FastMCP(instructions=...)with tool selection decision tree (injected into agent system prompt)Agent guidance: Rewrote all 11 tool docstrings to specify when to use each tool vs built-in alternatives
Doc: Documented write tools relationship to Claude Code's built-in NotebookEdit
Doc: Added "How agents discover when to use these tools" section explaining the 3-channel guidance pattern
v0.2.0 (2026-02-25)
Added write tools:
nb_write_cell,nb_insert_cell,nb_delete_cellModularized into 6-file architecture
Added
nb_headings,nb_read_section,nb_search_dir
v0.1.0
Initial release:
nb_metadata,nb_overview,nb_read_cell,nb_read_cells,nb_search
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tony-zhelonkin/notebook-tools-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server