A small, extensible coding agent for your terminal.

Small enough to read end to end. Stubborn enough to .

$ curl -fsSL https://tapir.dev/install.sh | sh

A Tapir session: edits the CLI, writes a test, runs it, switches model.

A core small enough to trust

The core stays deliberately small — read, bash, edit, write — and everything past it is something you bolt on: tools, providers, skills, plugins. Tapir bends to the habits you already have instead of teaching you new ones.

It ships as one self-contained binary on a Tokio async runtime — nothing to install but the file itself. It cold-starts in milliseconds, streams as it thinks, and leaves your terminal the way it found it.

Read the docs

Every model behind one flag

Anthropic, Google, OpenAI (Responses) and any OpenAI-compatible endpoint — OpenRouter, DeepSeek, local servers. Authenticate with API keys, or with OAuth for Claude Pro/Max (tapir --login anthropic) and skip the key entirely.

Pick per run, by fuzzy name, with a thinking level:

$ tapir --provider google --model gemini-2.5-flash -p "..." $ tapir --model claude-sonnet-4-6:medium -p "..."

Switch mid-session with /model, or list the whole catalog with tapir --list-models:

$ tapir --list-models anthropic claude-opus-4-8 claude-sonnet-4-6 claude-haiku-4-5 google gemini-2.5-pro gemini-2.5-flash openai gpt-5.4 gpt-4.1 openrouter deepseek/deepseek-chat # …and any OpenAI-compatible model
  • Anthropic
  • Google
  • OpenAI (Responses)
  • OpenRouter
  • DeepSeek
  • local servers
  • OAuth · Claude Pro/Max

Every session is a file you can rewind

Conversations persist as JSONL under ~/.tapir/sessions/ and reload with context intact. Resume the last one with --continue, branch with --fork, or pick any with --session <id>. --no-session when you want it ephemeral.

Long runs compact themselves: as the context nears the model window, older turns are summarized and dropped, so --continue keeps working. In the TUI, /tree walks the whole history, /share and /export get it out, /compact trims it by hand.

You own the context window

Tapir keeps a minimal system prompt and hands you the levers that decide what goes into the window.

AGENTS.md / CLAUDE.md: project instructions from the current directory and its ancestors, injected at startup (disable with --no-context-files).

Compaction: automatic, structured summaries of older turns. Tune the reserve and keep windows with TAPIR_COMPACT_RESERVE and TAPIR_COMPACT_KEEP.

Skills: drop a SKILL.md in ~/.tapir/skills/<name>/; Tapir surfaces it and loads it on demand when the task matches.

Prompt templates: Markdown files become /name commands with $1, $@ and $ARGUMENTS substitution.

New tricks without a recompile

Built-in tools — read, bash, edit, write, plus grep, find and ls. Search is native (no rg/fd download) and respects .gitignore.

Tool plugins: any executable in ~/.tapir/plugins/ adds a tool via a tiny protocol — describe prints a JSON schema, call reads args on stdin. Any language, no recompile.

MCP servers: configure mcpServers and Tapir spawns each over stdio (JSON-RPC), adapting its tools as mcp__<server>__<tool>.

Bundle your setup, ship it anywhere

Bundle skills, prompts, themes and plugins as a package and install it from a git URL, an owner/repo, or a local path:

$ tapir install owner/repo $ tapir install https://git.tapir.dev/tapir.git/

Everything is tracked in tapir.toml. List what's installed with tapir list, drop one with tapir remove <name>.

Four ways in

Interactive: the full TUI — streaming output, slash commands and themes, rendered inline in your terminal (no alternate screen).

Print: tapir -p "query" for one-shots and scripts.

JSON: --mode json streams structured events as JSONL.

RPC: a JSON protocol over stdin/stdout to embed Tapir in other tools.

Small core, sharp edges

Tapir stays small on purpose. Everything past the core is a tool, a skill, a plugin or a package you opt into — so it stays something you reach for, not a framework you live inside.

Safe by default: a native permission gate blocks catastrophic bash — rm -rf /, fork bombs, mkfs, dd to a device — and you extend it with denyBash in settings.

Yours to look at: ships with tapir, claude, dark and light themes — switch live with /theme.

Download & verify

Every release lives in its own directory, mirror-style. The latest is 0.1.0. Grab a prebuilt binary or build from source — then verify it with signify before you run it.

/0.1.0/

Fetch the public key once, then check the signed checksum list (and every file in the directory) against it:

$ signify -C -p tapir.pub -x SHA256.sig

To check a single artifact, name it explicitly:

$ signify -C -p tapir.pub -x SHA256.sig \ tapir-0.1.0-x86_64-linux-gnu.tar.gz

Send patches by email

Tapir takes contributions the old, durable way: git send-email. No account, no pull request — just a patch in your maintainer's inbox. Patches go to [email protected].

Get the source — no account needed. Clone over HTTPS, or anonymously over SSH (anoncvs-style: no key, no password — read-only):

$ git clone https://git.tapir.dev/tapir.git # …or anonymously over SSH (read-only, public repos): $ git clone ssh://[email protected]/tapir.git

Browse it in the web UI at git.tapir.dev.

Point send-email at the maintainer once for this repo, then send:

$ git config sendemail.to "[email protected]" $ git send-email HEAD^ # last commit $ git send-email origin/main.. # a series

Reply to feedback with a new revision via git send-email -v2. New to this flow? git-send-email.io walks through the one-time setup.