<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Cordy¬e=a%20terminal%20coding%20agent%20in%20Rust&theme=dark">
<img alt="Cordy — a terminal coding agent in Rust" src="https://gfx.redstone.md/strip?label=Cordy¬e=a%20terminal%20coding%20agent%20in%20Rust&theme=light" width="840">
</picture>
**English** · [Русский](README.ru.md)
Hot-swap any model or provider mid-conversation. Edit files behind a permission gate.
MCP, skills, sub-agents, and background jobs — in one fast, keyboard-driven TUI.
[](https://github.com/redstone-md/Cordy/actions/workflows/ci.yml)
[](https://github.com/redstone-md/Cordy/releases)
[](https://crates.io/crates/cordy)
[](LICENSE)
[](https://www.rust-lang.org)
</div>
Cordy is a cross-platform terminal agent that talks to every major API family — OpenAI Chat
Completions, OpenAI-compatible endpoints, Anthropic Messages, and the OpenAI Responses API —
through one canonical model, so switching provider or model never loses your conversation. It
edits files with an exact, diff-confirmed `edit`, runs a builtin toolset whose command output is
compressed by a native token optimizer, and speaks the Model Context Protocol.
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Highlights¬e=what%20sets%20it%20apart&theme=dark">
<img alt="Highlights" src="https://gfx.redstone.md/strip?label=Highlights¬e=what%20sets%20it%20apart&theme=light" width="840">
</picture>
- **Hot-swap models & providers** mid-conversation — start on a local model, finish on a frontier
one, context intact. `^P` → pick a model, or `/connect` to add a provider.
- **Every API family** — OpenAI Chat, OpenAI-compatible (Ollama / vLLM / OpenRouter / Groq / …),
Anthropic Messages, OpenAI Responses. Wire formats never leak past the adapter.
- **Builtin tools** — `read` `write` `edit` `apply_patch` `multiedit` `grep` `glob` `ls` `bash`
`todo` `web_search` `web_fetch` `process` `rewind`, all behind a permission gate you can
pre-approve with globs. `apply_patch` applies a multi-file, multi-hunk patch as one reviewed
unit, matching context tolerantly so near-miss whitespace and smart quotes still land.
- **Background jobs** — run a dev server with `bash background:true`, then `process` to poll,
wait on a regex, or kill the whole process tree.
- **MCP, skills, sub-agents** — connect MCP servers, load progressive-disclosure skills, and
delegate work to isolated sub-agents via the `task` tool.
- **Free web search** — DuckDuckGo out of the box (no key), or Exa when `EXA_API_KEY` is set.
- **Workspace tabs** — up to five per project, each with its own session, model, mode, cost
counters, undo checkpoints and history. Background tabs keep streaming; the strip badges what
changed, and
Cordy warns when two tabs write the same file.
- **Direct-key panels** — `^D` mode · `^L` model · `^G` git · `^S` skills · `^K` context ·
`^T` terminal · `^E` editor · `^B` tabs. One overlay, one look, keyboard all the way down.
- **Real terminals in the UI** — `^T` opens a PTY panel beside the chat (shell, test watcher,
or a full-screen editor via `^E`), resizable and focus-switchable without leaving Cordy.
- **Modes that actually bind** — `build` `plan` `architect` `socratic` `challenge` `review`.
Each injects its own contract into the system prompt, and the read-only ones are enforced by
permission rules, not just asked for politely.
- **Steer a running turn** — `^Alt+S` (or `/steer …`) drops a correction into the turn that is
already in flight, so you redirect the agent instead of aborting and starting over.
- **Live cost & context HUD** — a header bar with git state, context meter and model chip; a
context inspector that breaks the next request down by section; and a model-events log with
per-call latency, tokens and cost.
- **42 themes, hot-reloaded** — plus custom themes as JSON in `~/.cordy/themes/`, re-read the
moment you save them.
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Install¬e=prebuilt%20binaries%20or%20from%20source&theme=dark">
<img alt="Install" src="https://gfx.redstone.md/strip?label=Install¬e=prebuilt%20binaries%20or%20from%20source&theme=light" width="840">
</picture>
**Linux / macOS**
```sh
**Windows** (PowerShell)
```powershell
The scripts download the signed binary for your platform, verify its checksum, and drop `cordy`
on your `PATH`.
**With cargo** — `cargo install cordy`
**Prebuilt binaries** — or grab the archive for your platform from the
[latest release](https://github.com/redstone-md/Cordy/releases/latest), unpack, and run `cordy`.
**From source** (Rust 1.88+) — the default build is full-featured (MCP included):
```sh
git clone https://github.com/redstone-md/Cordy.git
cd Cordy
cargo build --release
# binary at target/release/cordy
```
Want a leaner binary without the MCP client? `cargo build --release --no-default-features`.
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Quick%20start¬e=connect%20a%20provider%20and%20go&theme=dark">
<img alt="Quick start" src="https://gfx.redstone.md/strip?label=Quick%20start¬e=connect%20a%20provider%20and%20go&theme=light" width="840">
</picture>
Point Cordy at any OpenAI-compatible endpoint via environment variables, then run it:
```sh
export OPENAI_API_KEY=sk-...
export CORDY_BASE_URL=https://api.openai.com/v1 # or any compatible endpoint
export CORDY_MODEL=gpt-4o-mini
cordy
```
…or skip the env vars and press **`^P` → /connect** inside the app to add a provider through the
wizard. Providers you connect are saved to `~/.cordy/config.toml`, and the last one is restored on
launch. All user state — config, keys, sessions, cache — lives under `~/.cordy`.
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Keybinds¬e=panels%20%C2%B7%20tabs%20%C2%B7%20terminals&theme=dark">
<img alt="Keybinds" src="https://gfx.redstone.md/strip?label=Keybinds¬e=panels%20%C2%B7%20tabs%20%C2%B7%20terminals&theme=light" width="840">
</picture>
**Panels**
| `^D` · `^L` | mode / persona · model picker |
| `^G` · `^S` | git menu (status, diff, log, commit, push, stash) · skills browser |
| `^K` · `^P` | context inspector · command palette |
| `^T` · `^E` | terminal panel · editor panel (`$EDITOR`) |
**Tabs**
| `^N` · `Alt+W` | new tab · close tab |
| `Alt+1`…`Alt+5` · `^B` | focus tab · tab list |
**Terminal panel** (while focused)
| `^Alt+T` · `^Alt+W` | back to the chat · close the panel |
| `^Alt+N` · `^Alt+↑`/`↓` | next panel · resize |
**Composer**
| `Enter` | send · `^J` / `Alt+Enter` newline |
| `Tab` / `Shift+Tab` | cycle agent/mode |
| `↑` / `↓` | move across lines · scroll the transcript · then prompt history |
| `^↑` / `^↓` | prompt history, always |
| `PgUp`/`PgDn` · `Home`/`End` | page the transcript · jump to top/bottom |
| `Esc` · `^Alt+S` | interrupt the turn · steer it instead |
| `^X` then … | leader: `l` sessions · `m` models · `t` theme · `s` status · `y` copy reply · `g` top · `z` redraw |
| `^R` · `^-`/`^.` | rename session · undo/redo input |
Slash commands include `/connect` `/providers` `/model` `/tabs` `/context` `/events` `/term`
`/git` `/steer` `/sessions` `/permissions` `/compact` `/goal` and more — type `/` to autocomplete.
> Two bindings differ from stock readline: `^E` opens the editor panel (line-end moved to `Alt+E`
> and `End`), and `^D` opens the mode picker (quit is `^C` on an empty line, `^X q`, or `/quit`).
>
**Clickable**
The bottom row is a menu bar, not a cheat sheet: every hint is a button, and so are the header's
model / branch / context / spend chips, the tab strip, and every picker row. Clicking a tool row
unfolds its full output. The mouse is captured for this, which costs plain drag-select —
`Shift`+drag still selects, and `^X M` (or the `⠿` indicator, `/mouse`, `mouse = false` in config)
hands the mouse back to the terminal entirely.
Pasting is your terminal's own paste; `Alt+V` pastes an *image* from the clipboard.
**Seeing the UI without running it**
```sh
cordy render list # scenario names
cordy render git 120x30 # draw one, in color
cordy render chat 110x30 --plain # …or as plain text, for diffing
```
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Goals¬e=long-running%20work%2C%20on%20a%20budget&theme=dark">
<img alt="Goals" src="https://gfx.redstone.md/strip?label=Goals¬e=long-running%20work%2C%20on%20a%20budget&theme=light" width="840">
</picture>
A goal is an objective the session keeps working on by itself. While it is active, each finished
turn feeds the next one, so a long task runs unattended until it is done, out of budget, or stuck.
```
/goal fix the flaky auth test --budget 200k --cost 2.50 --turns 20
/goal # status: objective, tokens, elapsed
/goal edit # load the objective back into the composer
/goal pause # stop the loop, keep the goal
/goal resume # back to work
/goal clear # drop it
```
Budgets are the safety rail: whichever of tokens, dollars or turns runs out first flips the goal to
*limited by budget*, and the model is told to wrap up rather than start new work. It stops on its
own too — the agent marks the goal complete only after auditing the objective against the current
worktree, or blocked after the same obstacle recurs three turns running. `Esc` or typing anything
interrupts the loop; a resumed session waits for you before spending again. Defaults live under
`[goal]` in the config, and the goal travels with the session (including forks).
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Configuration¬e=hot-reloaded%20%C2%B7%20secrets%20stay%20in%20env&theme=dark">
<img alt="Configuration" src="https://gfx.redstone.md/strip?label=Configuration¬e=hot-reloaded%20%C2%B7%20secrets%20stay%20in%20env&theme=light" width="840">
</picture>
`~/.cordy/config.toml` (merged with a project-level `.cordy/config.toml`). It is **hot-reloaded**
— edits apply within a second, no restart. Secrets never live here; API keys go in the OS env or
`~/.cordy/keys.json` (written by `/connect`).
```toml
optimize = true
theme = "tokyonight" # cordy (default) · 42 builtins, or your own JSON in ~/.cordy/themes/
# Fine-tune any role color on top of the theme
[colors]
accent = "#7aa2f7"
surface = "#24283b"
# Autonomous goals: whichever cap is hit first ends the run
[goal]
enabled = true
token_budget = 200000
cost_cap_usd = 5.0
max_turns = 20
# Pre-approve commands so the agent stops asking
[permissions]
mode = "ask" # or "auto"
allow = ["bash:ls *", "bash:git *", "bash:cargo *"]
deny = ["bash:rm -rf *"]
# A provider (secrets stay in env / keys.json, never here)
[[provider]]
name = "openai"
kind = "openai-chat"
base_url = "https://api.openai.com/v1"
# An MCP server (in the default build)
[[mcp]]
name = "browsermcp"
transport = "stdio"
command = "npx @browsermcp/mcp@latest"
enabled = true
```
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Project%20layout¬e=one%20crate%2C%20clean%20module%20boundaries&theme=dark">
<img alt="Project layout" src="https://gfx.redstone.md/strip?label=Project%20layout¬e=one%20crate%2C%20clean%20module%20boundaries&theme=light" width="840">
</picture>
```
src/
core/ canonical model (ContentBlock/Message/WireEvent), agent loop, prompt, context,
sessions, permissions, goals (autonomous loop), auth
provider/ Provider trait + one adapter per API family (+ retry decorator)
tools/ Tool trait, builtins, native output optimizer, sub-agents, background jobs
skills/ progressive-disclosure skill loader
agents/ sub-agent registry
mcp/ MCP client (on by default; opt out with --no-default-features)
config/ TOML load/merge, model & provider profiles
tui/ ratatui MVU app — model/update/view, chrome (header, tabs, status),
overlay pickers, PTY terminal panels, themes, markdown
```
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=Contributing¬e=fmt%20%C2%B7%20clippy%20%C2%B7%20test&theme=dark">
<img alt="Contributing" src="https://gfx.redstone.md/strip?label=Contributing¬e=fmt%20%C2%B7%20clippy%20%C2%B7%20test&theme=light" width="840">
</picture>
Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Before opening a PR:
```sh
cargo fmt
cargo clippy --all-targets
cargo test
```
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://gfx.redstone.md/strip?label=License¬e=MIT&theme=dark">
<img alt="License" src="https://gfx.redstone.md/strip?label=License¬e=MIT&theme=light" width="840">
</picture>
Released under the [MIT License](LICENSE).
<div align="center">
<sub>Part of <a href="https://github.com/redstone-md">redstone.md</a></sub>
</div>