Memory that follows you.

mem stores what your AI agents learn — decisions, preferences, architecture, gotchas — as atomic facts, and injects the relevant ones into every new session, in any tool, for a few hundred tokens.

01What mem is

Every agent session starts from zero: the context you built up yesterday dies when the window closes. mem is the persistence layer underneath — a server (this one) that your tools write observations into and read ranked, task-relevant context out of.

  • Write path — you or an agent observe one-sentence facts. The server embeds them, detects duplicates and contradictions, and stores them.
  • Read path — a session asks for context for a task; mem returns the best handful of facts as plain prose, ready to inject. Never JSON, never metadata, ~15 tokens per fact.
  • Everywhere — the same memory serves Claude Code (via hooks), Claude Desktop and any MCP client (via /mcp), the CLI, and this web app.

mem runs no reasoning LLM. Distilling messy experience into atomic facts is the agent's job at write time; mem's job is embedding, ranking, storage, and honesty about what it knows.

02Core concepts

ConceptWhat it means
Memory (chunk)One atomic fact — a single self-contained sentence, stored verbatim with an embedding, confidence, staleness, and provenance. The unit of everything.
VaultThe isolation boundary. A scoped collection of memories owned by you or an org — a project, a team, a purpose. Nothing crosses vaults unless you arrange it.
KindEvery memory is episodic (what happened — fades in days), semantic (what is — the default), or procedural (how we do things — holds for months). Kinds set freshness decay and can bias retrieval.
TagsFirst-class labels ([backend], [infra]) that make memories filterable. The server suggests tags for new facts from their nearest tagged neighbours.
RemoteA named, tag-based view over a vault — "everything tagged #backend, nothing tagged #personal". Projects consume remotes, so one vault serves many scoped contexts.
Staged queueFacts waiting for commit. Local per machine (offline buffer) and server-side (shared across your devices). Nothing is embedded until commit.
Review inboxNew facts too similar to an existing one (possible contradictions) are stored but flagged, excluded from retrieval, and held here for a human verdict.
TokenThe credential. Full-account tokens are for your machines; vault-scoped tokens are for agents and can touch exactly one vault.

03Getting started

In this app

  • Create a vault (sidebar), add a memory in the Memories view, watch Review and Health as it grows.
  • Account → mint tokens for other machines and agents, set a password, manage server updates.

On a machine (CLI)

# once per machine
mem login --url https://mem.chrisgarlick.com --token mem_…

# once per project folder — creates .mem/ and installs Claude Code hooks
mem init
mem link my-project --create

# daily flow
mem observe "We deploy via signed release tarballs." --kind procedural --tag deploy
mem commit            # run staged facts through the pipeline
mem pull              # refresh the context cache for session injection
mem context --task "refactor the deploy script"

mem init wires two Claude Code hooks: SessionStart injects the cached context block at the top of every session, and Stop nudges the agent — once per session — to save durable lessons before finishing.

In Claude Desktop / any MCP client

Mint a vault-scoped token (Account → New token → pick the vault), then add https://mem.chrisgarlick.com/mcp with the token as a Bearer header. The agent gets mem_context, mem_observe, and mem_status.

04CLI reference

CommandDoes
mem login --url --tokenAuthenticate this machine (stored in ~/.mem/credentials, 0600).
mem initCreate .mem/ in the project + install the Claude Code hooks.
mem link <vault> [--create]Point this project at a vault (committed to git; holds no secrets).
mem observe "<fact>"Stage one atomic fact locally. --kind, --tag, --confidence.
mem statusLocal buffer + server queue counts.
mem stageUpload the local buffer to the server queue without committing.
mem commit / mem pushSync up, then commit the whole server queue — including facts staged from other devices.
mem pullRefresh the session-injection cache. --remote, --budget, --if-stale (ETag check).
mem context --task "…"Live retrieval. --kind-hint, --expand (graph neighbours), --budget, --remote.
mem search <query>Human-facing search: scored results with ids — the "why did the agent get told that?" tool.
mem exportWhole vault (or --remote view) as JSON or markdown. Zero lock-in; also the team-onboarding hand-off.
mem import --fileBring facts in from a JSON export or a plain text list; duplicates are absorbed.
mem remote create/ls/previewManage tag-rule views, with live token-count previews.
mem org …Orgs, members, roles, org vaults.

05How retrieval works

When a session asks for context, every stored fact competes:

  • Hybrid search — semantic similarity (embeddings) and keyword match (proper nouns like "BullMQ" that embeddings blur) run in parallel and are fused.
  • Composite ranking — relevance × confidence × freshness (per-kind half-life) × (1 − staleness), nudged by how often a fact has actually been used and by the query's kind hint.
  • Diversity — ten facts returned are ten different facts: near-paraphrases are dropped, not repeated.
  • Token budget — ask for budget=300 and the block fits it; the estimated spend is reported on every response.
  • Compression — facts sharing a subject merge on render: Kritano: uses BullMQ / targets UK SMEs.

Contradictions handle themselves: when a new fact lands very close to an old one, the old fact's staleness rises and it sinks in ranking — the vault heals toward current truth, and the flagged newcomer waits in Review for a human verdict.

06MCP tools

ToolParametersDoes
mem_contexttask, limit, budget, kind_hintRanked plain-prose context for the task. Call at the start of work.
mem_observeobservation, kind, tags, confidenceSave one atomic fact, verbatim. Distil before calling: one self-contained present-tense sentence.
mem_statusVault counts and health.

MCP tokens are vault-scoped: the tools operate on the token's vault automatically and can reach nothing else.

07HTTP API

Bearer-token auth on everything except /v1/health, /v1/login, /metrics, and these docs. Plain-prose endpoints return X-Mem-Tokens-Estimate.

EndpointDoes
POST /v1/loginEmail + password → a fresh session token.
GET /v1/me · POST /v1/passwordWho am I; set/replace password.
GET/POST /v1/tokens · DELETE /v1/tokens/{id}List, mint, revoke tokens.
GET/POST /v1/vaults · GET /v1/vaults/{slug}Vaults.
POST /v1/observeIngest one fact or a batch (observations: […], one embedding call).
GET /v1/context?vault&task&limit&budget&kind_hint&expand&remote → plain-prose block.
GET /v1/search?vault&q → scored JSON results.
GET /v1/vaults/{slug}/snapshotThe session-cache block; supports ETag / If-None-Match.
POST/GET /v1/staged · POST /v1/staged/commit · DELETE /v1/staged/{id}Server-side staging queue.
GET/POST…/chunks · PATCH/DELETE /v1/chunks/{id}Memories; updates use optimistic version locking.
GET /v1/chunks/{id}/history · POST …/rollbackFull version history; nothing is permanently lost.
POST /v1/chunks/{id}/resolveApprove a review-flagged memory back into retrieval.
GET …/tags · …/remotes · …/remotes/{r}/previewTags and remotes.
GET …/review · …/stats · …/log · …/graph · POST …/links/rebuildReview inbox, health, agent log, relationship graph.
POST/GET /v1/orgs …Orgs, members (owner/admin/member/viewer), org vaults.
/v1/admin/*Self-update: version, releases, upload, install, rollback (gated, see below).

08Security model

  • Tokens are the credential. The server stores only SHA-256 hashes — a token is shown once, at mint. Revocation is immediate (≤30s of cache).
  • Passwords are a door, not a key. Signing in with email + password just mints a session token. Forgot it? Log in with any account token and set a new one.
  • Agent tokens are confined. A vault-scoped token sees exactly one vault everywhere — API, app, MCP — and cannot mint tokens, manage orgs, or touch updates.
  • Rate limiting per caller; invalid tokens burn their own bucket.
  • No phoning home. The only outbound call is to the embedding provider you configured, with your key. Fonts, UI, docs — all served from the binary.
  • Releases are signed. Self-update refuses any artifact not Ed25519-signed by the operator's own key, which never leaves their machine.

09Self-hosting & updates

mem is one static binary (UI, docs, and migrations embedded) plus Postgres with pgvector. Full feature parity self-hosted, forever — no licence keys, no tiers.

  • Deploymake release builds a signed tarball; deploy/install.sh sets up the systemd service. mem-api doctor verifies the whole install in one command.
  • Update from this app — Account → Server updates: upload the tarball, click Install. The server verifies the signature, preflights the new binary against the real database, swaps, restarts (~4s), and can roll back with one click.
  • Operate/metrics for Prometheus; journalctl -u mem-api for logs; nightly pg_dump for backups.

For agents: a condensed, plain-markdown version of everything on this page lives at /docs.md, and a one-paragraph index at /llms.txt. Fetch those instead of parsing this HTML.