Coding agents on your own infrastructure.
Chetter is an open source control plane for autonomous coding agents. One Go server, one SQL database, plain containers — and the harnesses you already use.
No custom runtime — standard harnesses
Why Chetter
Hosted agent platforms want your code, your credentials, and a monthly bill.
Chetter is the opposite position on every one of those points.
Hosted platforms
- ✗Closed source, or open in name only
- ✗Agents run in their cloud, on proprietary sandboxes
- ✗Exotic infrastructure — Firecracker VMs, custom kernels
- ✗Custom agent runtime you can't reuse locally
- ✗Your code and secrets leave your network
Chetter
- ✓MIT licensed, full stack, no hosted tier
- ✓Runs on your Docker or Kubernetes — nothing exotic
- ✓Optional gVisor sandboxing, outbound egress filtering
- ✓Standard harness CLIs — same tools you use by hand
- ✓Code and credentials never leave your network
Design principles
Deliberately boring technology, composed well.
Not marketing values — constraints the codebase is held to.
True open source
MIT, no hosted service. Clone it, run it, own the execution path.
Standard harnesses
Execution delegated to existing CLI agents. No custom runtime.
Docker or Kubernetes
Standard containers anywhere. gVisor when you need a hard boundary.
GitHub-native
Agents open PRs, triage issues, post reviews, and merge, close, and label the result — with managed Git identities and an audit record for every write.
Plain containers
The agent image is a normal Docker image with your stack in it.
API & MCP first
Everything is a ConnectRPC endpoint and an MCP tool. The UI just observes.
Spec sheet
What the system actually does.
SKIP LOCKED claims under 2-minute leases that every 5-second heartbeat renews — a transient missed heartbeat can't strand a live execution — and a 30-second reaper that recovers dead runners' tasks. A runner never executes the same task twice at once. Each task's deadline is chosen at submission — presets from 15 minutes to 24 hours or a custom value, with the server default as the fallback — and can be extended while the task runs. No broker, and no Redis: multiple server replicas coordinate through the database alone.repos/<slug> directory. A single git_url is just a one-entry set, so existing callers are unchanged. The runner clones every repository before the agent starts — a failed clone fails the task instead of running the agent against a partial workspace — and each clone is credentialed through its own GitHub App installation rather than inheriting the primary's token. The set persists on the task and its session, so resumes reuse the same layout. A task may also carry no repositories at all — diagnostics runs do — which yields no checkout instead of a preparation failure.chetter_merge_pr, chetter_close_pr, chetter_issue_close, and chetter_issue_add_labels to close the work out. Raw gh write access stays blocked behind a read-only allowlist; every mutation is attributed to its task and logged.runsc) is the sandbox — a userspace kernel intercepting every syscall; plain Docker is not a boundary against a malicious task. A transparent HTTP + DNS proxy filters outbound egress by domain allowlist. CPU, PID & memory limits contain runaway tasks — memory caps are configurable per deployment and stamped onto every task by the control plane (CHETTER_TASK_MAX_MEMORY_MB), with runner-level caps bounding the worst case when several runners share one host — the supplied runners default to 8 GB RSS with bounded swap headroom (CHETTER_CONTAINER_SWAP_MB), so a compiler-heavy build that spikes past its resident cap spills to swap instead of being OOM-killed at it; a periodic reaper removes leaked task containers that no longer back live work, and never touches a sibling runner's sandbox. Enforced isolation admission keeps pending isolated work pending through a deploy drain — a fresh draining runner still advertises its isolation capability while admission is closed — instead of failing it as if no sandbox were available, while a stale or non-isolating fleet still fails it closed. Task containers run with all capabilities dropped and no privilege escalation./metrics, /api/server-info returning build identity and uptime only to authenticated callers, agent image downloads pinned and checksum-verified, task environment variables validated at submission (well-formed names only, with reserved names and prefixes rejected), SSRF-safe validation of outbound webhook and Slack callback destinations (HTTPS-only by default, with loopback, link-local, private, and metadata addresses re-checked on every dial), and known secret values redacted from every stored or published event. Inbound webhook endpoints authenticate with constant-time HMAC-SHA256 or bearer checks, and their secrets are referenced by environment-variable name only — never stored, logged, or returned.chetterctl CLI, or the web UI.How it works
Prompt to pull request in six steps.
Submit
MCP call, cron, or webhook creates a task.
Queue
Stored in the database as pending.
Claim
A runner wins the row lock and lease.
Prepare
Repos cloned, agent config injected.
Run
Harness executes in an isolated container.
Report
Events and artifacts stream back. PR opened.
See it running
A UI for watching, not for wizards.
Real views from a production instance that runs its own triage, implementation, and docs maintenance. Click any screenshot to inspect it.
Quick start
Running in four commands.
$ git clone https://github.com/flatout-works/chetter.git $ cd chetter && cp .env.example .env # set a token + one LLM key $ ./deploy/build.sh $ docker compose --env-file .env -f deploy/compose.yaml \ -f deploy/compose.local.yaml up -d # mcp → http://localhost:18088 ui → http://localhost:18090
Own your agent infrastructure.
No hosted service. No signup. Clone the repo and you're running.