I run Claude Code and Pi across everything I build. They’re good, but they also forget everything the moment a session ends.
Every project decision, every dead end I’d already ruled out, every preference I’d stated five times are gone at the end of the context window. I was re-teaching my agents the same context every morning, like onboarding a brilliant contractor with amnesia on a loop.
So I built them a memory for them it’s called commonplace, it’s open source under MIT, and it’s been running in daily use on the Ubuntu box in my office for weeks.
The trade-off everyone accepts
Give an agent persistent memory and you hit a wall fast. The good kind of memory — a knowledge graph, entities and relationships instead of a pile of text — gets built by running an LLM over your notes to extract what matters. That extraction step is the whole problem. It’s the exact moment your data gets handed to a model.
Every “AI memory” tool I looked at makes you send everything to a hosted model and get high-quality memory, but now your data lives in someone else’s extraction pipeline or keep everything local and eat the quality hit from a small model.
For my own notes, fine — send them to a hosted model. For real work or a client’s NDA material, absolutely not! I didn’t want to run two entirely separate systems to handle both.
Two tiers, one box
So commonplace splits memory by who’s allowed to do the extraction.
A personal tier for my own notes, projects, life. Local by default, but I can opt it into a hosted model — Claude Haiku — when I want sharper graphs on data that isn’t confidential.
A client-confidential tier for anything under NDA. Extraction runs entirely on a local GPU, on mistral:7b on my own hardware. That data never touches a hosted API. Not “encrypted in transit to a vendor.” Never leaves the machine. That’s the entire point of the tier, and it is not switchable and a guarantee only means something if it can’t be flipped off by accident.
Both tiers live on one always-on Linux host: two isolated graphs in a single FalkorDB, one shared embedder, reachable only over my Tailscale tailnet and never the public internet. My laptop is pure clients and it host nothing.
And retrieval — the part that runs on every single query — has no LLM in the path at all. It’s embeddings, keyword search (BM25), and graph traversal. The GPU only ever does slow, asynchronous extraction in the background, so queries stay fast and a query never ships your data anywhere. The confidential tier has no hosted dependency, period.
What it actually cost to build
The concept took an afternoon. Making it run took weeks, and almost all of that was fighting the sharp edges of a young, fast-moving stack with the current Graphiti MCP server, FalkorDB, Ollama. Landmines, several of which contradict the published docs.
There is no openai_generic provider string, even though half the internet says there is. The Anthropic tier silently queued every episode and processed none, because the provider needs an explicit numeric temperature and sends null without one. The :standalone image ships without the Anthropic SDK, so hosted extraction fails at startup until you add it back. FastMCP throws a 421 on any non-localhost request until you disable its browser-rebinding protection — safe on a tailnet, invisible until it bites. And my favorite: for two weeks the graph quietly lost all of its data on every redeploy, because the volume was mounted at the wrong path and FalkorDB was writing somewhere ephemeral.
I wrote every one of these down in the README, under a heading that says “learned the hard way — read before you copy this.” Fifteen of them. If you build on this, you inherit the scar tissue instead of earning it yourself. That’s most of what the repo is worth.
Why this, and why now
I’ve been writing about coordination being the hard part of building isn’t the code, it’s what gets coordinated across a company, and that the thing doing the coordinating needs a shared memory every teammate reads from and writes to.
commonplace is me building the smallest honest version of that idea and putting it in the open but not the coordination layer itself which is the memory underneath it and a substrate my agents actually share that respects the line between what’s mine and what belongs to a client.
It’s MIT-licensed and running today. If you’re wiring agents into real work especially work that comes with an NDA take it, break it, and tell me where it’s wrong.
The repo is the whole thing: github.com/itsmeduncan/commonplace. Setup, the architecture diagram, and that hard-won gotchas list are all in the README.