Metadata-Version: 2.4
Name: clikernel
Version: 0.2.2
Summary: Serve persistent Jupyter kernels to LLMs as concise text, over MCP or a plain stream protocol
Author: clikernel contributors
License: Apache-2.0
Project-URL: Repository, https://github.com/AnswerDotAI/clikernel
Project-URL: Documentation, https://AnswerDotAI.github.io/clikernel/
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastcore>=2.2.2
Requires-Dist: jupyasyncclient>=0.2.1
Requires-Dist: mcpmini>=0.0.1
Requires-Dist: aidialog>=0.0.7
Requires-Dist: pillow
Provides-Extra: dev
Requires-Dist: fastship; extra == "dev"
Requires-Dist: jupygate>=0.0.1; extra == "dev"
Dynamic: license-file

# clikernel


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

`clikernel` gives an LLM agent a persistent Python workbench built from two processes. A [jupygate](https://github.com/AnswerDotAI/jupygate) server runs all the time and hosts real Jupyter kernels ([ipymini](https://github.com/AnswerDotAI/ipymini) by default); kernels live there and persist until explicitly stopped. `clikernel` itself starts and stops with each conversation: a small translator the MCP host launches, speaking MCP to the model and the Jupyter kernels API to the gateway. Outputs come back as concise text — a bare `42` for a single result, tagged sections for several, tracebacks ANSI-stripped and capped.

Because kernels outlive conversations, an agent can `connect` back to yesterday’s kernel (or the user’s live solveit kernel) and find its state intact — and because nothing is ever stopped implicitly, the only way a kernel dies is an explicit `stop_kernel`. Creating a kernel runs the user’s `startup.py` and installs their `inspectors.py` cell-checking rules, delivered as source so remote kernels get the same setup as local ones.

## Install

``` sh
pip install clikernel
```

Plus the resident side: [jupygate](https://github.com/AnswerDotAI/jupygate) and a kernel ([ipymini](https://github.com/AnswerDotAI/ipymini) by default). Start the gateway (and keep it running, e.g. via launchd/systemd):

``` sh
jupygate --port 8787
```

## Use with an MCP host

Register the stdio server with your MCP host, e.g. for Claude Code:

``` sh
claude mcp add clikernel -- clikernel-mcp
```

The tools mirror jupygate’s kernel API plus one composite: `connect` (create a fresh kernel — running `startup.py` and installing inspectors — or attach to an existing one by id), `execute` (run code, get concise text), `list_kernels`, `stop_kernel`, `restart`, and `interrupt`. Nothing happens until the model calls `connect`, and nothing is ever stopped except by `stop_kernel` — a later conversation reattaches to a kernel by id and continues where the last one stopped. `$CLIKERNEL_HOST` overrides the default gateway (`http://127.0.0.1:8787`).

## Configuration

Three optional files in `$XDG_CONFIG_HOME/clikernel/` (usually `~/.config/clikernel/`):

- `startup.py` — run in every kernel clikernel creates, with `__file__` bound to its path; its output returns as part of the `connect` reply.
- `inspectors.py` — cell inspectors installed after startup. The file may define `inspect` and/or a list `inspectors`; each is called once per cell before it runs (1-arg: the cell’s AST; 2-arg: AST and raw source). Return a string to print a note before the cell’s output, raise `RuleBlock` (provided in the namespace) to block the cell; any other exception warns and the cell runs. See `examples/inspectors.py`.
- `gateways.toml` — named remote gateways, so tokens never appear in tool arguments:

``` toml
[gateways.solveit]
url = "https://solveit.example.com/gate"
token_env = "SOLVEIT_TOKEN"
```

## The stream protocol

Run `clikernel` as a plain CLI process and the same client speaks a delimiter-framed stdin/stdout protocol for token-reading clients: no echo, a cheap `.` acknowledgement per request, responses ended by a per-process random delimiter, multiline cells framed by `--` and the delimiter. The full recipe is announced in the process’s own startup banner. Run bare it creates a kernel and stops it on exit; `--kernel <id>` attaches to an existing kernel and leaves it as found.
