EB

evalssment/boxxkite

Developer tools
20 stars 0 forks Quality 47 Trend 31

Self-hostable sandbox for agent code execution — SandboxManager, control-plane, 4 SDKs, MCP server, running inside real Kubernetes pod isolation

Overview

Website · Quickstart · Docs · Self-hosting · Security · Roadmap · Examples · Discord Most "agent sandbox" projects give you raw isolation — a pod, a VM, a container — and leave you to build the tool surface an LLM agent actually needs on top of it. boxxkite is the other half: a complete bash/python/file/search/process tool surface running inside real Kubernetes pod isolation, self-hostable end to end. Point your agent framework at it and you have a real sandbox in minutes, on infrastructure you control.

README

boxxkite

Website · Quickstart · Docs · Self-hosting · Security · Roadmap · Examples · Discord

▶ Watch the demo

The missing batteries-included, self-hostable sandbox for agent code execution.

Most “agent sandbox” projects give you raw isolation — a pod, a VM, a container — and leave you to build the tool surface an LLM agent actually needs on top of it. boxxkite is the other half: a complete bash/python/file/search/process tool surface running inside real Kubernetes pod isolation, self-hostable end to end. Point your agent framework at it and you have a real sandbox in minutes, on infrastructure you control.

  • 15 framework-agnostic tools (plus an opt-in 8-tool git set) — LangChain, LangGraph, LlamaIndex, CrewAI, AutoGen, the OpenAI Agents SDK, or plain function calling, with no required dependency on any of them
  • One Kubernetes pod per session — non-root, all capabilities dropped, read-only root filesystem, network egress denied by default
  • A hosted-API control-plane you run yourself — accounts, API keys, fair-use limits, and client SDKs in four languages, if you want a real multi-tenant API in front of the sandbox instead of embedding it directly
  • CLI, MCP server, Helm chart, and a one-click Render deploy for the control-plane — see Self-hosting
  • Nothing held back. Every piece here — runtime, control-plane, all four SDKs, the MCP server — is Apache-2.0-licensed and self-hostable; there’s no separate closed hosted-only tier

Who this is for: teams building their own agent products that need isolated, multi-tenant code execution at scale. It’s not a single-user local dev-session sandbox like the built-in bash tool in an IDE or CLI coding agent — if you just want your own assistant to run shell commands on your machine, boxxkite is the wrong layer.

Start Here

If you are new to the repo, use this decision tree:

  1. I just want to try the sandbox locally
    Use boxxkite up from the Quickstart below. This is the fastest path and does not require Kubernetes.

  2. I want the real Kubernetes deployment on my laptop
    Use deploy/local-kind/README.md. It explains the kind-based flow, the Apple Silicon limitation, and the kubectl proxy step.

  3. I want the hosted API / multi-tenant control-plane
    Use the control-plane section below, then the examples/basic/hosted_control_plane/ guide.

  4. I want the repository documentation map Start with docs/, which groups getting started, guides, reference, architecture, and community material.

For contributors, the important mental model is: the root package gives you the sandbox runtime, while control-plane/, the SDKs, and mcp-server/ are separate packages with their own installs and tests.

Quickstart

Clone the repo, create a virtualenv, install the root package, then start the local stack:

git clone https://github.com/EvAlssment/boxxkite.git boxxkite && cd boxxkite
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
boxxkite up                # builds + starts sandbox, sidecar, and local MinIO
boxxkite exec "python3 -c 'print(1 + 1)'"

Running the test suite needs two extra things the quickstart above doesn’t: pip install -r sidecar/requirements.txt (several tests import sidecar/main.py directly, and its dependencies are tracked separately from pyproject.toml) and tmux on your PATH (it backs the sidecar’s PTY takeover session; tmux-dependent tests skip cleanly without it). See CONTRIBUTING.md.

The PyPI name is boxxkite-sandbox, not boxxkite (already taken). Install it with pip install -e ".[dev]" from the repo root; the import path (import boxxkite) and the boxxkite CLI command are unaffected.

If boxxkite up succeeds, the quickest smoke test is:

boxxkite exec "python3 -c 'print(1 + 1)'"
boxxkite files ls /

That confirms the sandbox, the sidecar, and the CLI are talking to each other correctly.

Start a project with boxxkite new

To create a small Python project wired to the hosted control-plane client:

boxxkite new my-agent
cd my-agent
cp .env.example .env
# Edit .env with your control-plane URL and API key.
set -a && source .env && set +a
python app.py

The generated project creates one sandbox, runs print(1 + 1), and cleans up the sandbox when it exits. The command never writes a live .env file and refuses to overwrite an existing destination. Its initial template is available as --language python --framework plain --use-case code-interpreter; the other integration choices can be added without changing the generated project contract.

from uuid import uuid4
from boxxkite import SandboxManager
from boxxkite.tools import create_sandbox_tool_specs

manager = SandboxManager()
session_id = str(uuid4())
await manager.create_session(organization_id=uuid4(), session_id=session_id)

specs = create_sandbox_tool_specs(sandbox_manager=manager, session_id=session_id)
bash_tool = next(s for s in specs if s.name == "bash_tool")
result = await bash_tool.handler(command="echo hello from boxxkite")

Framework adapters (boxxkite.tools.adapters) convert the same tool specs for LangChain, LlamaIndex, the OpenAI Agents SDK, Google ADK, or plain OpenAI/ Anthropic/Gemini/Mistral function-calling schemas — see the full integration guide and examples/ for a runnable version of every framework.

Self-hosting

Everything in this repo — including the control-plane/ hosted multi-tenant API — is something you deploy yourself:

  • Real Kubernetes — two steps. First lay down the cluster prerequisites (RBAC, NetworkPolicy, pod-security admission policy, ServiceAccount, Config/Secret scaffolding) by applying deploy/rbac.yaml/ network-policy.yaml/pod-security-policy.yaml, or helm install boxxkite deploy/helm/boxxkite. This chart does not deploy the control-plane itself (it has no Deployment/Service) — the per-session sandbox pods are created programmatically by the control-plane at runtime. Then deploy the control-plane/ API separately (see the Render button below or the developer docs). For Argo CD, Flux, or another Kustomize-based GitOps flow, use the generated Helm projection and environment overlays in deploy/kustomize/README.md. A local kind cluster works too: ./deploy/local-kind/setup.sh.
  • Per-cluster warm-pool sizing — use the optional declarative file in docs/FLEET-CAPACITY.md when each process needs a reviewed cluster-specific capacity target.
  • Serving more than one internal team? See docs/guides/self-hosted-multi-tenancy.md for what separates one tenant from another (and what doesn’t), plus reference ResourceQuota/LimitRange/NetworkPolicy manifests in deploy/multi-tenancy/.
  • One-click Render deploy for the control-plane API — (still needs a real Kubernetes cluster for actual sandbox execution).
  • docker-compose, for local iteration without a cluster — see the Quickstart above.

docker-compose mode shares a PID namespace with the sandbox container and execs into it via nsenter, the same mechanism the Kubernetes runtime uses — it no longer needs (or mounts) the host’s Docker socket. See SECURITY.md for the current list of disclosed limitations.

Full walkthroughs for every path above (Kubernetes, Helm, Render, the boxxkite CLI’s hosted mode, secrets, webhooks, MCP, and every SDK) are organized in the repository documentation map and the developer docs site.

Run the control-plane locally

The control-plane/ multi-tenant API is a separate service from the boxxkite up SDK path — it is not part of deploy/docker-compose.yml, and you run it on its own. To bring it up against a throwaway SQLite database (no Postgres required) for API exploration:

cd control-plane
uv venv                              # create .venv
uv pip install -e '../[dev]'         # install the boxxkite runtime (sibling pkg)
uv pip install -e '.[dev]'           # install the control-plane itself
ENVIRONMENT=development DATABASE_URL=sqlite+aiosqlite:///./cp.db \
  uv run uvicorn control_plane.main:app --port 8099

Then check it’s up:

  • http://localhost:8099/health — liveness (process is up)
  • http://localhost:8099/health/ready — readiness (round-trips a DB query)
  • http://localhost:8099/docs — interactive OpenAPI docs

This gets you the API surface (accounts, API keys, session bookkeeping), but actually executing sandbox pods still needs a real Kubernetes cluster — the control-plane creates per-session pods programmatically at runtime (a local kind cluster via deploy/local-kind/setup.sh works). Against SQLite with no cluster you can exercise the HTTP/auth surface, not real code execution.

Run the local MemoryBase embedding server

MemoryBase’s default embeddings and optional reranking can run in a separate local process using Hugging Face Transformers, without Ollama or PyTorch in the control-plane:

cd memory-model-server
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
BOXKITE_EAGER_LOAD=true .venv/bin/uvicorn app:app --host 127.0.0.1 --port 8000

The first start downloads the configured local embedding and reranker models. On Apple Silicon, device auto-detection selects MPS. Set the control-plane’s BOXXKITE_MEMORY_EMBEDDINGS_ENABLED and BOXXKITE_MEMORY_RERANKING_ENABLED to true to use the local endpoints.

For a managed embedding comparison, set BOXXKITE_MEMORY_EMBEDDING_PROVIDER=gemini, BOXXKITE_MEMORY_EMBEDDING_MODEL=gemini-embedding-2, BOXXKITE_MEMORY_EMBEDDING_DIMENSIONS=1024, and provide BOXXKITE_MEMORY_EMBEDDING_API_KEY. Gemini Embedding 2 uses a separate vector space, so switching providers requires re-embedding existing memories; the model ID and dimensions are part of the vector-store key for that reason.

What’s in this repo

One repo, several independently-versioned pieces, kept together deliberately (see CONTRIBUTING.md):

Piece What it is
src/boxxkite/ (boxxkite-sandbox on PyPI) The core: SandboxManager, WarmPoolManager, and the 15+ tool boxxkite.tools surface. Embed this directly against your own cluster.
sidecar/ The FastAPI service that runs in every sandbox pod — filesystem I/O, command exec via nsenter, storage sync.
control-plane/ Optional hosted-API layer in front of SandboxManager — accounts, API keys, fair-use limits.
sdk-python/, sdk-js/, sdk-go/, sdk-rust/ Thin HTTP clients for your own running control-plane.
mcp-server/ (boxxkite-mcp) Wraps the Python SDK as an MCP tool source for Claude Code, Claude Desktop, Codex, or Cursor.
src/boxxkite/handoff/ (boxxkite handoff , part of the main CLI) Moves an in-progress local Claude Code/Codex CLI/opencode/Cursor session into a fresh sandbox, full conversation history included — see the handoff guide.
bastion/ Standalone SSH server bridging into a session’s human-takeover WebSocket.
deploy/ Kubernetes manifests, Helm chart, Dockerfiles, docker-compose, Render Blueprint.
examples/ Runnable cookbook — LangGraph, LangChain, raw HTTP, OpenAI/Gemini/Mistral function calling, and more.

Security

boxxkite executes arbitrary, agent-generated code — its security posture is layered defense in depth: a per-pod shared-secret sidecar auth token, a fresh empty network namespace on every exec call, non-root execution with every Linux capability dropped, and a read-only root filesystem. No single one of these is meant to stand alone.

See SECURITY.md for the full model, known limitations, and how to report a vulnerability privately — this project runs arbitrary code, so a sandbox-escape report deserves a fast, private path, not a public issue. The repository’s isolation model covers the runtime boundary and its trade-offs.

Published packages and images

Package Registry
boxxkite-sandbox PyPI
boxxkite-client (Python) PyPI
boxxkite-client (JS/TS) npm
boxxkite-mcp PyPI
boxxkite-client (Go) pkg.go.dev
boxxkite-client (Rust) crates.io

Container images are published to GHCR (ghcr.io/evalssment/…):

Image Architectures
boxxkite-sandbox linux/amd64 only
boxxkite-sandbox-minimal linux/amd64, linux/arm64
boxxkite-sidecar linux/amd64, linux/arm64
boxxkite-control-plane linux/amd64, linux/arm64

boxxkite-sandbox is amd64-only. Its Dockerfile deliberately hard-fails on arm64 because the pinned Chrome-for-Testing release has no linux/arm64 build (deploy/sandbox.Dockerfile). arm64 / Apple-Silicon users should use boxxkite-sandbox-minimal (multi-arch, no Chrome/LibreOffice/pandoc stack), or build/run the full image under linux/amd64 emulation — docker-compose.yml already forces platform: linux/amd64 for exactly this reason. The other three images are multi-arch.

Community

Join the Discord — get help from other users and maintainers, report a bug, or discuss implementation ideas. The community guide links contribution, governance, conduct, security, roadmap, and release information.

License

Apache 2.0 — permissive, with an explicit patent grant. Use, modify, self-host, or build a competing hosted service on top of boxxkite; there’s no restriction.

Contributing

See CONTRIBUTING.md — we use the Developer Certificate of Origin (git commit -s), not a CLA. Questions before opening a PR? Ask in the Discord first.

View the full README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide New to MCP? Start with the mcpskill.org guide →