What it does
karucode is a coding agent you run yourself — and the whole of it is one binary. Point it at a project and it reads the files, searches them, edits them, runs commands with streamed output, and inspects git. It delegates work to subagents, and it keeps going through a multi-step task until the work is done or you stop it.
It is one Rust binary. State lives in a SQLite database in WAL mode — projects, sessions, runs and agents. The browser UI is embedded in that binary and served from the same origin, so there is no Node at runtime and nothing else to deploy.
A run is not cut off by a turn counter. max_iterations defaults to
0, which means no ceiling: the model works until the task is done, you cancel it,
or the wall clock runs out.
max_iterations 0 no turn ceiling (default) max_run_secs 86400 hard wall clock, 24 h loop guard stops a run repeating itself a non-zero max_iterations is an optional backstop
Approvals sit in front of every mutation: ask is the default for shell commands and
file writes. On restart, runs left in running become interrupted and
pending approvals expired. Nothing is silently retried.
Start here
Three pages, in the order most people need them.
- Quick start Nothing installed yet. One script, the wizard, then your first task.
- Configuration It runs and you want to change how. Environment variables, TOML, plugins, MCP, approvals.
- Security You are about to bind it to an interface or leave it unattended. Read this before you do.
How it is put together
Five jobs and one database. Each one is a layer you can reason about on its own, which is the point of keeping the whole thing in a single binary.
- axum API + SSE
- Serves the REST API and the embedded UI from one origin. Runs and their events stream to the browser over SSE.
- agent loop
- Owns approvals, subagents and budgets. Independent tool calls run in parallel; anything that can see a sibling’s effects — shell, plugins, MCP, subagents, approvals — runs in call order, so the transcript is the one a sequential run would have produced.
- provider
- Any endpoint that speaks the OpenAI chat-completions API with streaming tool calls. Providers are install-wide; a session can pin its own model.
- tools
- Files, search, shell, git, and karucode’s own documentation — plus a PTY terminal tab for you, which the model cannot call.
- plugins + MCP
-
Separate processes, namespaced as
plugin__<name>__<tool>andmcp__<server>__<tool>, so a third-party tool cannot shadow a built-in one. - SQLite (WAL)
-
Projects, sessions, runs and agents. This is what makes a crash survivable: a restart resumes
the same transcript, with unfinished runs marked
interruptedrather than retried.
The home page draws the same stack as a diagram, if you want the picture: architecture.
What it refuses to do
These are properties of the design, not gaps waiting to be closed. They are listed here because a tool you expose to a network should tell you where its edges are.
- No shell sandbox. Commands run as the server user. Use a container or a VM for
untrusted code, or for unattended
automode. - No built-in TLS. Put a reverse proxy in front for remote access; there is no certificate handling in the binary.
- No plugin sandbox. A plugin is a separate process with your permissions. A
rebuilt plugin is picked up by a reload —
POST /api/plugins/reload, orplugins_watch— rather than by restarting the server. - No per-project providers, no team workspaces, no cloud sync, no hosted service, no signup.
The full list lives on the home page under what it doesn’t do. The trust boundaries — what is contained, what is not, and how to expose it — are on Security.
Requirements
- Linux, x86_64 for the published release. The installer needs
curlandsh; the systemd path needs root. - No compiler. The release is a prebuilt binary with the UI inside it — Rust 1.89+ and Node 22.12+ are only needed to build from source.
-
Optional:
git, andripgrep— a pure-Rust search fallback is built in.
No cloud account, no signup, no telemetry. MIT licensed. Start with Quick start.