Skip to main content

Jupyter Server MCP Extension

PyPI version conda-forge version

A configurable MCP (Model Context Protocol) server extension for Jupyter Server that allows dynamic registration of Python functions as tools accessible to MCP clients from a running Jupyter Server.

https://github.com/user-attachments/assets/aa779b1c-a443-48d7-b3eb-13f27a4333b3

Overview

This extension provides a simplified, trait-based approach to exposing Jupyter functionality through the MCP protocol. It can dynamically load and register tools from various Python packages, making them available to AI assistants and other MCP clients.

Key Features

  • Simplified Architecture: Direct function registration without complex abstractions
  • Configurable Tool Loading: Register tools via string specifications (module:function)
  • Automatic Tool Discovery: Python packages can expose tools via entrypoints
  • Jupyter Integration: Seamless integration with Jupyter Server extension system
  • Streamable HTTP Transport: FastMCP-based HTTP server with proper MCP protocol support
  • Traitlets Configuration: Full configuration support through Jupyter's traitlets system

Installation

Install jupyter-server-mcp into the same environment as Jupyter Server or JupyterLab.

pip

python -m pip install jupyter-server-mcp

conda / mamba / micromamba

conda install -c conda-forge jupyter-server-mcp
mamba install -c conda-forge jupyter-server-mcp
micromamba install -c conda-forge jupyter-server-mcp

pixi

In an existing Pixi workspace:

# If conda-forge is not already configured for the workspace
pixi project channel add conda-forge
pixi add jupyter-server-mcp

Quick Start

1. Basic Configuration

Create a jupyter_config.py file:

c = get_config()

# Basic MCP server settings
c.MCPExtensionApp.mcp_name = "My Jupyter MCP Server"

# Optional: override the default MCP port (3001).
# If 3001 is already in use, choose another fixed port and use the same
# port in your MCP client configuration below.
# c.MCPExtensionApp.mcp_port = 8080

# Register tools from existing packages
c.MCPExtensionApp.mcp_tools = [
    # Standard library tools
    "os:getcwd",
    "json:dumps",
    "time:time",
    
    # Jupyter AI Tools - Notebook operations  
    "jupyter_ai_tools.toolkits.notebook:read_notebook",
    "jupyter_ai_tools.toolkits.notebook:edit_cell",
    
    # JupyterLab Commands Toolkit
    "jupyterlab_commands_toolkit.tools:list_all_commands",
    "jupyterlab_commands_toolkit.tools:execute_command",
]

2. Start Jupyter Server

jupyter lab --config=jupyter_config.py

The MCP server will start automatically on http://localhost:3001/mcp by default. If the configured port is already in use, startup fails with a clear error instead of silently choosing another port, because MCP clients need to be configured with the actual endpoint URL.

Any trait can also be set directly on the command line, without a config file. For example, to override the port:

jupyter lab --MCPExtensionApp.mcp_port=8080

3. CLI MCP Client Configuration

By default, this extension exposes a FastMCP streamable HTTP endpoint at http://localhost:3001/mcp. If you override the port via c.MCPExtensionApp.mcp_port or the --MCPExtensionApp.mcp_port=<port> CLI flag, replace 3001 in the examples below. If a client asks for a transport type, choose HTTP or Streamable HTTP.

The list below is intentionally curated rather than exhaustive and focuses on terminal-based coding agents. For a broader, community-maintained directory of MCP-compatible clients, see the MCP client directory: https://modelcontextprotocol.io/clients.

OpenCode

Use opencode mcp add, or add the following to opencode.json or ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "jupyter-mcp": {
      "type": "remote",
      "url": "http://localhost:3001/mcp",
      "enabled": true
    }
  }
}

Mistral Vibe

Add the following to ./.vibe/config.toml or ~/.vibe/config.toml:

[[mcp_servers]]
name = "jupyter-mcp"
transport = "streamable-http"
url = "http://localhost:3001/mcp"

Claude Code

Add the following to .mcp.json:

{
  "mcpServers": {
    "jupyter-mcp": {
      "type": "http",
      "url": "http://localhost:3001/mcp"
    }
  }
}

Or use the claude CLI:

claude mcp add --transport http jupyter-mcp http://localhost:3001/mcp

Codex

Use the codex CLI:

codex mcp add jupyter-mcp --url http://localhost:3001/mcp

Or add the following to ~/.codex/config.toml:

[mcp_servers.jupyter-mcp]
url = "http://localhost:3001/mcp"

Gemini CLI

Add the following to .gemini/settings.json:

{
  "mcpServers": {
    "jupyter-mcp": {
      "httpUrl": "http://localhost:3001/mcp"
    }
  }
}

Copilot CLI

Use /mcp add in interactive mode, or add the following to ~/.copilot/mcp-config.json:

{
  "mcpServers": {
    "jupyter-mcp": {
      "type": "http",
      "url": "http://localhost:3001/mcp",
      "tools": ["*"]
    }
  }
}

Architecture

Core Components

MCPServer (jupyter_server_mcp.mcp_server.MCPServer)

A simplified LoggingConfigurable class that manages FastMCP integration:

from jupyter_server_mcp.mcp_server import MCPServer

# Create server
server = MCPServer(name="My Server", port=8080)

# Register functions
def my_tool(message: str) -> str:
    return f"Hello, {message}!"

server.register_tool(my_tool)

# Start server
await server.start_server()

Key Methods:

  • register_tool(func, name=None, description=None) - Register a Python function
  • register_tools(tools) - Register multiple functions (list or dict)
  • list_tools() - Get list of registered tools
  • start_server(host=None) - Start the HTTP MCP server

MCPExtensionApp (jupyter_server_mcp.extension.MCPExtensionApp)

Jupyter Server extension that manages the MCP server lifecycle:

Configuration Traits:

  • mcp_name - Server name (default: "Jupyter MCP Server")
  • mcp_port - Server port (default: 3001)
  • mcp_tools - List of tools to register (format: "module:function")
  • use_tool_discovery - Enable automatic tool discovery via entrypoints (default: True)

Tool Registration

Tools can be registered in two ways:

1. Manual Configuration

Specify tools directly in your Jupyter configuration using module:function format:

c.MCPExtensionApp.mcp_tools = [
    "os:getcwd",
    "jupyter_ai_tools.toolkits.notebook:read_notebook",
]

2. Automatic Discovery via Entrypoints

Python packages can expose tools automatically using the jupyter_server_mcp.tools entrypoint group.

In your package's pyproject.toml:

[project.entry-points."jupyter_server_mcp.tools"]
my_package_tools = "my_package.tools:TOOLS"

In my_package/tools.py:

# Option 1: Define as a list
TOOLS = [
    "my_package.operations:create_file",
    "my_package.operations:delete_file",
]

# Option 2: Define as a function
def get_tools():
    return [
        "my_package.operations:create_file",
        "my_package.operations:delete_file",
    ]

Tools from entrypoints are discovered automatically when the extension starts. To disable automatic discovery:

c.MCPExtensionApp.use_tool_discovery = False

Configuration Examples

Minimal Setup

c = get_config()

# Optional: override the default port (3001)
# Use a fixed port that matches your MCP client configuration.
# c.MCPExtensionApp.mcp_port = 8080

Full Configuration

c = get_config()

# MCP Server Configuration
c.MCPExtensionApp.mcp_name = "Advanced Jupyter MCP Server"
c.MCPExtensionApp.mcp_port = 8080
c.MCPExtensionApp.mcp_tools = [
    # File system operations (jupyter-ai-tools)
    "jupyter_ai_tools.toolkits.file_system:read",
    "jupyter_ai_tools.toolkits.file_system:write", 
    "jupyter_ai_tools.toolkits.file_system:edit",
    "jupyter_ai_tools.toolkits.file_system:ls",
    "jupyter_ai_tools.toolkits.file_system:glob",
    
    # Notebook operations (jupyter-ai-tools)
    "jupyter_ai_tools.toolkits.notebook:read_notebook",
    "jupyter_ai_tools.toolkits.notebook:edit_cell",
    "jupyter_ai_tools.toolkits.notebook:add_cell", 
    "jupyter_ai_tools.toolkits.notebook:delete_cell",
    "jupyter_ai_tools.toolkits.notebook:create_notebook",
    
    # Git operations (jupyter-ai-tools)
    "jupyter_ai_tools.toolkits.git:git_status",
    "jupyter_ai_tools.toolkits.git:git_add",
    "jupyter_ai_tools.toolkits.git:git_commit",
    "jupyter_ai_tools.toolkits.git:git_push",
    
    # JupyterLab operations (jupyterlab-commands-toolkit)
    "jupyterlab_commands_toolkit.tools:clear_all_outputs_in_notebook",
    "jupyterlab_commands_toolkit.tools:open_document",
    "jupyterlab_commands_toolkit.tools:open_markdown_file_in_preview_mode",
    "jupyterlab_commands_toolkit.tools:show_diff_of_current_notebook",
    
    # Utility functions  
    "os:getcwd",
    "json:dumps",
    "time:time",
    "platform:system",
]

Running Tests

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run with coverage
pytest --cov=jupyter_server_mcp tests/

Project Structure

jupyter_server_mcp/
├── jupyter_server_mcp/
│   ├── __init__.py
│   ├── mcp_server.py      # Core MCP server implementation
│   └── extension.py       # Jupyter Server extension
├── tests/
│   ├── test_mcp_server.py # MCPServer tests
│   └── test_extension.py  # Extension tests  
├── demo/
│   ├── jupyter_config.py  # Example configuration
│   └── *.py              # Debug/diagnostic scripts
└── pyproject.toml         # Package configuration

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass: pytest tests/
  5. Submit a pull request

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jupyter_server_mcp-0.2.2.tar.gz (26.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jupyter_server_mcp-0.2.2-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file jupyter_server_mcp-0.2.2.tar.gz.

File metadata

  • Download URL: jupyter_server_mcp-0.2.2.tar.gz
  • Upload date:
  • Size: 26.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.12.14

File hashes

Hashes for jupyter_server_mcp-0.2.2.tar.gz
Algorithm Hash digest
SHA256 95bc02b73cdc292e46aa1d6137d0732257420899fe966e161780e6e9418b4301
MD5 7ac5c596be69e49e4838e571e7c45465
BLAKE2b-256 7a91eef6aef217a725e944f643cb71016827b8d52df3eb7bafd40523da0aa490

See more details on using hashes here.

File details

Details for the file jupyter_server_mcp-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for jupyter_server_mcp-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 89e7d83e1c88a5bc88a779f5aaef2215295685b4df1506faed4bc2b6ed1a1ed6
MD5 fbc6c46675b3f276f172d9ccf694dabb
BLAKE2b-256 cca7b616504ac4801a4679ec889a07214dafe03f219f5b56e24dfe3b98fa4cb9

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.3

2 files

This release

0.2.2 This release

2 files

0.2.1

2 files

0.2.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page