universal-notebook-mcp
Run Jupyter notebooks from any AI editor. Gives your AI assistant full access to read, edit, and execute .ipynb files with live kernel output — without needing to open JupyterLab.
Works in Antigravity, Cursor, Windsurf, Claude Desktop, Claude Code, and any MCP-compatible tool. Works on Windows, macOS, and Linux.
Quick start
1. Install Python 3.10+
Skip this step if you already have Python 3.10 or later (python --version to check).
Windows
Download from python.org and run the installer. Make sure to check "Add Python to PATH" during setup.
Or with winget:
winget install Python.Python.3.11
Linux
# Debian / Ubuntu
sudo apt install python3.11 python3.11-pip
# Fedora / RHEL
sudo dnf install python3.11
# Arch
sudo pacman -S python
2. Install the package
pip install universal-notebook-mcp
On macOS/Linux, if
pipmaps to Python 3.9, usepip3.11instead. On Windows,pipfrom the Python 3.11 installer works directly.
Verify it installed:
nb-mcp --help
3. Add to your editor
Pick your editor below and paste the config. Replace the path with the folder that contains your notebooks.
⚠️ Use the real absolute path — MCP clients pass arguments as literal strings and do not expand editor variables like
${workspaceFolder}.Windows paths: use forward slashes or escape backslashes:
C:/Users/you/notebooksorC:\\Users\\you\\notebooks
Antigravity
Create .antigravity/mcp.json in your project folder:
{
"mcpServers": {
"notebook": {
"command": "nb-mcp",
"args": ["--workspace-root", "/absolute/path/to/notebooks"]
}
}
}
Or go to Settings → MCP Servers and add the same block.
Cursor
~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project):
{
"mcpServers": {
"notebook": {
"command": "nb-mcp",
"args": ["--workspace-root", "/absolute/path/to/notebooks"]
}
}
}
Windsurf
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"notebook": {
"command": "nb-mcp",
"args": ["--workspace-root", "/absolute/path/to/notebooks"]
}
}
}
Claude Desktop
Config file location:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"notebook": {
"command": "nb-mcp",
"args": ["--workspace-root", "/absolute/path/to/notebooks"]
}
}
}
Claude Code
claude mcp add notebook -- nb-mcp --workspace-root /absolute/path/to/notebooks
4. Reload your editor and go
Your AI can now work with notebooks. Try:
"List the cells in my notebook" "Run cell 3 and show me the output" "Fix the error in cell 5 and re-run it"
What it can do
| Tool | What it does | |
|---|---|---|
| 📖 | notebook_list_cells |
See all cells (type, tags, first line) |
| 📖 | notebook_read_cell |
Read full source + saved outputs of a cell |
| 📖 | notebook_read_cell_output |
Read just the outputs (stream, result, error) |
| 📖 | notebook_read_metadata |
Read notebook metadata (kernel, language, etc.) |
| 📖 | notebook_list_stages |
List all pipeline stage tags in the notebook |
| ✏️ | notebook_edit_cell |
Edit a cell's source |
| ✏️ | notebook_insert_cell |
Insert a new cell at any position |
| ✏️ | notebook_delete_cell |
Delete a cell |
| ✏️ | notebook_edit_cell_metadata |
Add or update cell tags and metadata |
| ✏️ | notebook_edit_metadata |
Update notebook-level metadata |
| ▶️ | notebook_run_cell |
Execute one cell and get its output |
| ▶️ | notebook_run_range |
Execute a range of cells |
| ▶️ | notebook_run_all |
Execute all cells |
| ▶️ | notebook_run_pipeline |
Execute all cells tagged with a stage name |
| 🔧 | notebook_restart_kernel |
Clear kernel state (variables, imports) |
| 🔧 | notebook_list_kernels |
List all installed kernel environments |
| 🔧 | notebook_list_active_kernels |
See which notebooks have a live kernel |
Kernel state persists across calls — variables and imports from one cell are available in the next, just like a normal Jupyter session.
Edits are checkpointed — every edit creates a timestamped backup (.checkpoint_<timestamp>.ipynb) before writing, so you can always roll back.
Troubleshooting
nb-mcp: command not found (or 'nb-mcp' is not recognized on Windows)
The install directory isn't on your PATH. Find where pip installed it:
# macOS / Linux
python3 -m site --user-scripts # or: which nb-mcp after activating your venv
# Windows (PowerShell)
python -c "import sys; print(sys.prefix + r'\Scripts')"
Then either use the full path in your MCP config:
"command": "C:\\Users\\you\\AppData\\Local\\Programs\\Python\\Python311\\Scripts\\nb-mcp.exe"
Or add the Scripts/bin directory to your PATH permanently.
ModuleNotFoundError when running a cell
The kernel doesn't have your packages installed. Register your environment:
pip install ipykernel
python -m ipykernel install --user --name myenv --display-name "My Env"
Then restart the kernel via notebook_restart_kernel or ask your AI to switch kernels.
List available kernels:
jupyter kernelspec list
Windows: path format in MCP config
Both of these work:
"C:/Users/you/notebooks" ✓ forward slashes
"C:\\Users\\you\\notebooks" ✓ escaped backslashes
Avoid raw backslashes — they break JSON:
"C:\Users\you\notebooks" ✗ invalid JSON
For developers — running tests, contributing
git clone https://github.com/your-org/universal-notebook-mcp.git
cd universal-notebook-mcp
# macOS / Linux
pip3.11 install -e ".[dev]"
# Windows (PowerShell)
python -m pip install -e ".[dev]"
Run the tests:
python -m pytest # all tests
python -m pytest -m "not integration" # unit tests only (no kernel needed)
python -m pytest -m integration -v # integration tests (needs ipykernel)
Or use make targets on macOS/Linux:
make test # unit only
make test-all # unit + integration
make coverage # coverage report
make lint # ruff linter
Project layout:
src/universal_notebook_mcp/
server.py ← MCP tool surface (17 tools, FastMCP, stdio)
notebook_adapter.py ← nbformat cell CRUD + checkpoint backups
kernel_session.py ← jupyter_client async kernel lifecycle
notebook_runner.py ← cell execution + output capture
tests/
conftest.py ← shared fixtures (mocked kernel, workspace)
fixtures/ ← simple.ipynb, pipeline.ipynb, error.ipynb
test_*.py ← 125 tests (116 unit + 9 integration)
Security
All notebook paths are sandboxed to --workspace-root. Paths that escape it (e.g. ../secret.ipynb) or that aren't .ipynb files are rejected with an error.
License
MIT
Release files for universal-notebook-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| universal_notebook_mcp-0.1.0.tar.gz | 25.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| universal_notebook_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.3 kB
Release files / universal_notebook_mcp-0.1.0.tar.gz
| Download URL | universal_notebook_mcp-0.1.0.tar.gz |
|---|---|
| Size | 25.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7e855df6341075f0b99a8830ebd4262ef2d87072af39e316a90c4fb80bc7a546
|
|
BLAKE2b-256 checksum How to use checksums |
b36ca1f38070397dd744cbd04e520dfdb322104d0195403bfa749091bb492c5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / universal_notebook_mcp-0.1.0-py3-none-any.whl
| Download URL | universal_notebook_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bf61fd6d352896f93a577918e7533d56a73747dde545cd6b97ada58e92569a58
|
|
BLAKE2b-256 checksum How to use checksums |
902f284852717e36ff6068174253b4bf3742bf9f27018c34ff4417480bad67c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|