Local-first AI memory built to forget. Depth-axis architecture with verifiable purge receipts. Exposes the Lethe API as MCP tools over stdio.
Lethe MCP server has well-structured tool definitions with clear, domain-specific descriptions (avg 150-200 chars). All 11 tools have explicit input schemas with typed parameters and descriptions. However, output schemas are not formally documented in the code, responses are inferred from return statements. Parameter descriptions are generally good but lack explicit constraints (e.g., no min/max for k, no enum for 'kind' in log()). Error handling is minimal, no recovery guidance or actionable error messages visible. Tool naming is verb-forward and clear (inscribe, recall, release, purge, supersede, pin, unpin, consolidate, blame, log). No security issues detected (no secrets in params), but no explicit permission gates or audit logging visible.
For each memory matching the query, return its supersession chain: what it superseded, and what (if anything) has since superseded it.
Apply Hypnos gravity to every unpinned memory. Frequently-accessed facts sink slower; long-survivors get promoted above the surface. tau_seconds is the time constant (default: 7 days).
Store a fact on the surface of memory (depth = 1.0). Returns the new memory's integer id.
Query the append-only event log. Filter by kind (inscribe / recall / release / supersede / purge / pin / flow / promote) and/or time range.
Pin a memory above the surface (depth = +∞), immune to gravity. Only purge() can still remove it.
Hard-delete from disk. Only the event log remembers. Use for GDPR / compliance — irreversible at the data level.
Output schemas not formally documented. Tool responses are inferred from return statements (dicts with id, text, depth, score, etc.), but no explicit schema definitions visible in code. LLMs cannot reliably plan downstream tool calls without knowing response structure.
Parameter constraints missing. 'k' (number of results) has no min/max bounds, LLM could pass k=999999. 'kind' in log() accepts free-form strings instead of enum (inscribe|recall|release|supersede|purge|pin|flow|promote). 'tau_seconds' in consolidate() has no range validation.
No error handling or recovery guidance. Code does not show try-catch blocks, error classification, or actionable error messages. If purge_signed fails (missing signing key), LLM gets no guidance on next steps.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Hard-delete + return an Ed25519-signed PurgeReceipt anchored to the event-log Merkle root. Lets third parties verify, without database access, that the deletion was acknowledged at a specific moment. Requires a signing key (env LETHE_SIGNING_KEY or default key file).
Retrieve memories matching the query. lexical=True: pure BM25 (identifier lookup, e.g. emails, API keys). hybrid=True (default): RRF blend of vec + BM25. hybrid=False: vec-only. at: unix timestamp for time-travel — what did the agent believe at T?
Soft-evict: depth → 0. Memory is preserved on disk and visible to time-travel, but does not surface in normal recall.
Replace an old fact with a new one. The old memory sinks (depth → 0); the new one rises (depth = 1.0). A supersession edge is recorded for blame() to walk later.
Inverse of pin: drop back to surface (depth = 1.0).
Destructive operations lack confirmation step. purge() and purge_signed() perform hard deletes with no dry-run or confirmation mechanism. Agents can accidentally destroy data.
No audit logging or permission gates visible. Tools modify state (inscribe, purge, supersede) but no code shows who called what, when, or with what permissions. Compliance and debugging are at risk.