About Robust new jupyter server
A focused MCP server for users who need to read, edit, and execute a live Jupyter notebook. It works with one notebook and kernel, using session locking and explicit execution errors to avoid concurrent changes and accidental retries.
Key features
- 01Read consistent notebook snapshots
- 02Append Markdown cells
- 03Execute code with structured outputs
- 04Restart the kernel and session
- 05Expose notebook resource and analysis prompt
Use cases
- 01Inspect the current notebook
- 02Add explanatory or executable cells
- 03Run code and review outputs or errors
MCP support
Exposes notebook reading, editing, and execution tools over stdio, along with a read-only notebook resource and an analysis prompt.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.
Tools
Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.
Details
From the project READMEJupyter MCP Server
A focused Model Context Protocol server for safely reading, editing, and executing one live Jupyter notebook.
The implementation deliberately stays small: one notebook, one kernel, and the standard stdio
transport. Operations share a session lock, code is appended and executed exactly once, and the
server waits for the kernel's final execution reply—not the first visible output.
What it exposes
| MCP primitive | Name | Purpose |
|---|---|---|
| Tool | add_markdown_cell | Append and verify one markdown cell |
| Tool | add_execute_code_cell | Append once, execute once, and return structured outputs |
| Tool | read_notebook_content | Read a consistent notebook snapshot |
| Tool | kernel_restart | Replace the current kernel/session cleanly |
| Resource | jupyter://notebook | Read-only notebook JSON |
| Prompt | analyse_notebook | Analyze before changing the notebook |
HTML, image, JSON, stream, result, and traceback data are retained in structured output models. Execution failures, timeouts, and unknown outcomes are MCP errors rather than successful strings.
Requirements
- Python 3.10 or newer (3.12 recommended)
- A JupyterLab server with real-time collaboration enabled
uv(recommended) orpip
Local setup
Install the server and development tools:
uv sync --extra dev
Create a valid notebook document (an empty file is not a notebook):
uv run python -c "import nbformat; nbformat.write(nbformat.v4.new_notebook(), 'notebook.ipynb')"
In another environment or terminal, install and start Jupyter:
uv run --with jupyterlab --with jupyter-collaboration \
jupyter lab \
--port 8888 \
--ServerApp.port_retries 0 \
--ServerApp.root_dir . \
--IdentityProvider.token MY_TOKEN \
--no-browser
Run the MCP server:
NOTEBOOK_PATH=notebook.ipynb \
SERVER_URL=http://localhost:8888 \
TOKEN=MY_TOKEN \
uv run jupyter-mcp
The server opens Jupyter connections on first use, so importing the package or listing MCP tools does not require Jupyter to be running.
MCP client configuration
Use the following shape for clients that launch local stdio servers, replacing the repository
path with your checkout:
{
"mcpServers": {
"jupyter": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/jupyter_mcp_server_kshitij",
"run",
"jupyter-mcp"
],
"env": {
"NOTEBOOK_PATH": "notebook.ipynb",
"SERVER_URL": "http://localhost:8888",
"TOKEN": "MY_TOKEN"
}
}
}
}
Configuration
| Variable | Default | Description |
|---|---|---|
NOTEBOOK_PATH | notebook.ipynb | Path relative to the Jupyter server root |
SERVER_URL | http://localhost:8888 | Jupyter server URL |
TOKEN | empty | Jupyter authentication token; set it at runtime |
CONNECTION_TIMEOUT_SECONDS | 15 | Timeout for startup, cleanup, and interruption |
EXECUTION_TIMEOUT_SECONDS | 30 | Maximum kernel execution time |
CONNECTION_ATTEMPTS | 2 | Pre-mutation connection attempts |
Connection retries happen only before a mutation. Once execution starts, a disconnect produces an explicit “outcome unknown” error and the cell is never automatically repeated.
Docker
Build and run the non-root image. The token has no image default and must be supplied at runtime:
docker build -f dockerfile -t jupyter-mcp .
docker run --rm -i \
-e NOTEBOOK_PATH=notebook.ipynb \
-e SERVER_URL=http://host.docker.internal:8888 \
-e TOKEN=MY_TOKEN \
jupyter-mcp
Development
uv run pytest
uv run ruff check .
The unit tests use fake notebook and kernel clients; they do not require a live Jupyter server. For an end-to-end check, start Jupyter as shown above and exercise the tools with an MCP client or the MCP Inspector.
Safety and lifecycle guarantees
- Importing modules performs no network I/O.
- MCP lifespan cleanup closes both notebook and kernel clients on normal or exceptional shutdown.
- An
asyncio.Lockprevents concurrent notebook mutation, execution, reads, and restarts. - The notebook client's public sequence/export API is used; private
_docand_ycellsinternals are not accessed. - Kernel errors and timeouts become MCP errors. A timed-out kernel is interrupted, and an uncertain session is discarded before reuse.
- Only standard
stdiotransport is enabled; there is no silent raw-TCP fallback.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.