# Total Agent Memory

> Persistent memory for Claude Code & Codex CLI. Auto-extracted knowledge graph, multi-representation embeddings, 3D WebGL visualization. LongMemEval R@5=97.45%. Self-hosted, Ollama-optional

- **Type:** MCP server
- **Install:** `agentstack add mcp-vbcherepanov-total-agent-memory`
- **Verified:** Pending review
- **Seller:** [vbcherepanov](https://agentstack.voostack.com/s/vbcherepanov)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [vbcherepanov](https://github.com/vbcherepanov)
- **Source:** https://github.com/vbcherepanov/total-agent-memory
- **Website:** https://totalmemory.dev

## Install

```sh
agentstack add mcp-vbcherepanov-total-agent-memory
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# total-agent-memory

> **The only memory layer that learns _how_ you work — not just _what_ you said.**
> Persistent, local memory for AI coding agents: Claude Code, Codex CLI, Cursor, any MCP client.
> Temporal knowledge graph · procedural memory · AST codebase ingest · cross-project analogy · 3D WebGL visualization.

[](https://pypi.org/project/total-agent-memory/)
[]()
[]()
[](evals/longmemeval-2026-04-17.json)
[](benchmarks/results/)
[](docs/vs-competitors.md)
[](evals/results-2026-04-17.json)
[]()
[](LICENSE)
[](https://modelcontextprotocol.io)
[](https://www.npmjs.com/package/total-agent-memory)
[](https://pypi.org/project/total-agent-memory/)
[](https://github.com/vbcherepanov/total-agent-memory/pkgs/container/total-agent-memory)
[](https://github.com/vbcherepanov/homebrew-tap)
[](https://PayPal.Me/vbcherepanov)

**Why this, not mem0 / Letta / Zep / Supermemory / Cognee?** → [docs/vs-competitors.md](docs/vs-competitors.md)

---

## v12.2.0 — v11 W3 dispatch fix + Codex env alignment (2026-05-24)

Bugfix release. Four v11 W3 MCP tools — `memory_recall_iterative`,
`memory_temporal_query`, `memory_entity_resolve`, `memory_consolidate_status` —
were silently broken on `main`: the dispatcher forwarded an out-of-scope
`args` symbol, the resulting `NameError` was swallowed by `call_tool`'s
exception handler, and clients saw `"Error: name 'args' is not defined"`.
Fix passes the per-call args, with regression coverage via
`tests/test_v11_dispatch_args.py`.

Also aligns the Codex installer env with the `.tam` memory layout
(`TAM_MEMORY_DIR` canonical, `CLAUDE_MEMORY_DIR` kept as compatibility alias,
`MEMORY_MODE=fast` default) and isolates install tests from real
`launchctl` / `systemctl` / `XDG` directories. Full notes in
[`CHANGELOG.md`](CHANGELOG.md#1220--2026-05-24--v11-w3-dispatch-fix--codex-env-alignment).

---

## v12.1.0 — Claude Code v2.1.145 subagent lineage (2026-05-20)

Claude Code **v2.1.139+** emits subagent IDs on every API request
(`x-claude-code-agent-id` / `x-claude-code-parent-agent-id` HTTP headers,
plus the same fields as `agent_id` / `parent_agent_id` attributes on the
`claude_code.tool` and `claude_code.llm_request` OTEL spans). v12.1 wires
these through end-to-end:

- **Schema (migration `028_agent_lineage.sql`)** — nullable `agent_id` and
  `parent_agent_id` columns on `knowledge`, partial indexes (`WHERE … IS NOT NULL`)
  so lineage filters are free.
- **MCP tools** — `memory_save` and `memory_save_fast` accept two new
  optional inputs: `agent_id` and `parent_agent_id`. Old callers see no
  behaviour change.
- **`extract_transcript.py`** — reads `agent_id` / `agentId` /
  `parent_agent_id` / `parentAgentId` from `.jsonl` when Claude Code writes
  them, and falls back to `isSidechain=true` as a proxy: sessions with any
  sidechain activity get `agent_id = "session-"` plus a
  `has-subagent-work` tag on their auto-extracted rows.
- **KG fact `spawned_by`** — when `memory_save` carries both ids, the
  store auto-records `TemporalKG.add_fact(agent, "spawned_by", parent,
  source="agent-lineage", invalidate_previous=False)`. Idempotent.
  `kg_at(timestamp)` and `kg_timeline()` can now reconstruct the subagent
  lineage tree at any past moment.

A reconnect of the MCP `memory` server is required for clients to see the
updated `inputSchema`. Full notes in [`CHANGELOG.md`](CHANGELOG.md#1210--2026-05-20--claude-code-v21145-subagent-lineage).

---

## v12.0.0 — rebrand to `total-agent-memory` (2026-05-16)

The project was renamed from `claude-total-memory` to **`total-agent-memory`** to
reflect that it works with **every MCP client**, not just Claude Code (Cursor,
Codex CLI, Cline, Continue, Aider, Windsurf, Gemini CLI, OpenCode — all
covered).

**Nothing breaks.** The old PyPI package (`claude-total-memory==11.3.0`) is now a
deprecation shim that auto-resolves to `total-agent-memory>=12.0.0`. Legacy
imports, CLI binaries, env vars, and the `~/.claude-memory/` directory keep
working through automatic migration:

| Old | New | Backward-compat |
|---|---|---|
| `pip install claude-total-memory` | `pip install total-agent-memory` | old name still works (shim + warning) |
| `from claude_total_memory import …` | `from total_agent_memory import …` | old import still works (sys.modules alias + warning) |
| `claude-total-memory` CLI | `total-agent-memory` (alias `tam`) | old CLI still ships in v12 wheel |
| `CLAUDE_MEMORY_DIR` env | `TAM_MEMORY_DIR` env | old env still respected (deprecation warning) |
| `~/.claude-memory/` dir | `~/.tam/` dir | auto-migrated on first run; `~/.claude-memory` becomes a symlink to `~/.tam/` so pinned scripts keep working |

Six install paths — pick one:

```bash
npx -y total-agent-memory connect claude-code            # Node, zero-install
uvx total-agent-memory                                    # Python via uv (fast)
pipx install total-agent-memory                           # Python via pipx (isolated)
brew install vbcherepanov/tap/total-memory                # Homebrew (macOS / Linuxbrew)
docker run -p 37737:37737 -v ~/.tam:/data \
  ghcr.io/vbcherepanov/total-agent-memory:12.2.0          # Docker (multi-arch amd64+arm64)
git clone https://github.com/vbcherepanov/total-agent-memory \
  ~/total-agent-memory && cd ~/total-agent-memory && ./install.sh   # manual
```

The `npx` path also wires the MCP entry into the IDE you pass to `connect `:
`claude-code`, `codex`, `cursor`, `cline`, `continue`, `aider`, `windsurf`,
`gemini-cli`, `opencode`.

**Project URLs:** [totalmemory.dev](https://totalmemory.dev) · [PyPI](https://pypi.org/project/total-agent-memory/) · [npm](https://www.npmjs.com/package/total-agent-memory) · [Docker GHCR](https://ghcr.io/vbcherepanov/total-agent-memory) · [GitHub Release](https://github.com/vbcherepanov/total-agent-memory/releases/tag/v12.2.0)

Full migration notes (Docker volume names kept for backward-compat, brew formula
changes, etc.) live in [`CHANGELOG.md`](CHANGELOG.md). The historical sections
below (v11.1, v11.0, …) are preserved for reference.

---

## v11.1 — graph dedup + proactive save nudges

Two client-reported bugs fixed (2026-05-14):

**Bug #1 — orphan + duplicate `graph_nodes`.** The graph accumulated
case-variant duplicates (`Vue` / `vue` / `VUE`) and type-collision
duplicates (`vue/concept` vs `vue/technology` created by different
extractors), plus orphan nodes when an edge insert failed after both
nodes were already committed. Fixed by migration `026_graph_nodes_dedup`
(`name_norm` column, triggers, indexes), a case-insensitive UPSERT
rewrite of `add_node` with type-collision detection, a new atomic
`GraphStore.link_pair()` helper, and a one-shot cleanup tool
`src/tools/merge_duplicate_nodes.py` (dry-run by default).

```bash
# After upgrade migration 026 applies automatically. Then optionally:
.venv/bin/python src/tools/merge_duplicate_nodes.py --dry-run
.venv/bin/python src/tools/merge_duplicate_nodes.py --apply --add-unique
```

Verified on a real production DB (8304 nodes): 102 duplicates merged,
1472 stale edges cleaned, UNIQUE constraint installed.

**Bug #2 — model never calls `memory_save` on its own.** Sonnet/Haiku
skip the priority-10 save rule when SessionStart context fades. v11.1
adds in-session **nudges**: a counter in `~/.claude-memory/state/`
tracks writes-vs-saves per session, and `hooks/post-tool-use.{sh,ps1}`
emits a stdout line that Claude reads as system context on the next
turn. Soft nudge at 3 edits with 0 saves, hard at 7, and a
`MEMORY_FINAL_WARNING` on session stop. A new priority-10 rule
instructs the model to treat `MEMORY_NUDGE` as an immediate command.

Tunables: `MEMORY_NUDGE_DISABLE=1` to silence; `MEMORY_NUDGE_SOFT` /
`_HARD` / `_STEP` to retune (defaults `3 / 7 / 3`).

Test coverage: +24 graph tests, +12 nudge tests. Full details in
[`CHANGELOG.md`](CHANGELOG.md#1110--2026-05-14--graph-dedup--proactive-save-nudges).

---

## v11.0 — production memory engine

**v11.0 = production memory engine: fast deterministic memory core + async AI enrichment layer. Default mode is `fast`: zero LLM, zero Ollama, zero network in the save/search/recall hot path.**

The codebase is now split into two layers:

- **`src/memory_core/*`** — deterministic facade modules (storage, embeddings, vector_store, classifier, chunker, dedup, cache, graph_links, telemetry, health, embedding_spaces). No LLM imports allowed. Enforced by `tests/test_no_llm_hot_path.py`.
- **`src/ai_layer/*`** — every LLM-touching path (enrichment_worker, summarizer, keyword_extractor, question_generator, relation_extractor, contradiction_detector, reflection, self_improve, plus thin shims for quality_gate / coref_resolver / reranker / query_rewriter). Off-limits to memory_core.

Architecture details and full hot-path audit: [`docs/v11/audit.md`](docs/v11/audit.md).

### Modes

`MEMORY_MODE` selects the runtime profile. Default is `fast`.

| Mode | Hot-path LLM | Async enrichment | Reranker | Embed fallback | Use when |
|---|:-:|:-:|:-:|:-:|---|
| `ultrafast` | off | off | off | FastEmbed only (vector index off, FTS-only) | Throughput stress / CI |
| **`fast`** (default) | **off** | **off** | **off** | **FastEmbed only, Ollama fallback gated** | **Production coding-agent loop** |
| `balanced` | off (sync) | **on** | off | FastEmbed only | You want LLM-derived facets, but never on the critical path |
| `deep` | on (sync) | on | on (when `rerank=true`) | FastEmbed → Ollama ladder | v10.5 behaviour: quality gate / contradiction / coref / HyDE inline |

`deep` mode reproduces v10.5.0 defaults exactly. Set `MEMORY_MODE=deep` if you depended on synchronous quality_gate, contradiction_detector, or coref. `balanced` keeps the same ergonomics but moves enrichment off-thread.

Migration from v10.5: [`docs/v11/MIGRATION-FROM-V10.md`](docs/v11/MIGRATION-FROM-V10.md).

### v11.0 hot-path benchmark

Warm, in-memory SQLite, MacBook M-series, `MEMORY_MODE=fast`, `MEMORY_ALLOW_OLLAMA_IN_HOT_PATH=false`:

| metric              |   p50 |   p95 |   p99 |
|---------------------|------:|------:|------:|
| `save_fast`         |  6.5  |  9.0  | 27.8  |
| `save_fast` cached  |  0.3  |  0.4  |  1.1  |
| `search_fast`       |  3.7  |  4.0  |  6.2  |
| `cached_search`     |  0.0  |  0.0  |  0.0  |

**`llm_calls = 0`, `network_calls = 0`** across the entire hot path. Reproduce: `bin/memory-bench`. CI gate: `bin/memory-perf-gate`. Raw artifact: [`docs/v11/benchmark.md`](docs/v11/benchmark.md).

### v10.5 → v11.0 — same workload, same script

The v10.5 native bench (`benchmarks/v10_5_latency.py`) re-run on v11 fast against the recorded v10.5 baseline (`benchmarks/results/v10_5_latency.json`):

| metric                | v10.5 sync (with LLM) | v11.0 fast | speedup |
|-----------------------|----------------------:|-----------:|--------:|
| save p95              | 2150.51 ms            | 8.51 ms    | **252×** |
| save p99              | 2178.98 ms            | 11.09 ms   | **196×** |
| recall p95            | 1424.26 ms            | 5.81 ms    | **245×** |
| recall p99            | 1771.70 ms            | 6.75 ms    | **262×** |
| LLM calls / save      | 2-4                   | 0          | gate    |
| Network calls / save  | 1-3                   | 0          | gate    |

Even versus v10.5 _without_ LLM (`23.3 ms p95`), v11 fast is `2.7×` faster — the deterministic-only stages (quality_gate probe, contradiction candidate fetch, episodic event creation, project_wiki refresh) are now fully bypassed in fast mode and queued only when `MEMORY_ENRICHMENT_ENABLED=true`.

Recall quality is preserved: LongMemEval R@5 = 100% on a 30-question sample; hybrid retrieval (FTS5 + dense + RRF + base graph) is identical to v10.5 except for HyDE / analyze_query LLM expansion which is opt-in via `MEMORY_MODE=deep`. See [`docs/v11/benchmark.md`](docs/v11/benchmark.md) for the full table including LoCoMo and per-space embedding load characteristics.

### New MCP tools in v11.0

`memory_save_fast` · `memory_search_fast` · `memory_explain_search` · `memory_warmup` · `memory_perf_report` · `memory_rebuild_fts` · `memory_rebuild_embeddings` · `memory_eval_locomo` · `memory_eval_recall` · `memory_eval_temporal` · `memory_eval_entity_consistency` · `memory_eval_contradictions` · `memory_eval_long_context`

All previous tool names (`memory_save`, `memory_recall`, ...) continue to work unchanged.

### Multi-embedding-space contract

Every vector row now records `embedding_provider / embedding_model / embedding_dimension / embedding_space / content_type / language`. Spaces: `text` / `code` / `log` / `config`. Single Chroma backend; per-space model swap is one env flip:

```bash
MEMORY_TEXT_EMBED_MODEL=sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
MEMORY_CODE_EMBED_MODEL=jinaai/jina-embeddings-v2-base-code   # optional
MEMORY_LOG_EMBED_MODEL=                                       # falls back to TEXT
MEMORY_CONFIG_EMBED_MODEL=                                    # falls back to TEXT
```

Old chunks stay searchable in their space; new chunks pick up the swapped model. Backfill one space at a time via `memory_rebuild_embeddings`.

> v10.x sections below are preserved as **legacy v10.5 behaviour** — still available via `MEMORY_MODE=deep`. The numbers, screenshots, and benchmark blocks dated 2026-04-19 / 2026-04-25 / 2026-04-27 (v10) describe the deep-mode pipeline. v11 replaces *defaults*, not capabilities.

---

## Table of contents

- [v11.1 — graph dedup + proactive save nudges](#v111--graph-dedup--proactive-save-nudges)
- [v11.0 — production memory engine](#v110--production-memory-engine)
- [The problem it solves](#the-problem-it-solves)
- [60-second demo](#60-second-demo)
- [Benchmarks — how it compares](#benchmarks--how-it-compares)
- [Competitor comparison](#competitor-comparison)
- [What you get](#what-you-get)
- [Architecture](#architecture)
- [Install](#install)
- [Quick start](#quick-start)
- [CLI: `lookup-memory` for sub-agents](#cli-lookup-memory-for-sub-agents)
- [MCP tools reference](#mcp-tools-reference-60-tools)
- [TypeScript SDK](#typescript-sdk)
- [Dashboard](#dashboard-localhost37737)
- [Update](#update)
- [Upgrading from v8.x to v9.0](#upgrading-from-v8x-to-v90)
- [Upgrading from v7.x to v8.0](#upgrading-from-v7x-to-v80)
- [Ollama setup](#ollama-setup-optional-but-recommended)
- [Configuration](#configuration)
- [Performance tuning](#performance-tuning)
- [Roadmap](#roadmap)
- [Support the project](#support-the-project)
- [Philosophy & license](#philosophy)

---

## The problem it solves

**AI coding agents have amnesia.** Every new Claude Code / Codex / Cursor session starts from zero. Yesterday's architectural decisions, bug fixes, stack choices, and hard-won lessons vanish the moment you close the terminal. You re-explain the same things, re-discover the same solutions, paste the same context into every new chat.

**`total-agent-memory` gives the agent a persistent brain — on your machine, not in someone else's cloud.**

Every decision, solution, error, fact, file change, and session summary is:

- **Captured** — explicitly via `memory_save` or implicitly via hooks on file edits / bash errors / session end
- **Linked** — automatically extracted into a knowledge graph (entities, relations, temporal facts)
- **Searchable** — 6-stage hybrid retrieval (BM25 + dense + graph + CrossEncoder + MMR + RRF fusion), **96.2% R@5 on public LongMemEval**
- **Private** — 100% local. SQLite + FastEmbed + optional Ollama. No data leaves your machine.

---

## 60-second demo

```
You:     "remember we picked pgvector over ChromaDB because of multi-tenant RLS"
Claude:  ✓ memory_save(type=decision, content="Chose pgvector over ChromaDB",
                       context="WHY: single Postgres, per-tenant RLS")

[3 days later, different session, possibly different project directory:]

You:     "why did we pick pgvector again?"
Claude:  ✓ memory_recall(query="vector database choice")
         → "Chose pgvector over ChromaDB for multi-tenant RLS. Single DB
            instance, row-l

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [vbcherepanov](https://github.com/vbcherepanov)
- **Source:** [vbcherepanov/total-agent-memory](https://github.com/vbcherepanov/total-agent-memory)
- **License:** MIT
- **Homepage:** https://totalmemory.dev

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-vbcherepanov-total-agent-memory
- Seller: https://agentstack.voostack.com/s/vbcherepanov
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
