Skip to content

35 MCP Tools for Persistent AI Memory

toon-memory provides 35 MCP tools and 4 MCP resources for managing persistent memory:

Tool Description
memory_remember Save a decision, pattern, bug, knowledge, or warning (negative “do NOT do this” memory, recalled with a boost) (optional TTL, auto-tag inference, links, auto quality score, merge-dedup, confidence, optional importance: critical/high/medium/low)
memory_recall Search memory (use BEFORE reading files, filters expired TTL). mode: "graph" expands a relationship-aware subgraph for higher precision. Ranking uses RRF fusion (BM25×3 + graph centrality, adaptive k); pass rrf: false for the legacy linear score. sessionBias boosts entries from the current git branch. pathScope scopes results to a file path (supports globMatch). budget: "tiny" (top 3), "normal" (top 10), or "deep" (top 20). as_of re-includes entries superseded after a point-in-time date. explain: true appends a per-entry reason line (why it was retrieved). budget_tokens caps the output by estimated token count (0 = no limit). mode: "index" lists one line per entry (key, id, category, date, relevance %) with no content; ids bulk-fetches entries by id/key, order preserved
memory_forget Lifecycle ops by key or id: action: "soft" (default) marks obsolete, "hard" permanently removes, "restore" brings back to active, "supersede" retires it with a superseded_by link to new_key
memory_stats View memory state (including TTL stats, quality distribution, cold memories below quality/access thresholds, and hit-rate/duplicate/dead metrics: % recalled at least once, % exact-content duplicates, % obsolete entries)
memory_summary Save/retrieve file summaries
memory_archive Archive old entries (>30 days) and expired TTL entries
memory_diff Show changes since a date (24h, 7d, or exact date)
memory_suggest Find related entries for a given context
memory_captured List activity auto-captured by hooks (opt-in) or clear the log
memory_checkpoint Session checkpoint: creates a snapshot of current memory state with 7d TTL. Useful for rollback reference during long sessions
memory_consolidate Cleanup ops, deterministic (no LLM): mode: "identical" (default) de-duplicates entries with identical content, "similar" merges near-duplicates (Jaccard >50%), "low-quality" batch-compresses low-quality entries (minQuality, dryRun), "versions" detects entries describing the same subject at different library versions and retires the older ones in favor of the newest
memory_encrypt Enable AES-256-GCM encryption
memory_decrypt Disable encryption
memory_backup Create timestamped backup of memory file (auto-prunes to 10 most recent)
memory_secret Encrypted secrets vault (secrets.toon, AES-256-GCM): store/get/list/forget. Keeps data.toon readable while sensitive values stay encrypted at rest. Requires TOON_MEMORY_KEY
memory_export_global Write current project memory to the global file (~/.toon-memory/memory/global.toon). One-shot share of cross-project conventions
memory_import_global Merge cross-project conventions from the global file into this project (one-shot, deterministic, offline). merge: false replaces instead
memory_export_gist Export memory to a private GitHub Gist for cloud sync. Requires GITHUB_TOKEN env var
memory_import_gist Import memory from a GitHub Gist. Merges entries (keeps newer dates, combines tags)
memory_merge_sessions Merge observations from multiple sessions/branches into a consolidated view. Deduplicates and suggests entries to promote
memory_compress LLM-powered compression: select entries to compress into one concise entry (two-step: the tool provides context, you provide the summary)
memory_sessions Show active agent sessions, branches, and soft file conflicts for parallel-session coordination
context_brief One-call context briefing: memory + sessions + health in compact markdown. Use instead of 5-6 separate memory_* calls. Zero LLM
context_generate Full project briefing: combines project structure, git state, memory entries, and active sessions in one call. Replaces 5-6 manual tool calls
context_diff Incremental briefing: git commits + modified files + new/updated memory + active sessions since last session
context_focus Hyper-focused briefing: only relevant memory + related source files + callers + test files for a query
context_health Memory health audit: orphan links, duplicates, broken file refs, expired TTL, stale sessions, score 0–100
context_export Export memory as markdown: injectable context for system prompts (full or compact)
memory_smart_recall Unified search: BM25 + graph + quality + freshness + decay + session bias in one call
memory_visualize Open interactive graph viewer inline in MCP Apps–compatible hosts. Force-directed graph, stats, timeline, detail panel
memory_pin Pin an entry (with priority 1-5): pinned entries always appear at the top of recall results sorted by priority, even without a keyword match
memory_unpin Unpin an entry: remove the priority flag
memory_search Unified search with filters: same as memory_recall plus category, tags, from_date, to_date filters. Tag filter uses AND logic — all specified tags must match. sessionBias boosts entries from the current git branch
memory_tag Batch tag operations: add, remove, or set tags on one or more entries by key or id
memory_reflect Memory reflection: deterministically ranks entries by staleness, quality, and over-connection to surface what needs attention or cleanup. Zero LLM
memory_promote Auto-promote drafts: promote low-confidence entries to active status deterministically (default threshold 0.65, Jaccard dedup > 0.5, dryRun by default)

Since v3.7.0 every edge in the memory graph carries a type, written as type:key:

Edge type Meaning Example
relates Generic relatedness — explicit links you declare when saving relates:engine-arch
superseded_by Entry replaced by a newer one (written on the old entry) superseded_by:new-key
supersedes Entry that replaces an older one (mirrored on the new entry) supersedes:old-key

Explicit links become relates:key edges, memory_forget(key, action: "supersede") adds the superseded_by/supersedes pair, and recall’s graph expansion can traverse them — so you can tell how entries relate, not just that they do.

Memory is also exposed as MCP resources for direct context reading:

Resource URI Description
Memory Entries toon://memory/entries Full memory dump
Memory Stats toon://memory/stats Category counts and TTL info
Memory Summaries toon://memory/summaries Auto-generated system primer: knowledge map, recent memories, and key decisions
Memory Graph Viewer ui://viewer Interactive D3.js force-directed graph rendered inline in any MCP Apps–compatible host

Resources let agents read memory as context without tool invocations — useful for system prompts or session startup. The system primer provides instant context about your project’s knowledge state.

memory_remember({
category: "decision",
key: "use-zod",
content: "Use Zod for validation",
file: "src/types.ts",
tags: "validation;types"
})
// 🧠 Guardado: decision/use-zod (a1b2c3d4)
// 🎯 Quality: 0.80 | Confidence: 1.00
// 🔗 Entradas relacionadas:
// [pattern] zod-schemas — Shared Zod schemas for API validation

Entries are auto-scored for quality (0-1) based on tags, links, content detail, and specificity. You-asserted memories get confidence 1.0; inferred/gathered memories get 0.65-0.75.

memory_remember({
category: "knowledge",
key: "sprint-deadline",
content: "Sprint ends July 18, feature freeze is July 16",
ttl: "7d"
})
// 🧠 Guardado: knowledge/sprint-deadline (x1y2z3w4)
// 🎯 Quality: 0.55 | Confidence: 1.00
// ⏰ TTL: 2026-07-19

Use ttl for temporary context like deadlines or sprint info. Supports relative (7d, 30d) or exact dates (2026-12-31). Expired entries are auto-filtered from search.

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

When tags is empty, the system infers them from content using a vocabulary of 20+ categories: redis, auth, api, db, security, test, deploy, config, performance, refactor, error, logging, types, async, state, ui, storage, email, payment, webhook. On top of that, toon-memory init writes a project vocabulary derived from your dependencies (package.json, Cargo.toml, requirements.txt, pyproject.toml, go.mod), so an entry mentioning a dependency like redis also gets auto-tagged redis. More tags = higher quality score.

memory_recall({ query: "redis" })
// [bug] redis-pool-fix (i9j0k1l2)
// Added max_connections=20
// File: redis.ts | Tags: redis;fix | Date: 2026-07-10 | Quality: 0.82

Results are quality-weighted — entries with more detail, tags, and links surface first.

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. Use explain: true when you want to know why the agent was shown those entries. Entries saved with an explicit importance level also report it (e.g. · explicit critical).

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: Combine budget_tokens with budget: "deep" for a context window that stays inside a hard token ceiling regardless of memory size.

Browse the memory index (progressive disclosure)

Section titled “Browse the memory index (progressive disclosure)”
memory_recall({ mode: "index" }) // or { query, mode: "index" } for a filtered view
// 📇 Memory index (15 entries):
//
// [1] use-zod (a1b2c3d4) · decision · 2026-07-10 · 100%
// [2] redis-cache-config (e5f6g7h8) · decision · 2026-07-09 · 82%
// ...

mode: "index" shows one line per entry — key, id, category, date, relevance % — with no content, so a large memory costs almost nothing to browse. Pick the ids you need, then bulk-fetch the full entries:

memory_recall({ ids: "a1b2c3d4,e5f6g7h8" })
// Fetched 2 entries:
// [decision] use-zod (a1b2c3d4)
// Use Zod for validation
// File: src/types.ts | Tags: validation;types | Date: 2026-07-10

ids accepts entry ids or keys, comma/space/;-separated, and preserves your order (unknown entries are skipped). Three layers: browse the index → fetch by ids → search with mode: "flat" for the full ranked result.

Record options you decided against so the agent never re-proposes them. A lightweight convention — a decision entry tagged rejected, no extra schema:

memory_remember({
category: "decision",
key: "rejected-graphql",
content: "Rejected GraphQL: REST + generated types wins on codegen and schema drift risk.",
tags: "rejected;api;graphql"
})

Tag the entry with rejected and use a rejected-<topic> key so the keyword is easy to recall. Link it to the winning alternative if useful (links: "rest-api"). The next memory_recall for that idea surfaces the rejection with its reason — your “no” becomes part of the project memory instead of being re-debated every session.

memory_recall({
query: "redis",
from_date: "2026-07-01",
to_date: "2026-07-31"
})
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

Supports since as relative (24h, 7d) or exact date. Filter by type: all, created, or updated.

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
memory_archive()
// 📦 Archivadas 5 entradas antiguas
// 📋 Quedan 42 entradas activas
memory_encrypt()
// 🔐 Encriptación habilitada
// ⚠️ Guarda esta clave (no se puede recuperar):
// a1b2c3d4...
memory_sessions({ conflictsOnly: false })
// 🧭 Sesiones activas (2) — ventana 10 min:
//
// • opencode @ feature/foo
// id: sess-B
// Archivos:
// • src/shared.ts
// • claude @ feature/foo (tú)
// id: sess-A
//
// 🔥 Conflictos suaves (1):
// ⚠️ src/shared.ts ↔ opencode@feature/foo, claude@feature/foo

Use memory_sessions({ conflictsOnly: true }) if you only care about clashes. See Coordinación multi-sesión below.

When you run several AI agent sessions in parallel (e.g. three OpenCode sessions on the same repo at once), they can clobber each other’s work. memory_sessions is a file-based coordination tool — no server, no network, no LLM calls — that lets every session see what its siblings are doing.

  • On startup, a SessionStart hook writes a heartbeat file for the session at .toon-memory/memory/sessions/<id>.json. Each process writes only its own file, so there is no lock contention.
  • The heartbeat records the agent name, the git branch, the files touched, and a last-seen timestamp.
  • Reading across all those files gives every session a shared, eventually-consistent view of who else is active.
  • A session is “active” while its last heartbeat is within the TTL window (10 min). Dead sessions (process PID no longer alive and a stale heartbeat) are pruned lazily.
  • Soft conflicts are files touched by 2+ active sessions — surfaced by memory_sessions so you can avoid stepping on sibling work.
  1. At session start, the SessionStart hook prints other active sessions, their branches, and any soft conflicts.
  2. Before editing shared files, run memory_sessions() to confirm no sibling is touching them.
  3. When you finish, your heartbeat is marked ended and the files are released.

For larger memories, a flat keyword search can return too much or miss relationships. toon-memory can treat memory as a lightweight knowledge graph so recall returns the right entries with fewer tokens. Combined with quality scoring, the most useful entries surface first.

It is fully deterministic and offline — no embeddings, no vector DB, no LLM, no server. Edges come from:

  • Explicit links — keys you declare when saving an entry.
  • Implicit [[key]] refs — any [[some-key]] mention inside the content.
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)

memory_recall({ mode: "graph" }) finds keyword matches (seeds) and expands the ego-subgraph up to hops (1 or 2). Relevance propagates from seeds to neighbors, so a related spec or decision surfaces even without the query word. The result is capped (limit, default 6) for a smaller, more precise context.

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

Use mode: "graph" when a decision ripples across several entries (architecture, specs, related bugs). For isolated facts, the default flat mode is enough. The graph is built on read, so there is no extra index file to maintain.

When every token counts, pass compact: true to 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

What compact changes:

  • Each entry gets a stable numeric index ([1], [2], …) in score order.
  • id, date, and file are dropped — only tags is kept.
  • In graph mode, 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.
  • The stored .toon file is never mutated — compact only reshapes the response.

Recall is deterministic and offline (no embeddings, no LLM). Since v3.7.0 the default ranking is RRF (Reciprocal Rank Fusion):

  • BM25 relevance — probabilistic term-frequency score over id + category + key + content + file + tags, fused three times (the only real retriever on a small memory graph).
  • Graph centrality — degree-normalized (0..1), fused once: a hub connected to many entries ranks near the top even without the query word.
  • Adaptive kk = clamp(3..60, round(sqrt(n))), where n is the candidate count. The textbook k=60 flattens rank differences on small graphs, so it scales with sqrt(n).
  • Per-hop decay — nodes d hops from a seed are multiplied by 0.5^d, keeping distant context below nearby context.
  • Session bias — entries whose file appears in the current session get a 1.15× boost.
  • Language family — entries written in the same script as the query (latin/CJK/cyrillic/…) get a +0.1 boost via languageFamily().
  • Folder match — entries whose path_scope folder matches the current file get a +0.05 boost.
  • Explicit importancememory_remember({ importance }) lets you set critical (+0.3), high (+0.15), medium (0), or low (−0.1); critical decisions surface before low notes, and the level shows up in explain reasons and budget: "deep" output. Empty = auto (recency + frequency).
  • Priority — pinned entries sort first regardless of score.

Pass rrf: false to fall back to the legacy linear weighted score (BM25 + 0.4·centrality + 0.25·importance + seed bonus). In graph mode, recall seeds on keyword matches, expands the ego-subgraph up to hops, and returns the top limit (default 6) by combined score. memory_smart_recall combines all these signals in one call.

A unified search that combines BM25, graph, quality, freshness, and decay in one call:

memory_smart_recall({ intent: "redis cache configuration", hops: 2 })
// Combines BM25 relevance + graph centrality + quality score + freshness decay
// Returns top results ranked by combined score

This is the recommended way to recall memory — it handles everything in a single call instead of requiring you to orchestrate multiple tools.

Every entry is automatically scored for quality (0-1) based on:

  • Tag coverage (0.3 weight) — more tags = higher score
  • Link richness (0.2 weight) — more links = more connected
  • Content detail (0.2 weight) — longer, more detailed content scores higher
  • Recency (0.15 weight) — recent entries score slightly higher
  • Specificity (0.15 weight) — entries with file references and specific keys score higher

High-quality entries surface first in recall results, ensuring the most useful context is always prominent.

When you save an entry with an existing key, the system merges attributes:

  • Tags: union of both tag sets
  • Links: union of both link sets
  • Quality: max of both scores
  • Confidence: max of both scores
  • Content: kept as-is (no overwriting)
  • Date: updated to now
  • Importance: the higher explicit level wins (critical > high > medium > low)

This means re-saving an entry enriches it rather than replacing it.

On toon-memory init, the CLI scans your dependency manifests and writes a vocab table into .toon-memory/memory/config.json:

{
"vocab": {
"react": ["react"],
"zod": ["zod"],
"redis": ["redis"]
}
}

memory_remember matches new entries against this vocabulary on top of the built-in one. Re-run toon-memory init after adding major dependencies to refresh it. The vocab key is merged (never clobbered) with the encrypted/capture flags in config.json. More tags = higher quality score.

Entries are organized by category:

Category Use Case
decision Design decisions (“Why X over Y?”)
pattern Project patterns (“Uses Zod for validation”)
bug Bug fixes (“Redis pool exhaustion”)
knowledge General knowledge (“Broker uses RESP”)
warning “Do NOT do this” — anti-patterns, landmines, mistakes to avoid (recalled with a +0.2 boost)