Claude Code starts every session with a fresh brain. You re-explain the architecture, the test command, the weird rule about not touching legacy_payments.py – then 40 minutes later you hit compaction and lose half of it. Recall just landed on Show HN as a fully-local project memory plugin for Claude Code, and the comment section is split in a useful way. Some people love it. One commenter said project-level memory barely helps them at all. Both can be true – which is exactly why you should understand what this thing does before installing it.
This is a hands-on guide: install, what it actually writes to disk, where it can bite you, and when not to bother.
The problem Recall is solving (and the one it isn’t)
Anthropic already shipped its own answer. Each Claude Code session begins with a fresh context window, and two mechanisms carry knowledge across sessions: CLAUDE.md files you write, and auto memory Claude writes for itself (as of mid-2025, this requires Claude Code v2.1.59 or later and is on by default, according to the Claude Code memory docs).
So why a third option? CLAUDE.md is hand-written rules – “how I want you to work” – but it’s manual upkeep and it doesn’t record what actually happened in a session. Recall fills the gap: an automatic, deterministic record of what each session did, condensed into a compact resume point.
Read that again: deterministic. No model writes your summary. That’s the whole pitch.
Install Recall in two commands
The repo is its own plugin marketplace, so installation is two slash commands inside Claude Code:
/plugin marketplace add raiyanyahya/recall
/plugin install recall@recall
Zero friction: no pip install, no local model to run, no key to configure, works offline. It starts working the moment the plugin loads. The full TF-IDF + TextRank implementation lives in summarizer.py. If numpy is importable, it’s used to vectorize the math (faster on big sessions); if not, an identical pure-Python TextRank runs instead – same output either way.
After install, .recall/ appears in your project root. Two files live inside: history.md is the append-only log capturing every session – your prompts, Claude’s replies, files touched, commands run. context.md is the condensed “where are we right now” – goal, summary, next steps, files touched, and where you left off – overwritten by the local summarizer each time you save.
What the summarizer actually does
This is the part most posts skip. The summarization is not an LLM call – it’s a classical information-retrieval algorithm, and that matters for predicting what your summary will look like.
No LLM call anywhere. The summary comes from TF-IDF + TextRank (extractive summarization) running locally on your machine. context.md wraps that output with deterministic facts pulled straight from the transcript and git: the goal (your first ask), files touched, commands run, where you left off, and git diff --stat.
“Extractive” is the key word. The algorithm picks sentences that already exist in your transcript – it doesn’t paraphrase. If your session was 80% Claude monologuing about React hooks, context.md will be flavored by that monologue. If you barked short commands and Claude executed them silently, your summary will be sparse. You shape the summary by shaping the conversation.
The lifecycle: when memory gets written and read
Three Claude Code lifecycle events. Understanding the order saves you from “why didn’t it remember” debugging later.
| Hook | What Recall does | Result |
|---|---|---|
| SessionStart | Surfaces context.md to Claude, asks if you want to resume and whether to keep logging | Claude opens already knowing where you stopped |
| Stop / SessionEnd | Appends new activity to history.md | Raw log grows; nothing summarized yet |
| /recall:save (manual) or auto_save_context | Runs the local summarizer over history.md and overwrites context.md | New resume point ready for next session |
Run /recall:save and the local summarizer reads history.md and overwrites context.md. Or set auto_save_context: "on_end" and context.md regenerates every time a session ends – no manual save needed. The hook system Recall plugs into is the same one documented in Anthropic’s hooks reference – nothing exotic, just a clean use of stdout-as-context.
A real-world session loop
Here’s what a normal day looks like once Recall is installed. Monday morning, fresh terminal:
- Start Claude Code in your project. The SessionStart hook injects
context.md. Claude says something like “Last session you were wiring the Stripe webhook to a queue. Open thread: the retry policy for failed deliveries. Resume?” - You confirm. No five-minute project re-explanation.
- You work for an hour. Claude edits three files, runs the test suite twice, hits one failing test, fixes it.
- You quit. SessionEnd appends the turn-by-turn log to
history.md. Ifauto_save_contextis on,context.mdis regenerated immediately. - Tuesday: open Claude Code. The injected context now reads “Stripe webhook + queue: shipping. Open thread: dead-letter handling for poison messages.”
That’s the loop. The win isn’t magic – it’s that you stopped typing “this project uses Hono on Cloudflare Workers, here’s the schema, here’s the test command” twelve times a week.
Three things the README mentions but most tutorials won’t
1. context.md is a prompt-injection surface if you commit it.context.md is injected into the model at session start. If you commit .recall/ as shared team memory, treat it like any other shared input: a teammate (or a bad actor with repo write access) could craft a context.md to attempt prompt injection. SessionStart fences the content and labels it untrusted data, and Claude asks before relying on it – but if you don’t fully trust who can write the repo, keep .recall/ git-ignored. The default .gitignore ships with .recall/ excluded for exactly this reason.
2. A bad session corrupts your next start.auto_save_context: "on_end" rewrites context.md every time, including the session where you went down a wrong rabbit hole and never recovered. The next session will resume from “we were debugging an approach that turned out to be wrong” unless you open context.md manually and delete the noise. A 30-second edit is cheaper than 20 minutes of Claude marching back down the dead end.
3. The skeptics on HN aren’t wrong about everything. One commenter on the Show HN thread described starting fresh anytime a task wouldn’t directly benefit from existing context, and finding little benefit in explaining the project overall to Claude – they deleted most of that explanation from CLAUDE.md because it didn’t seem to change Claude’s output much. If your work is short, isolated tasks (one bug, one PR, done), Recall is overkill. The tool pays off for long-running features, multi-day refactors, and anything where “where did we leave off” is a real question.
Pro tip: Treat
context.mdlike a commit message you’d write for your future self. After/recall:save, open it. Delete anything that isn’t actionable next session. Add one sentence at the top stating the immediate next step. Two minutes of curation beats five minutes of re-orientation tomorrow.
Recall vs the built-in auto memory
Both ship free. The distinction matters.
Claude’s built-in auto memory (as of Claude Code v2.1.59, mid-2025) loads the first 200 lines of MEMORY.md, or the first 25KB – whichever comes first – at the start of every conversation. It’s machine-local; all worktrees and subdirectories within the same git repository share one auto memory directory, and files don’t sync across machines.
The split: built-in auto memory captures inferred rules and preferences (“user prefers no stack traces in prod logs”). Recall captures session narrative (“yesterday we moved the auth middleware into a shared package and the JWT verify test is still red”). They don’t conflict – they write to different places. Run both if you want.
FAQ
Does Recall send anything to Anthropic or any external server?
No. The summarizer is a Python TextRank implementation that runs on your machine. No API key required.
Will Recall blow up my context window?
The injected context.md is engineered to land around 1-2K tokens – small compared to a full project re-explanation. The danger isn’t context.md itself; it’s history.md growing unbounded if you never run /recall:save and let raw logs pile up. Run save regularly or flip on auto_save_context so the heavy file stays out of the prompt path. The raw log lives on disk only – it’s not what Claude reads.
Can I use Recall and CLAUDE.md together?
Yes, and you should. CLAUDE.md is for rules that never change (coding style, forbidden patterns, the test command). Recall is for state that changes every session (what we just did, what’s next). Putting session state in CLAUDE.md turns it into a junk drawer; putting rules in Recall means they get rewritten by the summarizer and may drift. Keep them separate and each does its job.
Try it on one project this week
Pick a project where you’ve felt the cold-start pain – something you’ve been working on for more than a week. Install Recall, run one normal session, run /recall:save, open context.md, and read it like a stranger would. If it tells you something useful, keep the plugin. If it reads like noise, your sessions might be too short for it to help – and that’s a real answer, not a failure.