Toon Memory
Description
toon-memory es un servidor MCP de memoria persistente 100% local diseñado para asistentes de código con IA (Cursor, Claude Code, Windsurf, etc.). Utiliza el formato ultraeficiente TOON para reducir el consumo de tokens hasta en un 30%, permitiendo a los agentes guardar, buscar y…
About
toon-memory es un servidor MCP de memoria persistente 100% local diseñado para asistentes de código con IA (Cursor, Claude Code, Windsurf, etc.). Utiliza el formato ultraeficiente TOON para reducir el consumo de tokens hasta en un 30%, permitiendo a los agentes guardar, buscar y consolidar el contexto y las decisiones…
Details
- Author
- luiggival08
- Categories
- AI, Other
Jump to
Setup
Install Toon Memory in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/luiggival08/toon-memory
Follow the installation instructions in the repository README, then restart your MCP client.
English|Español|中文|日本語|한국어|Português (BR)|Deutsch|Français
The Continuity Layer for AI Agents — AI agents shouldn't have to relearn your project every session.
- Overview
- Blog Post
- Features
- Installation
- Supported Agents
- MCP Tools
- Coordinación multi-sesión
- Memory Graph (recall basado en grafo)
- Tips & Best Practices
- CLI Commands
- Configuration
- How It Works
- Why TOON?
- Troubleshooting
- FAQ
- Development
- Contributing
- Security & Privacy
- License
Ever had that feeling where your AI agent forgets everything from yesterday's session? You explain the same architecture decision for the third time, and it still suggests the approach you already rejected?
toon-memory fixes this.It's the Continuity Layer for AI Agents — a lightweight system that preserves your project's knowledge, decisions, and conventions across sessions, so every session starts where the last one ended. Fully local and private, over MCP — no cloud, no server.
ReadHow toon-memory Makes Your AI Agent Smarterto see a real-world demo of persistent memory in action.
- A complete memory toolkit— Full memory management via Model Context Protocol, includingmemory_smart_recall(unified recall with session bias),memory_sessionsfor multi-session coordination,context_tools for one-call context generation (briefing, diff, focus, health audit, export),memory_compress(LLM-powered compression),memory_consolidate(deterministic dedup/merge/cleanup),memory_primer(auto-injected context),memory_merge_sessions(cross-session merge),memory_pin/memory_unpin(pin important entries with priority 1-5),memory_checkpoint(session snapshot with 7d TTL),memory_search(unified search with tag filters + session bias),memory_tag(batch tag operations),memory_export_gist/memory_import_gist(GitHub Gist sync),memory_secret(encrypted secrets vault),memory_export_global/memory_import_global(cross-project conventions),memory_forget(soft/hard delete, restore, supersede),memory_reflect(staleness/quality reflection), andmemory_promote(auto-promote low-confidence drafts)
- MCP Resources— Read memory as context without tool invocations, including a System Primer (auto-generated knowledge map)
- 22 agents supported— OpenCode, VS Code, Claude Code, Cursor, Windsurf, Cline, Continue, Codex CLI, Gemini CLI, Zed, Antigravity, Aider, KiloCode, OpenClaw, Kiro, Qwen, Kimi, Goose, Junie, Amp, Grok, Trae
- Interactive installer— Select which agents to configure from a menu
- SessionStart hooks— Auto-reminders for Claude Code, Codex CLI, Gemini CLI, Antigravity
- TOON format— 22% fewer tokens than JSON (measured), better LLM comprehension
- Per-project memory— Each project gets its own memory file
- Zero config— Just install and use
- Auto gitignore— Automatically adds.toon-memory/memory/to.gitignore
- Date filtering— Search memory by date range
- Auto-archive— Old entries (>30 days), expired TTL entries, or 100+ entries moved to archive automatically
- Encryption— AES-256-GCM encryption for sensitive data
- Watch mode— Auto-backup every N minutes
- Memory TTL— Configurable per-entry expiration (7d, 30d, or exact dates)
- Tag inference— Auto-detect tags from content when tags are empty (built-in vocabulary + project dependencies)
- Memory diff— See what changed since your last session
- Related entries— Auto-suggest related memories when saving
- Memory graph— Connect entries withlinks/[[key]]refs;memory_recallcan expand a relationship-aware subgraph for more precise, lower-token recall (no embeddings, no LLM)
- Token-efficient recall—memory_recall({ compact: true })returns numeric-indexed entries, dropsid/date/file, renders graph edges as->2, and truncates graph neighbors to snippets
- BM25 + centrality ranking— Recall re-ranks by BM25 relevance and graph centrality (hubs surface even without the query word); per-hop decay keeps distant nodes low
- Auto-tag from dependencies—toon-memory initscanspackage.json/Cargo.toml/requirements.txt/go.modand writes a project vocabulary so entries mentioning a dependency get auto-tagged with it
- Smart Recall—memory_smart_recallcombines BM25 + graph + decay + quality in one call; the LLM calls this at the start of every task
- Quality scoring— Every entry gets a 0–1 quality score based on structure (tags, links, content specificity, recency, access count); high-quality entries surface first
- Merge-dedup— Saving with the samekeymerges attributes (union of tags, max confidence, latest date, combined links) instead of overwriting
- Near-duplicate detection— Consolidation detects near-duplicates via Jaccard similarity (threshold 0.7) and merges them
- Confidence score— Each entry tracks reliability: user-asserted = 1.0, inferred = 0.65–0.75
- LLM-powered compression—memory_compressuses AI to summarize long entries;memory_consolidate(mode: "low-quality")does batch cleanup deterministically
- Cross-session merge—memory_merge_sessionsmerges observations across parallel sessions for a file
- GitHub Gist sync—memory_export_gistandmemory_import_gistsync memory entries via GitHub Gist (zero dependencies)
- Verbatim mode—config.verbatimpreserves original entries instead of overwriting on save
- Context generation tools—context_generate(full briefing),context_diff(incremental),context_focus(targeted),context_health(audit),context_export(markdown) — each replaces 5-6 manual tool calls. Zero LLM, pure deterministic aggregation
- System Primer— Auto-injected at session start viasystemPrimer(), showing top 5 memories for instant context
- Path Scoping— Entries can be scoped to file paths via glob patterns (path_scope); recall filters by scope automatically
- Budget Control— Three output levels:budget: "tiny"(key+1 line, ~50 tokens),"normal"(compact with tags/edges),"deep"(all fields with origin/scope/status). Backward compatible withcompact: true
- Origin Tracking— Each entry tracks its origin (human,agent,inferred); human assertions get a quality boost
- Soft Delete—memory_forgetsoft-deletes by default (setsstatus=obsolete). Restore withmemory_forget(key, action: "restore"), hide withaction: "soft", permanent removal viaaction: "hard"
- Enhanced Health Audit—context_healthnow detects missing-evidence (path_scope without file) and stale-claims (overlapping content in same category)
- Typed graph edges— Edges carry types (superseded_by,supersedes,relates), written astype:keyin the graph. Explicitlinksbecomerelates:key, so you can tellhowentries are related, not just that they are
- RRF ranking— Recall fuses BM25 (×3) and graph-centrality ranks with Reciprocal Rank Fusion and an adaptivek = clamp(3..60, round(sqrt(n))). Benchmark (8 gold queries): nDCG 0.776, MRR 0.917 — exact parity with the previous linear scoring. Passrrf: falseto fall back
- Memory reflect—memory_reflectranks entries by staleness, quality, and over-connection to surface what needs attention or cleanup. Deterministic, zero LLM
- Memory supersede—memory_forget(key, action: "supersede", new_key)marks an entry as replaced by a newer one (superseded_bylink +supersededOndate).memory_recall({ as_of })re-includes old entries for point-in-time queries before their supersession
- Auto-promote—memory_promotepromotes low-confidence drafts to active entries deterministically (threshold 0.65, Jaccard dedup), withdryRunby default
- Explain WHY—memory_recall/memory_smart_recallacceptexplain: trueand append a deterministic reason line to every returned entry (↳ 100% relevance · used 14× · used today · importance HIGH) —whyit was retrieved, no LLM
- Token budgets—budget_tokenscaps the recall output by estimated token count; entries accumulate greedily and the tail that would exceed the budget is dropped (0= no limit)
- Version supersession—memory_consolidate(mode: "versions")detects entries describing the same subject at different library versions (e.g. "Use React 18" vs "Use React 19") and retires the older ones in favor of the newest
- Negative memories— awarningcategory for "do NOT do this" facts;warningentries get a recall boost so the agent sees the landmines before repeating them
- Language + folder ranking— recall boosts entries written in the same script family (latin/CJK/cyrillic/…) and entries whosepath_scopematches the current file
- Explicit importance—memory_remember({ importance })setscritical,high,medium, orlow. Critical decisions surface first (+0.3), low notes stay out of the way (−0.1); empty = auto (recency + frequency). Re-saving keeps the higher level
- Evidence layer— everymemory_remembersave is annotated with an evidence level:verifiedwhen its referenced file exists on disk,unverifiedwhen it doesn't,conflictwhen it overlaps a warning or critical/high decision. Conflicts get a +0.15 recall boost (verified +0.03, unverified −0.02) and a ⚠️ CONTRADICTION warning on save — but never block the write
- Secrets vault—memory_secretstores credentials in an encrypted sidecar (secrets.toon, AES-256-GCM) sodata.toonstays a readable open format while sensitive values never hit plaintext
- Global memory import/export—memory_export_globalwrites project memory to~/.toon-memory/memory/global.toon;memory_import_globalpulls cross-project conventions back with a one-shot, deterministic, offline merge (never a live dual source)
- ~1 MB install— three tiny prompt packages (@inquirer/checkbox/select/confirm); the MCP SDK, zod, and the TOON parser are bundled into the shipped binary — a singlenpm i -gdownloads ~1 MB (was ~14 MB) and lands ~4.4 MB on disk (was ~33 MB)
# macOS / Linux curl -fsSL https://raw.githubusercontent.com/LuiggiVal08/toon-memory/main/install.sh | sh # Windows (PowerShell) irm https://raw.githubusercontent.com/LuiggiVal08/toon-memory/main/install.ps1 | iex # Or with npm (any platform) npm i -g toon-memory
Tip:The npm install is the most reliable method. The curl/irm scripts are convenience wrappers.
Size:A barenpm i -g toon-memorydownloads ~1 MB and installs ~4.4 MB — three tiny prompt packages; everything else (MCP SDK, zod, TOON parser) ships bundled.
# Interactive installer — detects agents and configures MCP npx toon-memory
- Detect which AI agents you have installed
- Ask which ones to configure
- Add the MCP server config automatically
That's it! In your next agent session, try:
memory_stats # See what's in memory memory_recall # Search memory before reading files memory_remember # Save important decisions
Tip:Always runmemory_recallat the start of a session. Your agent will have context from previous sessions instantly.
{ "mcpServers": { "toon-memory": { "command": "npx", "args": ["-y", "toon-memory", "mcp"] } } }
{ "mcpServers": { "toon-memory": { "command": "npx", "args": ["-y", "toon-memory", "mcp"] } } }
Add to~/.codeium/windsurf/mcp_config.json:
{ "mcpServers": { "toon-memory": { "command": "npx", "args": ["-y", "toon-memory", "mcp"] } } }
Tip:You can configure toon-memory for multiple agents at the same time. Each agent gets the same shared memory file at.toon-memory/memory/.
Memory is also exposed as MCP resources for direct context reading:
memory_remember({ category: "decision", key: "use-zod", content: "Use Zod for validation — simpler than Joi, better TS support", file: "src/types.ts", tags: "validation;types" }) // 🧠 Guardado: decision/use-zod (a1b2c3d4) // Quality score: 0.65 (2 tags, detailed content) // 🔗 Entradas relacionadas: // [pattern] zod-schemas — Shared Zod schemas for API validation
Tip:Use descriptive keys likeuse-zodinstead of vague ones likevalidation. Your agent searches by key and content, so specificity helps. Saving with the same key auto-merges (union of tags, max confidence).
memory_remember({ category: "knowledge", key: "sprint-deadline", content: "Sprint ends July 18, feature freeze is July 16", ttl: "7d" }) // 🧠 Guardado: knowledge/sprint-deadline (x1y2z3w4) // ⏰ TTL: 2026-07-19 // Quality score is calculated automatically.
Tip:Use TTL for temporary context like deadlines, sprint info, or time-sensitive notes. Entries with expired TTL are automatically filtered from search results.
memory_remember({ category: "decision", key: "db-choice", content: "We chose Postgres over MySQL — JSONB for flexible schemas, better extension ecosystem", importance: "critical" }) // 🧠 Guardado: decision/db-choice (a1b2c3d4) // 🎯 Importance: critical (+0.3 boost) — surfaces above routine entries
Tip:Mark foundational decisionscriticalso they always rank near the top of recall.importanceacceptscritical,high,medium, orlow; leave it empty to let the system rank by recency and frequency automatically.
memory_remember({ category: "bug", key: "redis-connection-timeout", content: "Redis connection timeout in production, increased pool size" // tags left empty — auto-inferred from content }) // 🧠 Guardado: bug/redis-connection-timeout (a1b2c3d4) // 🏷️ Tags inferidos: redis // Quality score is calculated automatically based on inferred tags and content.
Tip:Leavetagsempty and the system will infer them from your content using a built-in vocabulary of 20+ categories (redis, auth, api, db, security, etc.)plusa project vocabulary derived from your dependencies atinittime. So if your project depends onredis, any entry mentioning "redis" gets auto-taggedredis.
memory_recall({ query: "redis" }) // [bug] redis-pool-fix (i9j0k1l2) // Added max_connections=20 // File: redis.ts | Tags: redis;fix | Date: 2026-07-10
Tip:Search before you read files. This saves tokens and gives your agent context it wouldn't get from code alone. Quality-weighted ranking ensures the most useful entries surface first. Or usememory_smart_recallfor a more comprehensive result.
memory_recall({ query: "redis", from_date: "2026-07-01", to_date: "2026-07-31" })
Tip:Use date filters when you remember roughlywhensomething happened but not exactlywhat. Quality-weighted ranking still applies.
memory_archive() // 📦 Archivadas 5 entradas antiguas // 📋 Quedan 42 entradas activas
Tip:Run this periodically to keep memory lean. Archived entries are still searchable viamemory_recallwith date filters. Entries with expired TTL are also archived automatically. Low-quality entries get lower recall priority. Low-quality entries get lower recall priority.
memory_diff({ since: "24h" }) // 📋 Cambios desde 2026-07-11: // // ➕ Nuevas (2): // [decision] use-zod (a1b2c3d4) // Use Zod for validation // [bug] redis-timeout (e5f6g7h8) // Redis connection timeout fix
Tip:Usememory_diffat the start of a session to see what your agent learned since you last worked on the project. New entries include quality scores. New entries include quality scores.
memory_suggest({ context: "redis cache configuration" }) // 🔍 Sugerencias para "redis cache configuration": // // [decision] redis-cache-config (a1b2c3d4) // Redis cache layer for session storage // File: src/cache.ts | Tags: redis;cache | Date: 2026-07-10 // // [bug] redis-pool-fix (i9j0k1l2) // Added max_connections=20 // File: redis.ts | Tags: redis;fix | Date: 2026-07-10
Tip:Usememory_suggestwhen you need context about a topic but aren't sure what to search for. Or usememory_smart_recallfor a more comprehensive result.
memory_smart_recall({ intent: "diseño de base de datos para backend" }) // [1] decision/use-postgres // Choose Postgres for ACID compliance and JSON support // tags: db;decision · edges: ->2 // // [2] pattern/db-migrations // Use sequential migration files, never edit committed ones // tags: db;pattern · edges: ->1 // // [3] bug/redis-timeout // Redis connection timeout — increased pool to 20 // tags: redis;bug
Tip:Usememory_smart_recallat the START of every task. It combines BM25 + graph + decay + quality in one call — no need to guess what to search for.
memory_recall({ query: "redis", explain: true }) // [decision] redis-cache-config (a1b2c3d4) // Redis cache layer for session storage // File: src/cache.ts | Tags: redis;cache | Date: 2026-07-10 // ↳ 92% relevance · used 14× · used today · importance HIGH
The↳reason line is deterministic (relevance %, access count, last-used, importance) — no LLM involved. Useexplain: truewhen you want to knowwhythe agent was shown those entries.
memory_recall({ query: "redis", budget_tokens: 300 }) // Entries accumulate greedily; the tail that would exceed the estimate is dropped. // budget_tokens: 0 (default) = no limit.
Tip:Combinebudget_tokenswithbudget: "deep"for a context window that stays inside a hard token ceiling regardless of memory size.
context_generate({}) // # Project Briefing (full) // // ## Project // - Name: my-app // - Root: /path/to/project // - Package Manager: npm // - TypeScript: ✓ (v5.3) // // ## Git Status // - Branch: main // - 3 uncommitted, 0 untracked // // ## Memory (42 entries, 12 patterns, 8 bugs) // [1] decision/use-postgres // Choose Postgres for ACID compliance // tags: db;decision // // ## Sessions // - egraterol (main, 2m ago): 42 files touched
Tip:Usecontext_generateat the start of a session to get full context in one call. Replaces 5-6 separate tool calls.
context_health({}) // # Memory Health (score: 87/100) // // ## Summary // - 42 entries (12 patterns, 8 bugs, 15 decisions, 7 knowledge) // - 65.3% average quality // // ## Issues (3) // - Orphan link: pattern/db-migrations → pattern/db-seed (key not found) // - Duplicate: [bug] redis-pool-fix has identical content // - Expired TTL: [knowledge] sprint-deadline (expired 2026-07-20) // // ## Stale Files (1) // - src/legacy.ts (deleted, 2 refs)
Tip:Runcontext_healthwhen memory feels cluttered. Shows orphan links, duplicates, expired TTL entries, broken file references, missing-evidence entries (path_scope without file), and stale claims (overlapping content).
When you save with the samekey, attributes are merged instead of overwritten:
// First save memory_remember({ category: "decision", key: "use-zod", content: "Use Zod for validation", tags: "types" }) // 🧠 Guardado: decision/use-zod (a1b2c3d4) // Later save with same key — merges automatically memory_remember({ category: "decision", key: "use-zod", content: "Use Zod for validation — also handles API response parsing", tags: "types;api" }) // 🧠 Actualizado: decision/use-zod (a1b2c3d4) // 🔗 Merge: tags combinados, fecha y links actualizados // Tags now: "types;api" (union of both)
Tip:Use descriptive, stable keys. The same key = merge, different key = new entry.
Every entry gets an automatic quality score (0–1) based on structure:
High-quality entries surface first in recall. Check quality withmemory_stats:
memory_stats() // ... // Calidad promedio: 0.58 (12 con score)
Each entry tracks how reliable the information is:
Confidence is preserved on merge (max of both entries).
The System Primer is an auto-generated knowledge map exposed as an MCP resource. Agents load it at session start for instant context:
// Exposed as toon://memory/summaries // Auto-regenerates on every read // Contains: top entries, categories, patterns
Tip:Addtoon://memory/summariesto your agent's system prompt for instant context at session start.
// First, set TOON_MEMORY_KEY in your environment (or .env file): // export TOON_MEMORY_KEY="your-secret-key-here" memory_encrypt() // 🔐 Encriptación habilitada
Warning:The encryption key must be set viaTOON_MEMORY_KEYenv var before encrypting. Save it somewhere safe — if you lose it, your memory data is gone forever. Quality scores and confidence are preserved through encryption.
When you runseveral AI agent sessions in parallel(e.g. three OpenCode sessions on the same repo at once), they can accidentally clobber each other's work. toon-memory ships withmemory_sessions, a file-based coordination tool that lets every session see what its siblings are doing — withno server, no network, and no LLM calls.
- On startup, aSessionStarthook writes aheartbeat filefor the session at.toon-memory/memory/sessions/<id>.json. Each process writesonly its ownfile, so there's no lock contention.
- The heartbeat records the agent name, thegit branch, thefiles touched, and alast-seentimestamp.
- Reading across all those files gives every session a shared, eventually-consistent view of who else is active.
- Dead sessions (process PID no longer aliveanda stale heartbeat past the TTL window) are pruned lazily.
memory_sessions({ conflictsOnly: false }) // 🧭 Sesiones activas (2) — ventana 30 min: // // • opencode @ feature/auth (tú) // id: a1b2c3d4 // hace 2 min // Archivos: // • src/auth.ts // // • claude @ feature/db // id: e5f6g7h8 // hace 9 min // • src/db.ts // // 🔥 Conflictos suaves (1): // ⚠️ src/types.ts ↔ opencode @ feature/auth, claude @ feature/db
- PassconflictsOnly: trueto skip the session list and show only soft conflicts:
memory_sessions({ conflictsOnly: true }) // 🔥 Conflictos suaves (1): // // ⚠️ src/types.ts // ↔ opencode @ feature/auth (a1b2c3d4), claude @ feature/db (e5f6g7h8)
- At the start of every session, theSessionStarthook already prints the other active sessions and any soft conflicts.
- Runmemory_smart_recall({ intent: "what I'm working on" })to get full context (memory + graph + quality).
- Runmemory_sessions()to see the full picture (branches, files, last-seen) andmemory_sessions({ conflictsOnly: true })if you only care about clashes.
- If you share a file with another session, sync up before editing so you don't overwrite each other's changes.
Tip:This is purely local and lock-free — safe to run as often as you like. Combine it withmemory_smart_recall({ intent: "project context" })at session start for both cross-sessionmemoryand cross-sessionpresence. The system primer (MCP resource) also provides instant context.
When your memory grows, a flat keyword search can return either too much (every match) or the wrong context (no relationships). toon-memory can treat memory as alightweight knowledge graphso recall returns theright*entries with fewer tokens. Combined with quality scoring, the most useful entries surface first.
It's fullydeterministic and offline— no embeddings, no vector DB, no LLM, no server. Edges come from two sources:
- Explicitlinks— keys you declare when saving an entry.
- Implicit[[key]]refs— any[[some-key]]mention inside the content.
- memory_rememberstoreslinkson the entry (space- or;-separated keys). Quality score is calculated automatically.
- memory_recall({ mode: "graph" })finds keyword matches (seeds), then expands theego-subgraphup tohops(1 or 2) along the edges.
- Relevance propagates from the seeds to their neighbors, so a related decision or spec surfaces even if it doesn't contain the query word. Quality-weighted ranking ensures the most useful entries appear first.
- The result set is capped (limit, default 6) →smaller, more precise contextfor the agent. Or usememory_smart_recallfor a unified call.
memory_remember({ category: "decision", key: "risk-engine-priority", content: "The engine prioritizes risk over speed (see [[risk-spec]]).", file: "spec.md:10", tags: "risk;spec", links: "engine-arch" // explicit edge to another entry }) // 🧠 Guardado: decision/risk-engine-priority (a1b2c3d4) // Quality score is calculated automatically based on tags, links, and content detail.
memory_recall({ query: "riesgo", mode: "graph", hops: 2 }) // [decision] risk-engine-priority (a1b2c3d4) // The engine prioritizes risk over speed (see [[risk-spec]]). // File: spec.md:10 | Tags: risk;spec | Date: 2026-07-01 // links: engine-arch // // [knowledge] risk-spec (a2b3c4d5) // Risk specification for the engine. // links: risk-engine-priority;engine-arch // // [pattern] engine-arch (e6f7g8h9) // Engine architecture. // links: risk-spec
Tip:Usemode: "graph"when a decision ripples across several entries (architecture, specs, related bugs). For isolated facts, the defaultflatmode is enough. Or usememory_smart_recallwhich combines graph + BM25 + quality automatically.
When every token counts, passcompact: trueto get a denser output:
memory_recall({ query: "riesgo", mode: "graph", hops: 2, compact: true }) // [1] decision/risk-engine-priority // The engine prioritizes risk over speed (see [[risk-spec]]). // tags: risk;spec · edges: ->2, ->3 // // [2] knowledge/risk-spec // Risk specification for the engine. // tags: risk · edges: ->1 // // [3] pattern/engine-arch // Engine architecture. // tags: engine · edges: ->1
- Each entry gets a stable numeric index ([1],[2], …) in score order.
- id,date, andfileare dropped — onlytagsis kept.
- Ingraphmode, edges render as->2(numeric, not key names).
- Neighbors reached via the graph (non-seeds) are truncated to a short snippet with an ellipsis, while directly-matched seeds keep their full content.
- Quality-weighted ranking ensures the most useful entries appear first.
- The stored.toonfile isnevermutated —compactonly reshapes the response.
Tip:Combinecompact: truewithmode: "graph"for the smallest possible context window when recalling from a large, interconnected memory. For proactive/background recall, usebudget: "tiny"which returns just the key + one line (~50 tokens). Or just usememory_smart_recallwhich does this automatically.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.




