Hand it a software task and get back finished, tested code. zot is an automated software factory in a single binary - an autonomous coding harness that plans, edits, runs, and verifies until the work is done.
Give it a brief and walk away:
zot "add rate limiting to the API, with tests"zot reads the repo, writes and edits the code, runs the build and the tests, and fixes what it broke - on its own, from that one brief to a recorded outcome. When it stops you have a changed working tree and a full session log of every step it took. No chat loop, no approving each edit: one brief in, finished work out.
Most coding tools optimize the conversation between a developer and an agent. zot optimizes the production run: it drives the whole job from one brief, without a follow-up prompt at every step and without a hosted engine.
It talks straight to a model provider over the OpenAI-compatible API - OpenAI, Anthropic, Groq, Mistral, DeepSeek, OpenRouter, a local Ollama, or anything else that speaks the same API - so all you need is a provider key. No account beyond the provider's own, and nothing is sent anywhere except the provider you configure.
Grab a prebuilt binary from the releases page - no toolchain required:
VERSION=vX.Y.Z; OS=linux ARCH=amd64 # e.g. darwin/arm64 on Apple Silicon
curl -L "https://github.com/openzot/openzot/releases/download/${VERSION}/zot-${VERSION}-${OS}-${ARCH}.tar.gz" | tar xz
mv "zot-${VERSION}-${OS}-${ARCH}/zot" ~/.local/bin/ # or any directory on your PATHzot defaults to the zai backend running glm-5.2. Export a key and
give it a job:
export ZAI_API_KEY="…"
zot "add input validation to the signup handler and a test"Any OpenAI-compatible provider works - --backend anthropic --model claude-5-sonnet, a local --backend ollama, gateways, or a custom endpoint; see
docs/backends.md. To build from source or run the container
image, see docs/development.md and
docs/docker.md.
The harness is zot's own, in the agent package:
agent.ExecuteWithToolsruns the model in a loop - it calls tools, sees the results, and goes again - until it records an outcome (_success/_failure) or a budget or guard stops it.agent.DefaultTools()gives it the toolbox:read,write,listandshellfor the work, plusplanandprogressto structure and narrate it.
That package is importable, so the same engine drives more than coding: Rook, an AI bug-hunting and security-audit agent, is built on it with its own toolset and skills.
What sits under that is the part worth knowing about:
- Thread assembly fits the conversation to the model's context window, newest-first, keeping tool calls paired with their results.
- Context strategy decides what happens as that window fills.
compact(the default) summarises the older history into a checkpoint with a model call, so a long run keeps a condensed memory of its early turns instead of losing them;truncatesimply drops the oldest messages to fit. A checkpoint is preserved verbatim and never re-summarised, and an outright provider rejection falls back to a no-model summary and retries. Configurable - see configs/zot.example.yaml. - Loop detection notices when the agent has stopped making progress - four overlapping heuristics, because the obvious one (repeated messages) silently misses reasoning models, which interleave a thought between every tool call.
- Settle mode ends a run when the agent records an outcome, not when its prose happens to sound final. An answer containing "task completed" is not an ending. Note the boundary, though: settle mode checks that the agent declared done, not that the work is done. The agent verifies its own work by running the tests (its instructions tell it to); zot does not yet independently gate the outcome on a check of its own.
- Session logs record every run to disk as it happens, so a run nobody
watched is still answerable afterwards - and so it can be picked up again with
--resume(see docs/configuration.md).
zot itself is a read-only Bubble Tea
viewer over that run - it renders the event stream into a scrollable log and has
no text input, because the run is autonomous.
zot has no native sub-agent primitive, by design. There is no spawn, no
built-in supervisor, no fixed orchestration graph baked into the engine - and
that absence is deliberate, not a gap waiting to be filled. A fixed hierarchy
would decide, in advance, how work should be divided for every task; most tasks
do not divide the way the framework guessed.
What the engine gives instead is the raw capability, and it lets the agent decide how to use it:
- An agent can call into itself. It has a
shelltool, so it can invokezotagain - a fresh run with its own brief, its own working directory, its own budget - and read back the result. Delegating a self-contained piece of work to a clean context is a shell command, not a special API. Direct instructions in yourAGENT.md, or a skill, are what tell it when that is worth doing. - Agent-to-agent communication is left open, too. zot does not prescribe a message bus or a protocol. Two runs coordinate through whatever they already share - the filesystem (a scratch file, a work queue as a directory of tasks), a git branch, an HTTP endpoint, a channel daemon. The mechanism is a choice the task makes, not one the engine imposes.
The intent is that the agents themselves figure out how to organise and
communicate, from the task in front of them, the context in the repository,
and any guidance a relevant skill supplies. Encode the pattern you want - a
map/reduce fan-out, a reviewer that re-runs the worker, a pipeline of
single-purpose runs - as a skill (<name>/SKILL.md), and it becomes
available exactly when the model judges it relevant, without changing the
engine. Orchestration is content, not framework.
zot is fully autonomous and has real file-write and shell-exec access
from --dir. The flag changes the process working directory; it is not a
filesystem sandbox. Absolute paths and shell commands retain all permissions
of the zot process. Point it at a scratch directory or a disposable git checkout
you are happy for it to change - not your home directory.
Configured backend credentials are resolved into zot's in-memory configuration and then removed from the process environment before the agent starts, so its shell commands do not inherit those API keys. Other secrets already present in the environment or readable from disk remain accessible to those commands.
The published container image is the practical way to bound
this: the agent can only touch the volume you mounted, and docker run gives you
the rest of the levers (read-only root, dropped capabilities, resource limits) in
one place.
zot is 0.x: functional and in active use, with improvements landing release to release. Until 1.0 the CLI flags, config, and behavior may still change between versions - pin a version and skim the changelog before upgrading.
- docs/backends.md - providers, credentials, gateways, custom endpoints, the Responses API
- docs/configuration.md - config file, flags, controls, sessions,
AGENT.md& skills - docs/development.md - building from source, release vs developer builds, the codebase map
- docs/portable-config.md - baking the configuration into the binary
- docs/docker.md - running the container image
- CHANGELOG.md · RELEASES.md
| Project | Role |
|---|---|
| Rook | An AI bug-hunting and security-audit agent built on zot's engine |
| Pantalk | Connect coding agents to the chat platforms people already use |
| MCPShim | Turn MCP servers and HTTP APIs into standard CLI commands |
| crmkit | Give agents a shared CRM and system of record over HTTP or MCP |

