Skip to main content
Glama

ipynb-mcp

An agent-agnostic MCP server that lets any AI agent (Claude Code, OpenAI Codex, etc.) drive a local JupyterLab session via the Model Context Protocol.

Getting started with an AI agent

After installation, use one of the following prompts to kick off a session.

Fresh start (no server running):

Start a new notebook project using ipynb-mcp. Venv is at ~/lib/python/uv-osm, notebook dir is /path/to/notebooks. Project goal: [one sentence description].

Reconnect to an already-running JupyterLab:

Continue a notebook project using ipynb-mcp. JupyterLab is already running on port 8888 with token [token]. Notebook dir is /path/to/notebooks. Continue working on [notebook.ipynb].

The token is printed to the terminal when JupyterLab starts — look for a line like:

http://localhost:8888/lab?token=abc123...

Known limitation: browser reload required

When the agent writes or updates cells via the REST API, JupyterLab's browser tab does not auto-refresh. After the agent makes changes, reload the notebook manually with File → Reload Notebook from Disk to see the latest cells and outputs.


Related MCP server: mcp-devtools

How it works

┌─────────────────────┐  stdio (MCP)  ┌───────────────────┐
│   AI agent          │◄─────────────►│   ipynb-mcp       │
│  (Claude Code /     │               │   (this server)   │
│   OpenAI Codex /    │               │         │         │
│   any MCP client)   │               │  Jupyter REST API │
└─────────────────────┘               │  + kernel WS      │
                                      │         │         │
                                      │  JupyterLab       │
                                      │  (subprocess)     │
                                      └───────────────────┘

Unlike colab-mcp (which proxies tools from a remote browser extension), ipynb-mcp talks directly to the Jupyter REST API and kernel WebSocket — no browser extension required.

Installation

This project uses the shared uv-osm virtual environment. Always activate it before running any commands.

Prerequisites

source ~/lib/python/uv-osm/bin/activate && uv pip install jupyterlab

Install ipynb-mcp

source ~/lib/python/uv-osm/bin/activate && cd ipynb-mcp && uv pip install -e .

Note: Use uv pip install (not plain pip install). Never install packages globally.

Configuring your agent

Use the full venv binary path in all agent configs so the server always runs inside the correct environment regardless of the shell's active venv.

Claude Code

Register the server once, from your project root directory (not from inside the ipynb-mcp source folder — Claude Code scopes MCP servers to the directory where the command is run):

cd /path/to/your/project
claude mcp add ipynb-mcp -- /home/<user>/lib/python/uv-osm/bin/ipynb-mcp

Verify it registered correctly by running /mcp in the Claude Code prompt — you should see ipynb-mcp · ✔ connected in the server list. If the server doesn't appear, check that you ran claude mcp add from the right directory. The server starts on demand when a tool is called; no manual pre-launch needed.

Or add to .claude/mcp.json in your project:

{
  "mcpServers": {
    "ipynb-mcp": {
      "command": "/home/<user>/lib/python/uv-osm/bin/ipynb-mcp",
      "args": []
    }
  }
}

Replace /home/<user> with your actual home directory (or use the ~ expansion if your client supports it).

Generic mcp.json (OpenAI Codex, Cursor, Zed, etc.)

Most MCP-compatible clients read a configuration file. Create or extend mcp.json:

{
  "mcpServers": {
    "ipynb-mcp": {
      "command": "/home/<user>/lib/python/uv-osm/bin/ipynb-mcp",
      "args": [],
      "env": {
        "IPYNB_MCP_NOTEBOOK_DIR": "/path/to/your/notebooks",
        "IPYNB_MCP_PORT": "8888"
      }
    }
  }
}

Using the full venv path ensures the server finds all its dependencies without needing the shell to be activated first.

Environment variables

Variable

Default

Description

IPYNB_MCP_NOTEBOOK_DIR

$PWD

Root directory for notebooks

IPYNB_MCP_PORT

8888

Port for JupyterLab

Available tools

Tool

Description

start_jupyter

Launch JupyterLab and open the browser tab

open_notebook

Create or open a notebook; opens it in the browser

get_cells

List all cells (id, type, source, outputs)

add_code_cell

Insert a Python code cell

add_text_cell

Insert a Markdown cell

update_cell

Replace a cell's source (clears outputs)

delete_cell

Remove a cell

move_cell

Reorder a cell

run_code_cell

Execute a code cell on a live kernel

Typical agent workflow

agent → start_jupyter()           # launches JupyterLab, opens browser
agent → open_notebook("work.ipynb")
agent → add_text_cell(path, "# My analysis")
agent → add_code_cell(path, "import pandas as pd\ndf = pd.read_csv('data.csv')")
agent → run_code_cell(path, cell_id)   # executes, returns outputs
agent → get_cells(path)                # inspect outputs
agent → update_cell(path, cell_id, "...fixed code...")
agent → run_code_cell(path, cell_id)

Differences from colab-mcp

colab-mcp

ipynb-mcp

Runtime

Google Colab (remote)

Local JupyterLab

Architecture

Proxy → browser extension → Colab

Direct Jupyter REST + kernel WS

Browser extension

Required

Not required

Internet

Required

Optional (fully offline capable)

Agent compatibility

Any MCP client

Any MCP client

GPU / TPU

Via Colab (free tier limits)

Via local hardware

Persistence

Session-based

Standard filesystem

A
license - permissive license
-
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

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/nils-holmberg/ipynb-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server