There’s a specific kind of frustration I’ve been living with for the past year.
I open a new Claude Code session. I start working on a feature. Somewhere in the first few messages I end up explaining — again — that this project uses Zod for all external API validation, that we don’t use default exports, that the database layer lives in internal/store and not in the handlers. Things I’ve explained a hundred times. Things the AI doesn’t remember.
Then I switch to Cursor to do something else. Same thing. Start from scratch.
It’s not a complaint about the tools — they’re genuinely incredible. It’s a fundamental limitation: AI coding assistants have no persistent memory. Every session is a blank slate.
The Problem Is Worse Than It Sounds
The obvious answer is “just put it in your README or .cursorrules.” And I tried that. But it breaks down in a few ways:
Static files don’t capture decisions. A .cursorrules file is great for stable conventions, but what about the decision you made last Tuesday to switch from REST to tRPC? Or the three approaches you already tried for the caching layer that didn’t work? That context lives in your head, not in a file.
Context windows fill up fast. Even if you dump everything into a system prompt, you’re burning tokens on context that may not be relevant to the current task. You want the AI to surface the right memories, not spray everything at once.
Cross-agent is broken by design. I use Claude Code for most things and Cursor for others. They have completely separate context. Save something in one, the other has no idea. There’s no shared memory layer — each tool is an island.
The result: I’m the human glue between my AI tools. I’m the one carrying context from session to session, tool to tool. That’s the exact problem AI is supposed to solve.
What I Built
I built memtrace — a local-first, cross-agent memory engine for AI coding tools.
It’s a CLI and MCP server backed by SQLite. You run memtrace serve and it gives every connected AI agent access to a persistent, searchable memory store scoped to your project. Claude Code, Cursor, Windsurf, VS Code Copilot, Gemini CLI — anything that speaks MCP.
The magic moment looks like this:
# Claude Code session
You: always use Zod for validating external API responses in this project
Claude: [calls memory_save]
→ Saved memory (convention): always use Zod for validating external API responses
Now open Cursor on the same project — fresh session, no shared context:
# Cursor session
You: how should I validate the response from this external API?
Cursor: [calls memory_recall → finds the Zod convention]
→ Based on your project conventions, use Zod for this...
Cursor already knows. You didn’t paste anything. You didn’t repeat yourself. The memory crossed agents on its own.
How It Works
memtrace is a Go binary — single executable, no runtime dependencies, no Docker, no external database.
brew install memtrace-dev/tap/memtrace
cd your-project
memtrace init
memtrace setup # auto-detects Claude Code, Cursor, VS Code, etc.
memtrace init creates a .memtrace/ directory with a SQLite database and auto-imports existing context from your .cursorrules, .claude/ memory files, and git history. memtrace setup writes the MCP server config and instructions into each agent’s rules file so they start using memtrace tools automatically.
Under the hood, the retrieval pipeline is hybrid: BM25 full-text search combined with vector similarity (via Ollama or OpenAI embeddings), weighted by recency and confidence decay. Memories that haven’t been accessed in a while get scored lower. Memories referencing files that have changed since they were written get flagged as stale.
Memory types
Memories aren’t just freeform strings. They have types:
- convention — coding standards, patterns, rules (“always use Zod”)
- decision — architectural choices and why (“switched to tRPC because REST was getting messy”)
- fact — project truths (“the auth service lives at
internal/auth”) - event — things that happened (“tried Redis for caching, had TTL bugs, reverted”)
This structure makes retrieval more precise. When you ask about “authentication approach”, you get decisions and conventions, not session events.
Code awareness
One thing I wanted beyond simple key-value memory: awareness of the codebase itself. memtrace can parse your source files (Go, TypeScript, Python, Rust) and link memories to specific symbols — functions, types, interfaces. When you’re about to edit internal/auth/middleware.go, calling memory_context surfaces not just general auth conventions but memories specifically linked to that file and the symbols in it.
What Makes It Different
There are other memory MCP servers out there. Most are general-purpose — they store whatever you tell them and search by keyword or vector similarity. That’s useful, but it misses the developer use case.
OpenMemory by Mem0 is local-first with a nice web dashboard but requires Python/Docker and has no concept of code structure. It’s agent memory for any use case, not specifically for writing software.
The gap I cared about filling: memory that understands code. Not just “what did you tell the AI”, but “what does this project know about itself.”
The Lifecycle Problem
Here’s something most memory tools ignore: memories go stale.
You save a convention about a file. Six months later that file is refactored or deleted. The memory is now wrong — and worse, it’s confidently wrong. An AI citing stale conventions is worse than an AI that admits it doesn’t know.
memtrace tracks this. Every memory that references a file path is checked during memtrace scan. If the file has been modified or deleted since the memory was last updated, the memory is flagged stale and scored lower in retrieval. Confidence also decays over time with a 90-day half-life — old memories don’t disappear, they just matter less until you either refresh them or they’re recalled again.
The Setup
Install:
brew install memtrace-dev/tap/memtrace
Initialize a project:
cd your-project
memtrace init # creates .memtrace/, imports existing context
memtrace setup # configures MCP for all detected agents
Check health:
memtrace doctor
Browse your memories:
memtrace browse # bubbletea TUI
memtrace list
memtrace search "authentication"
The MCP server runs as a subprocess spawned by your agent — no ports, no daemons, no config beyond what memtrace setup writes.
What’s Next
The current version covers the solo developer case well. What I’m building toward is the team case: shared memory spaces, review queues for memory changes, sync across machines. The individual experience is free and open-source forever. The team layer is where the business goes.
But honestly, right now I’m more interested in hearing how other people use it. If you’re the kind of developer who’s been manually re-explaining your project to AI tools, this is for you.
The code is at github.com/memtrace-dev/memtrace. MIT licensed. Issues and feedback welcome.
If you found this useful, I’d appreciate a star on GitHub. It helps more than you’d think.