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
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.
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 ondeHEADe 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#sectionexato 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):
| Recuperador | Hit@1 | Recall@12 | MRR@12 |
|---|---|---|---|
| Lexical, padrão (FTS5 / bm25) | 0.83 | 0.83 | 0.83 |
Semântico + híbrido (--semantic) | 1.00 | 1.00 | 1.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.
Um comando conecta tudo: o Claude Code reporta mnemos ✓ conectado.
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áriomake installpadrã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:
| Hook | Correspondência | Efeito |
|---|---|---|
SessionStart | startup|resume|compact | Injeta 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. |
UserPromptSubmit | frases de sinalização de recordação | Quando 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 (porchunk_id) ou um documento inteiro (poruri). Passefollow_links: truepara 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). Passefollow_links: truepara 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 comresolved: false. Filtre comdirection(saída/entrada/ambos) elimit.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 flagindexed, para que tanto arquivos armazenados quanto ainda não indexados fiquem visíveis. Filtre porpath,collection,typeou estado de indexação.
Escrita (requer allow_write = true)
mnemos.remember: escreve uma nota na memória. Passe umpathopcional (ex.:"adr/0003-rule-engine.md") para colocá-la em um local explícito na árvore OKF em vez de nomeação automática sobkb/capture/. O conteúdo é verificado por segredos antes de ser escrito e indexado.mnemos.okfy: converte um arquivo.txt/.mdexistente na árvore em um documento OKF (frontmatter + corpo) emout(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
typeOKF do documento. Um enum conhecido (ostatusoupriorityde 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 comotypesão somente leitura. - CONTENT: o corpo, entregue a
$EDITORpara 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/typetornam-se sinais de ranqueamento difuso no FTS, - links de markdown são capturados como arestas e percorridos:
mnemos related(e a ferramentamnemos.related) percorre os links de saída e backlinks de entrada de um documento,follow_linksos anexa a uma chamada de leitura ou contexto, e[search] graph_expansion = truepreenche slots de resultado vazios com os vizinhos de 1 salto dos principais hits, - arquivos
index.mdsã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
- docs/commands.md — todos os comandos CLI e seus flags.
- docs/configuration.md: o
<MNEMOS_DIR>/mnemos.tomlem camadas, com todos os padrões. - docs/paths-and-indexing.md — como o estado é localizado, o que é indexado, onde as gravações caem e as regras de idempotência/URI.
- docs/architecture.md — princípios de design e a metodologia de avaliação de recuperação.
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].excludesã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 = falsepara 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/).