mcp server
ginko
Experimental local-first canonical memory layer for AI agents. Go + SQLite + HTTP API + MCP.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 26, 2026Ginko
Ginko — install for your Claude Code agent
Persistent memory for your Claude Code agent. Like ginkgo biloba — but it actually works.
Note: Ginko is unrelated to the Ginkgo Go testing framework.
go install github.com/salemarsm/ginko/cmd/ginko@latest
ginko setup claude-code
Or via the Claude Code plugin marketplace (recommended):
/plugin marketplace add salemarsm/ginko
/plugin install ginko
That's it. Restart Claude Code and the memory tools are available to the agent.
The plugin includes:
- MCP server (
ginko mcp) - Memory Protocol skill — teaches the agent when and how to remember
- SessionStart hook — recovers context from previous sessions automatically
- PreCompact hook — auto-checkpoints memory before context compaction
- Slash commands
/ginko:saveand/ginko:recall
For the design rationale, schema, retrieval pipeline, and competitive analysis, see the white paper and the project documentation below.
English
ginko is a durable memory layer for AI agents, coding assistants, RAG systems, and local LLM workflows.
It solves a common problem: agents often confuse chat history, vector search, document chunks, and durable memory.
ginko keeps them separate.
- Memories are compact, structured, auditable records.
- Documents and chunks are evidence.
- Embeddings are optional indexes.
- LLMs are clients, not databases.
- SQLite is the canonical source of truth.
Vector search is not memory. Chat history is not memory. The LLM is not the database.
Status
Experimental v0.x. The local core, HTTP API, CLI, MCP server, token-budgeted context, and heuristic suggestion flow are implemented. APIs and schemas may change before v1.0.
Implemented today:
- SQLite canonical memory store
- append-only events
- FTS5 memory search
- HTTP API and local GUI
memctl,memmcp, andginkoCLIs- MCP tools:
memory_context,memory_suggest,memory_remember,memory_search - heuristic memory suggestions
- document/chunk schema foundation for future RAG ingestion
- HTTP API bearer-token auth for non-loopback binds
Planned / not production-ready yet:
- Docling ingestion command
- hybrid vector ranking
- full contradiction resolution policy
- production multi-user isolation
- stable v1 API guarantees
Technical deep dive
For readers who want the full model and rationale, see the white paper:
It covers the canonical-memory model, SQLite schema philosophy, retrieval/context pipeline, RAG boundaries, governance/auditability, and why embeddings remain optional indexes instead of the source of truth.
The problem
Most agent memory systems confuse three different things:
- raw conversation history
- retrieved document chunks
- canonical durable memory
Vector databases are useful indexes, but they are poor sources of truth.
Prompts are not databases. LLMs are not memory owners. Chat logs are not durable knowledge.
ginko separates these layers:
raw events -> audit trail
documents -> evidence
chunks -> retrievable evidence
memories -> canonical conclusions
context -> compact prompt-ready projection
LLM -> client
SQLite -> source of truth
Why not just...?
| Approach | Good for | Weakness |
|---|---|---|
| Markdown files | Human-readable project knowledge | Weak querying, no audit model, hard to automate safely |
| Vector DB only | Semantic search over large corpora | Not canonical, hard to audit, embeddings drift |
| Chat history | Short-term continuity | No durable schema, noisy, context-window bound |
| LangChain-style memory | App-level convenience | Often runtime-coupled and prompt-format dependent |
| Plain SQLite | Durable local storage | You still need an agent memory model and retrieval policy |
ginko | Canonical durable memory for agents | Needs integration with your agent/runtime |
What you get
- canonical memory records in SQLite
- append-only event log
- SQLite FTS5 search without requiring embeddings
- optional embedding references without making vectors canonical
- supersession for replacing stale memories without destroying history
- scopes:
global,project,session,private - types:
preference,fact,decision,task,note,relationship - HTTP API
- embedded local web GUI
- CLI tools
- MCP server for transparent agent integration
- token-budgeted context endpoint
- memory suggestion flow
- RAG document/chunk foundation
- no CGO via
modernc.org/sqlite
Positioning vs similar projects
Projects like Mem0, Zep, LangMem, sqlite-memory, and Engram validate the category. ginko should not compete as a generic "memory layer" clone.
The sharper niche is:
Canonical local memory for coding agents and personal AI infrastructure.
See Choosing Engram or Ginko for the closest direct comparison and the implementation practices we should borrow without losing this project's canonical-memory focus.
5-minute quickstart
git clone https://github.com/salemarsm/ginko.git
cd ginko
make build
bin/ginko init
bin/ginko doctor
bin/ginko ui
Open:
http://127.0.0.1:8787
Store your first memory:
echo "The user prefers direct technical answers." \
| bin/memctl -subject botmaster -scope global -type preference remember
Retrieve compact prompt context:
bin/memctl -subject botmaster -scope global -max-tokens 400 context "How should I answer?"
Suggest durable learnings from text:
bin/memctl -subject botmaster suggest "I prefer direct answers and Go examples."
More: Quickstart, CLI, MCP.
Operational flow
User prompt
↓
Agent calls /api/context or MCP memory_context
↓
ginko retrieves compact relevant memories
↓
Agent answers normally
↓
Agent calls /api/suggest or MCP memory_suggest
↓
Human/policy approves durable candidates
↓
Memory is stored or superseded
↓
Event log records what happened
RAG is evidence. Memory is conclusion.
Documents and chunks answer:
Where did this come from?
Canonical memories answer:
What durable thing should the agent remember?
Example:
Document chunk:
"In meeting notes, the team decided to use SQLite for local-first storage."
Canonical memory:
"The Ginko project uses SQLite as the canonical local-first store."
Evidence:
doc_id=..., chunk_id=...
See RAG pipeline. Docling ingestion is planned; document/chunk tables are implemented as the foundation.
Memory types
| Type | Use for | Example |
|---|---|---|
preference | stable user/project preferences | User prefers Go examples over Python examples. |
fact | durable factual statements | The project uses SQLite as the canonical store. |
decision | architecture/project decisions | Embeddings are optional indexes, not canonical truth. |
task | long-lived pending actions | Add API token support. |
note | low-structure observations | The GUI is currently local-only. |
relationship | links between entities | Project X belongs to client Y. |
Full model: Memory model.
Memory write policy
Agents should not store everything.
Store:
- explicit user preferences
- stable project facts
- architectural decisions
- corrections
- durable constraints
- long-lived tasks
- approved learnings inferred from repeated or explicit behavior
Do not store:
- transient chat context
- secrets or credentials
- sensitive personal data without explicit approval
- raw document chunks as memories
- uncertain inference as fact
- private data in shared/group contexts
More: Security, MCP transparent usage, Suggestion engine.
HTTP API
The API is documented in docs/openapi.yaml.
Core endpoints are available under /api/... and /api/v1/...; new integrations should prefer /api/v1/....
Core endpoints:
| Endpoint | Purpose |
|---|---|
POST /api/context | compact token-budgeted prompt context |
POST /api/suggest | suggest durable memories/learnings |
POST /api/memories | create/update memory |
POST /api/search | raw memory search |
POST /api/supersede/{id} | replace stale memory |
DELETE /api/memories/{id} | forget memory |
GET /api/events | audit events |
GET /healthz | local health check |
Example response from POST /api/context:
{
"context": "- [preference/global conf=0.95 src=conversation:msg-123] User prefers direct technical answers.",
"items": [
{
"id": "mem_01J...",
"type": "preference",
"subject": "botmaster",
"content": "User prefers direct technical answers.",
"scope": "global",
"confidence": 0.95
}
],
"estimated_tokens": 31,
"budget_tokens": 400,
"truncated": false
}
Real SQLite schema excerpt
The canonical memory table is intentionally boring and inspectable:
CREATE TABLE memories (
id TEXT PRIMARY KEY,
type TEXT NOT NULL,
subject TEXT NOT NULL,
content TEXT NOT NULL,
source_kind TEXT NOT NULL,
source_ref TEXT NOT NULL,
scope TEXT NOT NULL,
confidence REAL NOT NULL CHECK(confidence >= 0 AND confidence <= 1),
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
valid_from TEXT,
valid_until TEXT,
supersedes_id TEXT,
superseded_by TEXT,
tags_json TEXT NOT NULL DEFAULT '[]',
embedding_refs_json TEXT NOT NULL DEFAULT '{}'
);
CREATE TABLE memory_tags (
memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
tag TEXT NOT NULL,
PRIMARY KEY(memory_id, tag)
);
CREATE VIRTUAL TABLE memories_fts
USING fts5(id UNINDEXED, content, subject, tags);
Full schema notes: Memory model.
Transparent MCP integration
memmcp exposes memory as MCP tools:
memory_contextmemory_suggestmemory_remembermemory_search
The target UX is invisible memory:
- user asks normally
- agent silently calls
memory_context - agent answers normally
- agent calls
memory_suggest - safe/approved candidates are stored with
memory_remember
Generate MCP snippets:
bin/ginko install-mcp claude-code
bin/ginko install-mcp codex
bin/ginko install-mcp openclaw
Details: MCP integration.
Architecture
┌──────────────────────────┐
│ OpenClaw / Claude / Codex │
└────────────┬─────────────┘
│ MCP / HTTP / CLI
┌────────────▼─────────────┐
│ Ginko API │
├──────────────────────────┤
│ Context builder │
│ Suggestion engine │
│ Write policy │
├──────────────────────────┤
│ Canonical memories │
│ Append-only events │
│ Documents / chunks │
├──────────────────────────┤
│ SQLite + FTS5 │
│ Optional vector indexes │
└──────────────────────────┘
Security model
Current default assumption:
- local-only usage
- bind to
127.0.0.1 - no public network exposure
- no secrets in memory content
- no production multi-user isolation yet
Do not expose the HTTP server to untrusted networks until API token/local auth is implemented.
See Security.
Use cases
Coding agent memory
Remember project decisions, coding style, architecture, local commands, and constraints.
Personal AI assistant
Remember stable preferences and recurring workflows without pinning them to one model vendor.
RAG + canonical memory
Convert messy documents into evidence and durable conclusions.
Research lab / security workflows
Keep project-specific knowledge compartmentalized per tool, target, client, or engagement.
Roadmap
v0.1 — Local core
- SQLite store
- migrations
- FTS5 search
- event log
- HTTP API
- embedded GUI
- CLI
v0.2 — Agent integration and local safety
- MCP tools
- token-budgeted context
- memory suggestion
- CLI integration
- OpenClaw / Claude Code / Codex examples
- local API token
v0.3 — Governance
- memory write policy enforcement
- sensitive-data guardrails
- soft delete vs hard delete
- audit UI
v0.4 — RAG bridge
- document import
- Docling ingestion
- chunk evidence
- memory candidate extraction
- citation linking
v0.5 — Retrieval quality
- hybrid ranking
- confidence scoring
- recency weighting
- supersession-aware retrieval
- optional vector adapters
Documentation
- Quickstart
- Concepts
- Architecture
- Memory model
- HTTP API
- OpenAPI
- White paper
- White paper source
- CLI
- MCP
- Suggestion engine
- RAG pipeline
- Security
- Roadmap
- Backlog
License
MIT.
Português
ginko é uma camada local-first de memória canônica para agentes de IA, coding assistants, sistemas RAG e fluxos com LLM local/remota.
Ele resolve um problema comum: agentes confundem histórico de chat, busca vetorial, chunks de documentos e memória durável.
ginko separa essas camadas:
- Memórias são registros compactos, estruturados e auditáveis.
- Documentos e chunks são evidência.
- Embeddings são índices opcionais.
- LLMs são clientes, não bancos de dados.
- SQLite é a fonte canônica da verdade.
Busca vetorial não é memória. Histórico de chat não é memória. A LLM não é o banco de dados.
Aprofundamento técnico
Para leitores que quiserem a fundamentação completa, leia o white paper:
Ele detalha o modelo de memória canônica, a filosofia do schema SQLite, o pipeline de retrieval/contexto, os limites entre RAG e memória, governança/auditoria e por que embeddings são índices opcionais, não a fonte da verdade.
O problema
A maioria dos sistemas de memória para agentes mistura três coisas diferentes:
- histórico bruto de conversa
- chunks de documentos recuperados
- memória canônica e durável
Vector DBs são índices úteis, mas são fontes ruins da verdade.
Prompts não são bancos de dados. LLMs não são donas da memória. Logs de chat não são conhecimento durável.
ginko separa:
eventos brutos -> trilha de auditoria
documentos -> evidência
chunks -> evidência recuperável
memórias -> conclusões canônicas
contexto -> projeção compacta pronta para prompt
LLM -> cliente
SQLite -> fonte da verdade
Por que não só...?
| Abordagem | Boa para | Fraqueza |
|---|---|---|
| Arquivos Markdown | conhecimento legível por humanos | consulta fraca, pouca auditoria, automação difícil |
| Só vector DB | busca semântica em corpus grande | não é canônico, difícil auditar, embeddings mudam |
| Histórico de chat | continuidade curta | sem schema durável, ruidoso, preso à janela de contexto |
| Memória estilo LangChain | conveniência em app | frequentemente acoplada ao runtime/prompt |
| SQLite puro | storage local durável | ainda falta modelo de memória e política de retrieval |
ginko | memória canônica durável para agentes | precisa integrar com o agente/runtime |
Começo rápido
git clone https://github.com/salemarsm/ginko.git
cd ginko
make build
bin/ginko init
bin/ginko doctor
bin/ginko ui
Abra:
http://127.0.0.1:8787
Guardar primeira memória:
echo "O usuário prefere respostas diretas e técnicas." \
| bin/memctl -subject botmaster -scope global -type preference remember
Recuperar contexto compacto:
bin/memctl -subject botmaster -scope global -max-tokens 400 context "Como devo responder?"
RAG é evidência. Memória é conclusão.
Documentos e chunks respondem:
De onde isso veio?
Memórias canônicas respondem:
O que o agente deve lembrar de forma durável?
Exemplo:
Chunk documental:
"Nas notas da reunião, o time decidiu usar SQLite para storage local-first."
Memória canônica:
"O projeto Ginko usa SQLite como store canônico local-first."
Política de escrita
Agentes não devem salvar tudo.
Salvar:
- preferências explícitas
- fatos estáveis do projeto
- decisões arquiteturais
- correções
- constraints duráveis
- tarefas de longo prazo
- aprendizados aprovados
Não salvar:
- contexto transitório
- segredos ou credenciais
- dados pessoais sensíveis sem aprovação explícita
- chunks brutos como memória
- inferência incerta como fato
- dados privados em chats compartilhados
Integração MCP transparente
A UX desejada é invisível:
- usuário pergunta normalmente
- agente chama
memory_contextsilenciosamente - agente responde normalmente
- agente chama
memory_suggest - candidatos seguros/aprovados são salvos com
memory_remember
Gerar snippets MCP:
bin/ginko install-mcp claude-code
bin/ginko install-mcp codex
bin/ginko install-mcp openclaw
Segurança
Premissas atuais:
- uso local
- bind em
127.0.0.1 - sem exposição pública
- sem segredos no conteúdo da memória
- sem isolamento multiusuário de produção ainda
Não exponha o servidor HTTP a redes não confiáveis até existir API token/auth local.
Documentação
A documentação detalhada está em docs/.
Licença
MIT.