{
  "markdown": "<p align=\"center\"><img src=\"assets/norn-logo.png\" alt=\"Norn\" width=\"140\" /></p>\n\n# Norn\n\nPersistent, visible memory for AI coding agents.\n\n**[Live site](https://norn-web-three.vercel.app)** · [Releases](https://github.com/samad001z/Norn/releases) · [Quickstart](#quickstart) · [Connect your AI tool](docs/connecting.md)\n\n![The Norn dashboard: browse memories by project, search them live, and forget any one with a moment to undo](assets/demo.gif)\n\nYour AI forgets you every session. Norn is a local MCP server that remembers your\ndecisions, preferences, and project context across every session and project, for\nClaude Code, Cursor, and any MCP client. Unlike most memory tools it is fully local\nand fully inspectable: a dashboard lets you see exactly what it stored and forget\nanything you do not want.\n\n## Quickstart\n\n**What you need:** just **Node.js 20 or newer** — you don't install Norn separately,\nthe command below fetches it automatically. Check with `node --version`; if it's\nmissing or below v20, grab the LTS from [nodejs.org](https://nodejs.org).\n\n**Connect to Claude Code** — one command, no clone:\n\n```bash\nclaude mcp add norn -- npx -y @samad001z/norn-server\n```\n\n**Or use the CLI in your terminal** — run it on demand, or install the `norn` command:\n\n```bash\nnpx @samad001z/norn-core list           # no install — npx fetches it each time\nnpm install -g @samad001z/norn-core     # or put the `norn` command on your PATH\n```\n\n**Any other MCP client** — add this to its MCP config:\n\n```json\n{\n  \"mcpServers\": {\n    \"norn\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@samad001z/norn-server\"]\n    }\n  }\n}\n```\n\nRestart your tool. Norn registers four tools: `remember`, `recall`, `forget`, `list`.\n\n> **Optional — flag possible conflicts:** add `\"env\": { \"NORN_DETECT_CONFLICTS\": \"1\" }`\n> to the config above and Norn will surface memories that might disagree, for you to\n> resolve in the dashboard. Off by default; it downloads a small extra model the first\n> time it finds a candidate, and it never changes your store on its own.\n\n> **Not sure where that config goes?** The **[Connect Norn to your AI tool](docs/connecting.md)**\n> guide has exact, copy-paste setup for Claude Desktop, Cursor, Windsurf,\n> VS Code + GitHub Copilot, and Gemini CLI — plus a beginner \"what you need\" and\n> troubleshooting. (VS Code + Copilot uses a `servers` key instead of `mcpServers`.)\n\n**Verify it's connected:** tell your assistant *\"Remember that I prefer pnpm over\nnpm,\"* then in a new chat ask *\"What package manager do I prefer?\"* — it should answer\n**pnpm** by calling Norn's `recall` tool.\n\n> The first `remember` or `recall` downloads a local embedding model\n> (all-MiniLM-L6-v2, ~25 MB) once, then runs fully offline.\n\n<details>\n<summary>Or run from source</summary>\n\n```bash\ngit clone https://github.com/samad001z/Norn.git\ncd Norn\nnpm install\nnpm run build -w @samad001z/norn-core && npm run build -w @samad001z/norn-server\nclaude mcp add norn -- node \"$(pwd)/server/dist/index.js\"\n```\n\n</details>\n\n## See it work\n\nMemory survives across sessions, and recall is semantic: it matches meaning, not\nkeywords.\n\n**Session 1**\n\n> You: Remember that we deploy to production from the main branch on Vercel.\n>\n> Claude calls `remember(\"deploy to production from the main branch on Vercel\", project: \"acme\")`\n\n**Session 2, the next day, in a fresh context window**\n\n> You: How do we ship to prod?\n>\n> Claude calls `recall(\"how do we ship to prod\")`\n>\n> Norn returns \"Deploy to production from the main branch on Vercel.\" even though the\n> query shares no keywords with the stored note.\n\n## Using memory: it's explicit, not automatic\n\nNorn does **not** record your sessions. It is a memory store, not a logger — it never\nsilently captures your prompts, code edits, or terminal commands. A memory exists only\nwhen the agent calls `remember()`, which happens in two ways:\n\n- **You ask for it.** *\"Remember that we deploy from `main` on Vercel.\"* The agent calls\n  `remember(...)` and the note is saved.\n- **The agent chooses to**, when it judges a fact worth keeping for next session — a\n  decision, a preference, a constraint.\n\nThat is the point: **you decide what's kept**, so the store stays signal, not noise. The\nflip side is that **if you never ask, nothing is saved** — so a sparse dashboard after a\nlong working session is expected, not a bug. The work itself lives in git; Norn is for the\ndurable facts you want recalled later.\n\nA few habits that make it pay off:\n\n- End a task with **\"remember the key decisions from this\"** and the agent writes them down.\n- Front-load context once — **\"remember my stack and conventions\"** — instead of\n  re-pasting it every session.\n- Ask **\"what do you remember about X?\"** to make the agent call `recall()` on demand.\n\nEverything saved this way shows up in the dashboard, and you can forget any of it.\n\n## How it works\n\nThree local pieces share one local database:\n\n```\nClaude Code / Cursor  ──MCP (stdio)──►  Norn MCP server  ┐\n                                                          ├──►  ~/.norn/norn.db\n        Dashboard (Next.js)  ────────────────────────────┘     (SQLite + sqlite-vec)\n```\n\n- **MCP server** (`/server`): exposes `remember`, `recall`, `forget`, `list` over stdio.\n- **Store** (`/core`): SQLite + sqlite-vec, with embeddings from a local MiniLM model\n  (no API key). `recall` blends semantic similarity with recency and trims results to a\n  token budget; `remember` dedupes near-identical notes.\n- **Dashboard** (`/web`): a Next.js app to browse and manage everything.\n\nAll three resolve to the same store, so a memory written by your agent appears in the\ndashboard, and a memory you forget in the dashboard is gone for the agent too. The store\nis chosen in this order:\n\n1. `NORN_DB_PATH`, if set — an explicit override always wins.\n2. The nearest **project-local** `.norn/norn.db`, walking up from the working directory\n   (see [Per-project memory](#per-project-memory)).\n3. The global `~/.norn/norn.db`.\n\nWith no project store and no override, this is the original behavior: one global\n`~/.norn/norn.db`.\n\n## Per-project memory\n\nGive a repo its own memory that ships with it. From the project root:\n\n```bash\nnpx @samad001z/norn-core init   # or: norn init\n```\n\nThis creates a `.norn/` directory holding that project's `norn.db`. Because each project\nhas its own database file, **memories never bleed across projects**: an agent working in\none repo only sees that repo's memory.\n\n### How a project is detected\n\nNorn finds your project the way git does — by walking **up** from the working directory\nto the nearest ancestor that contains a `.norn/` directory. Run your agent (or the CLI)\nanywhere inside the repo and it resolves to the same store. The store is chosen in this\norder:\n\n1. **`NORN_DB_PATH`**, if set — an explicit override always wins.\n2. The nearest **project-local** `.norn/norn.db`, walking up from the working directory.\n3. The global **`~/.norn/norn.db`** — the original behavior when no project store exists.\n\nEven without `norn init`, projects stay isolated in the shared global store: every memory\nis stamped with the project root it was written under (a `scope`, derived from the nearest\n`.git`/`.norn` ancestor — distinct from the freeform project label), and recall only\nreturns the current project's memories plus global ones. Separate db files are the primary\nisolation; the scope stamp is defense in depth for the shared store.\n\n### Commit memory with the repo\n\n> `norn export` / `norn import` are available from **v1.1 onward**. On earlier versions,\n> commit the binary `norn.db` directly (the default `norn init` setup).\n\n`norn.db` is a binary SQLite file — it holds embedding vectors, so it has no readable git\ndiffs and can conflict on merge. To version your memory cleanly, commit a **diffable text\nexport** instead and let each checkout rebuild its own database:\n\n```bash\nnorn export   # writes .norn/memory.json — text, tags, project, ids, timestamps (no vectors)\n```\n\n`memory.json` is sorted deterministically, so re-exporting an unchanged store produces an\nempty diff. Embeddings are **not** stored in it; they are regenerated locally on import, so\nthe file stays small and review-friendly. Commit it and gitignore the binary store with a\n`.norn/.gitignore` like:\n\n```gitignore\n# .norn/.gitignore — commit memory.json, ignore the binary store.\n# norn.db is binary SQLite (it holds embedding vectors): no readable diffs,\n# and it can conflict on merge. memory.json (not listed here) is the\n# diffable file you commit; the sidecars below are always transient.\nnorn.db\nnorn.db-wal\nnorn.db-shm\nnorn.db-journal\n```\n\n> `norn init` (v1.1+) writes exactly this `.gitignore` for you, so `memory.json` is the\n> committed artifact out of the box. Prefer to commit the binary `norn.db` instead — no\n> import step on clone, at the cost of readable diffs? Just delete the `norn.db` line.\n\nOn a fresh clone, rebuild the local database from the committed file:\n\n```bash\nnorn import   # reads .norn/memory.json and regenerates embeddings locally\n```\n\n`import` upserts by id, so it is safe to re-run; it never duplicates a memory.\n\n### Try it: isolation, then commit-and-clone\n\nA self-contained, copy-paste walkthrough (uses `npx`, no install; needs Node 20+ and git):\n\n```bash\n# 1. Two separate projects, each with its own committed memory store.\nmkdir -p /tmp/demo/alpha /tmp/demo/beta\n\ncd /tmp/demo/alpha\nnpx @samad001z/norn-core init\nnpx @samad001z/norn-core remember \"Alpha API rate limit is 600 requests per minute per token\"\n\ncd /tmp/demo/beta\nnpx @samad001z/norn-core init\nnpx @samad001z/norn-core remember \"Beta deploys to prod from the main branch on Vercel\"\n\n# 2. Isolation: from Beta, ask for Alpha's fact. Beta only ever returns its own\n#    (and global) memories — Alpha's note never appears here.\nnpx @samad001z/norn-core recall \"what is the request rate limit\"\n\n# 3. Export Alpha's memory to a diffable file and commit it.\ncd /tmp/demo/alpha\nnpx @samad001z/norn-core export                       # writes .norn/memory.json\ngit init -q && git add .norn/memory.json && git commit -qm \"Add project memory\"\n\n# 4. Simulate a teammate's fresh clone: bring the export, NOT the binary db.\nmkdir -p /tmp/demo/alpha-clone/.norn\ncp .norn/memory.json /tmp/demo/alpha-clone/.norn/memory.json\n\n# 5. Rebuild the store from the committed file and confirm recall works.\ncd /tmp/demo/alpha-clone\nnpx @samad001z/norn-core import                       # regenerates embeddings locally\nnpx @samad001z/norn-core recall \"what is the request rate limit\"\n#   → \"Alpha API rate limit is 600 requests per minute per token\"\n```\n\n## Features\n\n- **Remembers across sessions and projects.** Stop re-pasting CLAUDE.md by hand.\n- **See everything it knows.** No black box: every memory is visible.\n- **Forget anything, with undo.** Full control over what it keeps.\n- **Surfaces stale memories.** Memories you haven't touched in a while are quietly\n  flagged in the dashboard so you can prune them. It surfaces — it never deletes.\n- **Possible-conflict detection (opt-in).** Set `NORN_DETECT_CONFLICTS=1` and Norn\n  flags memories that might disagree so you choose which to keep — it never\n  auto-resolves, edits, or deletes. Off by default; the extra model only downloads\n  once you turn it on.\n- **Norn Live: watch your agents use memory.** A live activity feed in the dashboard\n  shows every `remember`, `recall`, and `forget` as it happens, plus conflicts that\n  need your call. See [Norn Live](#norn-live-watch-agents-use-memory).\n- **Lives in your tools over MCP.** Claude Code, Cursor, and any MCP client.\n- **Local-first.** Your context, the embedding model, and the database all stay on your\n  machine.\n\n## Privacy\n\nLocal by default. The store is a SQLite file on your disk, the embedding model runs on\nyour machine, and nothing leaves it: no account, no API key, no telemetry. Delete\n`~/.norn/norn.db` and the memory is gone.\n\n## Manage your memories\n\nThe dashboard lets you browse by project, search, and forget any memory (with undo).\nIt runs from a clone of this repo (it is not part of the `npx` server package), and it\nreads the same local store your agent writes to — `~/.norn/norn.db` — so whatever Norn\nremembered shows up here.\n\nRun these four commands from a fresh terminal:\n\n```bash\ngit clone https://github.com/samad001z/Norn.git\ncd Norn\nnpm install          # install dependencies\nnpm run build:core   # build the store package the dashboard reads through (required)\nnpm run dev:web      # start the dashboard\n```\n\nThen open **http://localhost:3000/app**.\n\n> Skipping `npm run build:core` is the usual reason the dashboard opens empty: the web\n> app imports the compiled store from `@samad001z/norn-core`, so that package has to be\n> built once first. After that, `npm run dev:web` is all you need to reopen it.\n\nTo point the dashboard at a store in a non-default location, set `NORN_DB_PATH` to the\nsame path your agent uses before running `dev:web` (otherwise the default is fine):\n\n```bash\nNORN_DB_PATH=/path/to/norn.db npm run dev:web\n```\n\n![The Norn dashboard: browse by project, search, and forget your memories](web/public/app-screenshot.png)\n\nPrefer the terminal? Inspect the same store without the dashboard:\n\n```bash\nnpm run cli -w @samad001z/norn-core -- init    # give this project its own committed store\nnpm run cli -w @samad001z/norn-core -- list\nnpm run cli -w @samad001z/norn-core -- recall \"how do we deploy\"\nnpm run cli -w @samad001z/norn-core -- export  # write .norn/memory.json to commit with the repo\nnpm run cli -w @samad001z/norn-core -- import  # rebuild this checkout's store from memory.json\n```\n\n## Norn Live: watch agents use memory\n\nOpen **http://localhost:3000/app/live** (or the **Live** link in the dashboard sidebar)\nto watch agents use your memory in real time. Every `remember`, `recall`, and `forget`\nthat goes through Norn is recorded to a local activity log and streams into the feed as\nit happens — who acted, what they did, when, and a short preview of what it touched.\nA **needs you** panel collects possible conflicts (when detection is on) that are still\nwaiting for your decision; resolving one in the dashboard clears it here too.\n\nLike everything else in Norn, the log is local: events live in the same SQLite file as\nyour memories and never leave your machine. The page streams over server-sent events\nand falls back to polling if the stream drops.\n\n**Naming agents.** Events are attributed via the optional `agentId` tool argument, or\nthe `NORN_AGENT_ID` environment variable in your MCP config. Without either, a server\nsession gets a generated id like `agent-3f9c21` — activity still groups per session,\nit just isn't labeled. Set `NORN_MODEL` if you also want events tagged with the model;\nNorn never guesses it.\n\n**What it is and isn't:**\n\n- It logs **only Norn's own tools**. It is not a session recorder — your prompts, code,\n  and terminal never touch it. Plain `list` browsing isn't logged either.\n- Event logging is **best-effort by design**: a failed log write never blocks or rolls\n  back a memory write. Treat the feed as a trace, not an audit record.\n- Events need **server v1.3.0 or newer**. Older servers write no events, so the feed\n  stays empty until the `npx` command picks up the new version (it fetches the latest\n  automatically on next launch).\n- The log is currently **unbounded** — there's no retention cap yet; it grows with use.\n  Pruning is on the roadmap.\n\n## Roadmap\n\n- Swappable embedding backends (Ollama, OpenAI-compatible) behind the existing `Embedder`\n  interface.\n- Edit memories in place from the dashboard (adding and forgetting already work).\n- A larger labelled benchmark for conflict detection, to tune the thresholds with more data.\n- Retention for the activity log (age/count caps), so Norn Live's history doesn't grow\n  unbounded.\n- More editor and MCP-client integrations.\n\n## Contributing\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md). The short version:\n\n```bash\nnpm install\nnpm run build\nnpm test -w @samad001z/norn-core\n```\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n",
  "bytes": 16082,
  "sha": "752e6dd374a4296bb1c321b4b945ec62484e42c5c0c41e2f6c83b54dcd96066b",
  "repo_slug": "samad001z/norn",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_samad001z_norn_a7306547/readme"
}