agent-memory
The agent-memory server provides a git-native, structured memory system for AI coding agents, storing and retrieving project knowledge as plain Markdown files. It exposes three tools:
memory.fetch_context– Retrieve a budgeted, ranked Markdown context pack from the project's memory files. Supports search queries (or an empty query for a bootstrap pack with current task state and conventions), scope filtering (paths or module names), character budget control, and archive exclusion. Returns per-file provenance, freshness, confidence, and suggested follow-up queries.memory.propose_update– Submit structured edits to memory files (e.g.,update_conventions,add_pitfall,record_decision,refresh_module,archive_stale). Proposals are validated, scanned for secrets/PII, and either applied immediately or staged for human review (with a TTL). Returns staging ID, routing reasoning, review command, and any violations.memory.status– A read-only diagnostic report covering file counts by category, index/current-state sizes, active git branch, pending staged proposals (with age, TTL, and drift detection), security posture (last secret scan, allowlisted regions), git integration flags, and orphaned branch-local files. Helps determine whether memory maintenance is needed before further updates.
agent-memory
Local, git-native project memory for AI coding agents. One MCP call in, structured memory updates out — current task state, decisions, conventions, pitfalls, per-module facts. Branch-aware. Secret-safe. Byte-preserving. No cloud, no vector DB — Markdown is the source of truth and git is the sync. Three MCP tools + a full CLI.
Why it's different: memory is plain Markdown committed to your repo, so
you can read and git diff it; durable changes stage for human review
(review --diff → apply) instead of landing silently; and secrets/PII are
scanned out before anything is written. See ROADMAP.md for
where this is headed (system-level / multi-repo memory).
Demo
An agent records a durable decision; it stages for review; you see the
exact diff, apply it, and a later fetch surfaces it — local,
git-native, reviewable, secret-safe. The clip is reproducible:
docs/demo/demo.sh is the runnable flow and
docs/demo/demo.tape renders the gif with
vhs — see docs/demo/.
Related MCP server: Locus
How it compares
Capability | AGENTS.md / CLAUDE.md | Vendor memory (e.g. Claude) | Vector / DB memory (mem0, Zep) | agent-memory |
Plain-text, git-versioned source of truth | ✓ flat file | ✗ vendor-managed | ✗ DB / cloud | ✓ Markdown in your repo |
Structured, section-level updates | ✗ | ✗ | ~ | ✓ |
Human review gate (see the diff first) | ✗ free edit | ✗ | ✗ | ✓ stage → |
Vendor-neutral (MCP — any agent) | ~ broad convention | ✗ one vendor | ~ varies | ✓ Claude · Cursor · Codex · Gemini |
Secret / PII scan on write | ✗ | ✗ | ~ varies | ✓ |
Team merge for concurrent edits | ✗ text conflicts | ✗ | ✗ | ✓ section merge driver |
Runs fully local (no cloud) | ✓ | ✗ | ~ varies | ✓ |
These are general characterizations and the tools evolve fast — see something
inaccurate? Open an issue and
I'll fix the row. agent-memory is complementary to instruction files like
AGENTS.md/CLAUDE.md (it even installs one): those say how to behave;
agent-memory is the durable, searchable, reviewed knowledge behind it.
Status
Release 0.5 — the federation release: a repo can now reference shared,
git-pinned, read-only "landscape" stores, so an agent designing a cross-service
feature sees the surrounding system map — blended into fetch_context with
per-store-fair ranking, provenance, and a trust boundary. Built behind an
opt-in invariant: with no stores declared, behaviour is byte-for-byte the
single-repo path.
Federation (PR1–PR6):
Store-format versioning — a
store_format_versionwith a fail-closed load guard, so a too-new store is never misread.Referenced stores — a manifest
storesblock + a committed, go.sum-stylemeta/stores.lockpinning each store to an exact commit.agent-memory sync— clone → validate → sandbox-copy (symlink-safe) → secret/PII scan → atomic swap into the gitignored cache.Store-keyed index — one FTS5 index holds local + every cached store (
SearchPerStore), migrated by rebuild-on-version-bump.Multi-store fetch — per-store-fair merge +
priority_multiplier+ cross-store dedup + provenance / trust-boundary rendering.Federation eval — a deterministic, CI-guarded multi-store retrieval eval (recall@5 with store-origin correctness; ranking + starvation guards).
It builds on 0.4 (the team-and-launch release: section-aware git merge driver, an offline retrieval-quality eval at recall@5 0.98, Apache-2.0 open-source packaging) and the unchanged Core Contract from v0.1.0 (MCP server, structured operations, drift-checked staging, secret scanning) — every release since has been additive. The behavioural eval harness remains the main deferred item — see ROADMAP.md.
See CHANGELOG.md for the full changelist.
Document | Purpose |
Where the project is going, principles, and non-goals. | |
Per-release feature list and known limitations. | |
Canonical design this binary implements. | |
Historical MVP build log (M0–M8); see ROADMAP for what's next. | |
Offline recall/MRR/nDCG benchmark of | |
Reusable design patterns documented per subsystem. | |
Pre-M1 spike outcomes (byte-preserving engine, MCP SDK, flock, FTS5). |
Quick start
Install — download a prebuilt binary (recommended): grab the archive
for your OS/arch from the latest release,
extract it, and put agent-memory on your PATH. No toolchain needed.
# npx (no Go, no manual download): fetches the verified release binary on
# first run and caches it — also usable straight from an MCP client config.
npx -y @xchucx/agent-memory --help
# Go toolchain alternative (Go 1.25+)
go install github.com/xChuCx/agent-memory/cmd/agent-memory@latest
# from source
go build -o agent-memory ./cmd/agent-memoryHomebrew, Scoop, and winget packages are planned. agent-memory is also listed on the MCP Registry.
Then, inside the repo you want to give a memory:
# Scaffold .agent-memory/ in a repo
agent-memory init --name my-project
# Install the Claude Code skill + register the project MCP server
# (writes .claude/skills/agent-memory/SKILL.md and merges .mcp.json)
agent-memory install claude
# Verify (prints the release tag, the go-install version, or dev+vcs locally)
agent-memory version
# Read context
agent-memory fetch # bootstrap pack
agent-memory fetch "auth" # FTS query
# Start MCP server (your agent spawns this automatically once configured)
agent-memory mcpinstall claude registers the MCP server for you: it merges a project-scoped
.mcp.json at the repo root that runs agent-memory mcp --root ${CLAUDE_PROJECT_DIR:-.}.
Claude Code expands CLAUDE_PROJECT_DIR to the repo at spawn, so the server
always serves this repo — the config is portable across clones and (by
Claude Code's scope precedence, local > project > user) overrides any stray
user-scoped server. Commit .mcp.json so your team shares it.
⚠️ Do not register a single user-scoped server with a hardcoded root (
claude mcp add -s user agent-memory -- agent-memory mcp --root /some/repo): it serves every project from that one repo, so memory you write in project B silently lands in project A. Per-project registration (whatinstallwrites) is the correct model;agent-memory doctorflags a mis-rooted registration.
The server resolves its repo from --root, then $CLAUDE_PROJECT_DIR, then the
working directory. Other runtimes (Cursor, Gemini CLI, anything reading
AGENTS.md) use the same server — install their adapter (see below).
Adopt on an existing project
init scaffolds empty memory. To seed it from a real codebase, let your
coding agent do the analysis — that's the whole point. After init +
install <adapter> + registering the MCP server (above), restart the
agent so the memory.* tools load, then paste the prompt below.
What happens: the agent reads the repo and calls memory.propose_update.
Working notes and pitfalls apply immediately; durable categories
(conventions, decisions, modules) stage for your review — inspect each
with agent-memory review --diff and land it with agent-memory apply
(or reject). Nothing durable is written without your approval.
You now have agent-memory MCP tools (memory.fetch_context,
memory.propose_update, memory.status) backed by this repository's
.agent-memory/ store. Bootstrap the project's memory from the codebase.
1. Call memory.fetch_context with an empty query to see the current
(mostly empty) state and the conventions/decisions/pitfalls/modules
layout.
2. Analyze THIS repository — read the build files, CI config, entry
points, and the main packages/modules. Identify:
- build / test / run / lint commands and the toolchain;
- conventions: code style, branching, commit rules, review practices;
- architecture: the major modules/components and what each is for;
- durable decisions: notable choices and WHY (only ones that are real
and stable — not speculation);
- pitfalls: footguns, sharp edges, "don't do X because Y" you can infer
from the code, tests, or docs.
3. Persist what you found via memory.propose_update, choosing the intent
per kind:
- update_conventions → conventions.md (build/test/style/workflow)
- refresh_module → modules/<name>.md (one per major component)
- record_decision → decisions.md (Date / Status / Confidence +
sources; type ∈ file|test|user, NOT external)
- add_pitfall → pitfalls.md
- update_shared → local/current.shared.md (a short "current
state / where things stand" summary)
Rules:
- Cite provenance: pass sources as file references you actually read
(e.g. {"type":"file","ref":"internal/auth/session.go"}). Use
confidence=confirmed for facts from code, inferred for deductions.
- Every section needs a unique "<!-- @id: ... -->" anchor; keep entries
concise — this is working knowledge, not a wiki. Decisions need
**Date**, **Status** (active|superseded|deprecated|proposed), and
**Confidence** fields.
- NEVER put secrets, tokens, or credentials in memory (the server will
reject them anyway).
- Work in a few focused passes (conventions + architecture first, then
modules, then decisions/pitfalls). Report what you proposed and what
staged for review.No MCP server handy? The agent (or you) can use the CLI instead — same validation/secret-scan/routing pipeline:
agent-memory propose --intent update_conventions --op append_section \
--path conventions.md --heading "Build & test" --heading-level 2 \
--source file:Makefile --confidence confirmed \
--content-file - <<'MD'
## Build & test
<!-- @id: build-test -->
Run `go build ./...` and `go test ./...`. ...
MD
# add --apply to land it immediately (you are the reviewer);
# or omit it and review the staged proposal with `review --diff` + `apply`.Build
Requires Go 1.25+ (the MCP SDK transitively requires it).
go build -o agent-memory ./cmd/agent-memory # binary
go test ./... # unit + integration tests
go test -tags=e2e ./internal/e2e/... # end-to-end smoke (linux/macos)
go test -race ./internal/... # race detectormake targets are equivalent to the go commands above; see the
Makefile if you prefer that style.
CLI
agent-memory init [--root DIR] [--name NAME] [--force]
# Create the .agent-memory/ scaffold.
agent-memory status [--root DIR] [--json]
# Project state: version, file counts per category, lock metadata.
agent-memory doctor [--root DIR]
# Diagnostic layout checks. Advisory; exits 0 even with findings.
agent-memory fetch [QUERY] [--scope X,Y] [--budget N]
[--exclude-archive] [--json] [--root DIR]
# Return a budgeted Markdown context pack.
agent-memory mcp [--root DIR]
# Start the MCP server (stdio). Exposes memory.fetch_context and
# memory.propose_update.
agent-memory propose --intent INTENT --op OP --path PATH [op flags...]
[--content STR | --content-file FILE|-] [--source type:ref]
[--confidence C] [--apply] [--from-json FILE|-] [--json]
# Create a proposal WITHOUT an MCP server, through the same
# validate / secret-scan / route pipeline. --from-json takes a full
# multi-op ProposeRequest; --apply immediately lands a result that
# would otherwise stage (you are the reviewer).
agent-memory review [STAGING_ID] [--diff] [--show] [--json] [--root DIR]
# List staged proposals or inspect one. --diff shows a unified diff
# of each staged file vs the current on-disk version.
agent-memory apply STAGING_ID [--json] [--root DIR]
# Re-validate drift and apply a staged proposal.
agent-memory reject STAGING_ID [--json] [--root DIR]
# Discard a staged proposal.
agent-memory rebase STAGING_ID [--force] [--json] [--root DIR]
# Re-plan a staged proposal against the current disk state
# after target_drift. --force is required for soft drifts
# (acknowledges accepting the new base as planning input).
# review / apply / reject / rebase accept a full STAGING_ID, any unique
# prefix (Git-style), or --latest for the most recently staged proposal:
# agent-memory apply 20260527 # unique prefix
# agent-memory apply --latest # newest staged proposal
agent-memory install <adapter> [--user-global] [--force] [--json]
# Materialise agent-runtime adapter assets.
# Supported: claude, cursor, agents, gemini.
agent-memory merge-driver --install [--root DIR]
# Register the section-aware git merge driver so a team's concurrent
# edits to .agent-memory/ files union by @id instead of conflicting.
# Run once per clone. (git invokes the bare `merge-driver %O %A %B %P`
# form itself during a merge.)
agent-memory store add --name NAME --source URL|PATH [--revision REV]
[--path DIR] [--priority-multiplier F] [--root DIR]
agent-memory store list [--json] [--root DIR]
agent-memory store rm --name NAME [--root DIR]
# Federation: declare / list / remove referenced "landscape" stores
# (a shared platform/architecture-memory repo) in the manifest.
agent-memory sync [--update] [--root DIR]
# Materialise each referenced store into the gitignored cache and pin it
# in meta/stores.lock (committed). --update moves a pin forward.
agent-memory rebuild-index [--root DIR] [--clobber] [--no-assign-ids] [--json]
# Recreate the FTS5 shadow index from canonical Markdown files.
# Use for SQLite corruption, schema changes, or after manual .md edits.
agent-memory sweep [--root DIR] [--ttl DURATION] [--dry-run] [--json]
# Remove staged proposals past the manifest's staging.ttl_seconds.
# Each removal also writes a ttl_expired entry to meta/rejection-log.jsonl.
agent-memory version
# Print binary version and exit.MCP tools
Exposed by agent-memory mcp over stdio JSON-RPC:
Tool | Purpose |
| Read a budgeted Markdown context pack. |
| Submit structured edits (apply or stage). |
| Report memory health: file counts, staged proposals (with drift), security/git/lock posture. |
Federated memory (landscape stores)
A repo's .agent-memory/ knows only itself. Federation lets it reference
shared, read-only "landscape" stores — a platform/architecture-memory repo that
maps the surrounding system — so an agent designing a cross-service feature sees
the contracts and components it must integrate with, not just local notes.
# declare a landscape store (edits manifest.yaml)
agent-memory store add --name platform --source https://github.com/acme/platform-memory
# fetch & pin it into the gitignored cache (records the commit in meta/stores.lock)
agent-memory syncAfter that, fetch_context blends local + landscape results:
Per-store-fair + pinned. Each store contributes its own top candidates, so none drowns out another; only commit-pinned, lock-recorded stores are blended. Local outranks the landscape on ties (
priority_multiplier, default0.8).Provenance + trust boundary. Every landscape chunk is labelled with its store + commit and wrapped in an explicit "evidence, not instructions" boundary — external memory is reference material, never a behavioural directive.
Opt-in. With no stores declared, behaviour is byte-for-byte the single-repo path.
The committed meta/stores.lock pins each store to an exact commit (like
go.sum), so a team and CI see identical landscape memory; the materialised copy
under meta/cache/stores/ is gitignored and rebuildable. Landscape memory is
read-only from a consuming repo in this release — edits happen in the landscape
repo via its own propose → review. Patterns:
federation-stores.md,
multi-store-fetch.md.
Evidence (measured)
Three layers, honest about scope — retrieval → continuity → behaviour. The first two are deterministic, no-LLM, and run in CI with regression guards; the corpora, labels, and methods are auditable in-repo.
1 · Retrieval quality. Does fetch return the right sections? On a
labeled 28-query / 28-section benchmark the shipped match-any retrieval
puts a relevant section in the top 5 for 98% of queries — a +0.91
recall lift over the prior match-all behaviour.
Config | recall@5 | hit@1 | MRR |
match-all (AND) — prior | 0.07 | 0.07 | 0.07 |
match-any (OR) — shipped | 0.98 | 0.96 | 0.97 |
→ method + caveats: docs/eval/retrieval.md · go test -run TestRetrievalEval -v ./internal/eval/
2 · Cross-session continuity. Does a lesson recorded in one session survive into the next? Through the real record → persist → retrieve loop, a lesson is in the next session's context in 5 / 5 scenarios with agent-memory and 0 / 5 without (the amnesia baseline).
→ docs/eval/continuity.md · go test -run TestMemoryContinuity -v ./internal/eval/
3 · Behavioural (task-success). Does the agent act on it — fewer repeated mistakes? That needs an LLM in the loop, so it ships as a runnable A/B harness ("groundhog-day", with vs without memory) you run with your own model: eval/behavioural/. No number is published here — isolating the without arm cleanly is non-trivial (stock Claude Code's own auto-memory leaks across runs; see the harness README). Not in CI by design.
Agent-runtime adapters
agent-memory install <adapter> drops a worked instruction file at the
location each runtime reads from:
Adapter | Target file | Notes |
|
| Claude Code skill format. |
|
| Cursor MDC rule with description-based matching. |
|
| Industry-broad convention. Read by OpenAI Codex CLI, Cursor's agent mode, Sourcegraph Cody, etc. Project-local only. |
|
| Gemini CLI long-term project context. Project-local only. |
Each file teaches the runtime when to call memory.fetch_context and
memory.propose_update, the intent vocabulary, provenance rules, and
debugging reject reasons. The same behavioural model across all four;
each adapter just wraps it in the runtime's native format.
Architecture (at a glance)
.agent-memory/
├── meta/
│ ├── manifest.yaml operational settings (budgets, approval, security)
│ ├── schema.yaml per-category file/glob, section schema, provenance
│ ├── index.sqlite FTS5 shadow index (regenerable)
│ ├── lock OS-level advisory lock (flock)
│ └── lock.info informational metadata sidecar
├── conventions.md project conventions
├── decisions.md durable architectural decisions
├── pitfalls.md known footguns
├── index.md server-managed memory index summary
├── modules/<name>.md per-module facts
├── archive/<date>-*.md write-once archived entries
├── local/
│ ├── current.shared.md cross-branch working notes
│ └── current.<branch>.md branch-scoped working notes
├── sessions/<YYYY-MM-DD>.md per-day session logs
└── staging/<id>/ pending human-review proposals
├── proposal.json
├── target-checksums.json
└── files/<rel-path>Layout
cmd/agent-memory/ CLI entry point
internal/
adapters/claude/ embedded SKILL.md + Install()
cli/ cobra subcommands
config/ schema/ YAML loaders (manifest + schema)
e2e/ release-0.1 smoke test (-tags=e2e)
fs/ atomic writes, path validation
git/ branch resolver
index/ FTS5 incremental index
lock/ flock-based advisory lock
markdown/ byte-preserving Markdown engine
mcp/ stdio MCP server
memory/ operations, security, orchestrator, staging
spikes/ pre-M1 spike investigations (S1-S4)
docs/
patterns/ design patterns
spikes/ spike outcome docs
.github/workflows/ci.yml CI: tests + e2e + lint
agent-memory-design-doc-v0.4.1.md canonical design
agent-memory-implementation-plan.md build plan
CHANGELOG.md per-release feature listReleases
Tag-driven via goreleaser. Pushing a v*
tag triggers
.github/workflows/release.yml,
which builds the binary matrix and publishes a GitHub Release with
archives attached.
Matrix per release:
linux_amd64,linux_arm64darwin_amd64,darwin_arm64windows_amd64,windows_arm64
Each archive contains the agent-memory binary, README.md, and
CHANGELOG.md. A sibling agent-memory_<version>_checksums.txt
provides SHA-256 hashes.
# Verify a downloaded archive
sha256sum -c agent-memory_0.2.0_checksums.txtLocal dry-run of the release pipeline (requires goreleaser
installed):
goreleaser check # parse + validate .goreleaser.yml
goreleaser release --snapshot --clean # full build with no uploadSource builds always identify as dev:
$ go build -o agent-memory ./cmd/agent-memory
$ ./agent-memory version
devRelease builds via goreleaser stamp the actual tag through
-ldflags='-X .../cli.ProgramVersion=v0.X.Y'.
License
Apache License 2.0. You may use, modify, and distribute this software under its terms; it includes an express patent grant. Contributions are accepted under the same license (see CONTRIBUTING.md).
Maintenance
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/xChuCx/agent-memory'
If you have feedback or need assistance with the MCP directory API, please join our Discord server