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 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 a origem de uma afirmação.
O mnemos resolve isso dando a ele uma memória local e citável de:
- seus ADRs e documentos de design
- suas notas 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 Markdown simples funciona como está — e os disponibiliza via
MCP, para o Claude pesquisar, ler e citar seu próprio conhecimento em vez de adivinhar, com cada resposta apontando diretamente para o file#section exato e faixa 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 ingest docs --collection myproject # index a directory
mnemos search "why did we choose this architecture"
Prefira
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 --config absoluto):
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 a fonte:
Você: Como recupero commits perdidos?
Claude: Conforme
recovery/reflog.md, o reflog registra para ondeHEADe cada ponta de branch apontaram — mesmo após um hard reset — para que você possa fazer checkout do hash do commit perdido. (recovery/reflog.md — "Reflog: recuperar commits perdidos")
Esse é o loop completo — indexar → perguntar → resposta citada. Tudo abaixo é aprofundamento: por que é construído assim, como funciona e a lista completa de capacidades.
⚠️ Um problema: a identidade de um documento é seu caminho relativo a onde você executou ingest
O URI de um documento é o caminho relativo à raiz de varredura que você ingeriu (docs acima), não
seu diretório de trabalho. Ingerir dois diretórios que contenham (digamos) index.md
resolve ambos para o mesmo URI: a segunda ingestão substitui silenciosamente a primeira. Para
indexar várias árvores de forma limpa, ingira a partir de uma raiz comum (mnemos ingest .). Detalhes em
docs/paths-and-indexing.md.
Por que mnemos
- Verdadeiramente local primeiro: 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: construído para Claude Code, funciona com qualquer coisa que fale MCP.
- Respostas citadas: cada resultado vincula de volta ao
file#sectionexato e faixa de linhas, para que as afirmações sejam verificáveis. - Busca rápida por padrão: SQLite FTS5 / bm25 prontos para uso; busca semântica e híbrida opcional atrás de uma tag de build.
- Memória de leitura e 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 escrever; escritas são confinadas ao caminho e o conteúdo é verificado por segredos.
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 dar respostas vagas, e apontar de volta para a fonte:
- "Por que escolhemos essa arquitetura?"
- "Onde está o ADR sobre o motor 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 informações?
Uma ocorrência citada, pronta para usar (build lexical padrão, em um pacote de exemplo incluído):
$ mnemos ingest examples/git-recipes/bundle --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 faixa de linhas que você pode abrir — esse é exatamente o
objetivo.
Qualidade de recuperação, medida. mnemos eval deriva automaticamente pares de consulta→fonte reservados
de um pacote OKF (remove cada bloco de exemplo de seu próprio documento e depois verifica
se a recuperação ainda encontra o documento certo) e relata métricas no nível de documento. No
pacote examples/git-recipes incluído (6 receitas, consultas no estilo de palavras-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); quanto maior, melhor. O @K é a profundidade de recuperação — top‑1 para Hit, top‑12 para o resto:
- Hit@1 — proporção de consultas cujo resultado #1 é o documento correto (
0.83= 5/6). - Recall@12 — proporção em que o documento correto aparece em qualquer lugar no top 12.
- MRR@12 — recíproco médio da classificação: média de
1/(rank of the first correct doc)nos top 12 (1.0= sempre em primeiro lugar).
O build lexical padrão já acerta a recuperação por palavras-chave. O build de incorporação 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 reservadas são blocos JSON-LD / sitemap-XML que não compartilham nenhuma palavra-chave com a 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, 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
Conectar o Claude Code
O caminho de 60 segundos acima usou claude mcp add com um caminho --config absoluto:
claude mcp add mnemos -- mnemos serve --config /abs/path/to/project/.mnemos/mnemos.toml
Para compartilhar com o repositório, registre-o 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, portanto
ancorar ao arquivo de configuração é o que torna a recuperação confiável. mnemos serve
resolve um [storage].path relativo em relação ao diretório do arquivo de configuração, então
um --config absoluto é tudo que você precisa: o banco de dados, o diretório de captura e a raiz
da árvore ancoram ao lado desse arquivo, independentemente de onde o Claude Code inicia o
servidor. Um simples mnemos serve só encontra seus dados quando o diretório de trabalho do servidor
coincide com a raiz do projeto, o que o Claude Code não promete; quando
o banco de dados não pode ser encontrado, serve falha com um erro claro em vez de retornar silenciosamente
resultados vazios.
Um comando conecta: o Claude Code relata mnemos ✓ conectado
Busca semântica: a pergunta diz "desapareceu" — uma palavra que não aparece em nenhuma das notas — e mesmo 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, portanto não responde a uma pergunta sem palavras-chave como esta — busque por palavra-chave (por exemplo,mnemos search "recover lost commits", que atinge o mesmo documento).
Faça o Claude usar a memória automaticamente (habilidade opcional)
As ferramentas MCP são passivas: 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 a pena
guardar, e os modelos muitas vezes não fazem isso. A habilidade mnemos-okf incluída
fecha essa lacuna ao codificar quando recorrer à memória: recuperar antes de responder com base em
suposição, capturar fatos duráveis e guiar as ferramentas OKF.
É 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, por exemplo, no nível do projeto apenas para este repositório:
mkdir -p .claude/skills && cp -r skills/mnemos-okf .claude/skills/mnemos-okf
A captura é deliberadamente conservadora (somente fatos duráveis, verificação de segredos) e permanece
atrás de allow_write/allow_delete: a habilidade nunca concede acesso que a configuração
não autorizou. Veja skills/mnemos-okf/SKILL.md.
O loop de memória
mnemos é memória local de projeto para agentes de codificação: recuperaçã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 habilidade 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 habilidade é consultiva: o modelo decide quando disparar cada modo. Os hooks do Claude Code tornam o loop de memória determinístico. make install-skill (ou make install-hooks por si só) incorpora skills/mnemos-okf/hooks/settings.example.json ao 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 a 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 compactação de contexto. |
UserPromptSubmit | frases de recuperação | Quando o prompt corresponde a "como decidimos", "o que foi", "lembra quando" e frases semelhantes, injeta as 3 principais ocorrências de mnemos search. Requer jq. Sem efeito quando nenhuma frase corresponde. |
A persistência de PreCompact e Stop (resumos de sessão, descarga de captura) permanece na habilidade 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 permissão)
mnemos.search: recuperação classificada 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.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 sem destino são retornados comresolved: false. Filtre comdirection(outbound/inbound/both) 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 indicadorindexed, para que tanto arquivos armazenados quanto ainda não indexados fiquem visíveis. Filtre porpath,collection,typeou estado indexado.
Escrever (requer allow_write = true)
mnemos.remember: escreva uma nota na memória. Passe umpathopcional (por exemplo,"adr/0003-rule-engine.md") para colocá-la em um local explícito na árvore OKF em vez de nomear automaticamente sob[capture].dir. O conteúdo é verificado por segredos antes de ser escrito e indexado.mnemos.okfy: converta um arquivo.txt/.mdexistente na árvore em um documento OKF (frontmatter + corpo) emout(padrão: o caminho de origem com extensão.md) e indexe-o, deixando 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 pela mesma flag allow_write, sem ferramenta MCP própria. Veja Editar documentos interativamente.
Gerenciar (requer allow_delete = true)
mnemos.forget: remova um arquivo da árvore OKF e desindexe-o; idempotente.mnemos.move: mova um arquivo ou diretório dentro da árvore e reindexe-o 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
Ative 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 em execução sobre a árvore, as operações forget/move também são vistas pelo watcher (redundante, mas idempotente); as ferramentas atualizam o índice diretamente e funcionam sem watcher. Defina [capture] defer_to_watcher = true quando um watcher cobrir capture_dir 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 teclas de seta,tagsé redigitado como uma lista inteira, campos desconhecidos caem para 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 esse documento, então uma edição nunca é perdida mesmo se a reindexação falhar; gravações de frontmatter preservam o restante do arquivo (comentários, ordem das chaves, campos não relacionados) em vez de reescrevê-lo. Navegar para outro documento enquanto o atual não foi 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 que ainda apontam para o caminho antigo são relatados, não reescritos. Como mnemos mv, ele precisa de [mcp].allow_delete = true pois as entradas antigas do índice são excluídas.
Requer um uri: mnemos edit puro gera erro, ainda não há seletor de navegação em árvore. Ele é 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 é apenas CLI, para um humano no teclado.
Busca semântica (opcional)
O binário padrão é apenas 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 não captura ainda são resolvidas. Sem a compilação de embeddings (ou um modelo instalado), a flag é rejeitada com uma mensagem clara; mnemos search simples sempre funciona.
Como funciona internamente (modelo, inferência ONNX em Go puro, fusão RRF): docs/architecture.md.
Suporte a OKF
mnemos entende nativamente pacotes OKF (Open Knowledge Format) e qualquer vault Markdown com frontmatter YAML e links cruzados, sem modo especial:
- frontmatter
tags/typetornam-se sinais de classificação difusa no FTS, - links de markdown são capturados como arestas (armazenados, ainda não percorridos),
- arquivos
index.mdsão tratados apenas como estrutura (mantidos fora do FTS e do grafo de links).
Pacotes OKF servem também 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 comprometida. Veja docs/architecture.md.
Referência
- docs/commands.md — todos os comandos CLI e suas flags.
- docs/configuration.md — o
.mnemos/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 é apenas stdio.
- Binários distribuídos carregam SBOMs (gerados com syft) e são assinados com cosign (OIDC sem chave).
- Somente leitura por padrão. Write-back é opcional (
allow_write = true). Operações destrutivas (esquecer, mover) exigem um 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. - O conteúdo capturado é verificado por segredos antes de ser escrito ou indexado.
- 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 o conteúdo próprios do mnemos. O repositório também inclui 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 pacote OKF de exemplo em examples/onpage-seo/bundle/).