Agent Memory

One memory, shared by every agent on your machine

A decision Claude Code records is visible to Codex an hour later and to OpenCode next week — through one local Hyphae directory, not a cloud account, and never across projects.

What it is

Coding agents forget everything between sessions, and every agent forgets separately. Agent Memory is one local engine that Claude Code, Codex, OpenCode, and Pi all speak to through the same MCP profile, in priority order of support. No host receives host-specific memory semantics.

Host lifecycle hooks make recall proactive: project memory is injected before the host processes a prompt. Capture is deterministic and conservative — only explicit decisions, constraints, facts, and a narrow allowlist of successful reusable commands are persisted. Full prompts, full responses, reasoning, tool output, and detected secrets are never stored automatically.

Agent Memory data flow Claude Code, Codex, OpenCode and Pi each connect through a lifecycle hook or MCP call into one local Hyphae directory, which holds three physically separated collections — personal, work, and journal — and commits a store as the search document, its doc-values, and its lifecycle envelope in one transaction under one commit sequence number. Claude Code Codex OpenCode Pi hook / MCP One local Hyphae directory personal collection work collection journal collection store: search document + doc-values + lifecycle envelope + TTL one transaction · one commit sequence number

Five verbs, three separated collections

The bounded MCP profile exposes five verbs. The write profile adds store, journal, and forget; the read profile exposes recall and status only:

hyphae_memory_store     (write profile)
hyphae_memory_journal   (write profile)
hyphae_memory_recall    (all profiles)
hyphae_memory_forget    (write profile)
hyphae_memory_status    (all profiles)
  • store(project, text, kind?, scope?, agent?, ttl?) — the memory id and its expiry, if any.
  • journal(project, text, harness, model, ttl?) — a first-person model journal entry, kept in the separate journal layer and always rendered as historical model thought, never as user instruction.
  • recall(project, query, limit?, kind?, layer?, prove?) — memories ordered by relevance; with prove, the response carries the sealed proof, witness, and anchor for offline verification.
  • forget(project, id) — permanent removal, idempotent.
  • status() — redacted counts and service health; never memory content, never credentials.

Personal, work, and journal memories are physically separate search collections under one exclusive Native directory at ~/.local/share/hyphae/agent-memory/. Work holds user/project decisions; journal holds a model's first-person reflection, kept apart so it is never mistaken for user instruction.

Project isolation, TTL, and conservative capture

A recall sees exactly the memories of the named project, plus _global memories, clearly labeled. Two projects never observe each other's memories through any tool surface. The project string is normalized (NFKC, case-preserved) and compared exactly, so basecamp/omarchy and Basecamp/Omarchy are different projects by design.

Every memory carries an optional ttl from 1 second to 10 years. Expiry is evaluated on the engine's clock: an expired memory never appears in a recall again, and its storage is reclaimed by maintenance — never a background guess.

Automatic capture is deliberately narrow: explicit decisions, constraints, facts, and a narrow allowlist of successful reusable commands only. Full prompts, full responses, reasoning, and tool output are never stored automatically.

PII and secrets fail closed

The proactive bridge rejects detected personally identifiable information — email addresses, phone numbers, postal-address labels, government identifiers, payment cards, IP/MAC addresses, UUIDs, home-directory paths, and likely high-entropy credentials — and rejects likely secrets the same way. Detection is fail-closed: a candidate that matches any sensitive-data rule is discarded rather than partially redacted. Project identifiers are stored as local keyed-purpose BLAKE3-derived names, never as repository URLs or filesystem paths.

The spool, and the one-transaction store

When the local daemon is temporarily unavailable, already-sanitized capture candidates enter an owner-only durable spool under $XDG_STATE_HOME/hyphae/agent-hooks/, content-identified and deduplicated across retries, and drained opportunistically once the daemon returns. A pending record is removed only after a durable acknowledgement.

A store commits the search document (text, doc-values, and any vector branches), the lifecycle envelope, and its TTL in one transaction, under a single commit sequence number — a crash or abort can never leave a searchable memory without its lifecycle record, or vice versa. When a transport cannot serve that explicit transaction within its step budget, the store falls back to a historical ingest-then-set sequence, and recall still gates every hit on the live lifecycle record.

Offline-verifiable recall proofs

A proved recall returns the engine's standard sealed proof, witness, and anchor material. A third party runs hyphae proof verify offline, with no directory access and no network call, and checks what was actually recalled.

Set it up

hyphae agent setup
hyphae agent configure opencode --access read --apply
hyphae agent status

Use claude, codex, opencode, or pi as the host. --apply also installs proactive lifecycle integration: Claude Code and Codex get command hooks, OpenCode gets a local plugin, and Pi gets a local extension. Writer access is explicit — the default reader credential cannot store, journal, forget, manage keys, administer backups, or execute arbitrary SQL. Existing 2.1.0 mixed collection data moves offline with hyphae agent migrate-domains.

To point an MCP client directly at the bundled memory profile instead of a host's own hook integration:

hyphae mcp --endpoint LOCAL_ENDPOINT --native-api-key-file RESTRICTED_PATH

Memory retrieval measurements

A pinned, digest-verified evaluation harness runs the LoCoMo and LongMemEval-S-cleaned retrieval protocols against a disposable Native directory over the local protocol. These are retrieval measurements, not generated answer accuracy, and are not directly comparable to published LLM-as-a-judge scores from systems that perform model-based extraction or answer generation. No model ran during retrieval.

BenchmarkDenominatorEvidence recall@10NDCG@10
LoCoMo evidence retrieval, nested leave-one-conversation-out1,982 queries / 10 conversations70.12%48.40%
Frozen LoCoMo lexical baseline1,982 queries / 10 conversations54.24%40.15%
LongMemEval-S-cleaned, user-evidence retrieval419 eligible / 500 questions89.26%87.75%

The selected LoCoMo candidate won all ten outer folds; its Evidence Recall@10 uplift over the frozen baseline was +15.88 percentage points question-micro (exact two-sided paired sign-flip p = 0.001953125, Holm-adjusted 0.033203125; bootstrap interval [12.72, 18.77] points). LongMemEval's Recall-any@10 was 96.66%, Recall-all@30 was 97.85%, and Recall-all@50 reached 100%, with all 419 rankings repeat-stable. Runs were offline, over the local protocol, on declared DigitalOcean compute hosts.

Source: README.md, “Memory retrieval measurements” and docs/product/agent-memory.md, “External retrieval evaluation”. Harness: tools/long_term_memory_benchmarks.py.

What Agent Memory is not

It is not "Hyphae as another database". The product is the five-verb memory experience working identically across agents from one hyphae agent setup, reversible without data loss, and verifiable without trust. The engine underneath is an implementation detail the user never has to administer. There is no automatic indexing of the home directory, no replacement for Obsidian, dotfiles, or host configuration, no cloud memory or hosted account, and no LLM inside Hyphae.

Source: docs/product/agent-memory.md — read the full product contract for the memory envelope schema, permission profile table, and storage/backup/restore commands.