Metadata-Version: 2.4
Name: universal-notebook-mcp
Version: 0.1.0
Summary: Universal Jupyter Notebook MCP server — full cell I/O, kernel execution, and pipeline stages, compatible with Antigravity, Cursor, Windsurf, Claude Desktop, and any MCP-compliant editor
Project-URL: Repository, https://github.com/am-3/jupyter-mcp
Author: Atharva M
License: MIT
Keywords: ai,ipynb,jupyter,llm,mcp,notebook
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: OS Independent
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: ipykernel>=6.0.0
Requires-Dist: jupyter-client>=8.0.0
Requires-Dist: mcp[cli]>=1.0.0
Requires-Dist: nbformat>=5.9.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.12; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Description-Content-Type: text/markdown

# 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).

<details>
<summary><b>Windows</b></summary>

Download from [python.org](https://www.python.org/downloads/) and run the installer.
Make sure to check **"Add Python to PATH"** during setup.

Or with winget:
```powershell
winget install Python.Python.3.11
```
</details>

<details>
<summary><b>macOS</b></summary>

```bash
brew install python@3.11
```

Or download from [python.org](https://www.python.org/downloads/).
</details>

<details>
<summary><b>Linux</b></summary>

```bash
# Debian / Ubuntu
sudo apt install python3.11 python3.11-pip

# Fedora / RHEL
sudo dnf install python3.11

# Arch
sudo pacman -S python
```
</details>

---

### 2. Install the package

```bash
pip install universal-notebook-mcp
```

> On macOS/Linux, if `pip` maps to Python 3.9, use `pip3.11` instead.
> On Windows, `pip` from the Python 3.11 installer works directly.

Verify it installed:
```bash
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/notebooks` or `C:\\Users\\you\\notebooks`

<details>
<summary><b>Antigravity</b></summary>

Create `.antigravity/mcp.json` in your project folder:

```json
{
  "mcpServers": {
    "notebook": {
      "command": "nb-mcp",
      "args": ["--workspace-root", "/absolute/path/to/notebooks"]
    }
  }
}
```

Or go to `Settings → MCP Servers` and add the same block.
</details>

<details>
<summary><b>Cursor</b></summary>

`~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per-project):

```json
{
  "mcpServers": {
    "notebook": {
      "command": "nb-mcp",
      "args": ["--workspace-root", "/absolute/path/to/notebooks"]
    }
  }
}
```
</details>

<details>
<summary><b>Windsurf</b></summary>

`~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "notebook": {
      "command": "nb-mcp",
      "args": ["--workspace-root", "/absolute/path/to/notebooks"]
    }
  }
}
```
</details>

<details>
<summary><b>Claude Desktop</b></summary>

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`

```json
{
  "mcpServers": {
    "notebook": {
      "command": "nb-mcp",
      "args": ["--workspace-root", "/absolute/path/to/notebooks"]
    }
  }
}
```
</details>

<details>
<summary><b>Claude Code</b></summary>

```bash
claude mcp add notebook -- nb-mcp --workspace-root /absolute/path/to/notebooks
```
</details>

### 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:

```bash
# 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:

```json
"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:

```bash
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:
```bash
jupyter kernelspec list
```

---

### Windows: path format in MCP config

Both of these work:
```json
"C:/Users/you/notebooks"       ✓ forward slashes
"C:\\Users\\you\\notebooks"    ✓ escaped backslashes
```

Avoid raw backslashes — they break JSON:
```json
"C:\Users\you\notebooks"       ✗ invalid JSON
```

---

<details>
<summary><b>For developers — running tests, contributing</b></summary>

```bash
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:
```bash
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:
```bash
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)
```

</details>

---

## 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
