# Jupyter MCP Server Setup Guide

This document describes how to set up the [Datalayer Jupyter MCP Server](https://github.com/datalayer/jupyter-mcp-server) so that Claude Code can interact with Jupyter notebooks (create, read, edit, execute cells).

## Prerequisites

- Python >= 3.10
- `uv` installed (`pip install uv` or via system package manager)
- A project with a `pyproject.toml` and a `.venv`

## 1. Add Dependencies

Add the following to your `pyproject.toml` under `[project.optional-dependencies]` (e.g. in a `dev` group):

```toml
[project.optional-dependencies]
dev = [
    # ... your other dev deps ...
    "jupyterlab==4.4.1",
    "jupyter-collaboration==4.0.2",
    "jupyter-mcp-tools>=0.1.4",
    "ipykernel",
    "pycrdt>=0.12.17",
]
```

Then install:

```bash
uv pip install -e ".[dev]"
```

## 2. Create `jupyter.sh`

Create a script `jupyter.sh` in the project root:

```bash
#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "$0")"

uv run jupyter lab --port 8888 --IdentityProvider.token MY_TOKEN --ip 0.0.0.0
```

Make it executable:

```bash
chmod +x jupyter.sh
```

Replace `MY_TOKEN` with a token of your choice. This same token must match the one in `.mcp.json` (see below).

## 3. Create `.mcp.json`

Create a `.mcp.json` file in the project root:

```json
{
  "mcpServers": {
    "jupyter-notebook": {
      "command": "uvx",
      "args": ["jupyter-mcp-server@latest"],
      "env": {
        "JUPYTER_URL": "http://localhost:8888",
        "JUPYTER_TOKEN": "MY_TOKEN",
        "ALLOW_IMG_OUTPUT": "false"
      }
    }
  }
}
```

- `JUPYTER_TOKEN` must match the token used in `jupyter.sh`.
- `ALLOW_IMG_OUTPUT` is set to `"false"` to prevent base64-encoded images from filling up the context window. Set to `"true"` only if you specifically need the LLM to see plot images (be aware this can produce 70,000–100,000+ characters per plot and may exceed response limits).

## 4. Usage

### Start Jupyter Lab

In a separate terminal, run:

```bash
./jupyter.sh
```

Keep this running while using Claude Code.

### Start Claude Code

After creating/modifying `.mcp.json`, restart Claude Code so it picks up the MCP server configuration. Claude Code will automatically connect to the Jupyter MCP server and gain access to tools like:

- `execute_cell` — run a cell and get its output
- `add_cell` — add a new cell to a notebook
- `edit_cell` — modify an existing cell
- `read_notebook_with_outputs` / `read_notebook_source_only` — read notebook contents
- `read_output_of_cell` — read output of a specific cell

### Workflow

1. Start Jupyter Lab (`./jupyter.sh`)
2. Start/restart Claude Code
3. Claude Code can now create, read, edit, and execute Jupyter notebooks

## Known Issues

- **Image outputs fill context**: Even with `ALLOW_IMG_OUTPUT=false`, large text outputs from cells can still consume significant context. Keep cell outputs concise.
- **Collaboration sync**: UI edits in JupyterLab may stop syncing after Claude Code makes MCP edits ([#issue](https://github.com/datalayer/jupyter-mcp-server/issues)). If this happens, reload the notebook in JupyterLab.

## References

- [datalayer/jupyter-mcp-server (GitHub)](https://github.com/datalayer/jupyter-mcp-server)
- [Jupyter MCP Server documentation](https://jupyter-mcp-server.datalayer.tech/)
