
Norn
io.github.samad001zPublished by GitHub account samad001zv1.2.3Updated Oct 24, 2026
Local-first, persistent memory for AI coding agents — remember, recall, forget, and list, over MCP.
Overview
Norn is a local-first MCP memory server that lets an AI coding agent remember, recall, forget and list durable project facts across sessions.
- What you can do
- Save durable facts, decisions and preferences as memories, optionally scoped to a project, with near-duplicate notes merged automatically. Retrieve memories by meaning rather than keywords, blended with recency and trimmed to a token budget. Delete memories and browse what is stored. Optionally flag memories that may conflict, for the user to resolve in a dashboard. Export and import memories as a diffable text file for committing with a repository.
- When to use it
- Useful when working with Claude Code, Cursor or another MCP client on projects where decisions, conventions and stack preferences should carry over between sessions instead of being re-pasted each time. Suits users who want memory kept local and inspectable rather than captured automatically.
- Requirements
- Node.js 20 or newer; the server is fetched with npx and needs no separate install. Optional environment variables: NORN_DETECT_CONFLICTS to enable conflict detection, NORN_DB_PATH to choose the store, NORN_AGENT_ID and NORN_MODEL for activity labeling. The first remember or recall downloads a local embedding model of about 25 MB; no account or API key is needed.
Installation
In SourceWeft
- Open Norn in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
Norn
Persistent, visible memory for AI coding agents.
Live site · Releases · Quickstart · Connect your AI tool
Your AI forgets you every session. Norn is a local MCP server that remembers your decisions, preferences, and project context across every session and project, for Claude Code, Cursor, and any MCP client. Unlike most memory tools it is fully local and fully inspectable: a dashboard lets you see exactly what it stored and forget anything you do not want.
Quickstart
What you need: just Node.js 20 or newer — you don't install Norn separately,
the command below fetches it automatically. Check with node --version; if it's
missing or below v20, grab the LTS from nodejs.org.
Connect to Claude Code — one command, no clone:
Or use the CLI in your terminal — run it on demand, or install the norn command:
Any other MCP client — add this to its MCP config:
Restart your tool. Norn registers four tools: remember, recall, forget, list.
Optional — flag possible conflicts: add
"env": { "NORN_DETECT_CONFLICTS": "1" }to the config above and Norn will surface memories that might disagree, for you to resolve in the dashboard. Off by default; it downloads a small extra model the first time it finds a candidate, and it never changes your store on its own.
Not sure where that config goes? The Connect Norn to your AI tool guide has exact, copy-paste setup for Claude Desktop, Cursor, Windsurf, VS Code + GitHub Copilot, and Gemini CLI — plus a beginner "what you need" and troubleshooting. (VS Code + Copilot uses a
serverskey instead ofmcpServers.)
Verify it's connected: tell your assistant "Remember that I prefer pnpm over
npm," then in a new chat ask "What package manager do I prefer?" — it should answer
pnpm by calling Norn's recall tool.
The first
rememberorrecalldownloads a local embedding model (all-MiniLM-L6-v2, ~25 MB) once, then runs fully offline.
Or run from source
See it work
Memory survives across sessions, and recall is semantic: it matches meaning, not keywords.
Session 1
You: Remember that we deploy to production from the main branch on Vercel.
Claude calls
remember("deploy to production from the main branch on Vercel", project: "acme")
Session 2, the next day, in a fresh context window
You: How do we ship to prod?
Claude calls
recall("how do we ship to prod")Norn returns "Deploy to production from the main branch on Vercel." even though the query shares no keywords with the stored note.
Using memory: it's explicit, not automatic
Norn does not record your sessions. It is a memory store, not a logger — it never
silently captures your prompts, code edits, or terminal commands. A memory exists only
when the agent calls remember(), which happens in two ways:
- You ask for it. "Remember that we deploy from
mainon Vercel." The agent callsremember(...)and the note is saved. - The agent chooses to, when it judges a fact worth keeping for next session — a decision, a preference, a constraint.
That is the point: you decide what's kept, so the store stays signal, not noise. The flip side is that if you never ask, nothing is saved — so a sparse dashboard after a long working session is expected, not a bug. The work itself lives in git; Norn is for the durable facts you want recalled later.
A few habits that make it pay off:
- End a task with "remember the key decisions from this" and the agent writes them down.
- Front-load context once — "remember my stack and conventions" — instead of re-pasting it every session.
- Ask "what do you remember about X?" to make the agent call
recall()on demand.
Everything saved this way shows up in the dashboard, and you can forget any of it.
How it works
Three local pieces share one local database:
- MCP server (
/server): exposesremember,recall,forget,listover stdio. - Store (
/core): SQLite + sqlite-vec, with embeddings from a local MiniLM model (no API key).recallblends semantic similarity with recency and trims results to a token budget;rememberdedupes near-identical notes. - Dashboard (
/web): a Next.js app to browse and manage everything.
All three resolve to the same store, so a memory written by your agent appears in the dashboard, and a memory you forget in the dashboard is gone for the agent too. The store is chosen in this order:
NORN_DB_PATH, if set — an explicit override always wins.- The nearest project-local
.norn/norn.db, walking up from the working directory (see Per-project memory). - The global
~/.norn/norn.db.
With no project store and no override, this is the original behavior: one global
~/.norn/norn.db.
Per-project memory
Give a repo its own memory that ships with it. From the project root:
This creates a .norn/ directory holding that project's norn.db. Because each project
has its own database file, memories never bleed across projects: an agent working in
one repo only sees that repo's memory.
How a project is detected
Norn finds your project the way git does — by walking up from the working directory
to the nearest ancestor that contains a .norn/ directory. Run your agent (or the CLI)
anywhere inside the repo and it resolves to the same store. The store is chosen in this
order:
NORN_DB_PATH, if set — an explicit override always wins.- The nearest project-local
.norn/norn.db, walking up from the working directory. - The global
~/.norn/norn.db— the original behavior when no project store exists.
Even without norn init, projects stay isolated in the shared global store: every memory
is stamped with the project root it was written under (a scope, derived from the nearest
.git/.norn ancestor — distinct from the freeform project label), and recall only
returns the current project's memories plus global ones. Separate db files are the primary
isolation; the scope stamp is defense in depth for the shared store.
Commit memory with the repo
norn export/norn importare available from v1.1 onward. On earlier versions, commit the binarynorn.dbdirectly (the defaultnorn initsetup).
norn.db is a binary SQLite file — it holds embedding vectors, so it has no readable git
diffs and can conflict on merge. To version your memory cleanly, commit a diffable text
export instead and let each checkout rebuild its own database:
memory.json is sorted deterministically, so re-exporting an unchanged store produces an
empty diff. Embeddings are not stored in it; they are regenerated locally on import, so
the file stays small and review-friendly. Commit it and gitignore the binary store with a
.norn/.gitignore like:
norn init(v1.1+) writes exactly this.gitignorefor you, somemory.jsonis the committed artifact out of the box. Prefer to commit the binarynorn.dbinstead — no import step on clone, at the cost of readable diffs? Just delete thenorn.dbline.
On a fresh clone, rebuild the local database from the committed file:
import upserts by id, so it is safe to re-run; it never duplicates a memory.
Try it: isolation, then commit-and-clone
A self-contained, copy-paste walkthrough (uses npx, no install; needs Node 20+ and git):
Features
- Remembers across sessions and projects. Stop re-pasting CLAUDE.md by hand.
- See everything it knows. No black box: every memory is visible.
- Forget anything, with undo. Full control over what it keeps.
- Surfaces stale memories. Memories you haven't touched in a while are quietly flagged in the dashboard so you can prune them. It surfaces — it never deletes.
- Possible-conflict detection (opt-in). Set
NORN_DETECT_CONFLICTS=1and Norn flags memories that might disagree so you choose which to keep — it never auto-resolves, edits, or deletes. Off by default; the extra model only downloads once you turn it on. - Norn Live: watch your agents use memory. A live activity feed in the dashboard
shows every
remember,recall, andforgetas it happens, plus conflicts that need your call. See Norn Live. - Lives in your tools over MCP. Claude Code, Cursor, and any MCP client.
- Local-first. Your context, the embedding model, and the database all stay on your machine.
Privacy
Local by default. The store is a SQLite file on your disk, the embedding model runs on
your machine, and nothing leaves it: no account, no API key, no telemetry. Delete
~/.norn/norn.db and the memory is gone.
Manage your memories
The dashboard lets you browse by project, search, and forget any memory (with undo).
It runs from a clone of this repo (it is not part of the npx server package), and it
reads the same local store your agent writes to — ~/.norn/norn.db — so whatever Norn
remembered shows up here.
Run these four commands from a fresh terminal:
Then open http://localhost:3000/app.
Skipping
npm run build:coreis the usual reason the dashboard opens empty: the web app imports the compiled store from@samad001z/norn-core, so that package has to be built once first. After that,npm run dev:webis all you need to reopen it.
To point the dashboard at a store in a non-default location, set NORN_DB_PATH to the
same path your agent uses before running dev:web (otherwise the default is fine):
[The Norn dashboard: browse by project, search, and forget your memories]
Prefer the terminal? Inspect the same store without the dashboard:
Norn Live: watch agents use memory
Open http://localhost:3000/app/live (or the Live link in the dashboard sidebar)
to watch agents use your memory in real time. Every remember, recall, and forget
that goes through Norn is recorded to a local activity log and streams into the feed as
it happens — who acted, what they did, when, and a short preview of what it touched.
A needs you panel collects possible conflicts (when detection is on) that are still
waiting for your decision; resolving one in the dashboard clears it here too.
Like everything else in Norn, the log is local: events live in the same SQLite file as your memories and never leave your machine. The page streams over server-sent events and falls back to polling if the stream drops.
Naming agents. Events are attributed via the optional agentId tool argument, or
the NORN_AGENT_ID environment variable in your MCP config. Without either, a server
session gets a generated id like agent-3f9c21 — activity still groups per session,
it just isn't labeled. Set NORN_MODEL if you also want events tagged with the model;
Norn never guesses it.
What it is and isn't:
- It logs only Norn's own tools. It is not a session recorder — your prompts, code,
and terminal never touch it. Plain
listbrowsing isn't logged either. - Event logging is best-effort by design: a failed log write never blocks or rolls back a memory write. Treat the feed as a trace, not an audit record.
- Events need server v1.3.0 or newer. Older servers write no events, so the feed
stays empty until the
npxcommand picks up the new version (it fetches the latest automatically on next launch). - The log is currently unbounded — there's no retention cap yet; it grows with use. Pruning is on the roadmap.
Roadmap
- Swappable embedding backends (Ollama, OpenAI-compatible) behind the existing
Embedderinterface. - Edit memories in place from the dashboard (adding and forgetting already work).
- A larger labelled benchmark for conflict detection, to tune the thresholds with more data.
- Retention for the activity log (age/count caps), so Norn Live's history doesn't grow unbounded.
- More editor and MCP-client integrations.
Contributing
Contributions are welcome. See CONTRIBUTING.md. The short version:
License
MIT. See LICENSE.
Source: README.md at commit 837b9d5
Tools
0Version history
1- v1.2.3LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts