A local MCP server that gives agents a measurable, explainable knowledge base
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
- !Licence file present but not machine-readable
- !Install pipes a remote script into a shell (curl | sh)
git clone https://github.com/kKEo/memory-find{
"mcpServers": {
"memory-find": {
"command": "memory-find"
}
}
}Resumen de MCP Servers
<!-- mcp-name: io.github.kKEo/memory-find -->
# memo-mcp
A local [MCP](https://modelcontextprotocol.io) server that gives agents a measurable, explainable knowledge base: one Go binary, no cloud, no CGo, one SQLite file per knowledge base. Documents and facts go in with provenance; searches come back as one ranked list from four retrieval arms, each result with its address, trust and a reason for its rank. A human reads the same knowledge base from the terminal or as exported markdown.
It began as a Go rewrite of [obra/private-journal-mcp](https://github.com/obra/private-journal-mcp) and was rebuilt from scratch as a knowledge base in 2026-10. Version 1.0 fixes the contract: tool names and parameters, the `memo://` addresses, the explain fields and the export format. How search decides is written down in [`docs/architecture.md`](docs/architecture.md); the plan for the research layers (graph, compaction, web UI) is [`docs/roadmap.md`](docs/roadmap.md); the research behind it is [`docs/knowledge-base-sota.md`](docs/knowledge-base-sota.md).
## What it does
Claude (or any MCP client) gets ten tools over one knowledge base:
| Tool | Purpose |
|---|---|
| `ingest` | Store a document the agent fetched or wrote, as markdown; identical content is a no-op, changed content or a new version becomes a new revision |
| `search` | Find passages by words, exact identifiers and meaning, fused into one list; `response_format: explain` says why each result ranked |
| `read` | Dereference a `memo://` address: a passage, its section, or the whole document under a token budget |
| `remember` | Record one atomic fact with evidence and validity dates; to correct a fact, pass `supersedes` and the old one is kept as history |
| `forget` | Retire a document or fact with a reason; it leaves every index and its address resolves to "forgotten on … because …". Tool calls may only retire records written by tools |
| `promote` | Ask to raise a record's trust; tool calls cannot do it themselves. Clients that can show a dialog ask the human directly (excerpt, source, target level); others get the command a human runs |
| `explore` | Walk the graph index from one named thing: the passages that mention it and the things mentioned alongside it, each with evidence addresses |
| `compact` | Propose tidying work: entities that deserve a page, stale pages, facts that disagree, near-duplicate names and passages. Each item carries the passages and facts needed; the server never writes a page |
| `submit` | Hand back a page, a conflict decision or a merge decision. Pages are stored as derived (`is_inference`) with the passages they cite; the omission check reports facts the page left out; `dry_run` shows the diff first |
| `status` | Namespaces, the embedding model, pending vectors, background jobs, graph and page counts |
For a human there is `memo-mcp ui`: a read-only web page on loopback with the same search (and the same explain table the agent gets), documents and passages with provenance and history, the facts timeline, entity neighbourhoods, agent-written pages, status, lint and the query log. Nothing on it can change the knowledge base.
The same addresses are readable as MCP resources (`memo://doc/{id}`, `memo://chunk/{id}`, `memo://source/{id}`, `memo://fact/{id}`), and `memo://index` or `memo://ns/{namespace}/index` give a one-line-per-document view under 8 KB for the start of a session. [`SKILL.md`](SKILL.md) tells an agent how to use the tools well; `memo-mcp export --index` prints the same index for an `AGENTS.md` or `CLAUDE.md` file.
Everything is stored locally. There is exactly one outbound network call in the whole system: downloading the embedding model from Hugging Face on first start. After that, nothing leaves the machine. The server never fetches URLs; the agent fetches and passes the text.
## How search works
`search` runs up to three retrieval arms over the same pre-filtered set of live passages and fuses them:
- **Keyword arm** — SQLite FTS5 with the Porter stemmer and BM25 scoring, over the passage and its section header. "review" finds "reviewing".
- **Exact arm** — a second FTS5 index that keeps identifiers whole (`useCallback`, `net/http`, `ERR_CONN_RESET`). Added automatically when the query looks like code.
- **Semantic arm** — the query and every passage are embedded with the configured model (default `granite-small-r2`, IBM granite-embedding-small-english-r2, 384 dimensions, run locally via [hugot](https://github.com/knights-analytics/hugot)'s pure-Go ONNX backend) and compared by cosine similarity in a plain SQLite table. `memo-mcp model ls` lists the alternatives, including the instant static model `potion`.
The three ranked lists are combined with reciprocal rank fusion at equal weights (a keyword-only hit at rank 1 ties a vector hit at rank 1, so the keyword arm can add results rather than only reorder them), passages are aggregated to documents by their best passage, notes and conversations get a bounded recency boost (×0.8 to ×1.0, halving every 90 days; versioned docs do not age), the list is cut at the first large score gap, and results are packed to the requested token budget. A passage whose only evidence is a semantic similarity below the weak band (0.30) is dropped, so a question about nothing in the corpus returns zero results with a reason and a hint instead of a page of noise.
Two **structural arms** join when the question names two or more known things or asks how things relate: the entity arm returns the passages that mention the named entities, and the graph arm walks the mention graph with personalised PageRank from each named entity and returns the passages all the walks agree on, which is how a question about the Billing Service finds the replication page that never names it. `explore` walks the same graph by hand. Both are routed rather than always on because an always-on entity arm made plain lookups worse.
Curated **pages** are a third thing to search (`granularity: page`): markdown an agent wrote from passages through `compact` and `submit`, stored as derived, citing the passages it was built from, and marked stale the moment one of those passages' documents is revised or forgotten.
A fourth text arm matches **facts** recorded with `remember` and votes for their evidence passage ("facts as extra keys"); `granularity: fact` returns the facts themselves. `as_of` answers with what the knowledge base believed at a date: superseded revisions and replaced facts that were current then. Forgotten records are never returned, not even under `as_of`. Scope filters (namespaces, kinds, sources, library, version, tags, dates, minimum trust) are applied inside every arm's query, before ranking, so a filtered search never loses a result. Each result carries its provenance and a relevance band; with `response_format: explain` it also carries the per-arm ranks and contributions, the recency factor, and a per-query trace (which arms ran and why, what the scope excluded, where the list was cut). The terminal shows the same numbers: `memo-mcp search "<q>" --explain` and `memo-mcp explain "<q>" memo://chunk/<n>`.
## Storage
One SQLite file per `MEMO_KB` name, at `~/.memo-mcp/kb/<name>.db` (or under `$MEMO_HOME/kb/` if set); the deprecated `JOURNAL_TOKEN` keeps opening `~/.memo-mcp/<token>.db`. Directories and files memo-mcp creates are restricted to the owner (`0700`/`0600`); a directory that already existed with wider permissions is not tightened. WAL mode is on, so two processes touching the same token (e.g. two concurrent Claude Code sessions) don't collide.
The name is explicit rather than inferred from the working directory — set `MEMO_KB` per project (in the MCP server config, not the shell) and each project gets its own isolated knowledge base. Inside one file, namespaces are shelves that a search spans by default; separate files are the privacy boundary.
## Setup
**From a release.** Download the archive for your platform from [releases](https://github.com/kKEo/memory-find/releases), unpack `memo-mcp` somewhere on your `PATH`, and run `memo-mcp version`. Archives exist for macOS and Linux (amd64, arm64) and Windows (amd64). The server is also listed in the MCP registry as `io.github.kKEo/memory-find`.
**From source.** Requires Go 1.26+.
```bash
git clone https://github.com/kKEo/memory-find
cd memory-find
make build
```
This produces a single `memo-mcp` binary (`CGO_ENABLED=0`, ~30MB, no runtime dependencies).
With Claude Code:
```bash
claude mcp add memo --env MEMO_KB=my-project -- /path/to/memo-mcp
```
Add it to Claude Code or Claude Desktop's MCP config:
```json
{
"mcpServers": {
"memo": {
"command": "/path/to/memo-mcp",
"env": {
"MEMO_KB": "my-project"
}
}
}
}
```
On first start memo-mcp downloads the default embedding model (granite-embedding-small-english-r2, Apache-2.0, about 140MB) into `~/.cache/memo-mcp/models` and prints one line to stderr. Until the model is ready, search runs keyword-only and says so (`degraded`); documents written meanwhile get their vectors when the model arrives. To download ahead of time run `memo-mcp model pull granite-small-r2`. An interrupted download is detected and retried on the next run.
### Commands
Running the binary with no arguments starts the MCP server on stdio. From the terminal:
- `memo-mcp ingest <file|dir|-> [--ns --kind --uri --title --library --version --trust --context --embed=false]` — add markdown documents; identical content is a no-op, changed content becomes a new revision
- `memo-mcp search "<query>" [--mode auto|hybrid|keyword|exact|semantic --ns --library --version --kind --limit --format table|json|md --explain --no-model]` — search; `--explain` adds why each result ranked
- `memo-mcp explain "<query>" <memo://chunk/n>` — the full explanation for one result
- `memo-mcp log tail|calls|show <id>|replay|prune` — the opt-in query and call logs (`MEMO_QUERY_LOG=1`); `calls` lists tool cLo que la gente pregunta sobre memory-find
¿Qué es kKEo/memory-find?
+
kKEo/memory-find es mcp servers para el ecosistema de Claude AI. A local MCP server that gives agents a measurable, explainable knowledge base Tiene 0 estrellas en GitHub y su última actualización registrada es del 2026-10-03.
¿Cómo se instala memory-find?
+
Puedes instalar memory-find clonando el repositorio (https://github.com/kKEo/memory-find) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar kKEo/memory-find?
+
Nuestro agente de seguridad ha analizado kKEo/memory-find y le ha asignado un Trust Score de 72/100 (tier: OK). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene kKEo/memory-find?
+
kKEo/memory-find es mantenido por kKEo. La última actividad registrada en GitHub es del 2026-10-03, con 0 issues abiertos.
¿Hay alternativas a memory-find?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega memory-find en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/kkeo-memory-find)<a href="https://claudewave.com/repo/kkeo-memory-find"><img src="https://claudewave.com/api/badge/kkeo-memory-find" alt="Featured on ClaudeWave: kKEo/memory-find" width="320" height="64" /></a>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
The fastest path to AI-powered full stack observability, even for lean teams.