Mnemos

Servidor de memória MCP local-first sem dependências externas, com citações de fontes e KB em OKF/Markdown.

Documentação

mnemos

CI Go Report Card Latest release Go version License: MIT

OKF BundleDex

Dê ao seu agente de IA uma memória que ele possa citar.

Memória local para agentes de IA. Citações de fonte incluídas.

O Claude Code é poderoso, mas ele esquece o contexto do seu projeto:

  • ele esquece por que você rejeitou uma arquitetura,
  • ele perde seus ADRs,
  • ele inventa respostas em vez de ler seus documentos,
  • ele não consegue citar de forma confiável de onde uma afirmação veio.

mnemos resolve isso dando a ele uma memória local e citada de:

  • seus ADRs e documentos de design
  • suas anotações e runbooks
  • seu código-fonte
  • sua base de conhecimento OKF

Sem banco de dados vetorial. Sem Ollama. Sem serviço Python ou Node. Apenas um binário Go sem cgo que indexa seus arquivos — qualquer pasta de Markdown simples funciona como está — e os serve via MCP, para que o Claude possa pesquisar, ler e citar seu próprio conhecimento em vez de adivinhar, com cada resposta apontando para o file#section exato e intervalo de linhas.

mnemos CLI: init, ingest, and a search that returns a cited result

Experimente em 60 segundos

# 1. install — one cgo-free binary into $GOBIN (requires Go 1.25+)
git clone https://github.com/arhuman/mnemos.git && cd mnemos
make install

# 2. index a project
cd ~/work/myproject
mnemos init                              # creates ./.mnemos/ (mnemos.toml, kb, db, models)
mnemos add docs --collection myproject   # copy a directory into the kb and index it
mnemos search "why did we choose this architecture"

Prefere make build (→ ./bin/mnemos) para mantê-lo fora do seu $PATH. O build padrão é Go puro / sem cgo (CGO_ENABLED=0).

search imprime citações que você pode abrir:

1. security/scim.md#Provisioning
   lines 42-88
   score 12.7

Depois conecte-o ao Claude Code (observe o caminho absoluto do --config):

claude mcp add mnemos -- mnemos serve --config /abs/path/to/myproject/.mnemos/mnemos.toml

Agora o Claude responde a partir do seu projeto em vez de adivinhar, e mostra sua fonte:

Você: Como recupero commits perdidos?

Claude: Conforme o recovery/reflog.md, o reflog registra para onde HEAD e cada ponta de branch apontaram — mesmo após um hard reset — então você pode fazer checkout do hash do commit perdido. (recovery/reflog.md — "Reflog: recuperar commits perdidos")

Esse é o ciclo completo — indexar → perguntar → resposta citada. Tudo abaixo é profundidade: por que foi construído assim, como funciona e as capacidades completas.

⚠️ Uma pegadinha: add copia seus arquivos para a kb; ele não os rastreia

mnemos é um armazenamento gerenciado. Conteúdo endereçável vive sob .mnemos/kb/, e o URI de um documento é seu caminho relativo à raiz da kb. mnemos add docs tira snapshots docs/ em kb/docs/, então edições posteriores no seu docs/ original não são captadas até você executar mnemos add novamente. (mnemos ingest <kb-subpath> re-indexa conteúdo já dentro da kb; ele recusa um caminho fora dela.)

Duas fontes que chegam ao mesmo subcaminho da kb colidem, e a última vence. Use --into para dar a cada uma um lar distinto:

mnemos add ~/work/api/docs   --into api
mnemos add ~/work/infra/docs --into infra

Para uma árvore que precisa permanecer onde está, registre-a como uma origem em vez de copiá-la. Ela é indexada no local, somente leitura, sob seu próprio namespace de URI:

mnemos origin add ~/work/spec --prefix spec --collection spec
mnemos origin reindex spec    # picks up new files, evicts deleted ones

Duas árvores registradas podem conter o mesmo caminho relativo sem colidir, então uma árvore de especificação e uma árvore de código-fonte permanecem pesquisáveis juntas em um único armazenamento. mnemos nunca escreve em uma origem registrada.

Detalhes em docs/paths-and-indexing.md.

Por que mnemos

  • Verdadeiramente local-first: roda inteiramente na sua máquina. Sem rede, sem telemetria, nenhum dado sai do seu projeto.
  • Zero dependências: um único binário Go autocontido e sem cgo. Sem Python, Docker, Qdrant ou Ollama.
  • Qualquer cliente MCP: feito para o Claude Code, funciona com qualquer coisa que fale MCP.
  • Respostas citadas: cada resultado vincula de volta ao file#section exato e intervalo de linhas, então as afirmações são verificáveis.
  • Busca rápida por padrão: SQLite FTS5 / bm25 pronto para uso; busca semântica local opcional + híbrida atrás de uma build tag.
  • Memória de leitura-escrita: o agente pode capturar notas duráveis (remember); você pode gerenciar a árvore (forget, move, list).
  • Seguro por padrão: somente leitura a menos que você opte por participar; escritas são confinadas a caminhos, e o conteúdo é verificado por segredos no caminho para o índice (tanto captura quanto ingestão, controladas por exclude_secrets).

Como funciona

your files  →  mnemos index (SQLite/FTS5)  →  Claude Code memory  →  cited answers

Uma vez conectado, o Claude pode responder a partir do seu projeto em vez de improvisar, e apontar de volta para a fonte:

  • "Por que escolhemos esta arquitetura?"
  • "Onde está o ADR sobre o mecanismo de regras?"
  • "Resuma o que sabemos sobre provisionamento SCIM."
  • "O que mudou recentemente na memória deste projeto?"

Por baixo dos panos, o binário incorpora um servidor MCP, um pipeline de indexação, um armazenamento SQLite, busca de texto completo, um observador incremental de arquivos e uma CLI administrativa. Veja docs/architecture.md.

Ele realmente recupera?

Um resultado citado, pronto para uso (build lexical padrão, em um pacote de exemplo incluído):

$ mnemos add examples/git-recipes/bundle --into . --collection git
$ mnemos search "recover lost commits" --limit 1
1. recovery/reflog.md#Gotcha
   lines 24-28
   score 7.8

Cada resultado é um file#section real e intervalo de linhas que você pode abrir — esse é o ponto principal.

Qualidade de recuperação, medida. mnemos eval deriva automaticamente pares de consulta→fonte retidos de um pacote OKF (ele remove cada bloco de exemplo do seu próprio documento e então verifica se a recuperação ainda encontra o documento certo) e relata métricas em nível de documento. No pacote examples/git-recipes incluído (6 receitas, consultas estilo palavra-chave):

RecuperadorHit@1Recall@12MRR@12
Lexical, padrão (FTS5 / bm25)0.830.830.83
Semântico + híbrido (--semantic)1.001.001.00

Todos os três são frações em [0,1] (×100 para porcentagem); maior é melhor. O @K é a profundidade de recuperação — top‑1 para Hit, top‑12 para o resto:

  • Hit@1 — parcela de consultas cujo resultado #1 é o documento correto (0.83 = 5/6).
  • Recall@12 — parcela onde o documento correto aparece em qualquer lugar no top 12.
  • MRR@12 — posição recíproca média: média de 1/(rank of the first correct doc) sobre o top 12 (1.0 = sempre classificado em primeiro).

O build lexical padrão já resolve a recuperação por palavra-chave. O build de embeddings opcional (veja Busca semântica) se justifica em consultas mais difíceis de linguagem natural sobre dados estruturados: no pacote examples/onpage-seo, cujas respostas retidas são blocos JSON-LD / sitemap-XML que não compartilham nenhuma palavra-chave com sua prosa, a pontuação lexical é 0.00 enquanto --semantic recupera Hit@1 0.57 / Recall@12 0.86. Reproduza (N é 6 e 7 respectivamente — sinais de fumaça, não benchmarks):

mnemos eval examples/git-recipes/bundle              # lexical → 0.83
make build-embed && mnemos models install all-MiniLM-L6-v2
mnemos eval examples/git-recipes/bundle --semantic   # hybrid  → 1.00
mnemos eval examples/onpage-seo/bundle --semantic    # the hard case → 0.57

Conecte o Claude Code

O caminho de 60 segundos acima usou claude mcp add com um caminho absoluto do --config:

claude mcp add mnemos -- mnemos serve --config /abs/path/to/project/.mnemos/mnemos.toml

Para compartilhá-lo com o repositório, faça commit via .mcp.json:

{ "mcpServers": { "mnemos": { "command": "mnemos", "args": ["serve", "--config", "/abs/path/to/project/.mnemos/mnemos.toml"] } } }

Verifique com claude mcp list (deve mostrar mnemos ✓ connected) e /mcp dentro de uma sessão. O Claude então chama as ferramentas automaticamente; veja Capacidades.

Por que o caminho --config deve ser absoluto

O Claude Code não garante o diretório de trabalho em que inicia o servidor, então ancorar ao arquivo de configuração é o que torna a recuperação confiável. Passar --config <file> faz o diretório desse arquivo ser o MNEMOS_DIR, e cada localização é um subcaminho fixo dele, então um --config absoluto é tudo que você precisa: a base de conhecimento (kb/), o banco de dados (state/index.db) e o diretório de modelos todos se ancoram ao lado desse arquivo independentemente de onde o Claude Code inicia o servidor. Um mnemos serve falls back to discovery (the nearest project .mnemos, else ~/.mnemos), que só encontra seus dados quando o diretório de trabalho do servidor por acaso está dentro do projeto, e o Claude Code não promete isso. Veja docs/paths-and-indexing.md para a ordem completa de resolução.

Registering mnemos as an MCP server; Claude Code reports it connected
Um comando conecta tudo: o Claude Code reporta mnemos ✓ conectado.

Claude Code answering a keyword-free question via semantic search, citing recovery/reflog.md
Busca semântica: a pergunta diz "desapareceu" — uma palavra que não aparece em nenhum lugar das anotações — ainda assim o Claude encontra e cita recovery/reflog.md.

Este clipe usa o build semântico opcional (make install-embed + mnemos models install all-MiniLM-L6-v2 + use_vectors = true; veja Busca semântica). O binário make install padrão é somente lexical, então ele não responderá a uma pergunta sem palavras-chave como esta — pesquise por palavra-chave (ex.: mnemos search "recover lost commits", que atinge o mesmo documento).

Faça o Claude usar memória automaticamente (skill opcional)

As ferramentas MCP são passivas: elas estão disponíveis, mas o Claude ainda precisa decidir chamar mnemos.search antes de responder ou mnemos.remember quando você diz algo que vale guardar, e os modelos muitas vezes não fazem isso. A skill mnemos-okf incluída fecha essa lacuna codificando quando recorrer à memória: recordar antes de responder por suposição, capturar fatos duráveis e conduzir as ferramentas OKF.

Ela é opcional e específica do Claude Code: o servidor funciona com qualquer cliente MCP sem ela. Instale-a para o usuário (todos os projetos):

make install-skill        # copies skills/mnemos-okf -> ~/.claude/skills/ and merges its hooks

Ou coloque-a manualmente, ex.: em nível de projeto apenas para este repositório:

mkdir -p .claude/skills && cp -r skills/mnemos-okf .claude/skills/mnemos-okf

A captura é deliberadamente conservadora (apenas fatos duráveis, verificada por segredos) e permanece atrás de allow_write/allow_delete: a skill nunca concede acesso que a configuração não tenha optado por participar. Veja skills/mnemos-okf/SKILL.md.

O ciclo de memória

mnemos é memória local de projeto para agentes de codificação: recordação citada, estado durável do projeto, consolidação de conhecimento.

prompt
  -> recall (search first, cite)
  -> act
  -> capture durable facts to the inbox
  -> update project/task state
  -> consolidate raw captures into canonical docs
  -> cite everything

A skill mnemos-okf incluída codifica isso em seis modos: RECALL, CAPTURE, OKF, RESTORE, TASK e CONSOLIDATE. Tarefas são documentos Task agrupados por mnemos task list. A consolidação nunca sobrescreve silenciosamente: conflitos são apresentados e as passagens são registradas em diário.

O layout de referência está em examples/project-memory/bundle/, um projeto fictício com status, restrições, decisões, tarefas (divisão estado/histórico) e um diário de consolidação. Ingira-o para ver mnemos task list em ação:

mnemos add examples/project-memory/bundle --into aurora --collection aurora
mnemos task list
in_progress (1)
  aurora/tasks/rate-limit-ingest.md  Rate-limit the ingest endpoint
todo (1)
  aurora/tasks/csv-export.md  Add CSV export
done (1)
  aurora/tasks/fix-auth-timeout.md  Fix auth token timeout

Automação com hooks

A skill é consultiva: o modelo decide quando disparar cada modo. Os hooks do Claude Code tornam o ciclo de memória determinístico. make install-skill (ou make install-hooks sozinho) mescla skills/mnemos-okf/hooks/settings.example.json no seu ~/.claude/settings.json de forma idempotente, mantendo um .bak; passe SKIP_HOOKS=1 para optar por não participar, ou mescle o arquivo manualmente para um .claude/settings.json em nível de projeto. Dois hooks são ativados:

HookCorrespondênciaEfeito
SessionStartstartup|resume|compactInjeta o conjunto de trabalho no início da sessão: mnemos task list mais decisões recentes (mnemos ls decisions). A correspondência compact o reinjeta após a compactação de contexto.
UserPromptSubmitfrases de sinalização de recordaçãoQuando o prompt corresponde a "como decidimos", "o que foi", "lembra quando" e sinalizações semelhantes, injeta os 3 principais resultados de mnemos search. Requer jq. Sem operação silenciosa quando nenhuma sinalização corresponde.

A persistência PreCompact e Stop (resumos de sessão, descarga de captura) permanece na skill porque esses eventos de hook não podem injetar contexto no modelo.

Capacidades

O Claude alcança sua memória por meio de ferramentas MCP (e você pelos comandos CLI correspondentes). Observe a grafia: mnemos.search é a ferramenta MCP que o Claude chama; mnemos search é o comando CLI que você executa.

Consulta (somente leitura, sem gate)

  • mnemos.search: recuperação ranqueada e filtrada com citações.
  • mnemos.read: lê um trecho preciso (por chunk_id) ou um documento inteiro (por uri). Passe follow_links: true para também anexar os vizinhos de link de 1 salto do documento.
  • mnemos.context: resultados top-k como blocos de contexto prontos para LLM (uri:start-end → conteúdo). Passe follow_links: true para anexar os vizinhos de link de 1 salto de cada bloco de documento.
  • mnemos.related: os vizinhos do grafo de links de um documento, seus links de saída e backlinks de entrada (1 salto, nível de documento). Alvos de saída pendentes são retornados com resolved: false. Filtre com direction (saída/entrada/ambos) e limit.
  • mnemos.list: percorre a árvore OKF no disco e anota cada arquivo com metadados de índice (título, tipo, tags, coleção) além de um flag indexed, para que tanto arquivos armazenados quanto ainda não indexados fiquem visíveis. Filtre por path, collection, type ou estado de indexação.

Escrita (requer allow_write = true)

  • mnemos.remember: escreve uma nota na memória. Passe um path opcional (ex.: "adr/0003-rule-engine.md") para colocá-la em um local explícito na árvore OKF em vez de nomeação automática sob kb/capture/. O conteúdo é verificado por segredos antes de ser escrito e indexado.
  • mnemos.okfy: converte um arquivo .txt/.md existente na árvore em um documento OKF (frontmatter + corpo) em out (padrão: o caminho de origem com extensão .md) e o indexa, mantendo a origem intacta. O corpo da origem é verificado por segredos primeiro.

mnemos edit <uri> é a contraparte humana: um editor de terminal para um documento, controlado pelo mesmo flag allow_write, sem ferramenta MCP própria. Veja Editar documentos interativamente.

Gerenciamento (requer allow_delete = true)

  • mnemos.forget: remove um arquivo da árvore OKF e o desindexa; idempotente.
  • mnemos.move: move um arquivo ou diretório dentro da árvore e o reindexa sob o novo caminho. Um diretório move toda a sua subárvore, preservando a coleção de cada documento. Links de markdown de entrada para os caminhos antigos não são reescritos na V0 (registrados como aviso).

Mantenha a memória atualizada

Execute um watcher para reindexar em mudanças (incremental; remove arquivos excluídos):

mnemos watch . --collection myproject

Habilite o write-back em .mnemos/mnemos.toml para que o Claude possa capturar e gerenciar notas:

[mcp]
allow_write = true     # gates mnemos.remember and mnemos.okfy
allow_delete = true    # gates mnemos.forget and mnemos.move

Se um watcher estiver rodando sobre a árvore, as operações forget/move também são vistas pelo watcher (redundantes, mas idempotentes); as ferramentas atualizam o índice diretamente e funcionam sem watcher. Defina [capture] defer_to_watcher = true quando um watcher cobrir kb/capture/ para evitar indexação dupla de notas lembradas.

Editar documentos interativamente

mnemos edit <uri> abre um editor de terminal sobre um documento OKF por vez, dividido em três painéis:

  • NAV: os links de saída do documento, backlinks de entrada e (uma vez que uma compilação de embeddings tenha calculado embeddings para o corpus) documentos semanticamente semelhantes; caso contrário, essa seção mostra uma dica de indisponibilidade em vez de resultados.
  • METADATA: campos de frontmatter, tipados conforme o type OKF do documento. Um enum conhecido (o status ou priority de uma tarefa) cicla com as setas do teclado, tags é redigitado como uma lista inteira, campos desconhecidos caem em texto livre, e campos de propriedade do índice como type são somente leitura.
  • CONTENT: o corpo, entregue a $EDITOR para edição e recarregado ao sair.
mnemos edit tasks/ship.md

Teclas: tab foco, ↑↓ mover, enter abrir/editar, ←→ ciclar um enum, e $EDITOR, m mover/renomear, s salvar, b/backspace voltar, q sair. Salvar grava o arquivo primeiro e depois reindexa apenas aquele documento, então uma edição nunca é perdida mesmo se a reindexação falhar; gravações de frontmatter preservam o resto do arquivo (comentários, ordem de chaves, campos não relacionados) em vez de reescrevê-lo. Navegar para outro documento enquanto o atual não está salvo salva-o primeiro.

m move ou renomeia o documento aberto. Ele solicita com o uri atual: edite livremente, ou pressione tab para um seletor com filtro difuso dos diretórios que já contêm documentos (enter realoca o nome do arquivo sob o selecionado, esc retorna ao prompt). Confirmar renomeia o arquivo no disco, reindexa-o sob o novo uri e reabre o editor lá; links de entrada ainda apontando para o caminho antigo são relatados, não reescritos. Como mnemos mv, precisa de [mcp].allow_delete = true já que as entradas antigas do índice são excluídas.

Requer um uri: mnemos edit puro gera erro, não há seletor de navegação em árvore ainda. É controlado da mesma forma que mnemos.remember/mnemos.okfy:

[mcp]
allow_write = true   # also gates mnemos edit

Não há ferramenta MCP correspondente: mnemos edit é somente CLI, para um humano no teclado.

Busca semântica (opcional)

O binário padrão é somente lexical (FTS5 / bm25) e permanece pequeno e sem cgo. A recuperação semântica local + híbrida está totalmente implementada, mas compilada atrás da tag de build embed, então as dependências ONNX/tokenizer nunca entram no binário padrão. Para habilitá-la:

make build-embed                       # or: make install-embed  (still cgo-free, CGO_ENABLED=0)
mnemos models install all-MiniLM-L6-v2 # downloads the embedding model into ~/.mnemos/models
mnemos reindex --embeddings            # compute vectors for already-indexed chunks
mnemos search "why did we choose this architecture" --semantic

--semantic funde bm25 com similaridade vetorial, então consultas em linguagem natural que o índice lexical perde ainda resolvem. Sem a compilação de embeddings (ou um modelo instalado), o flag é rejeitado com uma mensagem clara; mnemos search puro sempre funciona.

Como funciona internamente (modelo, inferência ONNX em Go puro, fusão RRF): docs/architecture.md.

Suporte a OKF

mnemos entende nativamente OKF (Open Knowledge Format) bundles, e qualquer vault Markdown com frontmatter YAML e cross-links, sem modo especial:

  • frontmatter tags/type tornam-se sinais de ranqueamento difuso no FTS,
  • links de markdown são capturados como arestas e percorridos: mnemos related (e a ferramenta mnemos.related) percorre os links de saída e backlinks de entrada de um documento, follow_links os anexa a uma chamada de leitura ou contexto, e [search] graph_expansion = true preenche slots de resultado vazios com os vizinhos de 1 salto dos principais hits,
  • arquivos index.md são tratados apenas como estrutura (mantidos fora do FTS e do grafo de links).

Bundles OKF também servem como corpus para mnemos eval, que deriva automaticamente pares consulta→fonte retidos e relata Hit@1 / Recall@12 / MRR@12 contra uma linha de base confirmada. Veja docs/architecture.md.

Referência

Segurança

  • Sem rede, sem telemetria; o servidor MCP é somente stdio.
  • Binários enviados carregam SBOMs (gerados com syft) e são assinados com cosign (OIDC sem chave).
  • Somente leitura por padrão. Write-back é opt-in (allow_write = true). Operações destrutivas (esquecer, mover) exigem opt-in separado (allow_delete = true).
  • Todos os caminhos fornecidos pelo chamador são validados por um guarda de confinamento antes de qualquer operação de disco: travessia .., caminhos absolutos fora da raiz da árvore, escapes de symlink, acesso a .mnemos/ e globs [security].exclude são todos rejeitados.
  • Origens externas registradas são somente leitura: todo verbo de escrita recusa um uri em um namespace registrado e nomeia a origem proprietária. O guarda permanece inalterado para tudo fora de uma origem registrada, então um escape de symlink não registrado é rejeitado exatamente como antes.
  • O conteúdo é verificado por segredos antes de ser indexado, tanto no caminho de captura (remember, okfy, que rejeitam) quanto no caminho de ingestão (ingest, add, watch, reindex, que pulam o arquivo com um aviso nomeando as regras correspondentes e continuam a execução). Defina [security] exclude_secrets = false para desabilitar.
  • Padrões de exclusão de caminho/segredo mantêm .env, chaves e diretórios secretos fora do índice.

Veja SECURITY.md para a política completa.

Desenvolvimento

make build      # cgo-free binary -> bin/
make test       # go test -race ./...
make audit      # golangci-lint (incl. govet + staticcheck) + govulncheck + race tests
make tools      # install pinned dev tools (golangci-lint, govulncheck)
make help       # list all targets

Arquitetura, princípios de design e a metodologia de avaliação de recuperação estão em docs/architecture.md; decisões de design são registradas como ADRs. Contribuições são bem-vindas; veja CONTRIBUTING.md.

Licença

mnemos é licenciado sob a Licença MIT: isso cobre o código e conteúdo próprios do mnemos. O repositório também fornece material de terceiros que não é coberto pela Licença MIT e permanece sob seus próprios termos; veja THIRD-PARTY-NOTICES.md (notavelmente o bundle OKF de exemplo em examples/onpage-seo/bundle/).