Claude-Mem: Turn One-Off Chats into Perpetual Project Memory
“
Core question answered in one line: How can Claude remember what we did last time, even after a full restart?
Claude-Mem quietly captures every tool call, compresses it into searchable observations, and surfaces the right context when you ask—no manual notes, no copy-paste.
Quick Start: Three Commands to Persistent Memory
Core question: What is the absolute fastest way to get memory running?
Install the plugin, restart Claude Code, and speak naturally—memory appears in under two minutes.
After restart, ask “What did we do last session?” If you see an automatic mem-search call followed by a concise answer, the loop is live.
Author reflection
On my first run, the worker port collided with a local Grafana instance. The error is buried in ~/.claude-mem/logs/worker.log; a quick lsof -i :37777 and a port override in settings.json fixed it. The plugin could shout louder about port clashes, but once you know where to look, debugging is trivial.
How It Works: Five Hooks, Ten End-points, One Viewer
Core question: Which moving parts turn chat into recallable memory?
Five life-cycle hooks capture everything, a Bun-powered HTTP worker indexes it, and SQLite + Chroma let you query in plain English.
1. Hook time-line (what runs when)
PostToolUse actually splits into “success” and “failure” branches, so six scripts but five hooks.
2. Data flow (simplified)
graph TD
A[User prompt] -->|submitted| B(Observation created)
B --> C{SQLite store raw}
C --> D[Chroma vectorise]
D --> E[Wait for query]
E -->|natural language| F[mem-search endpoint]
F --> G[Return ranked snippets]
3. Search end-points at a glance
Progressive disclosure keeps token cost low: first payload ≈ 500 tokens; follow-up “tell me more” adds another 1 500 if needed.
Author reflection
The beauty is that you never type an SQL clause or vector-distance formula—you just ask. I often phrase queries as if talking to a teammate, and the hit-rate is uncanny. The secret sauce is hybrid scoring: BM25 for keywords + cosine for semantics, blended with a freshness boost.
Real-World Scenarios: Three Scripts You Can Reuse Today
Core question: Where does memory actually save time?
Below are copy-paste-ready mini-scripts for SDK continuity, recurring bug fixes, and onboarding new reviewers.
Scenario A: Keep SDK naming consistent across Mondays
Problem
Monday you decide all factory functions start with create. Wednesday Claude suggests newFoo. Divergence creeps in.
Steps
-
Monday closing prompt:
“Summarise today’s SDK naming rule in one sentence, do not store code.” -
Wednesday opening prompt:
“What naming rule did we set for the SDK?” -
Claude calls mem-search, returns Monday’s one-liner, continues withcreateprefix.
Outcome
Zero drift; no manual style guide needed.
Scenario B: Recurring port-conflict fix
Problem
npm run dev throws EADDRINUSE :::3000. You swear you solved this last week.
Steps
-
Ask: “How did we solve port 3000 being in use?” -
mem-searchsurfaces an observation taggedbug-fix, file fieldpackage.json. -
Viewer shows you changed the port to 3777 and added --if-present.
Outcome
Thirty-second copy-paste instead of another Stack Overflow detour.
Scenario C: New reviewer needs historical context
Problem
Reviewer sees debounce code in worker-service.ts and questions its necessity.
Steps
-
In PR comment: “@claude why is this debounce here?” -
Claude queries /search/files+/timelinearound the commit. -
Returns: “Added 2025-01-03 to prevent Redis reconnect burst—kept 500 ms.” -
Reviewer approves with confidence.
Outcome
Knowledge self-serve; no shoulder-tapping senior devs.
Installation Deep Dive: Dependencies, Ports, Upgrades
Core question: What can still go wrong after the three happy-path commands?
Version mismatches, port collisions, and privacy tags are the top three gotchas.
1. System requirements matrix
If Node < 18, the pre-hook script aborts with a clear message—no mystery failures.
2. Configuration sample (~/.claude-mem/settings.json)
{
"model": "claude-3-5-sonnet-20241022",
"workerPort": 37777,
"dataDir": "~/.claude-mem/data",
"logLevel": "info",
"contextInjection": {
"maxToken": 2048,
"strategy": "progressive"
},
"privacy": {
"excludeTags": ["private", "password"],
"maskPattern": "\\b\\d{4,}\\b"
}
}
Tweak workerPort if 37777 is taken; raise maxToken only if you routinely need deep context.
3. Upgrade / rollback flow
Author reflection
I once flipped to beta and hit a schema migration bug. The rollback button in the web UI instantly re-linked the stable plugin binaries—no data loss, but the incident reminded me to export a DB copy before channel hopping. A five-second cp data/claude-mem.db backups/ now lives in my pre-upgrade ritual.
Cost & Performance: Token Spend in the Real World
Core question: Does perpetual memory balloon your API invoice?
Progressive retrieval keeps the median injection under 600 tokens—roughly 15 % of a normal long-prompt turn.
4-week project stats (260 sessions)
Tips to stay lean:
- 🍂
Wrap verbose logs in <private>tags. - 🍂
Store one-line summaries instead of full code blocks. - 🍂
Always ask “is there…” first; expand only if relevant.
Privacy, Security & Compliance
Core question: How do I keep secrets out of the index?
Use inline <private> tags or list sensitive regex in maskPattern; either way, excluded text never hits disk.
Example prompt:
“Add the connection string mysql://user:pass@localhost:3306/db to .env”
The connection string remains in RAM for the current turn but is absent from both SQLite and Chroma.
For ultra-sensitive repos, point dataDir to an encrypted volume and wipe it after the session:
rm -rf ~/.claude-mem/data
Current Limits & Road-map
Core question: Where should I NOT rely on Claude-Mem yet?
Cross-project recollection, multimedia indexing, and multi-user shared memory are explicitly future work.
Action Checklist / Implementation Steps
-
Verify Node ≥ 18: node -v -
Install: - 🍂
/plugin marketplace add thedotmack/claude-mem - 🍂
/plugin install claude-mem
- 🍂
-
Restart Claude Code → open http://localhost:37777 -
Test memory: “What did we do last session?” -
(Optional) Adjust workerPortor privacy patterns insettings.json -
Before sensitive work, add <private>tags or extraexcludeTags -
Upgrade channel only after backing up data/claude-mem.db
One-page Overview
Claude-Mem inserts five life-cycle hooks into Claude Code, captures every tool call, compresses it into observations, and stores them in SQLite plus Chroma vector search. A local worker exposes ten HTTP end-points; you query in plain English and receive progressively disclosed context. Installation takes three commands, token overhead is ~15 %, and privacy tags keep secrets out of the index. Memory is project-scoped for now, with team sharing and multimedia on the road-map.
FAQ
-
Does it run on Windows?
Yes—provided Node ≥ 18 is first in PATH. -
Where is data stored?
~/.claude-mem/databy default; portable via a single SQLite file. -
How do I nuke all memory?
Delete the data directory while Claude Code is off. -
Can secrets leak?
Anything inside<private>tags or matchingmaskPatternis never persisted. -
What if port 37777 is taken?
ChangeworkerPortinsettings.jsonand restart. -
Is memory shared across projects?
Not yet—each folder gets its own DB. -
How big can the DB grow?
SQLite practical limit is TBs; typical projects see a few hundred MB per year. -
Can I downgrade after switching to beta?
Yes—use the web UI toggle; schema rollbacks are automatic.
Image source: Unsplash

