Inspiration
When coding with AI tools, hitting usage or context limits often means switching to another tool (Claude Code, Codex, Gemini CLI, opencode, Copilot, etc.) and re-explaining the same project context from scratch. I wanted limit-hopping continuity: move between tools without losing momentum, while keeping everything local and private.
What it does
Memoria is an offline “second brain” for AI coding tools. It captures coding sessions/transcripts from multiple tools, turns them into structured memories in a local SQLite database, and makes them instantly recallable across tools through an MCP server and a dashboard. It can also inject a handoff/context block into project instruction files (e.g. AGENTS.md, CLAUDE.md, GEMINI.md) so the next tool can pick up where the last one left off.
How we built it
- Engine: Node.js + TypeScript with
node:sqlite(WAL), schema migrations, and a local HTTP/MCP server. - Ingestion: File watchers/scanners (chokidar + per-tool parsers) to capture transcripts from supported coding tools without blocking the user.
- Retrieval: SQLite FTS5 keyword search with ranking, plus embedding support (Float32 BLOB) with model-dialect guards to avoid cross-model comparison.
- Intelligence tiers: Heuristic extraction by default so capture works without a model; optional local Ollama or OpenAI-compatible providers for richer extraction/embeddings.
- App/UI: Electron desktop app with a lightweight vanilla JS dashboard (SSE live updates, memory/task/project views).
- Sync (in progress): Stable UUIDs, HLC/outbox change capture, and encrypted manual
.memsyncbundles (AES-256-GCM, HKDF, recovery/passphrase-protected keys) for idempotent cross-device sync with LWW, conflict logging, and tombstones.
Challenges we ran into
- Tool diversity: Each AI coding tool stores sessions differently, so parsers and project identity had to work reliably across formats and paths.
- Non-blocking capture: Models can be slow or unavailable; extraction had to degrade gracefully so transcript capture never stalls.
- Search at scale: Keeping recall fast and relevant required FTS5 indexing, efficient on-disk embeddings, deduplication, and pagination.
- Privacy & security: Staying offline-first meant careful handling of local secrets (OS keychain/safeStorage), localhost-only APIs, and ensuring sync/export never includes embeddings, secrets, settings, or raw transcripts.
- Reliable sync: Designing deterministic IDs, change tracking, and encrypted bundles that apply idempotently across machines—without resurrecting deleted data—was non-trivial.
What we learned
- Continuity depends more on reliable capture and retrieval UX than on heavyweight models.
- Local-first design simplifies privacy but raises the bar for migrations, performance, and cross-device consistency.
- For sync, deterministic identifiers (UUID/HLC), append-only/outbox change tracking, and explicit LWW/tombstone rules are essential to make merges predictable.
Built With
- actions
- aes-256-gcm
- chokidar
- css
- electron
- fts5
- github
- hkdf
- html
- javascript
- model-context-protocol-(mcp)
- node.js
- node:sqlite
- ollama
- openai-compatible-api
- scrypt
- sqlite
- typescript

