Skip to main content
Glama

a-memory

Your AI agents forget. a-memory makes them remember. 4-tier agent memory with hybrid search and a real knowledge graph — all in plain SQLite files. Zero cloud. Zero external APIs.

CI codecov License: MIT Python 3.11+ Ruff MCP Compatible Docs Release

Also available on PyPI: pip install a-memory — optional extras: a-memory[embeddings] for real multilingual embeddings.


Why SQLite?

Every other memory server sends your agent's data through a cloud API or requires a separate vector database.

a-memory stores everything in SQLite files on your machine.

  • Zero infrastructure. No Docker, no database server, no embedding API keys.

  • Zero data leaving your network. Works air-gapped.

  • Layer-isolated by design. User facts and agent identity never share a namespace.

  • One directory = entire memory. Back up with cp, sync with rsync.


Related MCP server: ContextStream MCP Server

Why this exists

Three problems a-memory solves:

① Agent self-evolution — your AI stops repeating mistakes between sessions. It remembers decisions, errors, and corrections in a dedicated agent layer, and an hourly consolidation sweep promotes what matters into long-term facts.

② User persona persistence — your agent knows who it's talking to even after weeks of silence. Preferences, history, emotional context live in the user layer, isolated from agent identity.

③ Project continuity — project tracks per-project context: decisions with rationale and outcomes, artifact maps, a graphify-powered code index — so a fresh session picks up where the last one left off.


Get started

pip install a-memory
a-memory          # MCP server on stdio — connect from any MCP client

The server runs without these, but the privacy gate (hooks ingest) and the graph miners need two spaCy NER models. Neither is on PyPI — en-core-web-sm 404s there and ru-core-news-sm is an unrelated placeholder — so they can only be installed by wheel URL, and a wheel URL cannot be a dependency: PyPI rejects any distribution whose metadata carries a direct URL. One command installs them from the URLs the package already knows:

a-memory-ner                 # install (console script, ships in the wheel)
a-memory-ner --check         # report what is missing, install nothing

From a source checkout, python scripts/install_ner_models.py is the same command.

Skipping them is safe: the gate falls back and reports degraded instead of failing.

Point your MCP client at it:

{
  "mcpServers": {
    "a-memory": {
      "command": "a-memory"
    }
  }
}

HTTP transport with dashboard:

a-memory --transport http --port 8000 --dashboard

Or run from source:

git clone https://github.com/Cipher208/a-memory.git
cd a-memory
uv sync
uv run ariel-memory

The seven primitives

Agents see exactly seven tools — one verb per intent, plus the event bridge (6 verbs + memory_hook), no tool-choice paralysis:

Primitive

Intent

What it does

think

remember

Routes content to the right layer (L4 facts / L3 episodes / wiki / graph) based on importance, emotion, and relations

dream

recall

Hybrid search across ALL layers (FTS5 + binary embeddings + wiki + graph), returns a token-budgeted digest

forget

let go

Context-aware deletion with Shadow Bin archival (exact / fuzzy / recent) — plus a dry run that writes nothing and an undo that puts back what the bin kept

evolve

grow

Records personality/rules evolution for the agent

project

continue

Per-project identity, decision log, artifact map, code index

wake_up

resume

One-call memory lift for a fresh session — the critical set in one call, instead of walking a recall protocol step by step

memory_hook

signal

The event bridge: fires one lifecycle event (session_started, new_message, …) so an external harness can push memory into ariel on its own schedule

Quick demo — Python MCP client:

# think — routed to the right store automatically
await session.call_tool("think", {"text": "User prefers dark mode", "layer": "user"})

# dream — finds it across every store, a week later
res = await session.call_tool("dream", {"query": "dark mode preference"})
print(res["summary"])

66 fine-grained operations exist in total, grouped into coherent opt-in tiers: the 7 primitives are exposed by default; add context (recall protocol, /new session recap, smart context budget, steering hints, tool-output compression), insight (Memory Query DSL, provenance fact-blame, quality loop, reflections, stats), write (typed memory schemas, declarative rules engine, scratchpad, counterfactuals, episodes), plus wiki and review (staged mutations, memory_report_card, daily_brief). The usual live-agent surface is one preset — ARIEL_EXPOSE=agent (59 tools), equivalent to primitives,context,insight,write,wiki,review. The remaining 7 are admin-tier: ARIEL_EXPOSE=operator (66) or all.

Tier history, because older guides still name a brief tier: it was dissolved on 2026-09-07 — daily_brief now rides review. If a doc tells you to pass brief, it is pre-1.10 and the token is simply ignored.

⚠️ Env sanitization gotcha (stdio): MCP clients pass a sanitized environment to stdio servers — setting ARIEL_EXPOSE in your shell profile does nothing. Define the tier set in your MCP client config (the env block of the server entry — see configuration guide). The server logs its resolved surface at startup (tool exposure: N/M tools) — if your agent reports seeing only the primitives, check that line first, then restart the client session (tool lists are cached per session).


Features

Category

What's inside

🧠 Memory

L1 Reflex (atomic persistence) → L2 Sessions → L3 Episodic → L4 Core, importance scoring, typed memory kinds with TTL policies, layer isolation; bi-temporal fact history (is_current view hides superseded rows globally, changed_since delta-polling, drill-down to raw source surviving cold archival), hash-chained L0 journal with hot/warm/cold tiers; 66 tools (tiered exposure; 59 on the agent preset, 7 primitives by default) including /recall protocol (multi-axis + disclosure triggers), session continuity recap (/new recovery pack), one-call wake_up, open-question registry surfaced in the session brief, steering hints, tool-output compression + recall verification, provenance fact-blame, Memory Query DSL (faceted tags), typed memory schemas, a declarative rules engine, smart context budget (weighted token floors), reflections, counterfactuals, was_useful quality loop, operator diagnose/heal + integrity score

🔍 Search

FTS5 + MIB binary embeddings + hybrid RRF ranking, multi-source merge (RAG + Wiki + Episodic + Core + Graph), EDM/ITS dual-route rerank (information-gain scoring, №11-eval winner), semantic dedup gate (cosine, opt-in), RU-lemma key normalization (pymorphy3), counter-signal pessimisation, ACT-R activation with per-query min-max multipliers and memory-kind weights, embedding-path circuit breaker (graceful hash-fallback), deterministic retrieval mode, dream digest

🕸️ Graph

Epistemic knowledge graph + temporal timeline, typed nodes and edges, BFS traversal, 1-hop GraphRAG expansion (provenance-aware edge filter), 12 self-maintaining miners (degree-capped anti-hub, wiki↔fact provenance bridges with metadata backlinks, co-retrieval, zero-result gaps), orphan-anchor GC, nightly gap-registry — and a reader for it: the registry now records how often each hole is re-observed (seen_count) and surfaces the most persistent ones in the session brief, so an agent sees her own unanswered questions instead of a table nobody reads. Opt-in HDBSCAN embedding clusters with louvain agreement

📁 Projects

Decision log (what/why/outcome), artifact map, graphify code index — survives between sessions

⚡ Auto-Hooks

Push-model memory: a per-agent daemon tails the conversation and ariel saves what matters on its own — importance thresholds (EMA-adaptive), staged mutations (proposal → review → apply → revert), DREAM: markers, session-start inject, gap reports, compaction-aware rehydrate (drift log + salvage + one-shot rehydrate blocks), ru-NER privacy gate (cyrillic PERSON/ORG/LOC masking). Native integrations: Hermes runs ariel as an in-process MemoryProvider plugin, MiMoCode via a fork-hooks plugin, CowAgent via code-level hooks. Wiring guide →

🎯 Skills

Skill = Memory: agent-read Markdown pages (first-class skill wiki type), progressive disclosure (wiki_list → wiki_search → wiki_read with related-facts hydration), 4KB lint cap, promotion from DREAM: skill: episodes, shared SSOT sync across agents, usage-driven reinforcement — skills guide →

🔐 Security

NaCl SecretBox (XSalsa20-Poly1305) envelope encryption for auth/saga secrets, master key chain, rate limiting

🛠️ Ops

Auto-backup cron, saga rollback pattern, Prometheus metrics, read-only replica, hourly self-maintenance (decay + consolidation + auto-VACUUM)

🌐 Wiki

FTS5-indexed markdown files — edit in Obsidian/VS Code, search from MCP, 6 analytical perspectives (wiki_summarize), schema lint on save, external-dir sync


Architecture

graph TD
    A[LLM Agent] -->|MCP Protocol| B[mcp_server]
    B --> C{Importance Scoring}
    C --> D[L1: ReflexBuffer]
    D --> E[L2: SessionStore]
    E --> F{EmotionTrigger?}
    F -->|high emotion| G[L3: EpisodicMemory]
    F -->|normal| H[L4: CoreMemory]

    B --> I[RAG Engine]
    I --> J[FTS5 Search]
    I --> K[MIB Binary Search]
    I --> L[Hybrid RRF Ranking]

    B --> M[Wiki System]
    M --> N[.md Files]
    M --> O[SQLite Index]

    B --> P[Knowledge Graphs]
    P --> Q[Epistemic Graph]
    P --> R[Temporal Graph]

    B --> S[Project Store]
    S --> T[Decisions / Artifacts / Code Index]

    U[Hourly Sweep] -->|consolidate| G
    U -->|promote| H
    U -->|auto-VACUUM| V[(SQLite)]

Comparison

a-memory

mem0

letta (memgpt)

chroma

MCP native

✅ 7 primitives

❌ no MCP server

❌

❌

Layer isolation

✅ User vs Agent namespaces

❌

❌

❌

Local-only (no cloud)

✅ SQLite — 0 infra

⚠️ API or self-host Docker

❌ needs LLM API

✅ local OSS + Cloud option

Own semantic search (no API)

✅ FTS5 + MIB binary hybrid

⚠️ BM25+entity (LLM-dependent)

❌ LLM-only

⚠️ hybrid on Cloud only

Knowledge graph

✅ Typed nodes + edges + temporal timeline

⚠️ entities only

❌

❌

Envelope encryption (secrets)

✅ NaCl SecretBox (auth/saga secrets; memory data is plaintext SQLite)

❌

❌

❌

Lifecycle hooks

✅ 19 names (12 user + 13 agent slots), per-layer, config-gated

limited

limited

none

Self-maintenance

✅ Hourly consolidation + auto-VACUUM

❌

❌

❌

Backup / restore

✅ Auto-cron + saga rollback

❌

❌

❌

Notes (Sep 2026): mem0 now ships a self-hosted Docker image and a managed cloud with hybrid BM25+entity search; chroma is 29k★ and added hybrid+FTS5 to its Cloud tier (OSS server remains vector-only). What still differentiates a-memory: zero-infra SQLite (no Docker), NaCl-encrypted auth/saga secrets, layer isolation, hourly self-maintenance, and the temporal graph timeline.


Roadmap

  • 4-layer memory hierarchy with layer isolation

  • Hybrid search (FTS5 + MIB binary embeddings)

  • Knowledge graphs (epistemic + temporal)

  • Hourly consolidation sweep + DB self-maintenance

  • mcp 2.x native SDK

  • Repo renamed to Cipher208/a-memory; PyPI package live (pip install a-memory)

  • Temporal timeline wired end to end (think/evolve/project events + dream recent digest)

  • Dream-cycle inject + auto-generated CONTEXT.md snapshot (curated context + 6 wiki perspectives + recent episodes, per-layer, per-agent)

  • Phase C — auto-hooks keystone (push-model memory: per-agent conversation daemons, external event dispatcher, importance-gated auto-save, staged mutations with review/revert, dream markers, session-start inject, gap reports; guide)

  • Phase D — compaction-aware rehydrate (drift log + salvage into the summarizer + one-shot rehydrate blocks; MiMoCode plugin / Hermes native MemoryProvider / CowAgent hooks — integration guide)

  • Phase D — /recall protocol (multi-axis proportional recall: markers → session → semantic → expand → day; drives Hermes per-turn prefetch)

  • Phase D — Skill = Memory (Markdown skills as a first-class wiki type, progressive disclosure wiki_list → wiki_search → wiki_read, 4KB lint cap, promotion pipeline, shared SSOT sync, usage-driven evolution — skills guide)

  • Phase D — working memory + meta-memories (agent scratchpad re-injected at session start, deterministic reflections, smart context budget with weighted floors, counterfactual notes, was_useful quality feedback loop)

  • Phase D — memory tools D1.2-D1.9 (session continuity recap + steering hints, tool-output compression + recall verification, provenance fact-blame, Memory Query DSL, typed memory schemas, declarative rules engine; coherent ARIEL_EXPOSE tiers: context / insight / write)

  • Phase E — hardening & closure (18 items across 3 waves): durability — atomic L1 persistence (temp→fsync→os.replace) + per-instance ring files, a circuit breaker guarding the embedding model path (3 failures → open 30s → hash-fallback keeps recall serving), least-privilege wiki roots + traversal-safe backup restore; operations — memory_diagnose/memory_heal (DB/migrations/L1-files/breaker checks + remigrate/reset-breakers/purge), integrity score in the report card, <cache:break> markers + stable-first inject ordering for provider prompt caches; retrieval — faceted tag queries (dimension:value, same-dim OR / cross-dim AND), memory-kind weights in ACT-R scoring, disclosure triggers («when X, surface Y» recall-side rules); wiring — real context_threshold/memory_pressure emitters (Hermes plugin + autohooks daemon), on_turn_end event, wiki_write staged mutations with revert, transition-level consolidation revert, causal-link producer on memory_graph_add; validation — DREAM markers anchored to message start (document-fragment false positives eliminated), post-compaction semantic audit (episode coverage by the L4 set)

  • Phase F — L0→L4 pipeline (bi-temporal fact intervals, hot/warm/cold L0 tiers with CLACK export, SHA-256 capture dedup, hash-chained journal, provenance drill-down)

  • Phase G — self-wiring graph (12 deterministic miners: sessions, markers, provenance, co-retrieval, entities, zero-result questions, wiki↔fact bridges)

  • Phase H closeout — EDM/ITS dual-route rerank + eval harness (NDCG@5, drift score, negative-control protocol, LongMemEval-S adapter)

  • S17 Stage-1 tail — deterministic retrieval mode, ENGRAM procedural kind, AdaptiveRAG pre-gate (27 LLM-free query features), EMA importance gate, counter-signal aliases, SHA-256 L0 dedup, zero-result miner, ru-NER privacy gate

  • S18-19 wave (15 items) — global is_current view + changed_since delta mode, per-query ACT-R min-max, per-block max_chars, semantic dedup gate, channel-granular sources, 3-option conflict contract (supersede/retain/annotate), orphan-anchor GC, nightly gap-registry, per-agent harness breaker, provenance edge filter, wiki↔fact metadata backlinks, wiki_read related-facts hydration, RU lemma keys (pymorphy3), 2-class textcat pilot (flag-gated), S17 supplements 8-11 (cold-archive drill-down, confirming layer, junk-vector detector, HDBSCAN clusters), B6 anti-hub degree cap

  • S20 eval — №11 ablation on MINI + LongMemEval-S (50-question stride): full dual-route arm wins on both datasets, published-baseline comparison (GPT-4o long-context league, above ChatGPT-memory); dense e5-small run 3: no parity gain over hash on this split — hash stays prod

  • Hardening wave (1.12.0) — the speaker-layer defect fixed at the writer (distill_and_route read a kind where it needed the speaker) plus a provenance-based purge of the 65 rows it had already mislabelled; a kind classifier that no longer hands a permanent label to harness boilerplate or to compound words (pre-commit, mergeCommit); the gap registry getting the reader S18 planned but never built; the L4 expectation measured against the L4 bar instead of the L3 one (71% of the diff_gap backlog was that one wrong number); and a quality gate that could not fail now failing correctly — an unpinned scanner had silently moved its JSON schema out from under it

  • Screenshot / asciinema demo in README

  • LLM-assisted consolidation on top of the deterministic sweep

  • Stage 2 — tool-surface redesign (slot system, URI keys, inject/key consolidation — planned with the A-remainder)

  • LongMemEval full 500-question split + dense-aware threshold retraining (e5-small parity shown, not a win on the 50-question stride)

Contributing

PRs welcome! See CONTRIBUTING.md.

License

MIT © Cipher208


⭐ If this project helps you, star it on GitHub.

Star History

Available Tools

7 tools
dreamC
Read-onlyIdempotent

Universal Primitive: Hybrid search across ALL layers (L3, L4, Wiki, Graph) with context construction.

ParametersJSON Schema
NameRequiredDescriptionDefault
layerNouser
limitNo
queryYes
intentNobalanced
user_idNodefault

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds 'context construction', hinting at a return behavior beyond raw search, but does not detail what context is built, pagination, or rate limits. With annotations covering safety, this is adequate but shallow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single sentence, so it is concise. However, the front-loaded 'Universal Primitive:' label is jargon that doesn't help an agent, and the rest is dense with undefined layer names. Structure is compact but not optimally front-loaded with useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained. But with 5 parameters at 0% schema description coverage, and a description that doesn't clarify any parameter or the layer mapping, an agent lacks enough information to invoke the tool correctly. The definition is materially incomplete for its complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for 5 parameters, so the description carries the full burden. It does not mention any parameter—not query, limit, intent, user_id, nor the layer enum (user/agent). 'Across ALL layers (L3, L4, Wiki, Graph)' even conflicts with the schema's layer values, leaving parameters completely undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a verb and resource: 'Hybrid search' and 'context construction'. However, 'Universal Primitive' and layer names like 'L3, L4' are internal jargon that an agent may not understand, and it does not differentiate clearly from siblings like memory_hook or think. The core purpose is identifiable but vague.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given on when to use this tool versus alternatives such as think, memory_hook, or wake_up. The description provides no context, conditions, or exclusions, leaving the agent to infer usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

evolveC
Destructive

Universal Primitive: update agent personality and triggering evolution.

ParametersJSON Schema
NameRequiredDescriptionDefault
user_idNodefault
instructionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the mutation profile is covered structurally. The description adds 'update personality' but does not disclose what state is overwritten, whether changes are reversible, or what 'evolution' concretely does, so its added behavioral value is thin.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single short sentence with no wasted words, which is good, but the front-loaded phrase 'Universal Primitive' spends the prime real estate on jargon rather than the actionable verb.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be explained, but for a non-idempotent, destructive mutation tool with two undocumented parameters, the description is far too thin to describe effects, scope, or preconditions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across two parameters, and the description offers no explanation of 'instruction' or 'user_id'. The agent gets no semantics for the required instruction field or the user scoping, so the description fails to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a rough verb+resource: 'update agent personality' gives a hint of what happens. But the framing 'Universal Primitive' is unexplained jargon and 'triggering evolution' is vague and undefined, so an agent cannot confidently tell this apart from siblings like dream, wake_up, or forget.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use, when-not-to-use, or alternative guidance at all. Given six semantically overlapping siblings (dream, think, forget, wake_up, memory_hook, project), the absence of routing guidance is a clear gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

forgetA
Destructive

Universal Primitive: context-aware forgetting with Shadow Bin support.

Scope: exact one L4 key; fuzzy a pattern across L4, L3 and the graph; recent everything newer than minutes; episode_ids exactly those episodes.episode_id values; undo puts the archived_ids back where they came from. Every scope reports what it touched, in entries / episodes / graph_nodes / not_found.

dry_run=True matches and writes nothing — the same computation as the real pass, so the preview cannot drift from it. Refused for recent, which has no shadow bin.

undo refuses a purged row, a row whose archived kind is unknown, another owner's id, and a row whose key is already back in the table — each with its reason rather than a bare zero; dry_run=True shows what would return and refuses the same rows. An id that two archived rows share is refused too, unless memory_type names the one you want. The archive is not a backup: restored_items names the fields a restored row could not bring back.

ParametersJSON Schema
NameRequiredDescriptionDefault
keyNo
layerNouser
scopeNoexact
dry_runNo
minutesNo
user_idNodefault
shadow_binNo
episode_idsNo
memory_typeNo
archived_idsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint=true annotation, the description discloses substantial behavior: dry_run performs the identical computation so the preview cannot drift, refusals are returned with reasons rather than bare zeros (purged rows, unknown kinds, foreign owner ids, already-restored keys, ambiguous shared ids), and the archive is explicitly not a backup. This is rich, non-obvious operational context an agent could not infer from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The scope list is front-loaded and the paragraphs are organized by concern (scopes, dry_run, undo refusals, archive caveat), with backticked identifiers aiding scanability. It is dense and slightly jargon-heavy ('Universal Primitive', 'L4 key', 'archived kind'), but each sentence carries substantive information rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter destructive mutation with no required args and no parameter descriptions, the description covers the risky paths thoroughly: scope selection, refusal semantics, dry-run preview, and the restore side effects recorded in restored_items. An output schema exists so return-value explanation is not needed. The remaining gap is the unexplained layer/user_id inputs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description must carry the load and does so for most parameters: scope (all five modes), dry_run, minutes, episode_ids, archived_ids, memory_type, and key are all given meaning. It leaves 'layer' (user/agent) and 'user_id' unexplained and does not directly define the shadow_bin boolean, so compensation is strong but not complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb+resource ('context-aware forgetting with Shadow Bin support') and enumerates the five distinct scopes (exact, fuzzy, recent, episode_ids, undo), so an agent understands what the tool does. It stops short of naming or contrasting any sibling tool, leaving the boundary with evolve/dream/wake_up implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Each scope is paired with its operating condition ('exact' one L4 key; 'fuzzy' a pattern; 'recent' everything newer than minutes; 'undo' restores archived_ids), which is effectively when-to-use guidance for selecting a mode, and it warns that 'recent' is refused for dry_run. It gives no explicit when-not or sibling alternative, so it is clear context rather than full routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

memory_hookA
Destructive

Fire one external lifecycle event (session_started, new_message, ...).

Args: event: one of KNOWN_EVENTS (session_started, session_ended, new_message, auto_save_candidate, context_threshold, memory_pressure, post_context_compression). payload: event body. Recognized keys per event: session_ended: {"summary": str}; new_message/auto_save_candidate: {"text": str}; post_context_compression: {"query": str}; session_started: {"text": str?, "budget": int?}. layer: "user" (default) or "agent". user_id: subject user (bound to API key on HTTP transports). ctx: MCP context (injected).

Returns: Handler results dict; unknown event raises ValueError (MCP error).

ParametersJSON Schema
NameRequiredDescriptionDefault
eventYes
layerNouser
payloadNo
user_idNodefault

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=false and destructiveHint=true, so the write/destructive profile is covered. The description adds genuinely new behavioral context: unknown events raise ValueError as an MCP error, user_id is bound to the API key on HTTP transports, and the handler result dict is returned. It stops short of describing side effects of firing an event (what state changes), so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose in the first line, then a structured Args/Returns block. The per-event payload mapping is dense but each line earns its place. Slightly long, but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A mutating, non-idempotent dispatch tool with 0% schema coverage but a rich description covering events, payload shapes, layer, user binding, and error behavior. An output schema exists, so return values need minimal explanation. Complete enough to call correctly, though it never states the concrete side effects of firing each event.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description carries the full burden and does so well: it enumerates the KNOWN_EVENTS values for 'event', lists the recognized payload keys per event type (summary, text, query, budget), explains 'layer' as user/agent with user as default, and clarifies that user_id is the subject user bound to the API key. This is far more semantic detail than the bare schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Fire') and resource ('external lifecycle event') and enumerates the actual event names (session_started, session_ended, new_message, etc.), so an agent knows precisely what the tool does. It does not explicitly distinguish itself from the cryptic siblings (evolve, think, dream, forget, project, wake_up), which keeps it at a 4 rather than a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The event enumeration implicitly signals the trigger contexts (session start/end, new message, memory pressure), but there is no explicit when-to-use versus when-not-to-use guidance and no mention of the sibling tools as alternatives. Usage is inferable but not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

projectC
Destructive

Universal Primitive: managing project-specific context and file mapping.

Projects are global (keyed by name). Structured data (identity, decisions, artifact map, code index) lives in projects.db; large documents go to the Wiki as project_spec pages.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
pathNo
roleNo
layerNouser
actionYes
statusNo
detailsNo
outcomeNo
user_idNodefault
decisionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, so the safety profile is partly covered. The description adds that structured data lives in projects.db and large docs go to Wiki pages, but it does not disclose which actions are destructive, what archive/update do, or any auth or rate constraints. It adds only minimal context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, front-loaded with the purpose statement and structured logically: purpose, then storage semantics. 'Universal Primitive' is expendable, but otherwise there is no wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter multi-action tool, the description leaves action semantics, required parameter usage, and when to choose it over siblings unspecified. An output schema exists, so return values need not be explained, but the invocation contract is largely missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 10 parameters with 0% description coverage. The description mentions 'keyed by name' but does not explain the action enum values, path, role, layer, status, details, outcome, user_id, or decision. With such low schema coverage, the description fails to compensate for the missing parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

States it manages project-specific context and file mapping, and notes projects are global and keyed by name. However, it never names a specific operation (init/update/archive/etc.) or explains what invoking the tool actually does, and 'Universal Primitive' is unhelpful jargon. It is more than a tautology but still vague about the core action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance is given relative to siblings (evolve, memory_hook, think, etc.) or any alternative. The note that large documents go to the Wiki hints at a boundary, but it is a storage implementation detail rather than invocation guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

thinkC
Destructive

Universal Primitive: routing thoughts to correct memory layers based on importance and content.

kind: optional declaration hint (one of L4_DECLARABLE_KINDS). A declared thought is authored canon — it bypasses the length/pattern gates straight to L4 (spec S4), rate-limited per user. Without it, behavior is unchanged.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo
textYes
layerNoauto
user_idNodefault
wiki_typeNo
wiki_titleNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the mutation profile (readOnlyHint=false, destructiveHint=true, non-idempotent). The description usefully adds that a declared thought bypasses length/pattern gates to L4 and is rate-limited per user, which is real context beyond the annotations. However it never explains what a destructive write here actually affects or what happens to prior memory.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The one-line purpose is front-loaded and the total length is short, which is good. But the second paragraph is dense with undefined internal jargon ("L4_DECLARABLE_KINDS", "spec S4") that consumes space without clarifying usage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent write tool with an output schema present, the description need not cover return values, but it should cover the five undocumented parameters and the layer-routing behavior. It does neither, leaving an agent unable to invoke the tool correctly beyond the single required `text` field.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 6 parameters, so the description must carry the burden. It explains only `kind` (optional declaration hint, one of L4_DECLARABLE_KINDS) and leaves text, layer, user_id, wiki_type, and wiki_title wholly undocumented in both schema and prose.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Routing thoughts to correct memory layers based on importance and content" gives a rough verb+resource, but "Universal Primitive" is opaque jargon and the description never distinguishes this tool from siblings like memory_hook, dream, or project. An agent can guess it stores/places a thought but not how it differs from the other memory-writing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no named alternatives among the six siblings. The `kind` paragraph describes one parameter's effect but never tells the agent when to reach for think rather than evolve, memory_hook, or forget.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wake_upB
Read-onlyIdempotent

Wake up (E10, Stage 2-C): one-call memory lift for a fresh session.

Glues memory_recap (continuity pack) and the inject critical set onto a shared token budget: recap takes at most half, inject gets the rest. Returns structured blocks plus a rendered markdown block with a cache:break between the two halves.

ParametersJSON Schema
NameRequiredDescriptionDefault
layerNouser
budgetNo
user_idNodefault

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only/idempotent/non-destructive, and the description adds real behavioral context: it glues two memory sources onto a shared budget where recap gets at most half and inject the rest, and it emits a cache:break between the two markdown halves. That budget-splitting and cache-boundary behavior is genuinely useful beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and the composition/budget mechanics follow in two tight sentences. The parenthetical codename is mild clutter but the whole thing is appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations cover the safety profile. However, with 0% param coverage the description should explain layer/user_id and give at least minimal when-to-use routing, which it does not.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and all three parameters are undocumented in the schema. The description touches the token 'budget' (shared, split half/half) but says nothing about 'layer' or 'user_id', leaving two of three parameters with no semantics anywhere.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific effect -- 'one-call memory lift for a fresh session' -- and names the two internal operations it composes (memory_recap continuity pack plus inject critical set). It is clear what the tool produces, though the internal jargon (E10, Stage 2-C) adds noise rather than meaning, and it never contrasts itself with the actual siblings (memory_hook, think, evolve).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'for a fresh session' is the only usage signal, implying it is the session-start entry point. There is no explicit when-not guidance and no routing against the sibling tools (memory_hook, think, dream), so the agent must infer selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv1.12.0
    • Changedforget7 fields changed
      • addedInput schema / properties / archived_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "integer"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Archived Ids"
        +}
      • addedInput schema / properties / dry_run
        Added value: +{
        +  "default": false,
        +  "title": "Dry Run",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / episode_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "integer"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Episode Ids"
        +}
      • addedInput schema / properties / key / default
        Added value: +""
      • addedInput schema / properties / memory_type
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Memory Type"
        +}
      • changedInput schema / properties / scope / enum
        Previous value: -[
        -  "exact",
        -  "fuzzy",
        -  "recent"
        -]New value: +[
        +  "exact",
        +  "fuzzy",
        +  "recent",
        +  "episode_ids",
        +  "undo"
        +]
      • removedInput schema / required
        Removed value: -[
        -  "key"
        -]
    • Changedthink1 field changed
      • addedInput schema / properties / kind
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Kind"
        +}
    • Addedwake_up
  2. 1 tool updatev1.9.0
    • Addedmemory_hook
  3. 30 tool updatesv1.8.0
    • Addeddream
    • Addedevolve
    • Addedforget
    • Removedmemory_api_key
    • Removedmemory_backup
    • Removedmemory_cleanup
    • Removedmemory_context
    • Removedmemory_context_inject
    • Removedmemory_data
    • Removedmemory_episode_get
    • Removedmemory_episode_list
    • Removedmemory_episode_recall
    • Removedmemory_episode_save
    • Removedmemory_forget
    • Removedmemory_graph_add
    • Removedmemory_graph_edges
    • Removedmemory_graph_nodes
    • Removedmemory_graph_query
    • Removedmemory_lucidity_purge
    • Removedmemory_recall
    • Removedmemory_remember
    • Removedmemory_saga
    • Removedmemory_search
    • Removedmemory_session_end
    • Removedmemory_session_list
    • Removedmemory_session_start
    • Removedmemory_stats
    • Removedmemory_sync_replica
    • Addedproject
    • Addedthink
  4. 25 tool updatesv1.4.0
    • First observedmemory_api_key
    • First observedmemory_backup
    • First observedmemory_cleanup
    • First observedmemory_context
    • First observedmemory_context_inject
    • First observedmemory_data
    • First observedmemory_episode_get
    • First observedmemory_episode_list
    • First observedmemory_episode_recall
    • First observedmemory_episode_save
    • First observedmemory_forget
    • First observedmemory_graph_add
    • First observedmemory_graph_edges
    • First observedmemory_graph_nodes
    • First observedmemory_graph_query
    • First observedmemory_lucidity_purge
    • First observedmemory_recall
    • First observedmemory_remember
    • First observedmemory_saga
    • First observedmemory_search
    • First observedmemory_session_end
    • First observedmemory_session_list
    • First observedmemory_session_start
    • First observedmemory_stats
    • First observedmemory_sync_replica

TDQS

B3/5.0

Scored across 7 tools

Disambiguation3/5

The metaphorical names (dream=search, think=routing/store, evolve=personality, forget=delete) obscure the underlying actions, so an agent wanting to store or retrieve could plausibly misselect between think and dream. Descriptions disambiguate reasonably well once read, but the boundaries are not self-evident from the names.

Naming Consistency3/5

Most tools are single imperative verbs (evolve, think, dream, forget, project, wake_up), which is fairly consistent, but memory_hook breaks the pattern with a noun_noun form and several names are metaphorical rather than descriptive. It reads cleanly but the convention is not uniform.

Tool Count5/5

Seven tools is well-scoped for a memory server covering store, search, forget, lifecycle, session lift, projects, and evolution. Each tool has a distinct role and none feels redundant.

Completeness4/5

The surface covers a full memory lifecycle: ingest (think), retrieval (dream, wake_up), deletion/undo (forget), lifecycle events (memory_hook), project context (project), and personality (evolve). Only minor gaps remain, such as no explicit standalone get/recall beyond the search-oriented tools.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides AI agents with persistent, searchable memory that survives across conversations using semantic search, temporal versioning, and smart organization. Enables long-term context retention and cross-session continuity for AI assistants.
    14
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to gain persistent, structured memory that is semantically searchable and graph-traversable, allowing them to store and query records and relationships without managing embeddings or schemas.
    64 npm
    Apache 2.0