{
  "markdown": "<p align=\"center\">\n  <img src=\"assets/logo.png\" alt=\"Engram logo\" width=\"120\" height=\"120\" />\n</p>\n\n<h1 align=\"center\">Engram</h1>\n\n<p align=\"center\"><b>The second brain your AI agents read and write.</b></p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/rwnalds/engram/blob/main/assets/demo.mp4\">\n    <img src=\"assets/demo.gif\" alt=\"Engram demo — a home dashboard with recent activity and a Claude Code agent querying the vault\" width=\"820\" />\n  </a>\n</p>\n\n<p align=\"center\"><sub><a href=\"https://github.com/rwnalds/engram/blob/main/assets/demo.mp4\">▶ Watch the full-length video</a> (real-time, full quality)</sub></p>\n\n<p align=\"center\">\n  <b><a href=\"https://engram-demo.up.railway.app\">↗ Try the live demo</a></b> — no signup. Search <code>retainer price</code> and watch the retired note get withheld.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://www.producthunt.com/products/engram-3?embed=true&amp;utm_source=badge-featured&amp;utm_medium=badge&amp;utm_campaign=badge-engram-4cb7e488-c380-4fa7-a2c7-0129b971c90e\" target=\"_blank\" rel=\"noopener noreferrer\"><img alt=\"Engram - Agent memory that knows what's still true | Product Hunt\" width=\"250\" height=\"54\" src=\"https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1202294&amp;theme=light&amp;t=1784627191540\"></a>\n</p>\n\n---\n\nEngram is a self-hosted **MCP server + dashboard** that gives Claude Code, Cursor, Hermes, and any\n[Model Context Protocol](https://modelcontextprotocol.io) agent **shared, long-term memory they read\n_and write_** — over a plain, **git-backed folder of markdown you own**. Built for the case a single\nagent's memory never hits: **a team running several agents against one brain.**\n\nAutonomous agents forget everything between sessions — and worse, they can't tell what they remember\nis _still true_. An agent pulls an old README, a retired price, an API doc you changed months ago, and\nquotes it with full confidence, because keyword and vector search both rank by resemblance, not truth.\nEngram makes **\"is this still true\"** a first-class, written property: mark a fact superseded or\nexpired and search **withholds it — and tells the agent what it skipped and why.** Per-agent read/write\ntokens and a git audit trail of who-wrote-what keep it sane when the writers are a fleet, not just you.\n\nUnlike a headless memory store, **you can watch it happen.** A fast dashboard lets you **search your\nbrain**, see exactly what every agent and teammate changed (with per-file **diffs**), **jump back** into\nrecent notes, and curate it all — while agents read and write the same vault over one MCP endpoint. No\ndatabase: your `.md` files are the source of truth, git is the durable store, and an in-memory index\npowers full-text search + a wikilink **knowledge graph**.\n\n[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/engram?referralCode=PEidIe&utm_medium=integration&utm_source=template&utm_campaign=generic)\n[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/rwnalds/engram)\n\n[![CI](https://github.com/rwnalds/engram/actions/workflows/ci.yml/badge.svg)](https://github.com/rwnalds/engram/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-black.svg)](./LICENSE)\n[![Docker](https://img.shields.io/badge/ghcr.io-engram-black?logo=docker&logoColor=white)](https://github.com/rwnalds/engram/pkgs/container/engram)\n\n> **Opinionated about _how_ it stores memory** — git-backed markdown, no database, agents write (not\n> just read), self-hosted. **Unopinionated about _what_ you keep in it** — any markdown vault, any folder\n> structure, any MCP client. Point it at a fresh repo or your existing **Obsidian vault**: no import\n> step, no lock-in.\n\n---\n\n**[What it's for](#what-its-for)** · **[How it compares](#how-it-compares)** · **[Features](#features)** ·\n**[Works with](#works-with)** · **[Quick start](#quick-start)** · **[MCP tools](#mcp-tools)** ·\n**[Deploy](#deploy)** · **[FAQ](#faq)** · **[Contributing](#contributing)**\n\n---\n\n## What it's for\n\n- **Shared memory for a team running multiple agents** — one vault, many agents reading and writing\n  concurrently, with per-agent read/write tokens and a git audit trail of who changed what.\n- **Memory that knows what's still true** — retire a price, a term, or a changed API doc and your agents\n  stop quoting it; they're told what they skipped and why. The failure a single agent's memory never fixes.\n- **Long-term memory for Claude Code** and other coding agents — stop re-explaining your project every session.\n- **A self-hosted, Obsidian-compatible second brain** exposed over MCP — your notes, your server, your git repo.\n- **Memory you can see, not a black box** — a dashboard to search, watch (with diffs), and curate what your agents remember.\n- **Markdown RAG without the vector database** — full-text search + a link graph over human-readable files.\n\n## How it compares\n\nMost agent memory is built to answer *\"what did I store about this?\"* Engram is built to answer\n*\"what is still true about this?\"* — a different question, and the one that bites when an agent\nquotes a price you retired months ago.\n\n| | **Engram** | Vector-store memory<br><sub>(mem0, Zep, …)</sub> | Markdown memory<br><sub>(Basic Memory, …)</sub> | Plain RAG over docs |\n|---|---|---|---|---|\n| **Storage** | markdown files, git is the database | embeddings in a vector DB | markdown files | embeddings in a vector DB |\n| **Ranking** | relevance **× authority** | similarity | relevance | similarity |\n| **Knows a fact is retired** | ✅ `superseded_by` + `valid_until`, enforced at search | — | — | — |\n| **Explains what it withheld** | ✅ `excluded[]` with a reason per note | — | — | — |\n| **Retire + replace atomically** | ✅ `brain_supersede`, one commit | — | — | — |\n| **Refuses contradicting writes** | ✅ at write time, not read time | — | — | n/a (read-only) |\n| **Audit trail** | ✅ git, per-write attribution, per-file diffs | varies | git, if you commit | — |\n| **Per-agent access control** | ✅ read / write token scopes | varies | — | — |\n| **Human UI** | ✅ dashboard, search, diffs, graph | varies | — | — |\n| **Runs on** | your box, one container | mostly hosted SaaS | your box | your box |\n\nThe row that matters is the third one. Similarity search cannot tell a contradiction from a\nduplicate — a retired price and a live one are textually identical, so the retired one often\n*outranks* the live one by being longer and more detailed. That can't be fixed at read time, which\nis why Engram writes the retirement down when it happens.\n\n<p align=\"center\">\n  <img src=\"assets/screenshot-note.png\" alt=\"Engram dashboard showing a note marked locked, superseding an earlier pricing note, with backlinks\" width=\"900\" />\n</p>\n\n<p align=\"center\"><sub>This exact pair ships in <code>sample-vault/</code>. Run <code>bun dev</code>, search <code>acme price</code>,\nand watch the retired note get withheld with a reason.</sub></p>\n\n<sub>Categories, not feature-by-feature audits of specific products, and accurate to the best of my\nknowledge as of July 2026. If something here misrepresents a tool you maintain, open a PR — I'll fix it.</sub>\n\n## Features\n\n- **MCP server** — 15 `brain_*` tools over one bearer-authenticated HTTP endpoint (`POST /api/mcp`,\n  streamable HTTP JSON-RPC). Connect any MCP client to a single URL. **Per-agent token scopes**:\n  a read-only token never even sees the write tools.\n- **Human dashboard** — a **search-first home**, file tree, note viewer with **Obsidian callouts,\n  wikilinks, and backlinks**, Preview / Edit / Split editor with autosave, ⌘K search + **in-page keyboard\n  navigation**, \"jump back in\" recents, and a **force-directed knowledge graph**.\n- **Authority-aware search** — ranking knows **relevance, not truth**, so a superseded note repeats your\n  query words as often as the live one. Every hit carries an **authority** (`authoritative` → `current`\n  → `provisional` → `superseded` → `archived`) derived from the note's folder and frontmatter — so your\n  agents quote the locked doc, not the dead one. Markdown RAG that won't hand back yesterday's answer.\n- **Temporal validity + explainable rejection** — mark a fact `superseded_by` another note or give it a\n  `valid_until` date, and search **withholds it by default** (even if it's `locked`) — then hands the\n  agent an `excluded` list of what it skipped, each with a reason (`\"expired 2026-06-01\"`). One atomic\n  **`brain_supersede`** retires the old fact and links the new one in a single commit, so add-and-retire\n  can't drift apart. This is the difference between an agent that *remembers* and one that knows what's\n  **still true**.\n- **Write-time contradiction guards** — authority ranking fixes *reading*; these stop the vault\n  accepting the contradiction in the first place. Engram refuses to create a second live note on a\n  subject a live note already covers (the `acme-pricing-2026.md`-beside-`acme-pricing.md` bug) and\n  points the agent at `brain_supersede` instead; refuses to overwrite a note the caller hasn't read;\n  and warns when a `status:` isn't a word the ranking model knows, so a typo can't silently strip a\n  note's authority.\n- **Audit trail + access control** — every write is attributed in **git** to the token or human that\n  made it, with expandable **per-file diffs** in the activity feed. Give an agent a **read-only token**\n  and it never even sees the write tools; a **write** token can create, edit, move, and archive.\n- **The Curator** *(optional)* — Engram's built-in **agent harness** over your vault. **Chat** with your\n  notes (grounded answers, wikilink citations). Or hand `brain_capture` a rough dump — a meeting note, a\n  voice transcript — and an **agentic loop searches what already exists, then files, merges, or archives**\n  and returns a manifest of what it touched. It reads before it overwrites and never deletes. Opus /\n  Sonnet / Haiku, your key.\n- **Markdown-native** — plain `.md` + YAML frontmatter + `[[wikilinks]]`. Drop in an existing\n  **Obsidian vault** and it just works.\n- **Git-backed** — optional auto commit + push of every change. Full history, no lock-in, your data\n  lives in **your** repo.\n- **No database** — files are the source of truth; an in-memory MiniSearch index + a ported wikilink\n  graph power search and backlinks. Nothing to provision.\n- **Multi-workspace** — connect multiple vault repos (URL + token or GitHub OAuth), rename, switch the\n  active one, or remove them — all from the UI.\n- **Self-hosted** — one Docker container. Railway / Render / Fly / any host with a volume.\n  **Not** serverless (it needs a persistent volume, a file watcher, and a long-running index).\n- **Team auth** — Google SSO + email allowlist for the dashboard; per-agent bearer tokens — or **OAuth\n  for Claude.ai custom connectors** — for MCP, created/revoked in the UI. Secrets encrypted at rest.\n- **Runtime config** — toggle git-sync and the Curator right from the home; manage commit author, keys,\n  and OAuth in **Settings** — no redeploy.\n\n## Works with\n\nAny client that speaks the **Model Context Protocol** — one endpoint, bearer-token auth. Most-used first:\n\n- **[Claude Code](https://claude.com/claude-code)** — Anthropic's agentic coding CLI\n- **Codex** — OpenAI's coding agent (CLI + IDE)\n- **Hermes** — always-on autonomous agent runtime\n- **openclaw** — open-source coding agent\n- **Cursor** — AI code editor\n- **Cline** — VS Code agent\n- **Windsurf** — agentic IDE\n- **Claude Desktop** — Anthropic's desktop app\n- …and any other MCP client — Continue, Goose, Zed, Amp, and the rest\n\nIf it speaks MCP, it can read and write Engram as shared memory.\n\n## Quick start\n\nWant to poke at it first? **[There's a live demo](https://engram-demo.up.railway.app)** — open,\nno signup, resets a few times a day. Break it all you like.\n\n```bash\nbun install\nbun dev            # http://localhost:3000 — runs against ./sample-vault\n```\n\nPoint it at your own vault:\n\n```bash\nVAULT_DIR=/path/to/your/obsidian-or-markdown/vault bun dev\n```\n\n### Two ways to run it\n\n- **Hosted mode (team):** the dashboard + HTTP MCP server above — self-host it once, many agents and\n  teammates connect over `POST /api/mcp`. This is the main mode.\n- **Local mode (stdio):** a plain stdio MCP server over a folder, no HTTP/auth/git — for a single\n  machine, Claude Desktop / Cursor, or a registry's Docker introspection:\n\n  ```bash\n  bun run mcp:stdio /path/to/your/vault      # defaults to ./sample-vault\n  ```\n\n  Same `brain_*` tools. Built from `Dockerfile.mcp`.\n\n**Each mode ships as its own image, and they are not interchangeable:**\n\n| Image | Mode | Use it for |\n|---|---|---|\n| `ghcr.io/rwnalds/engram-app` | HTTP — dashboard + `/api/mcp` | **Railway, Render, Fly, any host.** This is the one you deploy. |\n| `ghcr.io/rwnalds/engram` | stdio — JSON-RPC on stdin/stdout | Claude Desktop, Cursor, MCP registries. Never opens a port. |\n\nDeploying the stdio image as a web service is the one mistake worth calling out: it can only 502,\nbecause there is nothing listening. It now refuses to start on a PaaS and tells you this instead.\n\n## MCP tools\n\nAgents only ever see the active vault — no repo, workspace, or GitHub tools are exposed.\nA `read`-scope token sees only the read tools. `brain_capture` appears only when the Curator is `full`.\n\n| | Tools |\n|---|---|\n| **Read** | `brain_search` · `brain_read` · `brain_list` · `brain_recent` · `brain_tree` · `brain_backlinks` · `brain_graph` · `brain_schema` |\n| **Write** (needs a `write`-scope token) | `brain_write` · `brain_edit` · `brain_append` · `brain_move` · `brain_supersede` · `brain_create_folder` · `brain_delete` |\n\nConnect an agent (the dashboard → **Connect** page shows the exact command + token):\n\n```bash\nclaude mcp add --transport http engram https://<host>/api/mcp \\\n  --header \"Authorization: Bearer <token>\"\n```\n\n## Deploy\n\nRuns anywhere you can run a Docker container with a persistent volume — Railway, Render, Fly, or your\nown box. **Serverless (Vercel) won't work**: Engram holds a volume, a file watcher, and an in-memory\nindex that a serverless function can't keep alive.\n\n1. Deploy this repo (root `Dockerfile`), mount a volume at `/data`, set `ENGRAM_DATA_DIR=/data`.\n2. Connect your vault repo(s) **in the dashboard** (Workspaces) — by URL + token, or GitHub OAuth.\n3. Sign in with Google, create MCP tokens on the **Connect** page, point your agents at the URL.\n\nMost runtime config (git-sync, AI capture, GitHub OAuth, app name) is editable in the **Settings**\npage — only auth/infra bootstrap vars live on the host. Full setup: **[DEPLOY.md](./DEPLOY.md)**.\n\n- **Railway:** New Project → *Deploy from GitHub repo* → add a Volume at `/data`.\n- **Render:** one-click via the bundled `render.yaml` (Docker + a `/data` disk).\n\nDeploying from a prebuilt image instead of the repo? Use **`ghcr.io/rwnalds/engram-app:latest`** —\nnot `engram:latest`, which is the stdio server and cannot answer HTTP. Set the healthcheck to\n`/api/health`.\n\n## FAQ\n\n**How do I give Claude Code long-term memory?**\nDeploy Engram, connect a markdown vault, and `claude mcp add` the endpoint. The `brain_*` tools let\nClaude Code search, read, and write persistent notes across sessions.\n\n**Can multiple AI agents share one knowledge base?**\nYes. Every agent points at the same MCP URL and reads/writes the same active vault — that's the point.\nGive each agent its own bearer token, `read` or `write` — a read-only token can't mutate your notes.\n\n**How do I stop an agent from quoting outdated facts?**\nRetire the fact and search stops surfacing it. When a value changes, call **`brain_supersede(old, new)`** —\none atomic commit marks the old note `superseded_by` the new one, and it's **withheld from search by\ndefault** (even if it's `locked`). Or set **`valid_until: 2026-12-31`** on a note and it self-expires.\nRetired matches don't vanish silently: `brain_search` returns them in an **`excluded`** list with a\nreason (`\"expired 2026-06-01\"`), so the agent can say *what it ignored and why* instead of quoting it.\n\n**What stops an agent just adding a second, contradicting note?**\nEngram refuses the write. Told \"the price is now X\", an agent that can't overwrite a note it never\nread will happily *add* `acme-pricing-2026.md` next to `acme-pricing.md` — nothing is corrupted, and\nyou now have two live notes disagreeing about one number. That write is rejected with a pointer to\n`brain_supersede`, which retires the old note and adds the new one in a single commit. Pass\n`allow_conflict: true` when both notes genuinely belong.\n\n**How do I know what an agent changed?**\nEvery write is committed to git attributed to the token or human behind it, and the dashboard's\nactivity feed shows per-file diffs — a built-in audit trail for autonomous agents.\n\n**Does it work with my Obsidian vault?**\nYes. It reads plain markdown with frontmatter and `[[wikilinks]]`, and renders Obsidian-style callouts\nand backlinks. No import step.\n\n**Do I need a vector database?**\nNo. Engram uses full-text search (MiniSearch) plus a wikilink graph over human-readable markdown —\nno embeddings service, no vector store to run.\n\n**Can I chat with my notes?**\nYes — enable the optional **Curator**, a chat agent that searches and reads your vault to answer with\nwikilink citations (Opus / Sonnet / Haiku). It's read-only in chat, so it helps you think without\nchanging anything, and it runs on your own Anthropic key.\n\n**Can I see what my agents changed?**\nYes — the **Activity** view reads your vault's git history and shows every change (agents and teammates\nalike), expandable to per-file diffs. Since it's just git, you get the full audit trail for free.\n\n**Is my data locked in?**\nNo. It's just `.md` files in a git repo you own. Turn Engram off and you still have every note and its\nfull history.\n\n**Where does it run / is it self-hosted?**\nYou host it. One Docker container on Railway / Render / Fly / any VM with a volume. Your keys, your data.\n\n## Contributing\n\nIssues and PRs welcome — especially where the validity model breaks against a vault shaped\ndifferently from mine.\n\n- **[CONTRIBUTING.md](./CONTRIBUTING.md)** — setup, conventions, and the pre-PR checklist.\n- **[docs/curator.md](./docs/curator.md)** — how the optional Curator agent loop works.\n- **[SECURITY.md](./SECURITY.md)** — please report vulnerabilities privately, not as an issue.\n\n```bash\nbun install && bun dev\nbun test          # the ranking/authority suite, incl. the stale-truth fixtures\n```\n\nIf Engram is useful to you, **starring the repo** genuinely helps other people find it.\n\n## Stack\n\nNext.js 16 (App Router) · React 19 · TypeScript · Tailwind v4 · shadcn/ui · bun · MiniSearch ·\nd3-force · MCP SDK. **MIT licensed.**\n\n---\n\n<sub>**Keywords:** MCP server · Model Context Protocol · second brain for AI agents · agent memory ·\nlong-term memory for Claude Code · shared memory for AI agents · self-hosted knowledge base ·\nObsidian-compatible · markdown · knowledge graph · wikilinks · PKM · Zettelkasten · git-backed notes ·\nHermes agent memory · Cursor memory · RAG without a vector database · chat with your markdown notes ·\ngit-backed agent activity feed · audit trail for AI agents · authority-aware search · read-only vs\nwrite MCP tokens · agent access control · self-organizing notes · agentic note capture · AI that files\nyour notes · temporal validity · stale memory · agents quoting outdated facts · supersede · note expiry ·\nshared memory for a team of agents · Basic Memory alternative · mem0 alternative.</sub>\n",
  "bytes": 19573,
  "sha": "e85966aac91a4ff044fed3a708f5fa055fc4fb49e4684bad844044c7b7902274",
  "repo_slug": "rwnalds/engram",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_rwnalds_engram_c3d35416/readme"
}