Agent Jupyter Toolkit
A Python toolkit for building agent tools that interact with Jupyter kernels and the Jupyter protocol. This package provides high-level wrappers and abstractions around jupyter_client, jupyter_ydoc, and pycrdt, making it easy to manage kernels, execute code, and build agent-driven workflows for automation, orchestration, and integration with Model Context Protocol (MCP) servers.
Features
Kernel
- Async-first kernel sessions with pluggable transports:
- Local transport — direct ZMQ communication with local kernel processes
- Server transport — HTTP REST + WebSocket to remote Jupyter servers
- Code execution with bounded, coalesced streaming callbacks and separate callback diagnostics
- Notebook-compatible output state for deferred clears, display updates, stream coalescing, and bounded output
- Kernel introspection — tab-completion, object inspection, code-completeness checks, and execution history retrieval
- Kernel control — interrupt/restart, query metadata, and capability-gated debugger and subshell workflows
- Ownership-aware lifecycle — normal shutdown preserves attached/borrowed kernels
- Variable management — inspect and set strict JSON values through base64-encoded payloads
- Extensible hooks — pre/post execution and output hooks for instrumentation
Notebook
- Multi-notebook workspaces:
NotebookWorkspacemanages open sessions and a default notebook from Python. Switching defaults preserves other live sessions. See the workspace API. - Multiple notebook transports:
- Local file transport — filesystem-backed notebooks with thread-safe read/write
- Contents API transport — Jupyter Server-managed notebooks via REST
- Collaboration transport — real-time multi-client editing via Yjs/CRDT (pycrdt + jupyter_ydoc)
- Cell operations — append, insert, delete, set source, update outputs (full replace and delta)
- In-memory notebook buffer for staged edits with explicit commit
- Local notebook autosave with optional debounced writes
- Change observers — register callbacks for cell mutations, saves, and awareness events
- Validated persistence with atomic stable-cell identity, explicit normalization, and source/persistence conflicts
- Optional batch execution and trust inspection through public nbclient/nbformat APIs
Use Cases
- Build agent tools that execute code in Jupyter kernels
- Integrate Jupyter kernel execution into MCP servers or other orchestration systems
- Automate notebook and code execution for data science, ML, and automation pipelines
- Build collaborative notebook editing experiences with CRDT-based conflict resolution
Installation
Install from PyPI
# Using pip
pip install agent-jupyter-toolkit
# Install optional DataFrame serialization support
pip install agent-jupyter-toolkit[dataframe]
# Include a managed local Python kernel
pip install agent-jupyter-toolkit[local]
# Include the nbclient batch executor
pip install agent-jupyter-toolkit[batch]
# Or using uv
uv pip install agent-jupyter-toolkit
The local extra installs ipykernel, batch installs nbclient, and dataframe
installs pandas/Arrow serialization support. The integration extra is for
maintainers running the real Jupyter Server and collaboration tests.
Development (monorepo)
git clone https://github.com/Cyb3rWard0g/agent-jupyter-toolkit.git
cd agent-jupyter-toolkit
uv sync --all-packages --all-extras --dev
This installs both agent-jupyter-toolkit and mcp-jupyter-notebook in
editable mode into the .venv.
Quickstart
Local kernel execution does not require a Jupyter Server. The library starts a
local kernel process for you (via jupyter_client) and connects over ZMQ.
Basic execution
import asyncio
from agent_jupyter_toolkit.kernel import SessionConfig, create_session
async def main() -> None:
async with create_session(SessionConfig(mode="local", kernel_name="python3")) as session:
result = await session.execute(
"import os\n"
"from platform import node\n"
"user = os.environ.get('USER', 'friend')\n"
"print(f'Hello {user} from {node()}')\n"
)
print("status:", result.status)
print("stdout:", result.stdout.strip())
asyncio.run(main())
Introspection and control
async with create_session() as session:
# Tab-completion
result = await session.complete("import os; os.path.jo", cursor_pos=21)
print(result.matches) # ["join"]
# Object inspection
info = await session.inspect("len", cursor_pos=3)
print(info.data.get("text/plain", ""))
# Code-completeness check
check = await session.is_complete("for i in range(10):")
print(check.status) # "incomplete"
print(check.indent) # " "
# Execution history
hist = await session.history(n=5)
for entry in hist.history:
print(f"[{entry.line_number}] {entry.input}")
# Kernel metadata
kinfo = await session.kernel_info()
print(f"{kinfo.language_info['name']} {kinfo.language_info['version']}")
# Interrupt a long-running cell
import asyncio
task = asyncio.create_task(session.execute("import time; time.sleep(999)"))
await asyncio.sleep(1)
await session.interrupt()
For server-backed and notebook scenarios, see the quickstarts/ directory.
API Overview
Kernel Session
| Method | Description |
|---|---|
execute(code, *, timeout, output_callback, ...) |
Execute code with optional streaming callbacks |
debug(request) |
Send a DAP request when the kernel advertises debugger support |
create_subshell() / list_subshells() / delete_subshell() |
Manage advertised kernel subshells |
interrupt() |
Send SIGINT to cancel running execution |
complete(code, cursor_pos) |
Tab-completion suggestions |
inspect(code, cursor_pos, detail_level) |
Object documentation/signature |
is_complete(code) |
Syntax completeness check |
history(*, output, raw, hist_access_type, n) |
Execution history retrieval |
kernel_info() |
Kernel metadata (language, version, protocol) |
session_info() |
Non-secret kernel/session IDs, ownership, generation, and encryption state |
is_alive() |
Health check |
start() / shutdown() |
Start and close; shutdown terminates only resources created by this client |
shutdown_kernel() |
Explicitly terminate a kernel, including a borrowed one |
Notebook Document Transport
| Method | Description |
|---|---|
fetch() |
Get notebook content as nbformat dict |
save(content) |
Write notebook content |
append_code_cell(source, metadata, tags) |
Append a code cell |
append_code_cell_with_id(source, metadata, tags) |
Append and return its stable ID atomically |
insert_code_cell(index, source, metadata, tags) |
Insert a code cell at index |
append_markdown_cell(source, tags) |
Append a markdown cell |
insert_markdown_cell(index, source, tags) |
Insert a markdown cell at index |
set_cell_source(index, source) |
Update cell source text |
set_cell_source_by_id(id, source, expected_source) |
Resolve, verify, and update source atomically |
update_cell_outputs(index, outputs, execution_count) |
Replace cell outputs |
delete_cell(index) |
Delete cell at index |
on_change(callback) |
Register mutation observer |
Architecture
agent_jupyter_toolkit
├── kernel/
│ ├── session.py # Session + create_session() factory
│ ├── transport.py # KernelTransport protocol
│ ├── types.py # Dataclasses (SessionConfig, ExecutionResult, ...)
│ ├── manager.py # KernelManager (lifecycle, channels)
│ ├── messages.py # Wire-protocol message builders
│ ├── variables.py # VariableManager (inspect/set kernel vars)
│ ├── hooks.py # Extensible execution hooks
│ ├── mimetypes.py # MIME-type serialization registry
│ ├── serialization.py # High-level serialize/deserialize API
│ └── transports/
│ ├── local.py # LocalTransport (ZMQ)
│ └── server.py # ServerTransport (HTTP+WS)
├── notebook/
│ ├── session.py # NotebookSession (kernel + document orchestration)
│ ├── workspace.py # Multi-notebook registry, default selection, lifecycle
│ ├── _workspace_files.py # Private local and Contents API file operations
│ ├── transport.py # NotebookDocumentTransport protocol
│ ├── factory.py # make_document_transport() factory
│ ├── buffer.py # In-memory NotebookBuffer
│ ├── cells.py # Cell creation helpers (code, markdown)
│ ├── config.py # Environment-based Config (allowlist, timeout)
│ ├── utils.py # Path validation, output normalization
│ └── transports/
│ ├── local_file.py # LocalFileDocumentTransport (+ autosave)
│ ├── contents.py # ContentsApiDocumentTransport
│ └── collab/ # CollabYjsDocumentTransport (Yjs/CRDT)
└── utils/ # High-level helpers (factories, execution, packages)
Dependencies
| Package | Purpose |
|---|---|
| jupyter-client | Kernel protocol, ZMQ channels, kernel management |
| jupyter-ydoc | YNotebook schema for collaborative editing |
| pycrdt | CRDT types (Doc, Array, Map, Text, Awareness) |
| nbformat | Notebook file format handling |
| packaging | PEP 508 requirement and version checks |
| aiohttp | Async HTTP/WS for server transport |
| pandas + pyarrow | Optional dataframe extra for DataFrame variable inspection |
See the API reference for execution result fields and optional APIs, and configuration for collaboration modes and local launch options.
Contributing
See CONTRIBUTING.md for dev setup, testing, and the release process.
Contributions and feedback are welcome!
Metadata
Release files for agent-jupyter-toolkit 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agent_jupyter_toolkit-0.8.0.tar.gz | 135.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agent_jupyter_toolkit-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 272.4 kB
Release files / agent_jupyter_toolkit-0.8.0.tar.gz
| Download URL | agent_jupyter_toolkit-0.8.0.tar.gz |
|---|---|
| Size | 135.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b9ab98fb782dde372e977139a992a770aba47481f1ee98999ac40fa08261f3f9
|
|
BLAKE2b-256 checksum How to use checksums |
6a754c51fd2781d4e4bda7dd34e5d4f1a86c01838abb8dfec88195a8e0555474
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency logRelease files / agent_jupyter_toolkit-0.8.0-py3-none-any.whl
| Download URL | agent_jupyter_toolkit-0.8.0-py3-none-any.whl |
|---|---|
| Size | 137.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b8fb7dcaf0f57a4f5998fb5a57a1a394f9388a431222c70bfc93334f23897338
|
|
BLAKE2b-256 checksum How to use checksums |
8c71c2608710fabf22a38155de917e6ddbbc3665c47f51686693ffeb315cd85b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency log