GA

goldentrii/agentrecall-x

Developer tools
372 stars 58 forks Quality 85 Trend 33MIT

Correct your agent once. It remembers next session — and we measure whether it actually stopped.

Overview

Correct your agent once. It remembers next session — and we measure whether it actually stopped.

README

English · 中文

AgentRecall

Correct your agent once. It remembers next session — and we measure whether it actually stopped.

Local-first memory for AI agents, built around a corrections ledger and math you can audit. MCP · SDK · CLI · Skill.

claude mcp add --scope user agent-recall -- npx -y agent-recall-mcp

Contents

The problem

You tell your agent “don’t bump the version without asking.” It apologizes, fixes it, and the session ends. Next week a fresh session does it again — the correction lived in a chat log nobody reads.

AgentRecall turns that sentence into a structured, persistent rule, puts it in front of the next agent before it acts, and records whether the mistake came back.

── session 3 ─────────────────────────────────────────────
you   › no — never bump the version without asking me first
agent › remember(type: "correction")
        ✓ saved · severity p0 · applies_when: [release, npm]

── session 9 · new agent, no chat history ───────────────
session_start › project "my-app" · 1 critical correction
                watch_for: version bump → ask the owner first
you   › ship the fix
agent › Fix is merged. Want me to bump to 1.4.1, or leave the version?
        outcome recorded: heeded

Illustrative transcript.

What it does

AgentRecall is two things:

  1. A governed corrections ledger. Every correction (“not that version”, “put this section first”, “ask before you assume”) becomes a structured record — severity, evidence, applies_when, retraction, outcome — that persists across sessions, projects and agent restarts. Export format: corrections-export/v1, scrubbed on egress.
  2. A measurement instrument. Each correction accumulates retrieved_count, and every time the agent meets the same situation the outcome is logged as heeded or recurred. No public benchmark measures that step; we built the harness first and publish what it finds, including the unflattering numbers.

The session loop

flowchart LR
    A([session start]) --> B["/arstart · session_startload rules + context"]
    B --> C{work}
    C -->|need past knowledge| D["/arrecall · recall"]
    D --> C
    C -->|corrected| R["remembertype: correction"]
    R --> L[(correctionsledger)]
    C -->|risky action| K["check"]
    L -.-> K
    C --> E["/arsave · session_endjournal + compound"]
    E --> F([session end])
    L -. watch_for .-> B
    F -. every K sessions .-> G["/arreflectconsolidate"]
    G -.-> A
Command When What it does
/arstart First — every session OPEN. No args → status board across all projects → pick → load that project’s rooms, corrections and task recall. /arstart loads directly; /arstart bootstrap imports existing projects.
/arsave Last — every session SAVE. Journal + palace consolidation + awareness compounding. /arsave all merges every parallel session of the day.
/arrecall Mid-session SEARCH. Prior fixes, decisions, patterns for the current task.
/arreflect Every K sessions CONSOLIDATE. Confirm recurrences, cluster new error classes, propose rule re-abstractions (rule edits stay owner-gated).

Without /arstart, a fresh agent has zero orientation. Without /arsave, nothing compounds.

MCP tools

Five tools ship by default. Each description is written for the agent and says when to call it.

Tool Call it What it does
session_start First, before acting Loads corrections, insights and watch_for warnings for the project
remember The moment something is decided or corrected Saves one fact; auto-routes to journal / palace room / corrections / awareness
recall Whenever past context would help Ranked search across every store (RRF), with useful feedback that re-weights future ranking
check Before risky or irreversible actions Matches the plan against known corrections; returns verdict: "blocked" when one overrides it
session_end On save / exit Writes the journal, promotes insights, records trajectory, optionally opens/closes a pipeline phase

[!IMPORTANT] The Automaticity Law — why only 5. Memory only compounds if it fires without being asked. Across 44 projects and weeks of real use, the pull tools (recall, memory_query) saw zero organic calls — including from the agent that built them. Push channels (session_start, session_end, correction hooks) are what change behavior. Every extra default tool costs definition tokens every session for no return. (Self-measured on the owner’s store, 2026-06-12.)

So on Claude Code, wire the hooks — the loop then runs without agent discipline:

ar hook-start        SessionStart      load context, show watch_for warnings
ar hook-correction   UserPromptSubmit  capture corrections silently
ar hook-ambient      UserPromptSubmit  inject relevant memories (≥2-word overlap floor)
ar hook-save         UserPromptSubmit  "save"/"retain" → prompt session_end
ar hook-pretool      PreToolUse        warn on npm publish, git push, rm -rf, deploy, DROP TABLE
ar hook-end          SessionEnd        auto-save journal if not saved today
ar health            —                 recent hook failures (fail-loud)

The nature of memory — 5 layers

The cognitive-psychology taxonomy, mapped to plain files. Each layer forgets at a different speed, because human memory does.

# Layer Holds Path Forgets
1 Episodic What happened, per session journal/ fast — $S = 2$ days
2 Semantic Topic facts with [[wikilinks]]: architecture, goals, blockers palace/rooms/ barely — $S = 9999$ days, salience-ranked
3 Procedural IF-THEN production rules palace/skills/ by use
4 Narrative Phases: goal → what was hard → how solved → synthesis palace/pipeline/ never (history)
5 Correction Rules the agent must follow — severity, evidence, outcomes corrections/ never by time — only by retraction
+ Awareness Cross-project insights promoted from repeated corrections palace/awareness confirmation-weighted
~/.agent-recall/
├── projects//
│   ├── journal/            episodic — one entry per session
│   ├── corrections/        behavioral rules + outcome ledger
│   └── palace/
│       ├── rooms/          semantic
│       ├── skills/         procedural
│       ├── pipeline/       narrative
│       ├── identity.md
│       └── awareness       cross-project insights
├── dreams/                 nightly consolidation reports
├── dashboard.html          human-readable
└── dashboard.json          agent-readable snapshot

All layers share one naming grammar, so an agent can compose a retrieval path from intent. Older files keep working through a legacy_path view — no migration.

How memory compounds

flowchart LR
    C["correction(remember / hook)"] --> L[(ledger)]
    L --> S["session_startranked by severity,proof, recency"]
    S --> O{"same situationagain?"}
    O -->|heeded| P["proof_count +1stability × 1.3"]
    O -->|recurred| X["phantom→ /arreflectrewrites the rule"]
    P --> A["≥ 3 confirmations→ awareness(cross-project)"]
    X --> L

A correction gets stronger each time it is confirmed, weaker when it is marked unhelpful, and graduates to every project once it has been confirmed on three distinct (day, project) occasions. A rule that was saved but whose mistake came back is a phantom — the write cost was paid and behavior never changed — and gets re-written, not just re-saved.

The math

Most of the field ships “AI memory” as a black box. Every mechanism in AgentRecall is a formula you can read, with its constants in the source and an honest label:

Label Meaning
🟢 GROUNDED A published result restated exactly, or a constant tuned on real data with a reported metric
🟡 HAND-TUNED Principled functional form; constants chosen by judgment, not fit to recall outcomes
🔴 ASPIRATIONAL The claim is ahead of the math present — stated so, with the model that would close the gap

1 · Rank fusion — Reciprocal Rank Fusion 🟢

Palace, journal, insight and corrections each rank their own candidates; the lists are merged by rank, never by raw score, because the raw scores live on incomparable scales (Cormack, Clarke & Büttcher 2009 — the same $k$ Elasticsearch ships):

\mathrm{RRF}(d) \;=\; \sum_{\ell \,\in\, \text{lists}} \frac{w_\ell}{k + \mathrm{rank}_\ell(d)}, \qquad k = 60,\;\; w_\ell = 1

The optional semantic leg is just one more list with $w = 1.0$ — a weight measured, not chosen: 1.1 and 1.3 flooded the top-5.

[!NOTE] The math found a bug. Adjacent RRF ranks differ by only $\frac{1/(60+r)}{1/(61+r)} \approx 1.6\%$, so any post-fusion multiplier above ≈1.02 vaults an off-topic item over every on-topic one. The old ×3 / ×2 / ×1.3 “recent-item boost” did exactly that — top-5 filled with the last 72 h of diary lines. Removing it: 55.0% → 75.0% top-5 hit-rate on the golden set (twin-clone control, 2026-09-12).

2 · Forgetting — Ebbinghaus per source 🟢 form · 🟡 constants

R(t) = e^{-t/S}, \qquad S_{\text{journal}} = 2,\;\; S_{\text{knowledge}} = 180,\;\; S_{\text{palace}} = 9999 \text{ days}

3 · Spaced reinforcement — FSRS-lite 🟢 form · 🟡 constants

A two-component (stability, retrievability) simplification of FSRS-6 / SuperMemo — no difficulty term, because we never run review sessions:

R = e^{-\Delta t / S}, \qquad S_0 = 7\text{ d}, \qquad \underbrace{S' = 1.3\,S}_{\text{confirmed}}, \qquad \underbrace{S' = \max(1,\; 0.5\,S)}_{\text{marked wrong}}

Buckets: $R \ge 0.85$ hot · $\ge 0.6$ warm · $\ge 0.3$ cool · else archive candidate — surfaced on a dashboard, never auto-deleted.

4 · Salience — what a palace room is worth 🟡

\text{salience} = 0.30\,\text{recency} + 0.25\,\text{access} + 0.20\,\text{connections} + 0.15\,\text{urgency} + 0.10\,\text{importance}

with $\text{recency} = \max(0.05,\; \rho_c^{\,\text{days}})$, where the decay rate depends on category: goal $\rho = 0.99$ · architecture $0.98$ · decision / lesson $0.97$ · observation $0.95$ · blocker $0.90$. Self-reported importance is deliberately the weakest term — people mis-estimate it; what you actually use is the stronger signal.

5 · Learning from feedback — Beta–Bernoulli 🟢

Every recall result can be rated useful / not useful. The item’s score is multiplied by twice its Laplace-smoothed posterior mean (neutral = ×1.0; the only post-fusion score change on default paths):

\mathbb{E}[\theta] = \frac{\text{pos}+1}{\text{pos}+\text{neg}+2}, \qquad \text{multiplier} = 2\,\mathbb{E}[\theta] \in (0, 2)

6 · Association — ACT-R activation 🟡 (opt-in AGENT_RECALL_ACTIVATION=1)

Memories cited together become linked. The associative term of ACT-R’s declarative-memory equation (Anderson & Lebiere):

A_i = B_i + \sum_j W_j\, S_{ji}, \qquad S_{ji} = w_{ji}\, e^{-\Delta d / 30}, \qquad W_j = \tfrac{1}{|\text{context}|}

Re-rank: $\text{score}' = \text{score}\cdot\bigl(1 + 0.2\,\tfrac{x}{x+1}\bigr)$ — the $\tfrac{x}{x+1}$ squash keeps two incompatible scales from being summed, and is an exact no-op when there is no evidence.

7 · Paraphrase matching — set cosine 🟡 metric · 🟢 threshold

\cos(A,B) = \frac{|A \cap B|}{\sqrt{|A|\,|B|}}, \qquad \text{sim} = \max\bigl(\cos_{\text{concepts}},\; \cos_{\text{char-trigrams}}\bigr) \ge 0.20

Over stems + 13 hand-curated synonym groups (“publish / ship / release” collapse to one concept). It is fuzzy-lexical, not meaning. The 0.20 threshold is tuned by leave-one-out (predict-loo) as the highest-recall point that still holds 0% false positives.

8 · Promotion — admit, then vote 🟢

Nightly consolidation used to gate on $\tfrac{\text{obs}}{7}\times\text{recency} \ge 0.8$. At 2 AM the freshest journal is yesterday, so recency $\le 0.85$ and “3 observations in 7 days” scored $\tfrac{3}{7}\times 0.85 = 0.36$ — silently discarded for 22 nights, while uptime monitoring stayed green. The replacement separates admission from promotion:

\text{promote} \iff \#\{(\text{day},\,\text{project}) \text{ confirmations}\} \ge 3

and every night now writes a yield record, so a zero-output night is classified (empty-corpus · filtered · already-known · errored) instead of looking healthy.

9 · Measuring behavior change — heed rate + Wilson interval 🟢

\text{heed} = \frac{\text{heeded}}{\text{heeded} + \text{recurred}}, \qquad
\text{CI}_{95} = \frac{\hat p + \frac{z^2}{2n} \;\pm\; z\sqrt{\frac{\hat p(1-\hat p)}{n} + \frac{z^2}{4n^2}}}{1+\frac{z^2}{n}}, \quad z = 1.96

Small $n$ gets an honest, wide interval instead of a confident point. Events are tiered by evidence (heeded_verified · heeded_checkaction · heeded_default · recurred_verified · recurred_selfreport), and every KPI surface shows both tiers as a range — absence of evidence is not credited as “heeded.”

10 · Calibrated confidence 🟡

\text{conf} = \frac{\text{score}}{0.12}\;(\text{local RRF}) \;\;\big|\;\; \frac{\text{score}}{0.049}\;(\text{Supabase RRF}) \;\;\big|\;\; \cos\;(\text{vectors}) \;\;\longrightarrow\;\; \text{high} \ge .66,\; \text{med} \ge .40,\; \text{low} \ge .20

Open problem 🔴 — does redundancy reconstruct intent?

Today, accumulated corrections are clustering + decay + set-cosine: a tally, not a posterior. Calling that “intent reconstruction” would overstate it. The model that would earn the phrase treats each correction as a noisy sample of a latent preference $\theta$, with $x_i = \theta + \varepsilon_i,\; \varepsilon_i \sim \mathcal N(0, \sigma^2 I)$ and prior $\theta \sim \mathcal N(\mu_0, \tau^2 I)$:

\operatorname{Var}[\theta \mid x_{1..N}] = \Bigl(\frac{1}{\tau^2} + \frac{N}{\sigma^2}\Bigr)^{-1} = O\!\left(\frac{\sigma^2}{N}\right),
\qquad \mathrm{SNR}_N = \frac{\lVert \mu_N \rVert^2}{\operatorname{tr}\operatorname{Var}[\theta \mid x_{1..N}]}

Falsifiable claim: $\mathrm{SNR}_N$ rises monotonically for a consistent correction stream and stalls when corrections conflict. Want to build it? This is the most important open problem in the repo.

Full derivations, inputs, and every constant’s provenance: packages/core/src/MATH.md.

Measured, not promised

Agent-memory benchmarks test retrieval. None tests whether a correction changes what a fresh agent does. Here is what our own instrument says — including the parts that make us look bad.

Metric Value Source
🔁 Retrieval hit@5, golden fixture v1 (26 queries, hash-locked) 73.1% keyword [53.9, 86.3]80.8% + local embeddings [62.1, 91.5] npm run bench:golden
🔁 session_start context injected, median 244 tokens npm run bench:injection
🔁 session_start p95 warm / recall p95 97 ms / 209 ms npm run bench:latency
🔁 Correction-transfer fixture gate exact match npm run bench
🔒 Real corrections captured (dual-blind audit, n = 59) 35.3% [17.3, 58.7] UPDATE-LOG.md §M2
🔒 Heed rate, evidence-grounded 0 / 3 events scripts/eval/baselines/rmr-baseline-2026-07-03.json
🔒 Offline correction-transfer recall 0 / 4 [0, 49] scripts/eval/baselines/correction-transfer-real-2026-07-03.json
🔒 Golden eval on a lived-in store (keyword → embeddings) 75% → 90% fix7 report, 2026-09-12
🔒 session_start on a lived-in store 1,489 tokens · 363 ms p95 UPDATE-LOG.md §C2

🔁 regenerates from this repo · 🔒 self-measured on the owner’s private store, not reproducible here. Brackets are 95% intervals. The 80.8% embeddings leg is measured locally with the opt-in model (CI never downloads it, so no artifact is committed). Timings are machine-dependent; CI gates schema and determinism, never timing values.

Compared to other memory tools

Typical agent memory (Mem0, Zep/Graphiti, Letta, Supermemory) AgentRecall
Optimizes for Recalling facts Not repeating mistakes
Corrections Another memory row Governed ledger: severity, evidence, retraction, outcome
Measures Retrieval (LongMemEval, LoCoMo) Retrieval and behavior change across sessions
Storage Hosted service or DB Markdown on your disk; Supabase mirror optional
Ranking Usually opaque Every formula and constant labelled (see The math)
Per-session cost ~7k tokens/query (Mem0’s published figure) ~244 tokens at session_start (fixture)

Competitor figures are their own published numbers, not measured side by side. Landscape: docs/research/agent-memory-landscape-2026-07.md.

Install

MCP server — for agents

# Claude Code
claude mcp add --scope user agent-recall -- npx -y agent-recall-mcp

# Codex
codex mcp add agent-recall -- npx -y agent-recall-mcp
// Cursor — .cursor/mcp.json   ·   Windsurf — ~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }

// VS Code — .vscode/mcp.json
{ "servers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }

Skill — Claude Code

mkdir -p ~/.claude/skills/agent-recall
curl -o ~/.claude/skills/agent-recall/SKILL.md \
  https://raw.githubusercontent.com/Goldentrii/AgentRecall-X/main/SKILL.md

SDK — JS/TS apps

import { AgentRecall } from "agent-recall-sdk";

const memory = new AgentRecall({ project: "my-app" });
await memory.capture("What stack?", "Next.js + Postgres");
const ctx = await memory.recall("rate limiting");

Each instance gets its own isolated root (AsyncLocalStorage), so concurrent instances never share state.

CLI — terminal, CI, hooks

npx agent-recall-cli recall "rate limiting"
ar bootstrap            # scan git repos, Claude AutoMemory, CLAUDE.md files (read-only, secrets untouched)
ar bootstrap --import   # import what it found

Optional extras

Architecture

packages/
├── core/         storage, retrieval, math, tool logic     agent-recall-core
├── mcp-server/   thin MCP wrappers                        agent-recall-mcp
├── sdk/          programmatic API                         agent-recall-sdk
└── cli/          the `ar` command + hooks                 agent-recall-cli
flowchart LR
    Q[query] --> T[tokenize · stemsynonyms · IDF]
    T --> P[palace0.9 key + 0.1 salience]
    T --> J[journal0.5 recency + 0.5 exact]
    T --> I[insightsrelevance · exact · confirm]
    T --> K[correctionsexact · severity · proof]
    Q -. opt-in .-> V[local embeddingscosine top-8]
    P & J & I & K & V --> F["RRF  Σ w/(60+rank)"]
    F --> B["× Beta feedback"]
    B --> C[calibrated confidence]
    C --> R[results + alsoLinked]

All memory is local markdown. An optional Supabase mirror adds pgvector recall with the same RRF fusion; all-local stays the default. Writes go through a progress-aware file lock with NTFS-safe release; alignment and feedback logs are append-only NDJSON.

Platforms

Platform Mechanism Status
Claude Code MCP + skill + hooks Primary
Codex · Cursor · Windsurf · VS Code (Copilot) MCP Supported
Any JS/TS app agent-recall-sdk Supported
Terminal / CI ar Supported

CI runs build + regression + tests on ubuntu-latest and windows-latest.

Community

[!TIP] The 15-minute contribution that matters most. The field has vendor-selected positives and no external baselines for behavior change. Use AgentRecall for a week, then:

git clone https://github.com/Goldentrii/AgentRecall-X.git && cd AgentRecall-X
npm ci && npm run bench    # reads your local ~/.agent-recall corpus

Post the result in Discussions → Benchmark Numbers — a low score is a valid result. More in CONTRIBUTORS-WANTED.md.

Contributors

Thanks to @buer5, @lonelyhty and 雷昊 for the Windows portability work and fixes that shipped in 3.5.x.

Contributing

PRs welcome. Open an issue first for anything substantive — the design is opinionated and grounded in published research, and we want changes grounded the same way: a formula, a label, and a measurement.

License

MIT — see LICENSE.

View the full README on GitHub

Install

npx -y agent-recall-mcp
New to MCP? Start with the mcpskill.org guide →

Configuration

// Cursor — .cursor/mcp.json · Windsurf — ~/.codeium/windsurf/mcp_config.json { "mcpServers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } } // VS Code — .vscode/mcp.json { "servers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }