Skip to main content
kern

Kern Sandbox

Your model writes the code. This runs it where it can't touch your machine.

PyPI npm Python 3.9+ License: Apache-2.0

rootless · no daemon · no socket · no VM · no cloud · no account

Works with MCP clients · LangChain · pi · Python and Node

The runtime · MCP server · Security model · Benchmarks

An agent's tool-call, a generated snippet, a notebook cell, a CI step: it arrives, you run it, and nobody has read it first.

# the runtime: one static binary, checksum-verified by the script
curl -fsSL https://raw.githubusercontent.com/getkern/kern/main/install.sh | sh

# if the venv line fails, your distribution ships it separately:
#     sudo apt install python3-venv
python3 -m venv .venv && . .venv/bin/activate
pip install kern-sandbox
import kern_sandbox as kern

r = kern.run_code("print(sum(range(100)))")
print(r.stdout, r.fault)   # 4950  None

That call started a container from an OCI image, ran the code with no network, memory and PID caps and a deadline applied from outside, and threw the container away before returning. The next call gets a new one. Two things, not one: the isolation is the binary's, this package is the API in front of it.

The result says who stopped the run

A Python session: run_code returns ('4950', None); the same call on an infinite loop with timeout_s=3 returns fault.type 'timeout' and exit 137; and a 400 MiB allocation under memory_mb=128 returns 'oom' and 137. One box per call, no network, caps and a deadline, gone when it returns.

docker run gives you exit 137 and leaves you to guess whether that was your timeout, the OOM killer or something else. This tells you. Every row was run:

the code fault.type exit_code
print(sum(range(100))) None 0
while True: pass, timeout_s=3 timeout 137
bytearray(400<<20), memory_mb=128 oom 137
urlopen(...), network off None 1

The last row is the one a loop gets wrong: the network was off, so the code raised and the sandbox did nothing. fault is read from a pipe kern writes rather than from stdout, so code that prints [exit 0] can't fake it. Also killed, escape_blocked, exec_failed, startup_failed.

Works with

Any MCP client Cursor, Claude Code, Claude Desktop, LM Studio, Zed, Windsurf. The package ships kern-mcp, a dependency-free stdio server: the model writes code, kern runs it here, charts come back as images it can see. Per-client config in docs/MCP.md
LangChain kern_code_tool() is a StructuredTool your agent can call, and a sandbox fault comes back labelled for the model. There is a shell execution policy too: LANGCHAIN-SHELL.md
pi kern-pi routes its bash, read, write, edit, ls, grep and find into a box, your working directory at /workspace: integrations/pi
Python and Node the same API on both registries: pip install kern-sandbox and npm i kern-sandbox
{ "mcpServers": { "kern": { "command": "uvx", "args": ["--from", "kern-sandbox", "kern-mcp"] } } }

A client spawns the server from its own PATH, so a venv is invisible to it: uvx above installs nothing, pipx install kern-sandbox is the other way. From macOS or Windows the client is one hop away and it is still one line ("command": "wsl", or "command": "ssh" to a VM or a board).

Safe by default

A bare Sandbox() has no network, no host mounts, seccomp on, capabilities dropped and a mandatory timeout. Every relaxation is a named argument (image, setup, memory_mb, cpus, timeout_s, network, mounts, workspace, prewarm, and a dozen more).

Two that have surprised people, both measured:

  • Mounts over sensitive sources are refused even if you ask: the host's own directories, anything with .ssh/.aws/.kube in its path, and kern's own state. No opt-out. Mount a copy.
  • network=True includes the host's loopback, where unauthenticated services live. A test read the host's SSH banner off 127.0.0.1:22. egress_allow is the middle setting and is route-level.

How fast

Horizontal bar chart on a log scale, milliseconds per call: kern-sandbox with a prewarm pool 0.7 ms, kern-sandbox 14.5 ms, llm-sandbox with its session kept alive 77 ms, podman run --rm 286 ms, docker run --rm 292.8 ms, and Docker Sandboxes (sbx) into an already running sandbox 421 ms. Measured on an Intel i7-14700KF, Linux 7.0.0, rootless, 2026-09-21.

The number to quote is 14.5 ms, the default path, one tool-call end to end on an i7-14700KF. The box itself is 4.9 ms; most of the rest is CPython starting inside, which is a Python cost. The 0.7 ms bar is a prewarm burst and falls back to 14.5 when the pool cannot keep up. And print(1) flatters every runtime here: import json,re measures 47.3 ms against 320.8, 7x rather than 20x. Measure your own machine and take the p50.

Compared to what you are probably doing

a venv isolates imports, not the process: the code still has your files, your keys and your network
docker run per call the same idea with a daemon and a socket in front of it, at 292.8 ms against 14.5 ms on the same machine. That socket is root-equivalent
bubblewrap, nsjail the building blocks kern uses. They don't resolve images, don't apply cgroup caps, and give you no verdict: you get an exit code and work out the rest
a microVM (Firecracker, Kata) or gVisor a stronger boundary than this one, and the right answer when the code is actively hostile. It costs what a machine costs: about half a second per command
E2B, Modal, Daytona the same job in someone else's cloud, with an account and your code leaving the machine

Current limitations

  • Not a boundary against deliberately hostile code. This is namespaces, cgroups and seccomp: a kernel boundary, for your own or semi-trusted code. If the code is actively hostile, or belongs to someone else, use a microVM (Firecracker, Kata) or gVisor. That is a different job and costs what a machine costs: about half a second per command there against 14.5 ms here. Full statement in SECURITY.md.
  • Linux only. Windows works through WSL2; on a Mac the package installs and refuses to run, because macOS has no namespaces and no cgroups. Use a Linux VM.
  • The caps bind only where your host delegates a cgroup. kern doctor says whether yours does, and require_limits=True turns a silent no into a refusal to start.
  • Nothing bounds the workspace. It is a host directory, so a job can fill your disk. Point workspace= at a filesystem you have sized.
  • No --user, so an image that refuses to run as root (postgres, some databases) has no answer here yet.
  • pip install kern-sandbox does not install the sandbox. It drives a kern binary on PATH or in $KERN_BIN, a second thing to keep current. If a verdict looks wrong, print kern --version.

More

Charts and mime-typed results without a Jupyter kernel, the full API, kernel() for a warm interpreter, snapshots, and the measured sharp edges: SANDBOX-NOTES.md.

Requires unprivileged user namespaces and cgroup v2, and Python 3.9+: install notes. Apache-2.0.

Release files for kern-sandbox 0.2.34

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kern-sandbox 0.2.34
File Size Uploaded
kern_sandbox-0.2.34.tar.gz 252.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kern-sandbox 0.2.34
File Interpreter ABI Platform
kern_sandbox-0.2.34-py3-none-any.whl Python 3 none any Details

Total release size: 380.8 kB

Release files / kern_sandbox-0.2.34.tar.gz

Download URL kern_sandbox-0.2.34.tar.gz
Size 252.5 kB
Tags Source
SHA-256 checksum
How to use checksums
bdf03bfbc23a72b69fb2c6ceb50e5a06f2079d7da3f518abc32e3e79774f8f5c
BLAKE2b-256 checksum
How to use checksums
f2aef8904047772f25c0fdec983700d7c52961b2526ef4144ac02968a3b3f18a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / kern_sandbox-0.2.34-py3-none-any.whl

Download URL kern_sandbox-0.2.34-py3-none-any.whl
Size 128.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
315058e7926953885255fb33b14697b8c6bd93e5cde9860e17f9d4ba9066e1cd
BLAKE2b-256 checksum
How to use checksums
89886437d4582b24b1ab3ee7357f81dedff734e92a39acda11165e967f8601bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

0.2.39

2 release files

0.2.38

2 release files

0.2.37

2 release files

0.2.36

2 release files

0.2.35

2 release files

This release

0.2.34 This release

2 release files

0.2.33

2 release files

0.2.32

2 release files

0.2.31

2 release files

0.2.30

2 release files

0.2.29

2 release files

0.2.28

2 release files

0.2.27

2 release files

0.2.26

2 release files

0.2.25

2 release files

0.2.24

2 release files

0.2.22

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.17

2 release files

0.2.16

2 release files

0.2.15

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.43

2 release files

0.1.33

2 release files

0.1.32

2 release files

0.1.31

2 release files

0.1.30

2 release files

0.1.29

2 release files

0.1.28

2 release files

0.1.27

2 release files

0.1.26

2 release files

0.1.25

2 release files

0.1.24

2 release files

0.1.23

2 release files

0.1.22

2 release files

0.1.21

2 release files

0.1.20

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release 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