recall

Documentation

recall searches every past coding-agent session on your machine. Claude Code and Codex CLI, from any checkout of a repo, in about 30 milliseconds, with no index and nothing running in the background.

This page is the whole reference. It is also served as plain markdown if you would rather read it that way, or point an agent at it.

Install#

curl -fsSL https://raw.githubusercontent.com/mayberuk/recall/main/install.sh | sh

macOS, Linux and Windows. The script resolves the latest release, verifies its sha256 against the published checksums.txt, and puts the binary in ~/.local/bin. Set RECALL_INSTALL_DIR to put it somewhere else, or RECALL_VERSION to pin a release.

It registers recall with nothing. Reaching your agent is a separate, deliberate step, described under Model Context Protocol below.

From a checkout instead:

go install github.com/mayberuk/recall/cmd/recall@latest

The first search builds an archive under $XDG_DATA_HOME/recall, or ~/.local/share/recall. Set RECALL_HOME to move it. It is a data directory rather than a cache: it outlives the raw session store, which is the entire point, because agents delete old transcripts and the conclusions in them are what you came back for.

Which command answers which question#

You want to knowCommand
which session was thatrecall find <query>
what did we concluderecall turns <query>
what was said around itrecall show <session> [query]
when did this come uprecall when <query>
have I hit this before, anywhererecall find <query> --all
is the archive soundrecall doctor
am I on the latest releaserecall update --check

recall guide prints this same map at the terminal, plus how a query is read. It is one screen and costs no search, which is why it is the one thing worth running before your first query.

The commands#

recall find#

Which sessions talked about something, and how much. Ranked by concentration, meaning hits per conversation turn, so a session that was mostly about your topic beats one that mentioned it once in passing.

recall find idempotency
recall find "build number" --since 2w
recall find bitrise --results --author assistant
recall find wallet --brief --all
recall find wallet --ids | head -1 | xargs recall show

recall turns#

The passages themselves, ranked across every session at once rather than session by session. Use it when you want the answer, not the session that holds it. A turn’s own worth leads the ranking; the session’s concentration breaks ties.

recall turns "why did we pick bitrise"
recall turns agvtool --all --limit 3
recall turns codepush --author human --since 1m

recall show#

One session, with the turns around a match, so a conclusion arrives with the reasoning that led to it. Session ids match on any unique prefix.

recall show 5fd86b00
recall show 5fd86b00 "build number"
recall show 5fd86b00 --turn a1db2039
recall show 5fd86b00 bitrise --results --around 5

recall when#

Places a topic in time: first said, last said, and a per-month histogram of the months between. Chronological rather than ranked, for answering “when did we first hit this” rather than “who said it best”.

recall when flipper
recall when "retry budget" --all

recall doctor#

Archive integrity, coverage boundaries, and format drift. Reports what the archive holds, how current it is, and any record types this build has never seen. Run it when an answer looks wrong.

recall update#

Replaces this binary with the latest published release, verifying its sha256 against the release’s own checksums.txt first. --check reports what is available and installs nothing.

recall update
recall update --check

A binary built from a checkout reports dev rather than a version, and recall update declines to replace it: it was compiled on purpose, and overwriting it would throw away whatever was being tested.

recall guide#

The map above, plus query semantics, printed to the terminal. Written for an agent that will not open a documentation page but will run one command whose output then sits in its context for the rest of the session.

How a query is read#

Terms are ANDed. When no turn carries them all you get the turns carrying the most, and a line saying which terms were dropped. A query that misses does not come back silently empty.

Session ids match on any unique prefix, so recall show 5fd86b00 is enough.

What is searched, and what is not#

By default recall reads conversation only: what you and your agent said to each other. That is about 3% of what Claude Code writes to disk, and almost always the part you want. The rest is tool output stored twice and thinking-block signatures.

FlagAdds
--resultstool output
--toolstool invocation lines
--allevery repo on the machine, not just this one
--include-selfthe session asking the question
--include-recallrecall’s own recorded commands and output

Scope is the current repo, across all its checkouts. recall resolves a repo by its git remote rather than its path, so one query reaches every clone and worktree. This is the reason the tool exists: coding agents key transcripts by checkout path, so one logical repository sprawls across directories and a path-scoped search silently misses.

The coverage contract#

Every searching command ends in a ── footer naming what it left out: tier, scope, exclusions, how current the archive is, and what the answer cost to produce.

── 3 sessions · 3 searched · conversation only — tool output NOT searched (--results)
── live to 2026-05-12 · archived before that · refreshed just now
── scanned 3.0 KB · 14 turns · 7 ms
── 1.0 KB · ~264 tokens

If the footer does not mention a narrowing, that narrowing did not happen. That is a contract, not a courtesy. It is the reason you can trust a zero-result answer: a miss means the thing is not there, not that recall quietly declined to look.

The last line prices the answer in tokens, because checking an old decision should be cheaper than redoing it. --budget shapes the output to roughly a token count instead of refusing; --max-bytes refuses outright above a byte ceiling.

Filtering#

These apply to find, turns and when.

FlagEffect
--since, --until2w, 3d, 12h or a date
--authorhuman, assistant, agent or system
--mineonly turns you typed; the same as --author human
--agentonly turns from a subagent whose name contains this
--branchonly turns recorded on this git branch
--reposearch this repo identity instead of the current one
--sessionone session, by id or unique prefix
--sort recentoverride the verb’s own order

Shaping the output#

FlagEffect
--limitmost sessions, or passages for turns
--hitsmost matched turns per session
--briefone line per session, no snippets
--charsmost characters quoted per turn; 0 for the whole turn
--aroundturns of context each side of a match, for show
--fullthe whole session, for show
--budgetshape output to roughly this many tokens rather than refusing
--max-bytesrefuse to emit more than this many bytes; default 65536
--colorauto, always or never; auto colours a terminal and nothing else

Colour may add to an answer but never subtract from it. Stripping the escapes reproduces the plain bytes exactly, which is why every size recall reports stays honest with colour on. It is also structurally unable to reach --json, --format jsonl, --ids or the fzf record stream.

For calling agents#

Exit codes#

CodeMeaning
0hits
1nothing matched
2bad usage; the message names the valid flags
3archive problem
4output refused, because it breached --max-bytes

Exit 1 is a real answer, not an error. Branch on it rather than treating it as a failure.

Machine-readable output#

--json emits one object. --format jsonl emits one record per line, which is what you want when piping into something that reads a stream. --ids prints session ids only, one per line, for find, and session:uuid citations for turns.

recall find wallet --ids | head -1 | xargs recall show
recall turns "retry budget" --format jsonl

Every machine format carries the same coverage block the text footer states. It is a field, not a comment, so a caller can assert on it.

Choosing a provider#

--provider picks whose transcripts are read at all: auto, an agent name, or all. Every verb resolves through it. --agent is a different thing: it filters by subagent name within whatever the provider selected.

AgentSession storeStatus
Claude Code~/.claude/projectsread
Codex CLI~/.codex/sessions, or $CODEX_HOMEread
Gemini CLI, Cursornot readdetected, falls back to Claude Code and says so

Model Context Protocol#

Your agent can search its own history without you shelling out.

recall mcp install &#x3C;client>

Supported clients: claude-code, codex, gemini, copilot, cursor, opencode, windsurf.

recall mcp config <client> prints the same entry and writes nothing, if you would rather paste it yourself. --dry-run prints every path an install would create or modify and writes none of them. Any file recall merges into is copied to <path>.recall-backup first.

An install stops rather than overwrite a recall entry that already exists and differs from the one it would write, because that entry may be pointing at a build you chose. --force replaces it.

The five tools#

ToolAnswers
recall_guidehow a query is read, and which tool answers which question
recall_findwhich sessions talked about something, and how much
recall_turnsthe passages themselves, ranked across every session at once
recall_showwhat was concluded, with the turns around it
recall_whenfirst said, last said, and the months between

All five are read-only, and each runs the CLI verb it is named after, so a tool call and a command line can never disagree about what the corpus holds. Every tool result carries the same coverage block, so an agent can read what was skipped rather than assume nothing was.

Search defaults to the current repo. Pass all: true to reach every repo on the machine.

Staying current#

recall makes no network request of any kind except from two verbs you type for that purpose:

VerbWhat it does
recall updateresolves the latest release, verifies its sha256, replaces the binary
recall update --checkresolves the latest release and stops
recall doctorrefreshes the cached version number, silently, at most once a day

Nothing else opens a socket. A search reads a small file next to the archive and never asks anybody, which is why a search still costs what the benchmarks say it costs, and why there is still no daemon and no background process.

When that cached file records a newer release, commands print one line about it on stderr, only when stderr is a terminal, and at most once a day. It never touches stdout, so it cannot land in a piped answer, a --json document, or an agent’s context.

What a check sends is an ordinary HTTPS GET to api.github.com, which reveals your IP address and the request’s user agent, the same as visiting the releases page in a browser. It sends nothing about your machine, your repos, or anything recall has read. Set RECALL_NO_UPDATE_CHECK to any non-empty value and neither the check nor the notice happens at all.

Package managers work too: re-running install.sh replaces the binary the same way.

Interactive, with fzf#

source shell/recall.zsh
recall-fzf idempotency

Type and the list re-searches. ctrl-o opens the whole session in your pager; enter prints its id and exits, so it composes with everything above. fzf’s own matching and sorting are turned off, because recall did both already and letting fzf re-sort would discard concentration ranking.

Environment#

VariableEffect
RECALL_HOMEwhere the archive lives; defaults to $XDG_DATA_HOME/recall or ~/.local/share/recall
RECALL_INSTALL_DIRwhere install.sh puts the binary; defaults to ~/.local/bin
RECALL_VERSIONpin install.sh to a release instead of the latest
RECALL_AGENTdefault provider, overridden by --provider
NO_COLORset and non-empty disables colour, as does TERM=dumb
RECALL_NO_UPDATE_CHECKset and non-empty disables the version check and its notice

Questions#

What is recall?#

recall is a Go command line tool that searches every past coding-agent session transcript stored on your machine, from Claude Code and Codex CLI, and returns the sessions or the passages that talked about a topic. It is also a Model Context Protocol server, so a coding agent can search that history itself, mid-task, without you pasting anything.

How fast is recall?#

A typical search takes about 30 milliseconds against a store of 143 real conversations totalling 1.52 GB, measured start to exit. Including tool output takes about 93 ms, and a search that matches nothing takes about 113 ms, because every byte has to be read before it can be ruled out. The reproducible figures, against a corpus generated from a fixed seed, are on the benchmarks page.

Does recall need an index?#

No. There is no index to build, rebuild or keep current. recall reads the whole store on every query, which is why a conversation from ten minutes ago is findable immediately, why there is nothing to go stale, and why nothing runs in the background.

Does recall send my conversations anywhere?#

No. Every search runs on your machine against your own files. There is no account, no upload, no telemetry and no background process. The one network call in the whole binary is recall update, which asks the GitHub releases API which version is current, and only when you type it. Setting RECALL_NO_UPDATE_CHECK to any non-empty value turns that off too, after which recall opens no socket at all.

Which coding agents does recall work with?#

It registers itself as an MCP server with Claude Code, Codex CLI, Gemini CLI, GitHub Copilot CLI, Cursor, OpenCode and Windsurf, using recall mcp install <client>. The transcripts it reads are written by Claude Code and Codex CLI; other clients call it as a server rather than being read from.

What does recall search by default?#

Conversation turns only, meaning what you and your agent said to each other. Tool output is most of a session store and is searched only with --results; tool command lines only with --tools. Every answer ends with a footer stating exactly which of those narrowings were applied, so a narrowing you did not ask for cannot happen quietly.

Does recall work from any checkout of a repository?#

Yes, and it is the reason the tool exists. Coding agents file transcripts by checkout path, so one repository sprawls across clones and worktrees and a path-scoped search silently misses. recall resolves a repository by its git remote instead, so every checkout of it is one history, including branches you have since deleted.

What does recall cost?#

Nothing. It is free and open source under the MIT licence, with no paid tier and nothing to sign up for.

Reading further#