Persistent memory for Claude Code — so every session picks up where the last one left off
Install • What You Get • Commands • Configuration • How It Works • Sync Server
Every Claude Code session starts from zero. Claude doesn't know what you were working on yesterday, which architectural decisions you've already made, or that you tried and rejected approach X last week.
You end up repeating context, re-explaining decisions, and watching Claude suggest things you've already ruled out.
Claude Mneme fixes this. It silently captures your sessions and injects the right context when you start a new one — project state, key decisions, recent work, and anything you've explicitly told it to remember. ~2,000 tokens of signal, zero effort from you.
claude plugin marketplace add edimuj/claude-mneme
claude plugin install claude-mneme@claude-mnemeRestart Claude Code. That's it — Mneme starts working automatically.
When you start a new session, Mneme injects a structured memory summary. Here's what that looks like in practice:
<claude-mneme project="my-saas-app">
## Last Session
**Working on:** Fix the Stripe webhook race condition
**Done:** Added idempotency key check before processing payment events
**Open:** Write integration test for duplicate webhook scenario
## Project Context
SaaS billing app with Stripe integration, PostgreSQL, Express backend.
Multi-tenant with per-org billing.
## Key Decisions
- Stripe webhooks over polling — real-time, less API usage
- PostgreSQL advisory locks for payment processing — prevents double-charges
- JWT auth with Redis session store — fast validation, easy revocation
## Current State
- Webhook handler: Implemented with idempotency checks
- Billing dashboard: In progress — invoice list done, usage charts pending
- Multi-currency support: Planned
## Recent Work
- [Feb 8] Fixed webhook signature verification for test environment
- [Feb 7] Added org-level billing isolation
## Recently Active
- `webhook-handler.ts` [worked on] (3x this week)
- `billing-service.ts` [worked on, discussed] (5x this week)
- `handlePaymentIntent` [worked on] (2x this week)
</claude-mneme>
Claude reads this context and immediately knows: what the project is, what decisions have been made (and why), what you were doing last session, and which files are hot right now. No "let me explore the codebase first" — it just picks up where you left off.
| Approach | Limitation |
|---|---|
| MEMORY.md (built-in) | Manual. You write and maintain it yourself. No automatic capture |
| Heavy RAG/vector solutions | Complex setup, high token cost, often retrieves noise over signal |
| Claude Mneme | Automatic capture, structured summarization, ~2K tokens at startup. Configurable if you want more |
Mneme sits in the middle: enough memory to be genuinely useful, lightweight enough that you forget it's there.
/remember This project uses pnpm, not npm
/remember The auth system uses JWT tokens stored in Redis
/remember Tried Redis caching but serialization overhead made it slower
Remembered items are never auto-summarized — they persist until you remove them.
/forget my preference about tabs # AI finds matching entries
/forget # Lists all entries to choose from
/entity auth.ts # What does Mneme know about this file?
/entity handleLogin # Find references to a function
/summarize # Compress the log now
/summarize --dry-run # Preview what would be summarized
Summarization normally runs automatically when the log reaches 50 entries.
/status # Diagnose issues
/status --clear-errors # Clear the error log
Edit ~/.claude-mneme/config.json:
{
"maxLogEntriesBeforeSummarize": 50,
"keepRecentEntries": 10,
"model": "haiku"
}See CONFIG_REFERENCE.md for all options.
Core Settings
| Option | Default | Description |
|---|---|---|
maxLogEntriesBeforeSummarize |
50 |
Trigger summarization at this log size |
keepRecentEntries |
10 |
Recent entries to keep after summarization |
model |
haiku |
Model for summarization (haiku, sonnet, opus) |
responseSummarization |
"none" |
Response capture: "none", "extractive", or "llm" |
maxResponseLength |
1000 |
Max characters for captured responses |
Context Injection
Control what gets injected at session start:
{
"contextInjection": {
"sections": {
"projectContext": { "enabled": true },
"keyDecisions": { "enabled": true, "maxItems": 10 },
"currentState": { "enabled": true, "maxItems": 10 },
"recentWork": { "enabled": true, "maxItems": 5, "maxAgeDays": 7 },
"recentEntries": { "enabled": true, "maxItems": 4 }
}
}
}| Section | Priority | Default |
|---|---|---|
projectContext |
High | Always shown |
keyDecisions |
High | Last 10 |
currentState |
High | Last 10 |
recentWork |
Medium | Last 5 (within 7 days) |
recentEntries |
Low | Last 4 |
Deduplication
{
"deduplication": {
"enabled": true,
"timeWindowMinutes": 5
}
}When you work on something, multiple entries are created (prompt, task, commit). Deduplication groups entries within the time window and keeps only the highest-signal one.
Entity Extraction
{
"entityExtraction": {
"enabled": true,
"maxAgeDays": 30,
"categories": {
"files": true,
"functions": true,
"errors": true,
"packages": true
}
}
}Entities older than maxAgeDays are automatically pruned. Set to 0 to disable pruning.
Mneme hooks into Claude Code's lifecycle events:
SessionStart → Injects memory context into the conversation
UserPromptSubmit → Captures your prompts (filtered for noise)
PostToolUse → Captures task progress and git commits
SubagentStop → Captures agent completion summaries
PreCompact → Extracts context before conversation compaction
Stop → Captures response, writes session handoff
| Type | Source | Description |
|---|---|---|
prompt |
UserPromptSubmit | Your requests and questions |
task |
TaskCreate/Update | Work focus and progress |
commit |
Bash (git) | Git commit messages |
agent |
SubagentStop | Agent completion summaries |
response |
Stop | Assistant's response |
Before injection, entries go through:
- Deduplication — Groups related entries (prompt → task → commit), keeps highest-signal
- Relevance scoring — Ranks by recency, file relevance, and entry type
- Outcome tracking — Completed tasks rank higher than abandoned ones
- Entity extraction — Indexes files, functions, errors for
/entitylookups
Automatically filtered out:
- Short prompts (<20 chars), confirmations ("yes", "ok", "continue")
- Slash commands and duplicate task updates
When the log reaches 50 entries, Mneme uses Claude Haiku to compress older entries into a structured summary — preserving key decisions, project context, and current state while discarding low-signal noise. The 10 most recent entries are kept as-is.
~/.claude-mneme/
├── config.json # Global settings
└── projects/
└── <project>/
├── log.jsonl # Activity log (auto-summarized)
├── summary.json # Structured summary
├── remembered.json # Persistent /remember entries
├── entities.json # Entity index
├── handoff.json # Session handoff
└── .last-session # Timestamp for git tracking
Optionally sync memory across machines with a self-hosted server.
# Start the server
node server/mneme-server.mjs
# Enable in config
{
"sync": {
"enabled": true,
"serverUrl": "http://192.168.1.100:3847"
}
}Lock-based concurrency ensures one machine at a time per project. If the server is unreachable, Mneme continues with local memory.
Sync Details
Machine A Server Machine B
│ │ │
├── Session Start ──────────────►│ │
│ (acquire lock, pull) │ │
│ │ │
│ ... working ... │ (locked by A) │
│ │ │
│ │◄────────── Session Start ──────┤
│ │ (lock failed, local-only) │
│ │ │
├── Session End ────────────────►│ │
│ (push, release lock) │ │
│ │ │
│ │◄────────── Session Start ──────┤
│ │ (acquire lock, pull changes) │
Configuration:
{
"sync": {
"enabled": false,
"serverUrl": null,
"apiKey": null,
"projectId": null,
"timeoutMs": 10000,
"retries": 3
}
}Server config (~/.mneme-server/config.json):
{
"port": 3847,
"dataDir": "~/.mneme-server",
"apiKeys": ["your-secret-key"],
"lockTTLMinutes": 30
}For non-localhost deployments, enable API keys and consider a reverse proxy for HTTPS. See server/README.md for full server docs.
| Project | Description |
|---|---|
| tokenlean | CLI toolkit for examining codebases while minimizing token usage |
| claude-simple-status | Minimal statusline showing model, context, and quota |
| vexscan | Security scanner for AI agent plugins and configurations |
| claude-workshop | Collection of useful plugins and tools for Claude Code |
