ποΈ Mnemo β the agent that never forgets
A standalone AI assistant with a persistent, temporal memory brain. Tell it something in one session; ask about it in a completely new session and it recalls it β with who, what, and when β citing its sources.
Mnemo pairs a temporal knowledge graph (Graphiti on FalkorDB) with a Claude-session harness (MCP tools + hooks + skills), so any Claude Code session can remember and recall across time. Its persona is the archivist: precise, unhurried, and it never states a fact without saying where and when it was true.
you (session 1): "Remember: Marco leads Solaris; it launches Q4 2027; it depends on Helios."
you (session 2): "Who leads Solaris, when does it launch, what does it depend on?"
Mnemo: Lead: Marco Β· Launch: Q4 2027 Β· Depends on: Helios API (as of 2026-07-17)
How it works
Mnemo has two layers, exactly like a well-run agent: a git-versioned identity (markdown) and a memory brain (a graph database). A thin connection layer (MCP + hooks) plugs that brain into any Claude session.
flowchart TB
subgraph SESSION["π§ Claude session (this repo, any repo, or Claude Desktop)"]
Q["You ask a question<br/>or state a fact"]
end
subgraph CONNECT["π Connection layer"]
direction LR
MCPR["recall tool"]
MCPM["remember tool"]
SS["SessionStart hook<br/>Β· ensure DB up<br/>Β· surface tools"]
STP["Stop hook<br/>Β· auto-learn:<br/>summarize + ingest"]
end
subgraph BRAIN["πΎ Memory brain"]
direction LR
GR["Graphiti<br/>extract entities + typed edges<br/>bi-temporal validity"]
FDB[("FalkorDB<br/>property graph")]
EMB["fastembed<br/>local embeddings"]
end
Q -->|"tell"| MCPM --> GR
Q -->|"ask"| MCPR --> GR
GR <--> FDB
GR <--- EMB
SS -.injects context.-> SESSION
STP --> GR
Ingest and recall β remembering turns text into a graph; recalling runs a hybrid search over it and answers in persona:
flowchart LR
T["raw text<br/>(who / what / when)"] --> RM["remember()"]
RM --> EX["Graphiti extraction<br/>Β· entities as typed nodes<br/>Β· relationships as typed edges<br/>Β· dates/status as node attributes"]
EX --> KG[("FalkorDB<br/>temporal property graph")]
QQ["a question"] --> RC["recall()"]
KG --> HS["hybrid search_()<br/>vector + BM25 + graph traversal"]
RC --> HS
HS --> CTX["facts + entity attributes + source excerpts"]
CTX --> ANS["Claude answers in the<br/>archivist persona, with citations"]
Why memory survives across sessions β nothing is shared between sessions except the graph on disk:
sequenceDiagram
participant S1 as Session 1 (Mon)
participant M as Mnemo
participant DB as FalkorDB (volume)
participant S2 as Session 2 (Fri Β· fresh process)
S1->>M: remember("Marco leads Solaris, launches Q4 2027")
M->>DB: extract β nodes + typed edges + valid-time
Note over S1,DB: session ends β Stop hook summarizes & ingests it too
S2->>M: recall("who leads Solaris? when?")
M->>DB: hybrid search (edges + nodes + episodes)
DB-->>S2: Marco Β· Q4 2027 (cited, as-of dated)
The pieces
| Piece | File | Role |
|---|---|---|
| Identity | personality.md, CLAUDE.md |
The archivist persona + operating rules (git-versioned) |
| Graph types | mnemo/types.py |
Custom entities (Project, Feature, Person, Meeting, Company) + typed edges (BelongsTo, WorksOn, Said, DependsOn, Attended); dates/status/roles captured as node attributes |
| Memory wrapper | mnemo/memory.py |
ingest() and recall() β recall uses Graphiti's search_() (edges + nodes + episodes), not the edge-only default |
| MCP server | mnemo/mcp_server.py, .mcp.json |
Exposes recall / remember as MCP tools to any Claude session |
| Hooks | .claude/hooks/ |
SessionStart (ensure DB up, surface tools) Β· Stop (detached auto-learn worker) |
| Auto-learn worker | mnemo/ingest_session.py |
Summarizes a finished session and ingests it (kill-switch: create .mnemo-nolearn) |
| Skills | .claude/skills/{recall,remember} |
Ergonomic in-session use |
| Agent | mnemo/agent.py |
Recalls, then answers in persona with citations |
Embeddings run locally (fastembed, 384-dim) so no embeddings key is needed; the LLM (extraction + answers) is Claude, and the client accepts both a standard sk-ant-api03 key and a Claude Code sk-ant-oat OAuth token.
How Mnemo compares
Most "AI memory" is either a flat vector store (good at similar text, blind to relationships and time) or an opaque per-user blob you can't inspect. Mnemo is a temporal knowledge graph with a Claude-native connection layer.
| Capability | Mnemo | Vanilla RAG (vector DB) | Mem0 | Raw Graphiti / Zep | Letta (MemGPT) | ChatGPT-style memory |
|---|---|---|---|---|---|---|
| Storage model | temporal property graph | flat chunks + vectors | vectors (+opt. graph) | temporal graph | tiered memory blocks | opaque per-user store |
| Typed relationships (whoβwhat) | β | β | partial | β | β | β |
| Temporal "as-of" / fact invalidation | β bi-temporal | β | limited | β | β | β |
| Hybrid retrieval (vector + BM25 + graph) | β | vector only | vector | β | n/a | n/a |
| Cross-session persistence | β | β (if wired) | β | β | β | β (per user) |
| Auto-learns from each session | β (Stop hook) | β | manual | β (library) | β | β |
| Claude Code / MCP native (drop-in tools + hooks) | β | β | β | β | β | β |
| Runs fully local (offline embeddings) | β fastembed | depends | depends | depends | depends | β cloud |
| Works with a Claude Code OAuth token | β | n/a | n/a | n/a | n/a | n/a |
| Inspectable + cites source & time | β | β | β | partial | partial | β |
Where Mnemo sits: it is not a competitor to Graphiti β it is built on Graphiti. Think of it as Graphiti (the brain) + a Claude-session body: the MCP tools, the SessionStart/Stop hooks, the archivist persona, and the operational glue (OAuth-token auth, local embeddings, portable ${CLAUDE_PROJECT_DIR} config, comprehensive search_() recall) that turn a memory library into a memory agent you can talk to.
vs. a Notion/RAG-backed assistant (e.g. an agent whose "memory" is a Notion database): those retrieve documents by similarity. Mnemo retrieves facts and their relationships over time β it can answer "who used to own this, and who owns it now", which flat retrieval cannot.
What Mnemo is not (yet)
Honest scope β it's an experiment, not a product:
- No multi-user / auth on the graph β single local user.
- No managed hosting or horizontal scale (FalkorDB is a local Docker container).
- Extraction is LLM-driven and ~good, not perfect β occasionally a detail is missed (it will say "not found" rather than hallucinate).
- Auto-learned summaries vary in quality; recall-heavy sessions produce thin summaries.
- No daemon; the brain is up while
docker composeis running.
Quickstart
git clone <this repo> && cd mnemo-agent
cp .env.example .env # set ANTHROPIC_API_KEY (sk-ant-api03 key OR sk-ant-oat token)
docker compose up -d # start FalkorDB (defaults to port 6380)
python -m venv .venv && . .venv/bin/activate && pip install -r requirements.txt
python scripts/seed.py # load the fictional sample data (Atlas project)
pytest -v # prove it: ingest + recall + temporal, all live
Then talk to it from any Claude Code session in this repo β the SessionStart hook wires the recall/remember tools automatically. To use Mnemo from any repo or Claude Desktop, add the .mcp.json server to your global config.
Verified behaviour
Proven live (see the test suite + docs/):
- Cross-session: store in one
claudeprocess, recall in a separate one β including dates and dependencies. - Temporal: after a reassignment, "who currently owns X" returns the new owner, not the stale one (edge invalidation).
- Durable: survives a
docker compose restart(data in the FalkorDB volume). - MCP transport: tools list and call over the real MCP stdio protocol.
- Auto-learn: finished sessions are summarized and ingested by the Stop hook.
Design & internals
docs/2026-07-16-mnemo-agent-design.mdβ the design spec.docs/agent-memory-plan.mdβ the graph-first memory model this is built on (why a graph, not a flat table; the 3-tier idea; engine selection).
Tech stack
Python 3.12 Β· Graphiti graphiti-core Β· FalkorDB (Docker) Β· Anthropic Claude (extraction + answers) Β· fastembed (local embeddings) Β· MCP (FastMCP) Β· pytest.