Skip to main content

CLI daemon that proxies code execution to remote Jupyter kernels with local notebook logging

Project description

nbexec

PyPI

A CLI tool that lets AI agents (like Claude Code) execute code on remote Jupyter kernels. All executed code and outputs are logged to a local .ipynb notebook file for human review.

Why

When an AI agent needs to run code on a remote compute environment (a PySpark cluster, a GPU machine, a data warehouse notebook server), the options are limited. An agent could use browser automation to interact with a Jupyter UI, but that's slow and token-expensive. It just needs to send code, get results, and move on.

nbexec provides a token-efficient way to do this. The agent calls nbexec exec --code "..." and gets text output on stdout. Python execution state persists across calls: variables, imports, and dataframes created in one exec are available in the next, giving the agent a persistent runtime across multiple tool calls. It can also run an existing .ipynb notebook on the same kernel with nbexec exec --file ./analysis.ipynb. Behind the scenes, a daemon holds a persistent WebSocket connection to the remote Jupyter kernel, and every cell + output is recorded in a local .ipynb file that you can open in VS Code or Jupyter to see exactly what the agent did.

How it works

┌──────────────┐       ┌──────────────┐       ┌──────────────────┐
│    Agent     │       │nbexec daemon │       │ Remote Jupyter   │
│ (Claude Code)│       │  (background)│       │     Server       │
└──────┬───────┘       └──────┬───────┘       └────────┬─────────┘
       │                      │                        │
       │  exec --code "..."   │                        │
       │─────────────────────►│                        │
       │   (Unix socket)      │                        │
       │                      │  execute via WebSocket │
       │                      │───────────────────────►│
       │                      │                        │ run code
       │                      │         results        │
       │                      │◄───────────────────────│
       │                      │                        │
       │                      │ write cell + output    │
       │                      │ to local .ipynb        │
       │                      │                        │
       │   stdout: result     │                        │
       │◄─────────────────────│                        │
       │                      │                        │

The daemon is a long-running background process that holds persistent WebSocket connections to one or more remote Jupyter servers. CLI commands (exec, session create, etc.) are thin clients that talk to the daemon over a Unix socket. Each exec is a synchronous request/response.

This is the same protocol VS Code uses when you connect a local notebook to a remote Jupyter server. The notebook document stays local, only code strings are sent to the kernel. nbexec replicates this model for CLI/agent use, using jupyter-kernel-client to manage the kernel connection.

Installation

Requires Python 3.10+.

uv tool install claude-nbexec

Or with pip:

pip install claude-nbexec

Install the Claude Code skill

Clone the repo and run the skill installer:

git clone https://github.com/anish749/claude-nbexec.git && cd claude-nbexec
./install-skill.sh

This installs a skill to $CLAUDE_CONFIG_DIR/skills/nbexec/ that teaches Claude Code when and how to use nbexec.

Usage

All commands and options are documented in nbexec --help.

Why a CLI and not an MCP server or raw HTTP

Agents don't think in cells. Existing Jupyter MCP servers expose notebook operations: create cell, edit cell, move cell, run cell. But an agent executing code on a remote kernel doesn't care about cells. It just wants to send code and get results. It doesn't need to edit cell 5 or reorder cells. If something went wrong, it sends corrected code as the next execution. nbexec matches this model: send code, get output, move on. The notebook is just a side effect for human review, not something the agent manages.

Clean context. An MCP server's tool definitions live in the agent's prompt at all times. nbexec adds nothing to the prompt until the agent actually needs it. The skill loads on demand, and --help is only fetched when invoked.

Full visibility. Everything inside an MCP server is opaque to the agent; it can only call the tools that are exposed. With a CLI, the agent has access to the source code, can inspect how things work, and can understand or work around issues on its own.

Persistent connections without agent coupling. The daemon runs as a separate process, managing WebSocket connections and kernel sessions independently. The agent doesn't need to hold connections or re-establish them between calls. Sessions survive across multiple agent conversations. An MCP server's lifecycle is tied to the agent process that started it.

Fewer tokens than raw HTTP. The agent could call the Jupyter REST API directly via curl, but that means generating verbose HTTP requests for every cell execution, manually managing XSRF tokens, parsing WebSocket message framing, and tracking kernel/session IDs. A single nbexec exec --session spark --code "..." replaces all of that: fewer generated tokens, simpler logic, same result.

Self-documenting from the CLI. The agent runs nbexec --help and gets everything it needs: commands, options, examples, workflow patterns. No need to embed documentation in MCP tool descriptions or maintain it in two places.

Inspiration

The architectural pattern (a long-lived daemon process, CLI-driven interaction, persistent state across calls, and a skill file for agent discovery) is inspired by OpenClaw. nbexec applies the same intuition to a narrower problem: giving AI coding agents structured access to remote Jupyter kernels.

Project details


Download files

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

Source Distribution

claude_nbexec-0.2.1.tar.gz (72.0 kB view details)

Uploaded Source

Built Distribution

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

claude_nbexec-0.2.1-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file claude_nbexec-0.2.1.tar.gz.

File metadata

  • Download URL: claude_nbexec-0.2.1.tar.gz
  • Upload date:
  • Size: 72.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for claude_nbexec-0.2.1.tar.gz
Algorithm Hash digest
SHA256 c70c23aeac78268a9f946b57eb310c5220213330a4446cef4f1da61d7d340f4c
MD5 294e4494c6845c966ab1f726b1f4a7f4
BLAKE2b-256 5ba59f6b21773e7538d6fc0a496ba8c09254a874faed9c8a234f86797d910ea6

See more details on using hashes here.

File details

Details for the file claude_nbexec-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: claude_nbexec-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 19.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for claude_nbexec-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8b2f05d97fcc1ae1629a4463433acdf119344a6d9cb0d9a61915dc698a2d4bd5
MD5 667e9cf71d0cd859627f9084fca66512
BLAKE2b-256 9adedb899980762a3db636014766d3715f205d637ed80b32a877f94babab5ec8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page