Capo
A Rust-native coding agent CLI. Single binary, library-first, focused on shipping correct code through a small set of well-understood tools.
$ capo
Install
The crate is published as capo-cli (the name capo was already taken on
crates.io); the installed binary is still capo.
Or grab a pre-built binary from the latest GitHub Release.
Quickstart
Capo reads AGENTS.md / CLAUDE.md from the current directory upward, so per-project context is automatic.
Supported providers
Capo dispatches to one of six providers, selected by --provider <name> or model.provider in ~/.capo/agent/settings.toml (legacy settings.json is still read when no TOML file exists).
provider |
Backend | Auth |
|---|---|---|
anthropic |
Direct Anthropic API | ANTHROPIC_API_KEY env, or auth.json::anthropic.key |
claude-code |
Shells out to the claude CLI (Claude Code subscription) |
The claude CLI handles its own auth |
codex-cli |
Shells out to OpenAI's codex exec --json |
The codex CLI handles its own auth |
openai |
Direct OpenAI API | OPENAI_API_KEY env, or auth.json::openai.key |
gemini |
Direct Google Generative AI REST API | GEMINI_API_KEY env, or auth.json::gemini.key |
gemini-cli |
Shells out to Google's gemini CLI |
The gemini CLI handles its own auth |
Set the model name with --model <name> or model.name in settings; capo passes the name through to the provider's API verbatim.
Tools
| Tool | What it does |
|---|---|
read |
Read a file. Always allowed. |
grep |
Regex search over file contents. Always allowed. |
find |
List files/directories by glob. Always allowed. |
ls |
List a directory's entries. Always allowed. |
write |
Create or overwrite a file. Prompts unless allowlisted. |
edit |
Patch an existing file via unique-string replacement. Prompts unless allowlisted. |
bash |
Run a shell command via PTY. Prompts every time unless allowlisted. |
Configure allowlists in ~/.capo/agent/permissions.toml. See docs/superpowers/specs/2026-04-23-capo-design.md §4 for the full permission model.
Commands & editor
Inside the TUI:
- Type
/for the command palette —/help,/quit,/new,/model,/compact,/resume. - Type
@to fuzzy-search and insert a project file path. - A line starting with
!runs a shell command and sends its output to the agent;!!runs it and shows the output without sending. --resume(or/resume) opens an interactive picker of recent sessions for the current directory.- Attach an image: type
/image <path>(one or more paths, optional trailing text). Most modern terminals also let you drag an image file into the prompt — they paste the file's path as text, which Capo auto-detects when it appears at the start or end of your message. Supported: PNG, JPEG, GIF, WEBP. Max 5 MiB per image. Works against any vision-capable provider (Anthropic, OpenAI, Gemini). - Cumulative session tokens render in the footer (
Σ N↑ M↓) whenui.footer_show_cost = truein~/.capo/agent/settings.toml. Token-only — no price estimation. Providers that don't surface token counts (CLI-shell providers) showtokens: unavailable. - Type
/settingsto open an inline editor forsettings.toml. Edit any of 13 fields across 5 sections; navigate with↑/↓, edit withEnter, toggle bools withSpace, save withF2, cancel withEsc. Save tries the rebuild first — if the new settings fail to apply (e.g. invalid provider),settings.tomlstays unchanged on disk. - Reduce transcript noise with
[ui]collapse settings (edit via/settings):hide_thinking_blocks,collapse_tool_output_by_default,collapse_tool_args_max_lines,collapse_history_after. All apply to rendering only — the agent still sees full content. - Press
Ctrl+Eto globally expand all collapsed blocks in this session (toggle). - Press
F3to enter history-nav mode:↑↓orj/kmove selection,Spacetoggles the selected block's collapsed state (also works on default-collapsed blocks),ggjumps to top,Gto bottom,Escexits. Selection marker is▸in the left gutter; nav-hint row appears above the footer while active. - Thinking / reasoning blocks (Claude extended thinking) render as
dim italic in the transcript.
hide_thinking_blocks = true(the default) keeps them invisible; flip tofalsein/settingsto reveal. - Permission modes. Set how capo prompts for tool calls. Three
modes:
bypass(auto-allow everything except hard-blocked paths),accept-edits(auto-allow write/edit, prompt bash),prompt(current default — prompt write/edit/bash unless allowlisted). Hard-blocked paths (.git/**,.env*,**/.ssh/**) enforce in every mode. Switch sources, highest priority first:- CLI:
capo --mode bypass(or--mode accept-edits/--mode prompt) ~/.capo/agent/settings.toml:[permissions] default_mode = "bypass"- TUI runtime:
Shift+Tabcycles modes (session-only, doesn't write to disk) - RPC:
Command::SetPermissionMode { mode }
- CLI:
- Footer indicator shows current mode:
[bypass](red),[accept-edits](yellow),[prompt](dim). - The legacy
--dangerously-allow-allflag now also works in TUI mode (silently aliases--mode bypass). v0.9 ignored it outside--json.
JSON / RPC mode
Capo can speak structured JSON instead of running its TUI, for use from scripts and IDE plugins:
- One-shot:
capo -p "<prompt>" --jsonruns a single turn and streams the result as line-delimited JSON. Seedocs/json.md. - Persistent:
capo --rpcruns a long-lived server speaking bidirectional JSONL over stdin/stdout. Seedocs/rpc.md. - Attachments: in print and JSON mode, repeat
--image <PATH>on the command line (e.g.capo -p "describe these" --image a.png --image b.jpg --json). In--rpcmode, send attachments insideCommand::SendUserMessage'sattachmentsarray — seedocs/rpc.mdfor the wire form.
Skills
Markdown files in ~/.capo/agent/skills/<name>/SKILL.md (or flat <name>.md) become discoverable skills. They follow the Agent Skills standard:
name: rust-error-triage
description: Use when debugging Rust compile errors or runtime panics
Body content (loaded by the model via the `read` tool when the description matches).
Per-project skills live at <repo>/.capo/skills/.
Extensions
Capo loads third-party extensions from ~/.capo/agent/extensions.toml. An
extension is any executable that reads a JSON event on stdin and writes a
JSON action on stdout — capo spawns it fresh per event.
Three hook events:
session_before_switch— before/new,/resume,/model,/clone,/fork. Extension cancancelto block the action.before_user_message— before every Enter press, gets the user's text and attachments. Extension cancancelto block the turn ortransform_textto rewrite it.command— when the user types a slash command an extension has registered. Extension canreplywith a Notice orsenda synthesized user message.
Manifest example:
[[]]
= "dirty-repo-guard"
= "~/.capo/agent/extensions/dirty-repo-guard.sh"
= ["session_before_switch"]
Run capo and type /extensions to see what's loaded.
See examples/extensions/ for working scripts and
docs/superpowers/specs/2026-05-21-capo-v0.7-design.md
for the full design.
MCP
Capo speaks the Model Context Protocol. Servers configured in ~/.capo/agent/mcp.toml are connected at startup; their tools become available as <server>__<tool> (rendered as <server>:<tool> in the UI):
[]
= "stdio"
= "github-mcp-server"
= ["--scope", "read-only"]
= { = "${GITHUB_TOKEN}" }
Using capo-agent as a library
use ;
async
See crates/capo-agent/examples/list_rust_files.rs for a runnable version.
Architecture
Three crates, all under crates/:
capo-tui— Elm-style MVU TUI runtime/rendering; consumescapo-agentUI event types.capo-agent— coding-agent SDK; built onmotosan-agent-loop.capo— the binary you install.
Detailed design lives in docs/superpowers/specs/2026-04-23-capo-design.md.
License
MIT — see LICENSE.