amem

Local Agent Memory Without Docker: amem + MCP (facts stay in ~/.amem)

Documentation

amem

Personal agent memory that stays on your machine.

Coding agents forget between sessions. They re-grep the same tree, re-learn the same constraints, and burn tokens rediscovering decisions you already paid for once.

amem gives Cursor, Claude Code, and other local hosts a private, searchable memory of durable facts about your repos — what owns what, which files matter, what broke last time — so the next session starts oriented instead of cold.

amem context "sync auth startup"
# Agent Memory Context

## Best Claims
### claim.sync_auth_mode_startup
Kind: `constraint`
Why: `keyword+8`, `fts+18.0`, `embed+6.3`, `kind:constraint`, `fresh`

The sync service checks auth mode during startup before enabling Drive sync.
Anchors: `src/background/sync-service.ts`

Nothing is uploaded. Nothing is written into your product git history. Memory lives under ~/.amem/ on your laptop only.


Why amem exists

Without amemWith amem
Agent explores broadly every sessionAgent queries memory first, then verifies the right files
Decisions live in chat scrollbackDecisions become structured claims with file anchors
Team sharing pressure on “AI context” docsExplicitly personal — your prompts and learnings stay local
Flat AGENTS.md that goes staleSmall graph: components → flows → claims, updated via proposals

amem is not shared company wikiware and not a cloud RAG product. It is a local tool for individual developers who want agents that remember their work.


Privacy (non-negotiable)

PieceLocationShared?
The amem tool (this repo)GitHub / npmYes — installable
Your memory database~/.amem/graph.db (or .enc when locked)No
Cursor project rule.cursor/rules/amem.mdc in the product repoSafe to commit — guidance only, no memory contents
Exports / backups you createWherever you write themKeep private — do not commit

Guarantees:

  • ~/.amem is created with mode 0700
  • Local UI binds to 127.0.0.1 only
  • No telemetry, no managed sync, no “share with org” mode
  • Agents are instructed to store repo facts, not proprietary prompting strategy
  • Optional AES-256-GCM lock and encrypted local backups — still no cloud

Requirements

  • Node.js 20+ (native better-sqlite3)
  • git (repo identity uses remote URL / root path)

Install the tool

npx @iamem/amem setup   # Node 20+ — installs the `amem` CLI
# or
npm i -g @iamem/amem && amem setup

From a clone while developing:

git clone https://github.com/sslugic/amem.git
cd amem
npm install
npm link
amem setup

See docs/npm-release.md. CI runs npm test and npm run pack:check. better-sqlite3 uses its own prebuilds — no extra native step on common macOS/Linux + Node 20/22.

If npm install fails compiling native code, install Xcode CLT (macOS) or build-essential (Linux) and retry, or use a Node 20/22 official binary that matches the prebuild matrix.

Quick paths

# Cursor or Claude Code in a git repo
amem init --platform cursor    # or: claude

# Other hosts (thin installers, same local DB)
amem init --platform windsurf|continue|aider|zed

# Cross-repo “how I work” prefs (blended into project context)
amem init --personal
# or: amem setup --personal

Encrypt-at-rest + local backups

amem lock --passphrase '…'       # or AMEM_PASSPHRASE
amem unlock --passphrase '…'
amem backup --passphrase '…'     # ~/.amem/backups by default
amem backup schedule             # daily local timer (no cloud)
amem backup unschedule

While locked, set AMEM_PASSPHRASE (or unlock) before any command that opens the DB.

License SKU + local embeddings

Free includes the hashing embedder (no download). Pro/IT can switch to a local n-gram model or an external local command (stdin text → JSON vector). Still no cloud embed API.

amem license apply --file ~/Downloads/amem-license.json   # after checkout on getamem.com
amem embed use ngram
amem embed reindex
amem restore --file ~/.amem/backups/amem-….db.enc
amem hygiene
amem rules sync
amem it-pack --out ~/.amem/it-pack
amem doctor --attest                     # IT tier adds a vault/host SKU packet

See docs/license.md. Only vendor-signed license files unlock Pro/IT (verified offline). Nothing is uploaded.

Checkout + email delivery is a separate seller process (npm run shop) that is not published with the CLI. It can whitelist Mailtrap and Stripe names from another project’s .env — see shop/README.md.


First-time setup (recommended)

amem ui

That opens http://127.0.0.1:7843 on the Setup tab. It scans your home folder for git repos (skips Library, node_modules, Downloads, and similar noise). Check the ones you want, pick clients (Cursor, Claude Code, Windsurf, Continue, Aider, Zed, …), then Start tracking selected. Each pick is bound in ~/.amem and gets the matching installer when available.

The header has a Personal switcher (cross-repo prefs) and Lock / backup chrome — lock status, last backup, and a daily local schedule. Memory shows the same lock/backup chips. The Setup tab includes a copyable remember contract for any MCP host (amem recipe).

Optional: check Start amem ui when this computer logs in so the localhost server comes back after a reboot:

amem service install    # macOS LaunchAgent, Linux systemd --user, or Windows Startup
amem service status
amem service uninstall

Tabs after setup:

  1. Setup — scan/select repos, platforms, login auto-start, bootstrap proposal
  2. Memory — facts by file, scored drafts (approve / replace older / dismiss / reject noisy), edit/pin/delete, search, recent hits/misses
  3. Stats — estimated tokens saved per LLM, plus JSON / markdown / PDF export (proxies, not a bill)

Server-only (no browser open):

amem ui --port 7843 --no-open

To scan extra folders (or only a subset), set AMEM_SCAN_ROOTS to a colon-separated list of directories.

CLI alternative (no UI)

cd ~/path/to/your-real-project
amem init --platform cursor    # or: --platform claude
amem doctor
amem status

To wire both agents to the same local memory, run init once per platform (or select both in the UI).


Day-to-day loop

1. Query before exploring

amem context "billing webhook retry"

Or let the agent do it — Cursor gets an always-on project rule; Claude gets hook guidance. Both install the skills:

  • amem-bootstrap — seed baseline memory
  • amem-update-working-memory — save durable learnings after a session

Hooks also inject context on session start / prompt submit, store conversation notes, queue session-end drafts, and can queue miss→learn drafts after empty context lookups when the agent later cites real files. Approve drafts in Memory (or allow low-risk kinds via policy auto_apply_kinds).

2. Work as usual

Treat memory as a map, not source of truth. Read the anchored files before you change them. Prefer claims marked fresh; verify stale ones (anchored files changed after the claim).

3. Save what should survive

Ask the agent to run amem-update-working-memory, approve Memory drafts, or apply a proposal yourself:

amem propose validate /tmp/memory.json
amem propose diff /tmp/memory.json
amem propose apply /tmp/memory.json

4. Optional agent one-shot install

From inside the product repo, paste docs/agent-install-prompt.md into Cursor or Claude Code and let it run setup for you.


What gets stored

Memory is a small local graph in SQLite:

ObjectMeaning
ComponentA subsystem / module (component.api)
FlowHow work moves (flow.checkout)
ClaimA durable fact with file anchors (may be active or superseded; optional pin)
EdgeLinks (claim → flow → component); kind: "supersedes" archives the target claim
DraftPending session / miss→learn proposals waiting for Memory approve
Usage eventEach amem context hit + token estimate

Claims are the retrieval unit. Ranking combines:

  • SQLite FTS5 (Porter stemming) + keyword score
  • On-device hashing embeddings (no model download)
  • Pin boost, kind weights (constraint / gotcha > session), freshness
  • Optional personal prefs claims blended into project context

Each injected claim includes a Why: line. Stale claims (anchors changed after updated_at) are down-ranked.

Example claim:

{
  "id": "claim.webhook_idempotency",
  "kind": "constraint",
  "text": "Stripe webhooks must be idempotent on event.id before mutating invoices.",
  "code_anchors": ["src/webhooks/stripe.ts"],
  "supersedes": ["claim.webhook_old_rule"]
}

supersedes (or an edge with kind: "supersedes") marks older claim ids as archived so they leave retrieval.


Token savings (estimates)

Every amem context logs a usage event. The UI Stats tab breaks this down by platform (cursor, claude, …).

Automatic estimate:

estimated_avoided = max(0, anchors×4000 + claims×200 − packet_tokens)

This is a proxy for exploration avoided — not your Cursor/Anthropic bill. Money uses the same token proxy at $3 per 1M input tokens (Sonnet-class input). Cursor included usage and output tokens are not billed this way, so treat $ as an order-of-magnitude estimate.

Time saved is a separate proxy: each returned file anchor is treated as ~1.2s of tool round-trip the agent did not have to make. Local lookup duration is measured (SQLite on localhost). Hit rate is keyword matches on amem context — not Cursor/model API calls (those still happen). A miss means no stored fact matched the query; newest facts may still be injected as a weak fallback, and the agent still talks to the model.

Stats also shows a monthly projection: last 7 days of calls (or fewer if you just started), scaled to 30 days. Still a proxy, not a bill.

If you later know a better number:

amem usage report --platform cursor --saved 12000
# or attach to a specific event:
amem usage report --event-id usage_… --saved 12000

LLM clients (beyond git repos)

amem can bind a named workspace that is not a git checkout — for Luna Client or any tool that talks to Cursor/Claude/other models.

amem init --workspace my-app
# seeds starter facts and runs a context check automatically

Attach any LLM client yourself (HTTP or MCP). Keep amem ui running for HTTP. From the client, before each model call:

const res = await fetch("http://127.0.0.1:7843/api/context", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    workspace: "my-app",
    query: userMessage,
    platform: "app",
    sessionId,
  }),
});
const { markdown } = await res.json();
// prepend markdown to the prompt / tool result so the model skips a large retrieve

After a durable outcome:

await fetch("http://127.0.0.1:7843/api/remember", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    workspace: "my-app",
    text: takeaway,
    kind: "session",
    anchors: ["my-app"],
  }),
});

MCP config (any MCP host):

Keep amem ui running (or amem service install so it starts at login). GUI apps often cannot find amem on PATH, which shows up as “live tool discovery failed” / MCP error — not a sign-in prompt. Prefer HTTP:

{
  "mcpServers": {
    "amem": {
      "url": "http://127.0.0.1:7843/mcp?workspace=my-app"
    }
  }
}

Stdio also works if the host can spawn the binary. Print a config with absolute paths:

amem mcp --print-config --workspace my-app

Same localhost DB as git-repo memory. The UI switcher groups Git repos and Workspaces. Rename a workspace's display name anytime — the MCP slug (workspace=luna-ai) and stored claims stay on the same id.

amem rename "Luna Client" --workspace luna-ai

MCP tools (stdio or HTTP):

ToolWhen to use
amem_contextRanked memory packet for the current question
amem_rememberStore a durable fact after an outcome
amem_recipeGeneric read-then-write contract (any MCP host)
amem_reposWhat is monitored (git repos + named workspaces)
amem_statsLookup time, estimated tokens/ms saved, hit rate
amem_graphClaims / components / flows stored for a workspace or repo
amem_statusBinding + counts; omit workspace for a machine-wide overview

Command reference

amem setup [--personal] [--platform <host>]
amem init --platform cursor|claude|windsurf|continue|aider|zed
amem init --workspace <name> [--path <dir>] [--platform …]
amem init --personal
amem rename "<display name>" --workspace <slug>
amem status [--workspace <name>]
amem doctor [--attest] [--json]
amem context "<query>" [--workspace <name>] [--platform …]
amem remember "<text>" [--workspace <name>] [--kind …] [--anchor <path>]
amem recipe [--json]
amem mcp [--print-config] [--workspace <name>]
amem propose validate|diff|apply <file.json>
amem export [--out <file.json>]
amem wipe --yes
amem wipe --all --yes
amem lock|unlock --passphrase <secret>
amem backup [--out <dir>] [--passphrase <secret>] [--label <name>]
amem backup schedule [--out <dir>] [--hour <0-23>]
amem backup unschedule
amem session touch --platform cursor|claude [--session-id <id>]
amem hook
amem usage report --saved <n> [--platform …] [--event-id …]
amem usage export [--format json|md|pdf] [--days 30] [--scope current|all] [--out <file>]
amem license status|apply|activate|clear|issue|keys
amem embed status|use hash|use ngram|reindex
amem ui [--port 7843] [--no-open]
amem service install|uninstall|status
CommandPurpose
setupOne-shot personal workspace + optional host install
initBind a git repo, named workspace, personal prefs, or host
renameChange a workspace display name; MCP slug and memory stay bound
contextRetrieve a Markdown packet; log usage
rememberStore one local fact
mcpStdio MCP tools; HTTP MCP at http://127.0.0.1:7843/mcp while UI runs
propose diffPreview claim/component/flow changes before apply
propose applyUpsert structured memory locally
lock / unlockOptional AES-256-GCM encrypt-at-rest for graph.db
backupLocal snapshot (optionally encrypted); schedule for daily timer
uiSetup wizard + Memory + Stats on localhost
serviceLogin item so amem ui starts after reboot
doctor --attestPrivacy/policy attestation for IT tickets
export / wipePersonal backup or delete (still local)
wipe --all --yesOffboard: wipe every repo and remove ~/.amem

What install puts where

Cursor

ArtifactPath
Skills~/.cursor/skills/amem-*
Project rule.cursor/rules/amem.mdc (in the product repo)
Hooks~/.cursor/hooks.json

Reload Cursor if skills/rules do not appear immediately.

Claude Code

ArtifactPath
Skills~/.claude/skills/amem-*
Hooks~/.claude/settings.json (UserPromptSubmit / Stop / related → full amem hook)

Other hosts

HostWhat amem writes
Windsurf~/.codeium/windsurf/mcp_config.json MCP entry
Continue~/.continue/config.json MCP servers
Aider.aider.amem.md CLI hints in the repo
Zedsettings.json context_servers / HTTP hint

Develop amem itself

cd amem
npm install
npm run build
npm run test          # unit + integration + CLI e2e (node:test)
npm run smoke         # end-to-end CLI/API smoke
npm run test:all      # both
npm link

Layout:

src/           CLI, SQLite, policy, attest, installers, localhost API
ui-static/     Setup / Memory / Stats UI
skills/        Agent skill markdown
templates/     Cursor rule + example enterprise policy
docs/          Agent install prompt + IT endpoint runbook + backlog
test/          Comprehensive node:test suite
scripts/       Smoke tests + MDM offboard helper

Override the memory home for tests:

AMEM_HOME=/tmp/amem-test amem status

Enterprise endpoint (IT-managed)

amem is still personal memory on the laptop — not a shared wiki or cloud RAG.
IT / DevEx can govern the fleet: approved install, policy, attestation, offboarding.

ControlMechanism
Policy/etc/amem/policy.toml (system) overrides ~/.amem/policy.toml; or AMEM_POLICY_PATH
Attestationamem doctor --attest / --json (also GET /api/attest on local UI)
Secret hygieneBuiltin deny patterns + policy deny_claim_patterns on propose
Export lockallow_export = false
Platform / repo allowlistsallowed_platforms, allowed_remote_hosts
Auto-apply draftsauto_apply_kinds (empty = never; still local)
Offboardingamem wipe --all --yes or scripts/mdm-offboard.sh

Hard guarantees (not configurable away):

  • No telemetry
  • UI binds to loopback only (127.0.0.1)
  • Memory stays under ~/.amem (mode 0700)

IT quick start

# 1) Pin / install amem on the endpoint (internal npm, pkg, or npm link)
# 2) Deploy policy (root-owned on managed machines)
sudo mkdir -p /etc/amem
sudo cp templates/policy.example.toml /etc/amem/policy.toml

# 3) Verify for security review
amem doctor --attest --json

# 4) On offboard / laptop return
amem wipe --all --yes
# or: scripts/mdm-offboard.sh

Example policy: templates/policy.example.toml
Full IT runbook: docs/enterprise-endpoint.md

Suggested rollout: small DevEx pilot → MDM package + policy → signed builds/SBOM if procurement asks. Shared org memory is intentionally out of scope.


Non-goals

  • Company-shared or synced memory
  • Cloud hosted “team brain”
  • Exact provider billing integration
  • Cloud/remote embedding APIs (local FTS5 + on-device hashing embeddings only)
  • Writing memory contents into product git history

Upcoming ideas (not scheduled): see docs/backlog.md.


License

MIT — see LICENSE.