Skip to main content
Glama
Happypig375

VS Code Jupyter MCP Server

by Happypig375

Jupyter MCP Server

Marketplace version Marketplace installs GitHub repository

A notebook-specific MCP server that runs inside VS Code. An external MCP client can inspect, edit, execute, create, export, and manage notebooks open in the VS Code windows the user is working in. It has no dependency on Copilot Chat or Cursor. Notebook document operations use VS Code's native API; kernel operations require the installed ms-toolsai.jupyter extension.

Install and connect

  1. Install Jupyter MCP Server (publisher Happypig375) from the Marketplace, or run code --install-extension Happypig375.vscode-jupyter-mcp-server.

  2. Check the $(notebook) MCP status item and copy its URL, or use the output channel. The default endpoint is http://127.0.0.1:51303/mcp.

  3. Configure the external client to use Streamable HTTP and that copied endpoint.

The tool contract below describes 0.4.0; see the changelog for earlier versions. After an upgrade, refresh or reconnect the client's MCP tool catalog if it still advertises old parameters. The connected server's tools/list response is authoritative.

Related MCP server: VSC as MCP

How this project differs

The design is an in-extension broker over the user's live, shared in-memory NotebookDocument. Windows register as peers, duplicate URIs are disambiguated with short opaque notebookRef handles, and one broker port is taken over safely if its owner closes. The decisions below explain which documented ideas we adopted and which remain outside this project's boundary.

Design or workflow

This project's decision, benefit, and tradeoff

Relevant comparison

Shared live notebook document

Adopted. Read and edit VS Code's current document, including unsaved changes. The agent and user share notebook state; the notebook must be open in VS Code.

vscode-inmemory-notebook-mcp also supports live notebooks and external clients. mcp-jupyter-complete uses file edits and reloads; Datalayer supports standalone Jupyter Server workflows.

Window routing

Implemented inside the extension host. One window owns the broker, peers can take over its port, and short refs distinguish the same URI in different windows. This avoids a separate daemon process.

vscode-inmemory-notebook-mcp uses a daemon with per-window bridge workers.

Long-running execution

Adopted for 0.4.0. run_cells returns an executionId; get_execution follows that same run after a wait budget expires or waitMs: 0 returns immediately.

The operation-ID and polling pattern comes from vscode-inmemory-notebook-mcp.

Pushed output streaming

Not implemented. Bounded polling serves request/response clients. Pushed events would add client notification support and event-history management that this workflow does not require.

vscode-inmemory-notebook-mcp documents polling and streaming.

Cell locking

Not implemented. The server checks explicit targets and execution freshness without imposing an edit-ownership policy on the user and agent. Locking would require a separate coordination policy.

vscode-inmemory-notebook-mcp exposes cell-lock tools.

Per-run interruption

Not implemented as an isolated cancellation tool. interrupt_kernels explicitly requests a kernel-wide interrupt; stopping observation of a run does not prove its code stopped.

This server's interrupt implementation uses the notebook kernel command.

Provider startup and administration

Generic Jupyter integration; no dedicated Colab adapter. Reuse registered controllers and normal provider setup. The checked Colab extension exposes no public connect/start API for an adapter to call. Dedicated provisioning, Drive, terminal, and resource-management tools are not implemented.

Google Colab MCP bridges browser sessions; Colab CLI manages runtimes and files. The Colab VS Code guide documents its own setup and administration.

Whole-notebook reads, cell anchors, and export were inspired by vscode-inmemory-notebook-mcp; the execution-wait and output-capture pattern came from vscode-runtime-notebook-mcp.

Sources and repository documentation were checked on 2026-09-06. This is a bounded, documentation-scoped comparison; it does not claim competitor installation or behavioral testing.

Tools

Existing-notebook tools use notebookRef, or notebookRefs for a batch. Prefer the short ref from list_notebooks; a plain URI is also accepted when it identifies one open notebook. open_notebooks accepts file URIs in uris and an optional windowId; create_notebook accepts title and an optional windowId.

Cell references accept zero-based indices or the cell_id returned by a read. Prefer real cell IDs; an index:N fallback can change after insertion, deletion, or movement. Notebook refs remain valid across cell edits and resolve only against currently open notebooks.

Tool

Category

Description

create_notebook

Create

Create a workspace file or an untitled notebook in an empty window and open it

list_notebooks

Read

List grouped connected windows, including empty windows, with windowId, windowLabel, URI, and routable notebookRef

read_notebook

Read

Read an outline by default, or select source, outputs, or all; optionally target cellIds

search_cells

Read

Search cell source and output text with match locations

get_kernel_info

Read

Report observed active runtime fields and explicit unavailable reasons

get_execution

Read

Inspect a tracked executionId, or recover the notebook's latest run; optionally wait for its result

list_kernels

Read

List exact registered kernel/controller IDs; read-only

configure_kernel

Manage

Invoke Jupyter's provider configuration tool; normal picker/auth/consent UI may appear

edit_cells

Write

Insert, edit, delete, or exact-text replace cells; optional explicit rerun

move_cells

Write

Move cells while preserving content, outputs, and metadata

clear_cell_outputs

Write

Clear outputs and execution state

run_cells

Execute

Start a tracked, ordered run; waitMs bounds the caller's wait, and observation continues independently

select_kernel

Manage

Select an exact ID from list_kernels; no fallback or start

restart_kernels

Manage

Request notebook-kernel restarts; provider confirmation may be required

interrupt_kernels

Manage

Request kernel interrupts; completion cannot be confirmed

open_notebooks

Manage

Open file URIs, preserving an existing live model

save_notebooks

Manage

Persist file-backed notebooks, including remote execution state

upload_file / download_file

Kernel transfer

Chunked, hashed transfer between hostPath on the VS Code host and kernelPath in the active idle Python kernel

export_notebook

Manage

Export as markdown, Python, or HTML

Reading without excess output

read_notebook returns notebook and cell metadata in every view. source adds source text, outputs adds saved output, and all adds both within the requested limits. Source slicing uses 1-based inclusive startLine and endLine; maxSourceChars defaults to 12,000 per cell, with 0 requesting unbounded source explicitly. Truncation is reported.

For outputs, outputMode selects summary, preferred text, or full textual representations. maxOutputChars bounds each cell's returned output. Binary images are summarized rather than decoded. Saved output can be stale after an edit; saving does not refresh it.

Jupyter and providers

The package declares ms-toolsai.jupyter as a dependency. Kernel-backed tools (list_kernels, configure_kernel, select_kernel, run_cells, restart/interrupt, and file transfer) are registered when that extension is present; presence does not guarantee every runtime API is available. get_kernel_info and get_execution remain exposed for read-only diagnostics.

list_kernels lists currently registered controllers, including those contributed by other extensions; it does not discover every dormant provider. configure_kernel explicitly delegates setup to Jupyter and may display a picker, authentication, or consent UI. select_kernel requires an exact listed ID. Inspection, listing, and file transfer do not start or select a kernel. File transfer requires the public API of an active idle Python kernel; see Microsoft's kernel execution and authorization sample.

restart_kernels and interrupt_kernels request state changes through Jupyter's provider commands. A provider can display confirmation UI or acknowledge the command before the kernel state changes, so their responses report requests rather than confirmed completion. Use get_kernel_info, get_execution, or notebook inspection to observe subsequent state where available.

The optional Colab VS Code extension contributes controllers through Jupyter. On 2026-09-06, MCP server 0.3.0 with google.colab 0.9.3 passed live checks for targeted execution, nonadjacent output clearing, and a 524,425-byte upload/download round trip with matching SHA-256 hashes in an existing Colab Python session. Initial discovery used the normal Colab picker. This is evidence for that tested integration, not a claim that every Colab feature is MCP-integrated.

A bootstrap adapter was considered on the same date. The installed 0.9.3 command manifest has no connect/start command; current upstream activation returns no extension API, and Auto Connect is handled inside the Jupyter provider. The browser-focused Colab MCP server does not expose that VS Code provider.

Jupyter's public API lets an extension register its own server collection, but does not expose other extensions' provider instances. Its kernels.getKernel returns already-started kernels for open notebooks. The internal jupyter.kernel.selectJupyterServerKernel command accepts an extension ID, provider ID, and notebook, then invokes the normal server/kernel selector; it has no argument for choosing a server or provider action. The older addRemoteJupyterServer API is deprecated and rejects callers outside Codespaces. These routes do not provide unattended Colab bootstrap.

Providers can mark a sole setup command canBeAutoSelected, but the checked Colab provider does not use that option. A provider API for listing existing runtimes and connecting to an explicit runtime would justify an optional MCP adapter. Until such a route exists, initial Colab setup can still require user interaction; wrapping its picker would not remove that requirement.

  1. Call list_notebooks and select a notebookRef.

  2. Read its outline, then request view: "source" for the cells needed. Edit cells and refresh indices or fallback anchors after structural changes.

  3. If a kernel must be chosen, list its registered controllers and select an exact ID. Configure the provider explicitly when necessary.

  4. Call run_cells. waitMs defaults to 1,000; zero returns immediately, and larger values can wait for long jobs. This is a request wait budget, not an execution time limit. A returned ID or dispatch status does not prove execution started.

  5. If the run is unfinished, call get_execution with that ID. Its waitMs defaults to zero and also supports long waits. A client may impose a shorter request timeout; neither that timeout nor an expired wait budget interrupts execution. Omit the ID to recover the latest tracked run after a lost response.

  6. Read results and save edits or export the notebook. Completed background runs persist file-backed outputs, including remote results; untitled notebooks are not force-saved.

Runs submit cells in order and stop after an observed failure. Only one tracked run is active per notebook, with at most 16 active runs per window and 256 cells per run. The registry retains at most 32 notebooks and eight runs per notebook; terminal records expire after one hour and can be evicted earlier at capacity. Active runs have no one-hour expiry. Returned execution output is capped at 12,000 characters per cell and 48,000 per receipt. run_cells includes output by default; get_execution includes it only with includeOutputs: true. Lookup requires an open notebook, and records do not survive an extension reload. saveBeforeExecute pre-saves dirty notebooks before edit, move, or run; use save_notebooks to persist subsequent edits.

Tracking observes cell identity, source, execution summaries, and restart/interrupt requests made through MCP. Restarts initiated outside those tools are detected only when VS Code exposes corresponding cell or lifecycle changes. An unavailable result means completion could not be confirmed; it does not establish that the kernel stopped.

Updating clients from 0.3.0

  • Replace inspect_notebooks, read_cells, and read_cell_outputs with the appropriate read_notebook view.

  • Replace run_cells.wait and timeoutMs with the single waitMs budget, then follow executionId with get_execution.

  • Replace file transfer's localPath with hostPath, which names a path on the VS Code extension host.

Obsolete keys and tools are rejected; refresh the client's tool catalog after upgrading.

Multi-window routing

All windows share the configured loopback HTTP URL. The first window binds the broker; others register private loopback peers. If the broker closes, a peer can take over the same port. A URI that is ambiguous across windows fails; use the listed ref. Multi-notebook operations are grouped by owner.

Configuration

Setting

Default

Description

jupyterMcp.enabled

true

Enable the server

jupyterMcp.transport

http

Streamable HTTP on loopback; stdio is scoped to the extension host and has no standalone Node launcher

jupyterMcp.port

51303

Shared machine-scoped broker port

jupyterMcp.saveBeforeExecute

true

Pre-save dirty notebooks before edit, move, or run

Development and testing

Install dependencies with npm ci, then run npm run typecheck and npm run compile. Press F5 to open an Extension Development Host.

npm test compiles the extension and runs the MCP boundary, Jupyter integration, broker, and kernel-file suites. npm run coverage merges their c8 coverage and enforces statements/lines >=75%, branches >=55%, and functions >=85%. The tests use shims without downloading VS Code; live provider checks are separate. CI runs on Ubuntu, Windows, and macOS.

License

MIT

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers