Jupyter MCP Server
Provides MCP tools for interacting with JupyterLab notebooks, allowing agents to query, modify, execute, and set up notebooks via the Jupyter REST API, with state preservation and real-time collaboration support.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Jupyter MCP Serverinstall matplotlib and create a scatter plot"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Jupyter MCP Server
⚠️ API Compatibility Notice: This project is currently focused on MCP (Model Context Protocol) usage. There are no API compatibility guarantees between versions as the interface is actively evolving. Breaking changes may occur in any release.
Jupyter MCP Server allows you to use tools like Goose or Cursor to pair with you in a JupyterLab notebook where the state of your variables is preserved by the JupyterLab Kernel. This enables seamless collaboration where agents can install packages, fix errors, and hand off to you for data exploration at any time.
Architecture: Uses Jupyter's REST API for reliable agent operations while maintaining real-time user synchronization through RTC. See Architecture Documentation for detailed technical information.
Key Features
4 Consolidated MCP Tools (reduced from 11):
query_notebook- All read-only operations (view source, check server, etc.)modify_notebook_cells- All cell modifications (add, edit, delete cells)execute_notebook_code- All execution operations (run cells, install packages)setup_notebook- Notebook initialization and kernel connection
Workflow-oriented design optimized for AI agent collaboration
State preservation across notebook sessions
Automatic parameter validation with float-to-int conversion
This works with any client that supports MCP but will focus on using Goose for the examples.
Related MCP server: JupyterMCP
Requirements
You will need UV is required to be installed.
Installation
This MCP server supports multiple transport modes and can be added to client with the command uvx mcp-jupyter.
Transport Modes
The server supports two transport protocols:
stdio (default) - Standard input/output communication, ideal for local IDE integrations
http - Streamable HTTP transport with session management, enabling serverless deployments and remote access
Use Cases for HTTP Transport
Serverless deployments: Host the MCP server in cloud environments (AWS Lambda, Google Cloud Functions, etc.)
Remote access: Connect to the server from different machines or networks
Web integrations: Build web-based AI assistants that connect to the MCP server
Stateless operations: Use
--stateless-httpfor environments where session persistence isn't needed
To use a specific transport:
# Default stdio transport
uvx mcp-jupyter
# HTTP transport on custom port (stateful - maintains session)
uvx mcp-jupyter --transport http --port 8080
# HTTP transport in stateless mode (no session persistence)
uvx mcp-jupyter --transport http --port 8080 --stateless-httpUsing HTTP Transport with Cursor
To connect Cursor to an HTTP MCP server:
Start the server separately:
uvx mcp-jupyter --transport http --port 8090Configure Cursor's
.cursor/mcp.json:
{
"mcpServers": {
"notebook-http": {
"url": "http://localhost:8090/mcp/" // ⚠️ Trailing slash is REQUIRED
}
}
}Important: The trailing slash (/mcp/) is required for Cursor to connect properly to the HTTP endpoint.
Usage
Start Jupyter
The server expects that a server is already running on a port that is available to the client. If the environmental variable TOKEN is not set, it will default to "BLOCK".
Option 1: With Real-Time Collaboration (Recommended)
Real-time collaboration (jupyter-collaboration) enables automatic synchronization between the AI agent and your notebook interface. Changes made by the agent appear instantly in your browser.
# Using uv venv
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install jupyterlab jupyter-collaboration ipykernel
jupyter lab --port 8888 --IdentityProvider.token BLOCK --ip 0.0.0.0
# OR using uv project
uv init jupyter-workspace && cd jupyter-workspace
uv add jupyterlab jupyter-collaboration ipykernel
uv run jupyter lab --port 8888 --IdentityProvider.token BLOCK --ip 0.0.0.0Option 2: Without Real-Time Collaboration
You can use MCP Jupyter without jupyter-collaboration, but you'll need to manually sync changes:
# Using uv venv
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
uv pip install jupyterlab ipykernel
jupyter lab --port 8888 --IdentityProvider.token BLOCK --ip 0.0.0.0
# OR using uv project
uv init jupyter-workspace && cd jupyter-workspace
uv add jupyterlab ipykernel
uv run jupyter lab --port 8888 --IdentityProvider.token BLOCK --ip 0.0.0.0Important Workflow Differences Without RTC:
After the agent makes changes: Use the "Reload Notebook from Disk" command in JupyterLab to see the updates
After you edit in the notebook: Click Save (Ctrl+S / Cmd+S) so the agent can see your changes
With RTC enabled, these manual steps are not needed - changes sync automatically.
Goose Usage
Here's a demonstration of the tool in action:

You can view the Generated notebook here: View Demo Notebook
Development
Steps remain similar except you will need to clone this mcp-jupyter repository and use that for the server instead of the precompiled version.
MCP Server
Clone and setup the repository:
mkdir ~/Development
cd ~/Development
git clone https://github.com/block/mcp-jupyter.git
cd mcp-jupyter
# Sync all dependencies
uv syncUsing editable mode allows you to make changes to the server and only have you need to restart Goose, etc.
goose session --with-extension "uv run --directory $(pwd) mcp-jupyter"
LLM Evaluation
This project includes a comprehensive testing infrastructure for validating how well different LLMs can generate MCP tool calls from natural language prompts.
Test Architecture
The LLM testing system uses a pluggable provider architecture:
LLMProvider: Abstract base class that all providers implementLLMResponse: Standardized response format with success metrics and metadataParameterized tests: Same test runs against all available providers
Current Providers
ClaudeCodeProvider: Uses the Claude Code SDK (no API key required)
Running LLM Tests
# Run LLM tool call generation tests
uv run pytest -m llm -v
# See LLM working in real-time (shows detailed progress)
uv run pytest -m llm -v -s
# Run all tests except LLM tests (default behavior)
uv run pytest -vWhat the Tests Validate
Each LLM provider is tested on its ability to:
Understand natural language prompts about Jupyter notebook tasks
Generate correct MCP tool calls (
query_notebook,setup_notebook,modify_notebook_cells)Successfully execute the calls to create notebooks with expected content
Handle errors gracefully when operations fail
Adding New Providers
To add a new LLM provider:
Implement the interface:
# tests/llm_providers/my_llm.py
from .base import LLMProvider, LLMResponse
class MyLLMProvider(LLMProvider):
@property
def name(self) -> str:
return "my-llm"
async def send_task(self, prompt: str, server_url: str, verbose: bool = False):
# Implement LLM interaction
pass
async def get_final_response(self) -> LLMResponse:
# Return standardized response
pass
async def cleanup(self):
# Clean up resources
passUpdate configuration:
# tests/llm_providers/config.py - add to get_available_providers()
if os.getenv("MY_LLM_API_KEY"):
from .my_llm import MyLLMProvider
providers.append(MyLLMProvider())Test automatically: Your provider will be included in parameterized tests when its environment variables are set.
This infrastructure makes it easy to validate and compare how different LLMs perform at generating MCP tool calls for Jupyter notebook automation.
Available Tools
4 toolsexecute_notebook_codeA
Execute code in a Jupyter notebook on the user-provided server.
This consolidates all code execution operations into a single tool following MCP best practices.
IMPORTANT: Server URL Configuration
This tool requires that you first call setup_notebook with the correct server URL:
Required setup: setup_notebook("my_notebook", server_url="http://localhost:9999\")
Then you can use this tool: execute_notebook_code("my_notebook", "execute_cell", position_index=0)
Without setup_notebook, this will try to connect to http://localhost:8888 by default.
Args: notebook_path: Path to the notebook file (.ipynb extension will be added if missing), relative to the Jupyter server root. execution_type: Type of execution operation. Options: - 'execute_cell': Execute an existing code cell - 'install_packages': Install packages using uv pip in the notebook environment position_index: (For execute_cell) Positional index of cell to execute package_names: (For install_packages) Space-separated list of package names to install
Returns
Union[dict, str]:
- execute_cell: dict with execution_count, outputs, status
- install_packages: str with installation result messageRaises
ValueError: If invalid execution_type or missing required parameters
McpError: If there's an error connecting to the Jupyter server
IndexError: If position_index is out of range
RuntimeError: If kernel execution fails
| Name | Required | Description | Default |
|---|---|---|---|
| notebook_path | Yes | ||
| execution_type | Yes | ||
| position_index | No | ||
| package_names | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description covers setup dependency, default URL, execution types, return types, and errors. However, it does not disclose side effects (modifying notebook state) or safety considerations (e.g., code execution risks). Good but not fully comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections for setup, args, returns, raises. Front-loaded with purpose. Example code block is helpful. Minor bloat: redundant 'MCP best practices' line and repeated text. Still efficient for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all parameters, returns, errors, and setup dependency. Output schema exists, so return details not required. Lacks explanation of invalid notebook_path handling or deeper return structure usage. Adequate for a tool with moderate complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description compensates fully. Explains notebook_path with .ipynb addition, execution_type with two named options, position_index for execute_cell, and package_names for install_packages. Adds critical meaning beyond types and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Execute code in a Jupyter notebook on the user-provided server.' Differentiates from sibling tools (modify_notebook_cells, query_notebook, setup_notebook) by focusing on execution operations. Consolidates all execution types into one tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit setup requirement (must call setup_notebook first) and describes default behavior. Lists two execution types with corresponding parameters. Lacks explicit alternatives (e.g., when to use modify_notebook_cells instead), but the context is strong enough for an agent to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modify_notebook_cellsA
Modify notebook cells (add, edit, delete) on the user-provided server.
This consolidates all cell modification operations into a single tool following MCP best practices. Default to execute=True unless the user requests otherwise or you have good reason not to execute immediately.
IMPORTANT: Server URL Configuration
This tool requires that you first call setup_notebook with the correct server URL:
Required setup: setup_notebook("my_notebook", server_url="http://localhost:9999\")
Then you can use this tool: modify_notebook_cells("my_notebook", "add_code", "print('Hello')")
Without setup_notebook, this will try to connect to http://localhost:8888 by default.
Args: notebook_path: Path to the notebook file (.ipynb extension will be added if missing), relative to the Jupyter server root. operation: Type of cell operation. Options: - 'add_code': Add (and optionally execute) a code cell at end or specific position - 'edit_code': Edit a code cell at specific position - 'add_markdown': Add a markdown cell at end or specific position - 'edit_markdown': Edit an existing markdown cell at specific position - 'delete': Delete a cell at specific position cell_content: Content for the cell (required for add_code, edit_code, add_markdown, edit_markdown) position_index: Position index (0-indexed cell location) for operations. Must be an integer. - Optional for add_code/add_markdown: if provided, inserts at that position; if not, adds at end - Required for edit_code/edit_markdown/delete: specifies which cell to modify Examples: position_index=0 (first cell), position_index=2 (third cell) execute: Whether to execute code cells after adding/editing (default: True)
Returns
dict: Operation results containing:
- For add_code/edit_code with execute=True: execution_count, outputs, status
- For add_code/edit_code with execute=False: empty dict
- For add_markdown/edit_markdown: message and error fields
- For delete: message and error fieldsRaises
ValueError: If invalid operation or missing required parameters
McpError: If there's an error connecting to the Jupyter server
IndexError: If position_index is out of range
| Name | Required | Description | Default |
|---|---|---|---|
| notebook_path | Yes | ||
| operation | Yes | ||
| cell_content | No | ||
| position_index | No | ||
| execute | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully bears the burden of disclosing behavior. It details execution default, error types (ValueError, McpError, IndexError), and return values per operation, leaving no behavioral ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-organized with clear sections (Args, Returns, Raises) and front-loaded purpose. Minor redundancy exists (e.g., repeating default execute behavior), but overall it is efficient for the information provided.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description comprehensively covers return values for all operations and lists potential errors. It also clarifies the dependency on setup_notebook, making the tool fully self-contained in context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must explain each parameter. It does so thoroughly, including examples, default values, and conditionally required fields (e.g., position_index for edit/delete). This adds significant value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool modifies notebook cells (add, edit, delete) and explicitly distinguishes from siblings by noting it consolidates all cell modification operations. The verb 'modify' and specific operations listed make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on prerequisite setup (calling setup_notebook) and default behavior (execute=True). It does not explicitly contrast with siblings like execute_notebook_code, but the context is clear enough for an agent to infer appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_notebookA
Query notebook information and metadata on the user-provided server.
This consolidates all read-only operations into a single tool following MCP best practices.
IMPORTANT: Server URL Configuration
This tool requires a server URL to connect to your Jupyter server. You have two options:
Option 1 - Call setup_notebook first (RECOMMENDED): setup_notebook("my_notebook", server_url="http://localhost:9999") query_notebook("my_notebook", "view_source") # Uses stored URL automatically
Option 2 - Pass server_url explicitly every time: query_notebook("my_notebook", "view_source", server_url="http://localhost:9999")
If neither is done, it defaults to http://localhost:8888 which may not be correct.
Args: notebook_path: Path to the notebook file (.ipynb extension will be added if missing), relative to the Jupyter server root. query_type: Type of query to perform. Options: - 'view_source': View source code of notebook (single cell or all cells) - 'check_server': Check if Jupyter server is running and accessible - 'list_sessions': List all notebook sessions on the server - 'get_position_index': Get the index of a code cell execution_count: (For view_source/get_position_index) The execution count to look for. IMPORTANT: This is the number shown in square brackets like [3] in Jupyter UI. Only available for executed code cells. Must be an integer (e.g., 3). COMMON MISTAKE: Don't confuse with position_index! - execution_count=3 finds the cell that was executed 3rd (shows [3] in Jupyter) - position_index=3 finds the 4th cell in the notebook (0-indexed position) position_index: (For view_source) The position index to look for. This is the cell's physical position in the notebook (0-indexed). Examples: first cell = 0, second cell = 1, third cell = 2, etc. Works for all cell types (code, markdown, raw). Must be an integer. cell_id: (For get_position_index) Cell ID like "205658d6-093c-4722-854c-90b149f254ad". This is a unique identifier for each cell, visible in notebook metadata. server_url: Server URL to connect to. If not provided, uses the URL stored by setup_notebook, or falls back to http://localhost:8888
Returns
Union[dict, list, str, int]:
- view_source: dict (single cell) or list[dict] (all cells) with cell contents/metadata
- check_server: str status message
- list_sessions: list of notebook sessions
- get_position_index: int positional indexExamples
# View all cells in notebook
query_notebook("my_notebook.ipynb", "view_source")
# View cell by execution count (the [3] shown in Jupyter UI)
query_notebook("my_notebook.ipynb", "view_source", execution_count=3)
# View cell by position (first cell=0, second=1, etc)
query_notebook("my_notebook.ipynb", "view_source", position_index=0)
# Get position index of cell with execution count [5]
query_notebook("my_notebook.ipynb", "get_position_index", execution_count=5)
# Get position index by cell ID
query_notebook("my_notebook.ipynb", "get_position_index", cell_id="205658d6-093c-4722-854c-90b149f254ad")Raises
ValueError: If invalid query_type or missing required parameters
McpError: If there's an error connecting to the Jupyter server
| Name | Required | Description | Default |
|---|---|---|---|
| notebook_path | Yes | ||
| query_type | Yes | ||
| execution_count | No | ||
| position_index | No | ||
| cell_id | No | ||
| server_url | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description fully discloses behavioral traits: it's read-only (no mutations), handles connection to Jupyter server with defaults, and enumerates all query types with their effects. It also lists possible exceptions (ValueError, McpError) for error handling transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (introduction, configuration note, args, returns, examples, raises). However, it is somewhat verbose, especially with the configuration note being repeated in the args section. A slightly more concise version would be ideal, but the organization is good.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no annotations, the description is comprehensive: it covers all 6 parameters, 4 query types with behaviors, return types, default values, error cases, and provides multiple examples. The output schema is effectively described in the Returns section, making the tool fully understandable without external documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description compensates thoroughly. It explains each parameter in detail, including the distinction between execution_count and position_index, the automatic .ipynb extension, and the purpose of server_url. This adds essential meaning beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it queries notebook information and metadata, consolidating all read-only operations. It distinguishes itself from sibling tools like execute_notebook_code and modify_notebook_cells, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool (read-only queries) versus alternatives (execute or modify). It also offers a recommended workflow with setup_notebook, explains server URL configuration, and warns against common parameter confusion, leaving no doubt about usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
setup_notebookA
Prepare notebook for use and connect to the kernel on the user-provided server. Will create a new empty Jupyter notebook if needed on the server.
CALL THIS FIRST - This tool must be called before using other notebook tools to establish the server URL connection. All subsequent notebook operations will use the server URL stored by this tool.
This tool creates an empty notebook. To add content, use the modify_notebook_cells tool after creation:
Example usage: # Step 1: REQUIRED - Setup notebook with correct server URL setup_notebook("demo", server_url="http://localhost:9999")
# Step 2: Add cells (these now use the stored server URL automatically)
modify_notebook_cells("demo", "add_markdown", "# Title\\n\\nDescription")
modify_notebook_cells("demo", "add_code", "print('Hello World')")This tool assumes a Jupyter server is already running and accessible at the specified
server_url. It connects to this existing server to manage the notebook.
Note that notebook_path must be relative to the Jupyter server root, not an absolute filesystem path.
Args: notebook_path: Path to the notebook, relative to the Jupyter server root. server_url: Jupyter server URL (HIGHLY RECOMMENDED to specify explicitly). This URL will be stored and used for subsequent interactions with this notebook. If not provided, defaults to http://localhost:8888 which may not be correct for your setup. Common values: http://localhost:8888, http://localhost:9999, etc.
Returns
dict: Information about the notebook and status message.
| Name | Required | Description | Default |
|---|---|---|---|
| notebook_path | Yes | ||
| server_url | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that it connects to an existing server, stores the server URL for subsequent calls, and creates an empty notebook if needed. Does not mention overwriting behavior or authentication, but covers core behavioral traits. Annotations are absent, so description carries the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bold emphasis on key points, an example, and bullet-style parameter explanations. It is somewhat lengthy but each part adds value; slight redundancy in storage explanation could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description sufficiently explains the return value as a dict with status. It covers the tool's role in the workflow, parameter details, environmental assumption, and positioning relative to siblings. Complete for a setup tool with two parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description compensates fully: explains notebook_path as relative to Jupyter server root, and server_url with explicit recommendation, default, common values, and storage behavior. This provides essential meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool prepares a notebook and connects to a kernel, with specific actions: 'Prepare notebook for use and connect to the kernel' and 'Will create a new empty Jupyter notebook if needed'. This distinguishes it from sibling tools like modify_notebook_cells and execute_notebook_code.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly declares 'CALL THIS FIRST' and states it must be called before other notebook tools. Provides example usage showing the correct sequence and mentions alternatives like modify_notebook_cells for adding content. Also notes the required prerequisite of a running Jupyter server.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
4 tool updates
v2.0.2- First observed
execute_notebook_code - First observed
modify_notebook_cells - First observed
query_notebook - First observed
setup_notebook
TDQS
Each tool has a clearly distinct purpose: setup_notebook initializes and connects, execute_notebook_code runs code, modify_notebook_cells edits cells, and query_notebook retrieves information. No overlap in functionality.
All tools follow a consistent verb_noun pattern with underscores (setup_notebook, execute_notebook_code, modify_notebook_cells, query_notebook). The naming is predictable and clear.
With 4 tools, the count is appropriate for a Jupyter notebook server. Each tool is well-scoped, though some tools encapsulate multiple sub-operations, which could be split but is not problematic.
The tool surface covers the essential operations: setup, code execution, cell modification, and querying. Minor gaps like kernel management or file uploads are absent but not critical for basic notebook interaction.
Maintenance
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
System-of-record notebook for AI coding agents: pages, datastores, tasks, skills over MCP.
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceEnables AI agents to interact with collaborative Jupyter notebooks and documents in real-time, supporting notebook operations, document editing, user awareness tracking, and session management through Jupyter's RTC capabilities.MIT
- AlicenseAqualityCmaintenanceEnables AI agents to create, read, edit, and execute Jupyter notebook cells, manage kernels, and connect to remote Jupyter servers.21MIT
- AlicenseAqualityDmaintenanceAI-powered MCP server for connecting and managing Jupyter Notebooks. Enables interactive code execution, multi-notebook management, and multimodal output for data analysis, visualization, and machine learning.129MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to execute Jupyter notebook cells with persistent kernel state, output persistence, and structured JSON control surface.2-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/block/mcp-jupyter'
If you have feedback or need assistance with the MCP directory API, please join our Discord server