I've been running Crush as my daily coding agent for a while now, wired up to local models through Lemonade Server, and I genuinely love it. I have adjusted to the agentic coding process, and what I learned about trusting my local LLM with my code explains how I decide which model gets which job. But one thing quietly drove me up the wall: every session started from zero. The gotcha we found on Tuesday? Gone by Wednesday. I was spending the first ten minutes of every session re-explaining my own projects to the tool that helped build them. And I don't like that.
So I spent a weekend giving Crush persistent memory, and I went in with a tidy thesis: local models won't use memory tools on their own, so you write explicit instructions into the context file, and you're done. That thesis did not survive contact with my 30B. What I learned instead is sharper and a little unsettling: a local model will recite your rules back to you, word for word, and then completely ignore them. Making memory actually work took a different lever entirely — and the failures along the way were more instructive than the successes.
Two memory servers are better than one
A database for facts, a pile of Markdown for knowledge
The architecture is two layers with deliberately different personalities, both talking MCP to Crush. MCP Memory Service is the episodic layer: SQLite with the sqlite-vec extension, local ONNX embeddings, semantic search, and niceties like semantic deduplication — it flatly refused when my model tried to store the same fact twice. Basic Memory is the curated layer: every note is a plain Markdown file in a folder I can grep, edit, and rsync to the NAS like anything else. Facts go in the database, knowledge goes in the notes, and my data-hoarding heart gets a memory store it can actually read.
Before either server could matter, the plumbing had its say. Crush lives in WSL2 Ubuntu on my Windows machine while Lemonade serves models from the Windows side, and out of the box that bridge simply doesn't exist. My first curl to the API hung forever, because WSL2's default NAT mode gives Linux its own little network where localhost means nothing useful.
The obvious fix is the wrong one: binding Lemonade to 0.0.0.0 exposes the inference API and its internal control endpoints to your entire LAN, which is a lot of trust to hand out for one config shortcut. The right fix is two lines in .wslconfig — networkingMode=mirrored — after which localhost works in both directions, Lemonade never leaves loopback, and the whole security question evaporates. One warning from experience: the change only takes after a full wsl --shutdown, and Docker Desktop will quietly hold the VM open and make you think it didn't work.
Installation was where the weekend earned its next scars. The base pip package installs cleanly, runs happily, and silently degrades to hash pseudo-embeddings — similarity theater with zero semantic value — unless you install the [sqlite-ml] extra. Worse, the HTTP health endpoint reported "healthy" the entire time; only the stricter CLI status check admitted the embeddings were fake. Trust the strictest check you have, because the friendly ones lie.
Then the context ambush. Crush's opening message — system prompt, 51 tool schemas, context files — weighs in around 23,600 tokens, and llama.cpp's default context was 8,192. What felt like a slow RTX 5090 was actually four identical rejections in a row; nothing was slow, everything was failing. One persisted ctx_size setting later, the same card was prompt-processing at over 4,200 tokens per second and generating at 223. Agent workloads break assumptions tuned for chat, and the defaults are tuned for chat.
My model quoted the rules then ignored them
Recitation is not compliance and I proved it
Here's the part every memory guide skips. With everything wired and verified, I wrote a memory protocol into CRUSH.md. This included mandatory session-start search, save-immediately rules, the lot; and asked the model to quote it. It reproduced the mandate verbatim, all-caps and all. Then I opened a fresh session, said I was ready to work, and watched it list the directory, read the codebase, and offered me a task menu without a single memory call. The instructions were in context. They just weren't in charge; Crush's own explore-the-project system prompt was, and my protocol was an appendix arguing with the headliner.
I escalated twice — front-loaded the rule, then rewrote it as a response-format contract — and lost twice. And the failure modes got weirder as I went. Once, asked to recall, the model read project files and presented them as "relevant memories," a confident lie about provenance.
Another time, it delegated the memory search to Crush's task sub-agent, which has no MCP access at all — so an agent with no memory tools wrote me a four-paragraph philosophical essay about the concept of remembering and called the job done. My favorite failure was the smallest: told to search using the project directory name, it searched for the literal words "project directory name." Instruction followed as text, not as intent.
What finally worked wasn't better prose — it was a better channel. Trigger words, defined in the context file but invoked by me in the user's turn: "recall" runs the searches, "note this" saves a fact, "document this:" writes a curated note. User-turn instructions outrank ambient context, and compliance went from roughly never to essentially always overnight.
Sure, typing a six-letter ritual feels less magical than an agent that just remembers. It also works, and the asymmetry I've measured since is genuinely interesting: the model saves unprompted surprisingly often — it stored a tagged test result on its own initiative — but it has never once recalled unprompted. Saves volunteer; recalls must be summoned.
Guardrails matter more than instructions
Fifty-one rules is a lot of ways to get creative
Two memory servers means my Qwen3-Coder now stares down 51 MCP tools per session, including a genuine danger shelf: delete_note, delete_project, memory_cleanup, and a whole schema surface I never asked for. The protocol fences these off with a do-not-touch list, but the weekend taught me exactly what a fence made of prose is worth.
So the real enforcement lives in Crush's permission system: the six blessed tools — store, search, and the four note operations — are whitelisted to run without prompts, and everything else stops dead at a human-approval dialog. The context file says don't; the config says can't without me. Prose for the common case, a hard gate for the destructive one.
The other guardrail is a habit, not a config: verifying that memory operations actually happened. A real recall shows tool-call blocks in Crush's transcript; a confabulated one shows prose claiming success. After being lied to once, I now glance for the blocks the way you glance at a file-copy progress bar, and I'd tell anyone building this to do the same — because the sharpest failure mode isn't an agent that forgets, it's one that fakes remembering.
A forgetful agent with notes beats a brilliant one with amnesia
Two days in, the payoff is exactly what the headline promised: Crush opens a session on the tooling from when I connected Claude to my Proxmox cluster through MCP, surfaces the gotcha from last time, and continues where we left off. No re-explaining, no rediscovering solved problems, no API fees — the whole stack is local, and the memory store rsyncs to backup in under a second. It's not flawless. Recall quality depends on how well the save was worded; the occasional memory reads like it was written by a distracted goldfish, and the trigger ritual means the magic is scaffolded rather than spontaneous. But scaffolded magic that fires every time beats spontaneous magic that never fires, and it's not even close.
The bigger lesson travels beyond memory: every layer of an agent stack that can receive an instruction is a layer that can fake having followed it. Write the rules, sure — then build the triggers, the permission gates, and the verification habits that make the rules unnecessary. The next thing I need is to point this same memory store at my other agents, so every tool in the house shares one brain. That's either a great idea or the start of a very silly problem, and knowing my track record, I'll report back either way.