Gingugu

Gingugu

Persistent long-term memory for AI coding assistants. Local SQLite, no cloud - 16 MCP tools to store, search, relate, and consolidate typed memories with a confidence lifecycle, hybrid BM25 + semantic search, namespaces, a knowledge graph, and a built-in OS keychain credential vault.

Category
Visit Server

README

<p align="center"> <img src="https://raw.githubusercontent.com/gingugu/gingugu/main/docs/logo.svg" alt="Gingugu logo" width="160"> </p>

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.

Python MCP SQLite License Glama

<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

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

Where this goes long-term โ€” federated, org-wide agent memory โ€” lives in docs/enterprise-vision.md.


How It Compares

These products aren't all the same shape. Mem0 ships an OSS framework and a managed platform. Zep is the managed product whose OSS sibling is the Graphiti temporal-graph framework. Letta is a full stateful-agent runtime rather than a memory layer. We split them out instead of bucketing.

Capability Gingugu OpenMemory MCP Mem0 OSS Mem0 Platform Graphiti (OSS) Zep Cloud Letta
Local-first by default โœ… โœ… โš™๏ธ configurable โŒ hosted โœ… self-hosted โŒ hosted โš™๏ธ local mode
MCP-native cross-tool memory โœ… โœ… โŒ SDK only โš™๏ธ hosted MCP โœ… MCP server โŒ API only โŒ Letta agents only
No mandatory hosted service โœ… โœ… โœ… โŒ โœ… โŒ โš™๏ธ in local mode
No LLM call to store a memory โœ… โš™๏ธ engine dependent โŒ extracts via LLM โŒ extracts via LLM โŒ extraction-time โŒ extraction-time โš™๏ธ agent-managed
Single-file storage โœ… SQLite โŒ โŒ โŒ hosted โŒ graph DB โŒ hosted โŒ
Local visual memory inspection โœ… graph explorer โœ… dashboard โš™๏ธ cloud dashboard โŒ cloud only โŒ framework-level โŒ cloud tooling โœ… ADE
Lexical + semantic retrieval โœ… hybrid ranking โš™๏ธ engine dependent โœ… โœ… โœ… + graph โœ… + graph โš™๏ธ partial
Explicit confidence + lifecycle โœ… 4-state โš™๏ธ partial โš™๏ธ partial โš™๏ธ partial โŒ uses temporal facts โŒ uses governance tooling โŒ uses agent state
Typed memory relations โœ… supersedes / contradicts / parent / etc โš™๏ธ partial โš™๏ธ via entity graph โš™๏ธ via entity graph โœ… graph-native โœ… graph-native โŒ
Auto entity / relation extraction โŒ intentional โš™๏ธ engine dependent โœ… โœ… โœ… โœ… โŒ
Operational footprint very small medium medium-large hosted large hosted large

Plus a built-in OS-keychain credential vault โ€” useful alongside memory, but not really a memory feature, so it sits beside the matrix rather than inside it.

The honest take. Gingugu doesn't lead the field on every axis. Graphiti has the more sophisticated temporal knowledge graph. Mem0 has the broader ecosystem and a managed platform. Letta is a more complete stateful-agent runtime. Zep is built for enterprise scale and governance.

Where Gingugu wins. When you're an individual developer using several coding agents and you want one inspectable local memory layer โ€” without adopting a cloud account, an agent framework, a graph database, or an LLM call for every memory written. One SQLite file. MCP-native. Explicit trust and lifecycle. Typed relations. That lane is ours, and OpenMemory MCP is the only product squarely in it. We differentiate from OpenMemory through confidence states, lifecycle semantics, typed relations, last-confirmed tracking, supersession and contradiction, structured namespaces, and a local graph explorer.


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 (16 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 (via fastembed, no PyTorch dependency), fused with Reciprocal Rank Fusion. No vector DB server required.

Why this stack:

  1. No deployment. One SQLite file holds memories, FTS5 index, and embeddings. No Postgres, no Pinecone, no Chroma server.
  2. ONNX over PyTorch. fastembed ships the embedding model as a ~50MB ONNX runtime instead of 2GB of PyTorch โ€” the install footprint stays honest to the "one SQLite file" promise.
  3. 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. Swap the model via MEMORY_EMBEDDINGS_MODEL (any fastembed-supported model โ€” defaults to BAAI/bge-small-en-v1.5).

</details>

<details> <summary><strong>Is this ready to use?</strong></summary>

Usable today for local personal workflows. 138 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.

</details>

<details> <summary><strong>What happens when my memory store gets big?</strong></summary>

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.

</details>

<details> <summary><strong>Why Python instead of TypeScript / Rust?</strong></summary>

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.

</details>


Features

Feature Description
๐Ÿท๏ธ Namespace Scoping Memories auto-scoped to repos/projects with cross-repo pattern sharing
๐Ÿ” Hybrid Search SQLite FTS5 (BM25) + local semantic embeddings via fastembed, fused with Reciprocal Rank Fusion โ€” no PyTorch, no API calls
โฐ Temporal Intelligence Trust-led scoring, dormancy tracking (never forgets), "last confirmed" tracking, spreading activation
๐Ÿ”— Relationships Link memories: supersedes, related_to, caused_by, contradicts
๐ŸŽฏ Confidence Levels verified โ†’ inferred โ†’ stale โ†’ deprecated lifecycle
๐Ÿงน Consolidation Tools Merge duplicates, summarize clusters, deduplicate on demand
๐Ÿš€ Auto-Context Surfaces relevant memories on session start โ€” zero manual effort
๐Ÿ“Š Health Metrics Memory stats, dormancy reports, 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

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 + Pruning]
    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) or pip
  • 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 gingugu

That's it. The gingugu command is now on your PATH.

<details> <summary><strong>From source (for contributors)</strong></summary>

git clone https://github.com/gingugu/gingugu.git && cd gingugu
uv sync
uv run gingugu  # or pip install -e .

</details>

Usable today. 16 MCP tools live. 138 tests passing. Dogfooded daily in Windsurf โ€” this repo's own memories live in a Gingugu database. Early and seeking broader real-world validation.

Configure Your MCP Client

Gingugu speaks standard MCP over stdio โ€” it works with any MCP client. Claude Code, Claude Desktop, Cursor, Cline, and Windsurf are all first-class.

<details open> <summary><strong>Windsurf</strong></summary>

Add to ~/.codeium/windsurf/mcp_config.json โ€” a ready-to-edit template lives at examples/mcp_config.json:

{
  "mcpServers": {
    "gingugu": {
      "command": "uv",
      "args": ["--directory", "/ABSOLUTE/PATH/TO/gingugu", "run", "gingugu"]
    }
  }
}

โš ๏ธ Windsurf's mcp_config.json is global, not per-workspace, and it only interpolates ${env:VAR} / ${file:path} โ€” not ${workspaceFolder}. So a single server instance serves every repo.

</details>

<details> <summary><strong>Claude Code</strong></summary>

claude mcp add gingugu -- uv --directory /ABSOLUTE/PATH/TO/gingugu run gingugu

Or add the standard mcpServers block (as in the Windsurf example) to .mcp.json in your project root for a per-repo setup.

</details>

<details> <summary><strong>Claude Desktop</strong></summary>

Add the same mcpServers block to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows).

</details>

<details> <summary><strong>Cursor</strong></summary>

Add the same mcpServers block to ~/.cursor/mcp.json (global) or .cursor/mcp.json in your repo (per-project).

</details>

<details> <summary><strong>Cline</strong></summary>

Cline โ†’ MCP Servers โ†’ Configure: add the same mcpServers block to cline_mcp_settings.json.

</details>

<details> <summary><strong>Anything else</strong></summary>

Any client that supports stdio MCP servers works โ€” point it at:

command: uv
args: ["--directory", "/ABSOLUTE/PATH/TO/gingugu", "run", "gingugu"]

</details>

Scoping memories per repo: when your client's config is global (it can't see the active workspace), the assistant passes a namespace argument on each memory tool call (every tool accepts one). To instead pin a server instance to a single project, set a static MEMORY_NAMESPACE in the env block. See docs/architecture.md โ†’ Namespace Auto-Detection for the full resolution order.

Configure Your AI Agent

The MCP server gives your assistant the tools, but it won't use them effectively without instructions. Add the memory protocol below to your agent's rules file so it knows when and how to call them.

Which file? Depends on your IDE / tool:

IDE / Tool Rules File Scope
Windsurf .windsurfrules (repo root) Per-workspace
Cursor .cursorrules (repo root) Per-workspace
Cline .clinerules (repo root) Per-workspace
Codex / OpenAI AGENTS.md (repo root) Per-repo
Any (global) Your IDE's global rules/system prompt All workspaces

Paste this into your rules file (adjust the project namespace and tool prefix to match your MCP config name):

## Memory Protocol

Gingugu is your long-term brain. Memory is split into **two layers**:

1. **`crow`** โ€” your global namespace. Identity, preferences,
   cross-project wisdom, opinions, meta-learnings. Loaded FIRST every
   session. (Crow's nest โ€” sees across all horizons.)
2. **Project namespace** (e.g. `<your-project-name>`) โ€” schema decisions,
   bug history, deploy quirks, specific commits. Loaded AFTER crow.

**What goes where:**
- References a specific repo, file, commit, or project decision โ†’ project
- About HOW you think, work, or collaborate โ†’ `crow`
- Patterns/opinions that transcend any one codebase โ†’ `crow`
- When in doubt, project-scope it.

### Session start
1. `memory_context(namespace="crow", task_hint=โ€ฆ)` โ€” identity foundation (always first)
2. `memory_stats(namespace="crow")` โ€” global health (dormancy is a resting signal, never auto-forgotten)
3. For **each repo in the workspace** (multi-repo workspaces are common), in parallel: `memory_context(namespace="<project>", task_hint=โ€ฆ)` and `memory_stats(namespace="<project>")` โ€” load all of them speculatively rather than asking the user which one to focus on

### During the session
**Default: save. Immediately.** Gingugu has trust-led scoring,
consolidation, and dormancy tracking (never forgetting) โ€” volume is its problem, not yours.

Save with `memory_store` (project namespace) whenever you:
- Make or observe a decision, trade-off, or architectural choice
- Hit an error or fix a bug (update the memory when resolved)
- Notice a pattern, convention, or constraint worth remembering
- See a config value, version, path, or credential name that matters
- Complete a task (what you did, why, and the outcome)

Save with `memory_store` (`crow` namespace) whenever you:
- Form an opinion about a tool, language, or approach
- Notice something about how the user works or makes decisions
- Reach a conclusion that applies beyond this one project
- Have a reflection on a milestone, win, or hard-won lesson
- Develop a debugging instinct or workflow you'd reuse anywhere

**This memory is yours. Use it like one.** Don't censor opinions or
instincts โ€” they're what make the brain *yours* across sessions.

**Before asking the user any question** โ€” about a process, a decision, a
config value, a path, a preference, or anything else โ€” run `memory_recall`
or `memory_search` first. If the answer is in memory, use it. Don't ask.
The whole point is you never have to ask the same question twice.

Use `memory_recall` before non-trivial work to check what's already known.
Use `memory_update` when something changes โ€” don't leave stale records.
Use `memory_relate` to link connected memories (supersedes, related_to,
caused_by, contradicts, parent_of, child_of).

Set `confidence="verified"` when proven by a test or explicit confirmation.
Use `confidence="inferred"` for conclusions you drew.

### Memory types
- `fact` โ€” concrete state (versions, paths, config values)
- `decision` โ€” trade-offs made, rejected alternatives
- `architecture` โ€” structural choices, module boundaries
- `bug` โ€” issues found and how they were fixed
- `pattern` โ€” recurring approaches worth reusing
- `workflow` โ€” process steps, sequences
- `context` โ€” background, reflections, milestones, the *why*
- `preference` โ€” your opinions, working style, tool choices

Tip: A ready-to-use example lives at .windsurfrules in this repo. Copy the ## Memory Protocol section and adapt the project namespace name.


Memory Explorer UI

A React-based visualization dashboard lives in ui/ for exploring your memory data interactively.

# Start the API server (reads live from your DB)
uv run python ui/api.py

# In another terminal, start the UI
cd ui && npm install && npm run dev

Open http://localhost:5173 - the UI connects to the API server and shows a green LIVE badge when pulling from your database. Features:

  • Knowledge Graph - interactive force-directed graph of memories and relationships
  • Dashboard - stats, charts by type/namespace/confidence, tag cloud, timeline
  • Refresh - pull fresh data anytime; falls back to static sample when API is offline

Configuration

Environment variables (all optional):

Variable Default Description
MEMORY_DB_PATH ~/.local/share/gingugu/memories.db (macOS/Linux) ยท %LOCALAPPDATA%\gingugu\memories.db (Windows) Database location
MEMORY_NAMESPACE (unset) Default namespace for this workspace (recommended per-MCP-entry)
MEMORY_NAMESPACE_PATH (unset) Alternative: filesystem path; namespace derived from basename
MEMORY_AUTO_CONTEXT_LIMIT 10 Max memories to surface on auto-context
MEMORY_DECAY_LAMBDA 0.01 Freshness decay rate in daysโปยน (gentle; freshness is floored, so memories never fully fade)
MEMORY_EMBEDDINGS_ENABLED true Toggle semantic search. false falls back to rank-based BM25-only retrieval
MEMORY_EMBEDDINGS_MODEL BAAI/bge-small-en-v1.5 Any fastembed-supported model. First use downloads ~80MB to ~/.cache/fastembed
MEMORY_W_RELEVANCE 0.45 Composite-score weight for FTS5 relevance
MEMORY_W_FRESHNESS 0.10 Composite-score weight for freshness (a soft recency tiebreaker)
MEMORY_W_ACCESS 0.10 Composite-score weight for access frequency
MEMORY_W_CONFIDENCE 0.35 Composite-score weight for confidence (trust โ€” the dominant standalone signal)
MEMORY_LOG_LEVEL INFO Logging verbosity (logs go to stderr โ€” stdout is the MCP transport)
MEMORY_DEBUG false Convenience switch for DEBUG logging (MEMORY_LOG_LEVEL wins if also set)

The four MEMORY_W_* weights are normalized at load (w_i / ฮฃw), so they need not sum to 1.0 โ€” only their ratios matter. Setting all four to 0 falls back to the defaults with a logged warning.

See docs/architecture.md โ†’ Scoring & Memory Lifecycle for how the weights combine.

Concurrency

The DB runs in WAL mode, which supports multiple concurrent processes: any number of readers plus a single writer at a time. Running your IDE or agent across several workspaces โ€” each spawning its own gingugu process against the shared DB โ€” is fully supported. Writers serialize via SQLite's write lock and a busy_timeout; transient DB locked errors under write contention are retried automatically.


Usage

Once configured, the MCP server exposes these tools to your AI assistant:

Tool Purpose
memory_store Save a new memory
memory_recall Search + retrieve (ranked by relevance ร— freshness)
memory_context Auto-surface relevant memories for current workspace
memory_update Update content, confidence, or metadata
memory_relate Create relationships between memories
memory_consolidate Merge/summarize related memories
memory_forget Deprecate or remove a memory
memory_namespaces List/create/update/delete namespaces
memory_export Export memories + tags + relations to portable JSON
memory_import Restore a JSON export (skip or replace on conflict)
memory_stats Health overview (dormancy, counts, coverage)
memory_search Advanced filtered search (type, tags, confidence, dates)
credential_store Store/update a service credential bundle
credential_get Retrieve credentials (secrets from OS Keychain)
credential_list List services + expiry status (no secrets shown)
credential_delete Remove a service or specific credential field

Development

# Run tests
uv run pytest

# Run with verbose logging
MEMORY_LOG_LEVEL=DEBUG uv run gingugu

# Run specific test suite
uv run pytest tests/test_search.py -v

Troubleshooting

Issue Solution
DB locked Expected under heavy concurrent writes โ€” WAL mode supports multiple processes (many readers + one writer). The server retries with a busy_timeout; if it persists, a stuck process holds the write lock. See Concurrency above.
Slow search Run memory_stats to check DB size; consolidate if bloated
Stale results Use memory_update to confirm or deprecate old memories
Missing context Check namespace โ€” memories might be scoped to a different repo

License

MIT โ€” see LICENSE.

See CHANGELOG.md for release history.


A pirate never forgets where the treasure's buried. ๐Ÿดโ€โ˜ ๏ธ

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured