Open source · Docker isolation · One command
Give the agent a cage, not your keys.
Unattended, not unguarded.
Run Claude Code with full autonomous power, safely sandboxed in Docker.
$ curl -fsSL https://cleat.sh/install | bash
One command
Run it. It's already contained.
~ $ cleat
✔ Image ready (cached)
✔ Container started
✔ Auth shared
✔ Claude launched
Container: cleat-backend-a1b2c3d4
Project: ~/backend (same path, sandboxed)
Caps:
mount: git, ssh, env, hooks, gh
sandbox: docker (breaks isolation)
Claude is analyzing your project...
❯ ▊
A real recording: Claude Code hunts for keys and finds nothing, then rm -rf's the box's own OS. The host doesn't notice.
They say an agent bricked someone's Mac overnight. The truth is scarier: it can leak your keys and wipe your work, no reboot required. So I built Cleat.
Same power. Smaller blast radius.
| Without isolation | With Cleat | |
|---|---|---|
| Same power | ||
| Edit project files | ✓ | ✓ |
| Clipboard to host | ✓ | ✓ bridged |
| Browser auth (OAuth) | ✓ | ✓ bridged |
| Install packages | ⚠ your system | ✓ contained |
| Run any command | ⚠ your system | ✓ contained |
| Test Docker apps | ⚠ your system | ✓ opt-in via --cap docker |
| Smaller blast radius | ||
| Access other projects | ⚠ exposed | ✓ blocked |
| Modify your system | ⚠ exposed | ✓ blocked |
| Your machine stays clean | ⚠ global installs pile up | ✓ deps stay in the box |
| Read ~/.ssh, credentials | ⚠ exposed | ✓ blocked |
| Claude config & approvals | ⚠ shared, corruptible | ✓ per-project |
| Safe to leave overnight | ⚠ risky | ✓ yes |
Architecture
Your machine. Docker container. Clean boundary.
/home/coder/.claude
/workspace
caps:
mount: git, ssh, env, hooks, gh
sandbox: docker (breaks isolation)
Claude Code (full permissions)
Can: read/write project, install packages, run cmds
Cannot: touch host or other projects (by default)
Everything else is untouched.
Why not just write a Dockerfile? You could. But then you handle UID/GID mapping, clipboard bridging, browser auth, hook forwarding, host connectivity, session persistence, per-project container naming and a dozen edge cases. Cleat handles all of it in one command.
Features
One command. Everything wired up.
$ cleat
✔ Docker tuned for Cleat (24 GB VM, room for many parallel sessions)
✔ Image ready (cached)
✔ Container started
✔ Auth shared
✔ Claude launched
Container: cleat-myapp-a1b2c3d4
Project: ~/projects/myapp → /workspace
Caps: git, ssh
┌──────────────────────────┐
│ 8 hours later │
│ 47 files changed │
│ All tests passing │
│ Host system: untouched ✔ │
└──────────────────────────┘
One command. Leave it running. Walk away.
$ cleat ps
Cleat containers:
● cleat-api-a1b2c3d4
Up 2 hours
/Users/marcin/projects/api
● cleat-web-e5f6a7b8
Up 45 minutes
/Users/marcin/projects/web
● cleat-docs-c9d0e1f2
Exited (0) 5 hours ago
/Users/marcin/projects/docs
Resume with: cd <project-dir> && cleat resume
$ cleat kit
Cleat Kits (curated Claude pre-configurations)
Box: main · other boxes: cleat kit <name> <box>
▸ ● plan-big-execute-small
○ none (your own config, no kit)
Run your session on Fable 5: it plans and reviews while
worker and scout subagents (Sonnet 5 by default) execute
and explore, each in its own context window so the main
session stays lean. Flagship judgment on the plan and every
review, the mechanical bulk billed at the worker model's
rate, so heavy work burns your rate limit far slower.
Adapted from Anthropic's coordinator-pattern cookbook.
↑/↓ navigate ⏎/→ select q cancel
A better place to run Claude, not just a safer
one: Fable 5 judgment on the plan and every
review, a Sonnet 5 crew on the legwork, per box.
$ cleat kit plan-big-execute-small
Enable kit plan-big-execute-small for box main?
Run your session on Fable 5: it plans and reviews while worker
and scout subagents (Sonnet 5 by default) execute and explore,
each in its own context window so the main session stays lean.
Flagship judgment on the plan and every review, the mechanical
bulk billed at the worker model's rate, so heavy work burns your
rate limit far slower. Adapted from Anthropic's
coordinator-pattern cookbook.
Pattern from Anthropic's cookbook: big models for planning,
small models for execution. Link: cleat kit show plan-big-execute-small
This kit adds, inside the box only:
agents worker (model: sonnet), scout (model: sonnet, read-only by contract)
CLAUDE.md a delegation policy section (appended, yours stays)
planner your session's model, not changed by the kit
Your host ~/.claude and this repo are not touched.
Enable? [Y/n] _
Anthropic's coordinator pattern, the setup power
users hand-build, enabled in one command.
$ cleat
✖ Docker isn't installed.
Install Docker now? (via Homebrew)
1) Docker Desktop (standard; free personal, paid for cos)
2) OrbStack (fast, mac-native; paid commercially)
3) Colima (open source, CLI-only)
n) no
Choice [1/2/3/n] 1
✔ Docker installed
✔ Container started
No Docker? Cleat asks first, then installs and
carries on. macOS, Linux and WSL2. Never a blind pipe.
$ cleat
! Docker isn't running. Starting Docker Desktop...
⠹ waiting for the Docker VM (14s)
✔ Docker ready
✔ Image ready (cached)
✔ Container started
✔ Auth shared
✔ Claude launched
Rebooted? Docker Desktop, OrbStack, Colima,
WSL2: cleat starts your Docker and carries on.
$ cleat stop
✔ Session ended. Resume with: cleat resume
$ cleat resume
✔ Session resumed
Back where you left off.
> copy the API key to clipboard
● Bash(echo -n "sk-…" | pbcopy)
⎿ (No output)
● Done. The API key is in your clipboard.
Bridged to host. No X11. Zero config.
$ cleat config
Cleat Capabilities
Scope: global (~/.config/cleat/config)
▸ [✔] git Mount ~/.gitconfig (read-only) for commit identity
[·] ssh Mount ~/.ssh (read-only) and forward SSH agent
[·] env Load env vars from ~/.config/cleat/env and .cleat.env
[·] hooks Run your Claude Code hooks on the host (global + project)
[·] gh GitHub CLI auth (persists across rm/nuke/rebuild)
[·] docker Host Docker socket (breaks sandbox) to test Docker apps
↑/↓ navigate ␣ toggle ⏎ save q cancel
$ cleat
▸ Project .cleat requests host access: git, docker (beyond the sandbox)
Trust this project's .cleat? (applies its caps; approve once, undo with cleat untrust) [y/N] _
A cloned repo can't grant itself your keys.
Approve once, per project. Default is deny.
$ cleat shell
▸ Container cleat-api-a1b2c3d4
coder@a1b2c3d4e5f6:/workspace$
Drop into bash. Debug anything.
Same container, same state.
$ cleat config --enable hooks
✔ hooks enabled
Run your Claude Code hooks on the host (global + project)
(SessionEnd hook runs on host: macOS notification)
Your hooks, running on your host.
Global + project hooks just work.
$ cleat --cap docker
! Docker socket mounted. Container can create host-level processes
✔ Claude launched
$ docker compose up -d
Started api, db, redis
$ docker compose exec app npm test
All tests passed
Host daemon. Real containers.
The socket is a host bridge, opt-in.
$ cleat upgrade-claude
⠋ Upgrading Claude Code (latest)...
✔ Claude Code upgraded (2.1.40 → 2.1.156)
Recreate cleat-backend-a1b2c3d4 now to use it? [Y/n] _
Bump bundled Claude Code. No rebuild.
Your sessions and auth stay put.
Give the agent a cage, not your keys.
Start sandboxing Claude Code with one command.
Because you shouldn't need a Time Machine backup to use AI.
$ curl -fsSL https://cleat.sh/install | bash