Gingugu
Your AI forgets everything between sessions. Gingugu fixes that.
Gingugu is a local MCP server that gives AI coding assistants a real long-term brain — persistent, structured, searchable memory that survives across sessions, repos, and projects. No cloud, no API keys, no telemetry. One SQLite file on your machine.
<p align="center"> <img src="https://raw.githubusercontent.com/gingugu/gingugu/main/docs/demo.gif" alt="Memory Explorer UI — knowledge graph and dashboard" width="800"> </p>📋 Table of Contents
- Why Gingugu
- FAQ
- Features
- Architecture
- Setup
- Memory Explorer UI
- Configuration
- Usage
- Development
- Troubleshooting
Why Gingugu
Every session with an AI assistant starts from zero. The decisions you made yesterday, the bug you fixed last week, the architecture you settled on a month ago — gone. Existing memory tools dump observations into a flat pile with no structure, no staleness tracking, no relationships, and no sense of what's relevant right now.
Gingugu is designed to be a structured long-term brain — not a junk drawer:
- Remembers across sessions, repos, and projects
- Organizes knowledge by namespace, type, and relationships
- Ranks memories by relevance, freshness, and confidence
- Auto-surfaces relevant context when you start working
- Consolidates duplicate and related knowledge on demand
The protocol ships with it
Storage is the easy half. A memory server that an agent never writes to is an empty database, and an agent left to its own judgement will save almost nothing worth keeping — the failure mode isn't retrieval, it's discipline.
So Gingugu ships the discipline too. gingugu init wires a repo in one
command and installs a SessionStart hook that injects the memory protocol
at the top of every session: load these namespaces, check memory before asking
a question already answered, save at the moment of observation rather than
batching to the end, build a relation only when it records something search
cannot infer. There is no rules file to paste and nothing to remember to do —
the harness runs it whether or not the agent feels like it. A stop hook
then checks that a session with real work in it actually wrote something down.
That is the part that makes the memory worth having, and it is in the box.
Retrieval quality
Hybrid retrieval (BM25 over FTS5 + local embeddings, fused with Reciprocal
Rank Fusion) measured with the in-repo bench/
toolset — MRR 0.828, recall@1 0.611, recall@5 0.983.
Measured over 30 labeled questions against a real working brain (~1,100
memories), not a public benchmark suite, so read it as a regression baseline
for this workload rather than a cross-product comparison. The runner is
deterministic and committed, so you can point it at your own store and get
your own numbers: python -m bench --help.
Where this goes long-term — federated, org-wide agent memory — lives in docs/enterprise-vision.md.
FAQ
<details> <summary><strong>Why not just use Claude Projects / Cursor @memories / Windsurf Memories?</strong></summary>Those are great if you live in one tool. The moment you switch between Claude Code in the morning and Cursor in the afternoon, the memory is gone. Gingugu's memory follows you across every MCP client, lives on your machine, and is programmable (18 tools, structured types, relationships, confidence levels). The built-ins are convenience features. Gingugu is infrastructure.
</details> <details> <summary><strong>Why SQLite + FTS5 instead of a vector database?</strong></summary>Both, actually. We do hybrid retrieval out of the box: BM25 over FTS5 + local semantic embeddings, fused with Reciprocal Rank Fusion. No vector DB server required.
Why this stack:
- No deployment. One SQLite file holds memories, FTS5 index, and embeddings. No Postgres, no Pinecone, no Chroma server.
- Two embedding backends — pick one:
- fastembed (default) — ONNX-based, no PyTorch, ~80MB model download
to
~/.cache/fastembed. Works fully offline after first use. - Ollama — delegates to your already-running Ollama process via its
HTTP API. Zero extra memory footprint. Set
MEMORY_EMBEDDINGS_BACKEND=ollama.
- fastembed (default) — ONNX-based, no PyTorch, ~80MB model download
to
- It composes. Hybrid relevance feeds the composite (relevance × freshness × access × confidence) — every signal in one engine.
You can disable semantic search via MEMORY_EMBEDDINGS_ENABLED=false and
fall back to BM25-only.
Usable today for local personal workflows. 406 tests passing covering storage, search, migrations, concurrency, credentials, and edges. Hardened against adversarial input and write contention. WAL mode for concurrency. CI matrix across Python 3.11–3.13 on Linux/macOS/Windows. Dogfooded daily in this repo (the memories you see referenced in commits are Gingugu memories).
It's still early — broader real-world validation across MCP clients,
databases at large scale, and long upgrade horizons is the work ahead.
Treat it as an early cognitive-runtime framework, not a finished product.
See SECURITY.md for the threat model, and
docs/future-architecture.md for where
this is headed.
SQLite FTS5 comfortably handles millions of rows. Gingugu adds composite
re-ranking on top, but only over a small candidate pool (4× limit). For
typical personal/team use it should hold up well — though we haven't
yet benchmarked at the 100k+ memory scale. Use memory_consolidate to
merge duplicates or summarize clusters when things sprawl.
It's a local CLI/server tool. Python's SQLite + keyring + asyncio story is
mature, the install footprint via uv is small, and there's no JS bundling
or Rust toolchain required to use it. The MCP SDK is first-class in Python.
Features
| Feature | Description |
|---|---|
| 🏷️ Namespace Scoping | Memories auto-scoped to repos/projects with cross-repo pattern sharing |
| 🔍 Hybrid Search | SQLite FTS5 (BM25) + semantic embeddings fused with Reciprocal Rank Fusion. Two backends: fastembed (ONNX, offline) or Ollama (zero extra footprint, uses your existing Ollama process) |
| ⏰ Temporal Intelligence | Trust-led scoring, dormancy tracking (never forgets), "last confirmed" tracking, spreading activation |
| 🔔 Review Hints | Point-in-time memories ("PR #947 open, waiting on…", passed expiry dates) get advisory staleness flags on every read - you reconcile, the server never mutates |
| 🔗 Relationships | A typed graph over what similarity can't see: supersedes, contradicts, caused_by, parent_of/child_of (related_to as a fallback) |
| 🎯 Confidence Levels | verified → inferred → stale → deprecated lifecycle |
| 🧹 Consolidation Tools | Find near-duplicate clusters (read-only suggest scan), then merge, summarize, or deduplicate on demand |
| 🚀 Auto-Context | Surfaces relevant memories on session start - one call loads many namespaces deduped, with an optional compact mode for lighter payloads |
| 📊 Health Metrics | Memory stats, dormancy reports, review sweep, namespace overviews |
| 🔐 Credential Vault | Secure service-bundle storage for API keys/tokens via OS Keychain |
| 🌐 Memory Explorer UI | Interactive knowledge graph + dashboard for visualizing memory data |
| 📡 Central Brain (optional) | gingugu serve runs the same server over HTTP behind a Bearer token; gingugu promote harvests a local brain's durable knowledge up to it with provenance stamps |
Architecture
graph TD
A[AI Assistant<br/>any MCP client] -->|MCP Protocol| B[Gingugu Server]
B --> C[Search Engine<br/>FTS5 + BM25]
B --> D[Storage Layer<br/>SQLite + WAL]
B --> E[Decay Engine<br/>Scoring + Dormancy]
B --> F[Context Engine<br/>Auto-Retrieval]
B --> H[Consolidation Engine<br/>Merge + Dedupe]
B --> K[Credential Vault]
C --> D
E --> D
F --> D
H --> D
K --> D
K --> J[OS Keychain<br/>via keyring]
D --> G[(~/.local/share/gingugu/memories.db)]See docs/architecture.md for full technical details.
Setup
Prerequisites
- Python 3.11+
uv(recommended) orpip- macOS, Linux, or Windows — the credential vault uses your OS-native secret
store via
keyring(macOS Keychain, Windows Credential Locker, Linux Secret Service/KWallet). On headless Linux without a Secret Service backend, everything works except storing secrets.
Install
# Recommended: uv (fast, manages Python for you)
uv tool install gingugu
# Or with pip
pip install ginguguThat's it. The gingugu command is now on your PATH.
git clone https://github.com/gingugu/gingugu.git && cd gingugu
uv sync
uv run gingugu # or pip install -e .Usable today. 18 MCP tools live. 532 tests passing. Dogfooded daily in Claude Code and Windsurf — this repo's own memories live in a Gingugu database. Early and seeking broader real-world validation.
Upgrading
1. Upgrade the package.
uv tool upgrade gingugu # if installed with uv
pip install --upgrade gingugu # if installed with pip2. Restart your MCP client. The client spawns the server, so a running
client keeps the old code until it restarts. Schema migrations apply
automatically on the next start, and a one-shot backup of your database
(memories.db.bak-before-vN) is taken before any migration runs. Your
memories are never rewritten by an upgrade.
3. Re-run gingugu init in each repo to pick up improvements to the
hooks and the session protocol:
cd ~/code/my-repo && gingugu init --force--force is what refreshes managed files that already exist; without it,
init leaves them alone and you stay on the old hooks. Run --dry-run first
if you want to see the changes before they land. Your .claude/settings.json
is merged, not overwritten.
If you have edited a managed file yourself, --force saves your version
alongside it as <name>.bak before writing the new one, and says so in the
output. A file it would not change is left untouched and gets no .bak.
gingugu can be reachable through more than one install at once, and they
version
…