Model or dataset
Th0rgal/sandboxed.sh avatar
Th0rgal/sandboxed.sh

sandboxed.sh: a mission-execution backend that keeps autonomous agents off your host

Safe runtime for autonomous on-chain AI agents: isolated sandboxes, Library skills, encrypted secrets.

511 stars53 forksRustLicense varies

At a glance

What is it?
sandboxed.sh is a self-hosted Rust backend that runs Claude Code, Codex, OpenCode, Gemini and Grok missions inside throwaway Linux workspaces, driven over MCP by a separate coordinator. The split is the point, and it is also the main thing to evaluate before adopting it.
Who is it for?
Adopt sandboxed.sh if you already run an MCP-capable coordinator and need agent work to land in disposable Linux workspaces rather than on your host, and if you accept that the coordinator decides what to do while this project only executes. Do not adopt it if you want a single binary that both plans and runs, or if you cannot self-host the coordinator half.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem is where untrusted agent output actually runs

An agent that writes code, runs builds and opens pull requests needs a filesystem, git, and a shell. Giving it your laptop or your production host means every generated command executes with your privileges. sandboxed.sh addresses that specific gap. The README describes it as the "mission-execution backend" of a two-part system: the agent never runs untrusted code itself, it hands each unit of work to sandboxed.sh, which runs it in a throwaway workspace or container and streams back structured results. The intended user is someone running an autonomous loop over days, not someone asking a chat model a question. The README's own examples are telling: pointing an agent at a GitHub issue and letting it open a PR, or giving an agent SSH access to a home GPU through a VPN so it can fine-tune models overnight. Both assume a long-running process with real credentials, which is exactly the scenario where host isolation stops being optional.

The coordinator and the executor are separate programs

The architecture is a deliberate split, and the README states it plainly: sandboxed.sh is the half an autonomous agent drives over MCP to build things in isolation, while a coordinator decides what to do and when. The reference coordinator is the author's own Hermes fork, a Python gateway plus CLI with a bundled Electron desktop app, but the README says any MCP-capable assistant works. Data flows two ways. The coordinator calls MCP tools such as list_projects, update_project_status, set_project_grant and link_mission_to_project, and it can call start_mission. Results come back as SSE or webhooks. The target model is named in docs/AGENT_CONTROL_PLANE.md as portfolio, project, track, attempt, action, receipt, evidence. Four runtime concepts carry the current integration: a Project is the durable unit of work, stored in projects.db on the sandboxed.sh host and served at /api/projects/*, with a mode of active, blocked or paused, plus an autonomy grant covering merge authority, budget and parallelism. A Controller is a coordinator cron that wakes on a schedule, reads its control conversation, GitHub and project state, then dispatches work. A Conversation is the durable chat thread; the one bound to a project is its control conversation, and because continuations roll over it is addressed by route rather than a frozen ID. A Mission is one unit of execution, tagged with a project and track. The README's rule of thumb is worth quoting because it defines the boundary: a controller drives a project through its control conversation by dispatching missions. In-conversation subagents handle quick reasoning and decomposition; anything needing a real filesystem, git, builds or a PR is dispatched as a mission.

Isolation is systemd-nspawn, not a container you already know

The README lists isolated workspaces as containerized Linux environments using systemd-nspawn, with per-mission directories. That choice matters more than it looks. systemd-nspawn is a systemd-native container manager, so the sandbox story is tied to a Linux host running systemd, not to a Kubernetes cluster or a Docker daemon you may already operate. The README also mentions Docker in the architecture diagram, showing systemd-nspawn or Docker as the isolation layer, and it points to a separate Docker install guide alongside a native guide. Which of the two you end up on is not something the supplied material resolves; the comparison is deferred to a section of the README called choose your installation method, which is truncated here. Treat the isolation backend as a decision you make by reading docs/install-docker.md and docs/install-native.md, not one you can infer from the feature list. The per-mission directory layout is the concrete part: each mission gets its own workspace, so a failed build or a destructive command is scoped to that directory rather than to a shared home.

Getting it running: two documented paths and the MCP surface

The README does not inline an install command. It routes you to docs/install-docker.md for the Docker guide and docs/install-native.md for the native guide, and it frames the choice as an installation comparison in the README's own anchor. That is the honest starting point: this is not a curl pipe into sh, it is a self-hosted service you deploy and then point a coordinator at. The integration surface is MCP. Your coordinator needs the project tools (list_projects, update_project_status, set_project_grant, link_mission_to_project) and the ability to call start_mission, and it receives results over SSE or webhooks. Projects live in projects.db on the sandboxed.sh host and are served under /api/projects/*, which is also what the web dashboard's board at /, the desktop Projects board, and the iOS Projects tab render against. If your coordinator speaks MCP but not these tool names, the material here does not describe an adapter, so budget for writing one. The README also notes a state ingestor that folds controller status trailers from deliveries into the project record, which means text-only status updates still update the roster; that is a compatibility affordance for coordinators that do not call the structured tools.

Four runtimes share one harness, and that is a maintenance surface

The feature list names Claude Code, OpenCode, Codex, Gemini and Grok as runtimes running in the same infrastructure. Release v0.12.0 is titled Grok Build, Needs You, iOS UX, which is consistent with Grok being newer to the set than the others. Supporting several agent CLIs means tracking several upstream release cadences, and the release history shows how quickly that moves: v0.11.5 on 2026-05-14, v0.11.1 on 2026-05-03, v0.12.0 on 2026-05-16. Three releases in under two weeks. That pace is a maintenance cost you inherit. The other features follow the same pattern of breadth: model routing with provider fallback chains, health checks and rate-limit handling; an optional MCP registry for extra tool servers such as desktop or playwright; an OpenAI-compatible proxy queue mode that defers /v1/chat/completions when all routed providers are temporarily rate-limited; and capability-gated Chat Completions, Responses and Anthropic Messages protocols with provider-specific reasoning continuity, documented in docs/INFERENCE_PROTOCOLS.md. Each of those is a subsystem you may or may not need, and the README presents them as one package.

Where it is the wrong tool

The clearest limitation is structural: sandboxed.sh does not decide anything. If you want one program that reads an issue, plans, and executes, this is the wrong half. You supply the coordinator, and the reference implementation is the author's Hermes fork, so the well-trodden path runs through someone else's Python gateway and Electron app. The README says any MCP-capable assistant works, but the documented tool contract is the one Hermes uses. Second, the isolation layer assumes a Linux host with systemd if you take the native path; the supplied material does not describe a macOS or Windows host story. Third, the project model is opinionated and heavy. Projects, modes, autonomy grants with merge authority and budget, tracks, decisions, controllers, control conversations and missions are a lot of vocabulary to adopt before your first agent run. If your work is a single one-off script, that vocabulary is overhead. Fourth, the licence is not stated in the repository metadata provided, which is a real blocker for anyone whose adoption process requires a known licence. That is not a legal opinion, it is an observation that the field is empty in the material at hand.

What a plain container runner does differently

The obvious alternative is running the agent yourself in Docker or a similar container, with no coordination layer at all. The difference is not the isolation primitive, it is what surrounds it. A hand-rolled container gives you a sandbox and nothing else: you write the loop that decides what to run, you parse the agent's output, you track which task is in flight, and you decide when a result is good enough to merge. sandboxed.sh puts a durable project record in projects.db, an event stream over SSE and webhooks, and an MCP tool contract on top of the sandbox, so a scheduled controller can dispatch work and read structured state instead of scraping prose. The trade is that you now run two systems and keep them in sync. If your agents are short-lived and you review every output by hand, the container alone is less machinery for the same safety. If you are running multi-day operations where the deciding happens on a cron, the project record and the mission boundary are the parts you would otherwise rebuild badly.

Upgrades, licence and what to check before you commit

Upgrade cost is the release cadence. Three releases in roughly two weeks in May 2026, with titles that mix runtime additions, harness loop changes and iOS fixes, means the project is moving on several axes at once. Pinning a version and reading the release notes before each bump is the only defensible approach; the notes themselves are short, as the titles v0.11.5 Native Harness Loops & iOS Network Resilience and v0.11.1 Mission Workbench BugBot Fixes suggest. On licensing, the repository metadata supplied here does not name a licence, so you cannot assume permissive terms, and you should not treat anything in this article as legal advice. Confirm the licence file in the repository before you build on it. The concrete checks are small and specific: read docs/install-docker.md and docs/install-native.md to pick a path your host supports, read docs/AGENT_CONTROL_PLANE.md to confirm the MCP tool names match what your coordinator emits, and read docs/CONTROLLERS.md, which the README references for coordination between controllers, if you plan to run more than one controller against the same roster. If your coordinator cannot call set_project_grant or link_mission_to_project, the structured project state that justifies the extra layer is not available to you, and the remaining value is the sandbox.

Editorial conclusion

Adopt sandboxed.sh if you already run an MCP-capable coordinator and need agent work to land in disposable Linux workspaces rather than on your host, and if you accept that the coordinator decides what to do while this project only executes. Do not adopt it if you want a single binary that both plans and runs, or if you cannot self-host the coordinator half. Before committing, verify the licence (the repository metadata does not state one), confirm which install path your host supports by reading docs/install-docker.md and docs/install-native.md, and check whether the MCP tool names your coordinator expects match the ones in docs/AGENT_CONTROL_PLANE.md.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. Th0rgal/sandboxed.sh on GitHub
Community notes

Community notes