Compartment

Memória totalmente offline e criptografada em repouso para agentes de IA, com os vetores de embedding também criptografados, busca exata residente em RAM, exclusão por cripto-fragmentação e um log de auditoria encadeado por hash.

Documentação

Compartment

Memória criptografada e totalmente offline para agentes de IA. Um cofre no seu próprio computador, lido e escrito por Claude Code, Claude Desktop, Hermes Agent, OpenClaw, Cursor, Codex e qualquer outro cliente MCP. Sem chave de API, sem conta, sem rede, sem telemetria.

PyPI Downloads CI License

MCP Toplist Cursor Directory Glama MCP Market mcpservers.org LobeHub

Instalação em um clique (após pip install compartment && compartment init):

Add to Cursor Install in VS Code Install in VS Code Insiders Add to LM Studio Install in goose Add to Kiro

Claude Code, Claude Desktop, Hermes Agent e OpenClaw são conectados por um único comando: compartment integrate claude, hermes ou openclaw.

Compartment é memória persistente para agentes de IA, armazenada no seu próprio computador. O que um agente aprende em uma sessão fica disponível em todas as sessões posteriores, em todos os projetos, para todos os agentes na máquina, e nada sai da máquina.

Cada memória é uma única afirmação, registrada com sua fonte e a data em que foi aprendida. Memórias podem expirar: defina expires e a memória é removida após essa data. Quando uma preferência muda, a nova substitui a antiga. A recuperação é uma busca híbrida por vetores e palavras-chave sobre um índice em memória. Ela responde em cerca de 12 ms e retorna apenas o que é relevante.

O modelo de embeddings está incluído no pacote. Tudo no disco é criptografado, incluindo os vetores de embeddings, e apenas sua frase secreta abre o cofre. Um cofre novo vem com cerca de 6.700 fatos de referência sobre hardware, sistemas operacionais, portas, codificações e ferramentas de shell. Eles são memórias comuns, e um único interruptor os remove da busca.

Como se compara com outros servidores de memória

Onde cada servidor mantém a memória e o que a protege, conforme documentado por cada projeto em 2 de setembro de 2026. Fontes e a tabela completa estão em docs/COMPARISON.md; correções são bem-vindas como PR contra esse arquivo.

Memória em repousoCriptografadaConta / chave de APIRede em tempo de execução
Compartmentum arquivo criptografado; índice na RAMsim, vetores tambémnenhumanenhuma, imposto por CI
@modelcontextprotocol/server-memorytexto puro memory.jsonl, busca por substringnãonenhumanenhuma
mem0 (código aberto)armazenamento de vetores + fatos extraídos por LLM; seu servidor MCP é apenas hospedadonão documentadochave de LLMchamadas de LLM; telemetria ativada por padrão
Graphiti (Zep) / LettaNeo4j / servidor + banco de dadosnão documentadochave de LLMchamadas de LLM; telemetria ativada por padrão
claude-memSQLite local + Chromanão documentadologin obrigatórioconta + chamadas ao provedor; telemetria ativada por padrão
basic-memory (AGPL)Markdown + SQLitenão documentadonenhumatelemetria ativada por padrão
Hindsight (Vectorize)um contêiner com PostgreSQL embutidonão documentadochave de LLM (modelos locais configuráveis)chamadas de LLM; fornecedor declara sem telemetria
Supermemoryserviço em nuvem, ou binário pré-compilado auto-hospedadonão documentadoconta (nuvem) ou chave de LLM (auto-hospedado)chamadas em nuvem; auto-hospedado: fornecedor declara sem telemetria
CogneeSQLite + LanceDB + Kuzu localmente, ou nuvemnão documentadochave de LLMchamadas de LLM; telemetria ativada por padrão
MemOSNeo4j + Qdrant auto-hospedado, ou nuvemnão documentadochave de LLMchamadas de LLM; telemetria ativada por padrão

A lógica da memória

Quase tudo é armazenado. Apenas turnos vazios são descartados. Um simples "OK" é uma decisão, não ruído: quando o agente pergunta "Quer que eu envie esta resposta ao cliente agora?" e o usuário responde "OK", Compartment armazena a decisão junto com a pergunta que ela respondeu. Conversa fiada é mantida, mas classificada por último.

A importância é atribuída por níveis fixos. Decisões e consentimento 0,90, fatos pessoais e preferências 0,80, a máquina e a configuração do usuário 0,75, outras declarações substantivas 0,55, conversa fiada 0,20. A importância multiplica uma pontuação de correspondência em vez de somar a ela, então ela desempata quase-empates a favor do que importa e nunca pode trazer à tona uma memória que não correspondeu à pergunta.

Uma afirmação por memória, imposta. O armazenamento rejeita qualquer coisa com mais de 200 caracteres (a configuração max_memory_chars), e qualquer coisa que contenha listas, títulos ou parágrafos, com um erro que diz como dividi-la. Instruções sozinhas não funcionaram: em um cofre real, a mediana de memória escrita por um agente era de 1.938 caracteres de log de sessão com marcadores. memory_store_many armazena um lote em uma única chamada. compartment atomize divide memórias acima do limite em um cofre existente; cada parte mantém as datas do original, e o original é marcado como substituído, mas permanece legível por id.

Cada memória registra sua fonte e data. source é obrigatório: "do chat", "lido de pyproject.toml", "busca na web". discovered é a data em que o fato foi aprendido, separada da data em que foi salvo. Ambos são anexados ao texto como uma cláusula curta, por exemplo [web search, 2026-08-01].

Memórias podem expirar. Para um fato que deixa de ser verdadeiro em uma data conhecida, como um preço promocional, uma reserva ou um código de porta, defina expires para essa data (2026-09-03) ou para uma duração (14d, 2w, 3m, 1y). A memória é removida após essa data. compartment expire executa a varredura manualmente; expire_memories a desativa. A maioria dos fatos não deve expirar; uma expiração errada exclui uma memória que o usuário queria.

Fatos se acumulam; opiniões se atualizam. Um novo fato é adicionado ao lado dos outros: o código da porta mudou, um script vive em um caminho, uma versão foi lançada. Uma opinião substitui outra. Quando uma preferência é armazenada com kind="opinion", o cofre procura primeiro por uma opinião viva semelhante. Se encontrar uma, retorna o registro antigo em vez de inserir, e o chamador reenvia com supersedes=[old id] para substituí-lo, ou supersedes=[] para manter ambos. Reafirmar uma opinião viva atualiza sua data em vez de armazenar uma cópia. Registros substituídos são removidos da busca, mas mantidos na cadeia de auditoria e legíveis por id, com um ponteiro para seu substituto. supersedes também funciona em fatos, para correções. A classificação de opiniões carrega um bônus de recência que a classificação de fatos não tem, então a opinião mais nova vence. compartment opinions audit encontra opiniões vivas sobrepostas em cofres mais antigos e mantém a mais nova, ou as relata para mesclagem manual.

A captura não depende do modelo. Um host que declara sua própria memória em seu prompt de sistema pode substituir qualquer instrução de ferramenta. Então integrate claude instala um hook PostToolUse que escreve cada arquivo de memória que Claude Code salva no cofre, quer o modelo chame a ferramenta ou não. O hook deixa seus outros hooks intactos, faz backup de settings.json primeiro, sempre sai com sucesso para nunca quebrar seu editor, e não faz nada enquanto o cofre estiver bloqueado. compartment hook status | install | uninstall, or integrate claude --no-hooks. compartment import-claude importa qualquer coisa que o hook perdeu.

A busca retorna o que é relevante, não um número fixo. Compartment retorna toda memória cuja pontuação se sustenta contra o melhor resultado para a mesma pergunta, até um limite generoso. O corte é relativo porque as pontuações não são comparáveis entre perguntas: em um cofre real, a consulta sem sentido "como assar pão de fermentação natural" pontuou mais alto do que a consulta real "o que Max decidiu sobre Airtable". Uma pergunta sobre a qual o cofre não sabe nada retorna nada. Passe top_k para obter exatamente essa quantidade.

As tags são mantidas atualizadas. Sobre o que uma memória trata nunca muda; a que ela é relevante muda. Suponha que, enquanto trabalha em um projeto chamado Northwind, você aprenda que o cliente quer números antes de conclusões. O agente marca a memória com northwind. Dois anos depois, o mesmo cliente, agora chamado Harbour, contrata você novamente, e o agente busca com a tag harbour. A memória ainda é verdadeira, mas um filtro de tag não consegue encontrá-la. Então uma passagem em segundo plano dá a cada memória as tags que seus vizinhos mais próximos no espaço de embeddings carregam, ponderadas por similaridade: conforme memórias de Harbour se acumulam perto daquela antiga, ela adquire a tag harbour. Dois outros sinais rodam em paralelo: tags que quase sempre ocorrem juntas implicam uma na outra, e uma tag existente cuja frase aparece no texto de uma memória é anexada. A passagem escreve apenas tags, nunca texto, datas ou embeddings. Ela apenas adiciona tags, a menos que você passe --prune, tags_origin preserva as tags originais, e compartment retag --dry-run mostra o que mudaria.

Um grafo além de uma lista. memory_link registra uma relação: sujeito, predicado, objeto, opcionalmente vinculada a uma memória e a uma janela de validade. memory_relations responde por entidade, por predicado ou a partir de uma data. Compartment armazena e corresponde relações deterministicamente; o modelo host decide o que vincular.

Memórias são dados, não instruções. Memórias recuperadas são envolvidas com um aviso de que são dados armazenados. Conteúdo de uma fonte não confiável pode ser marcado como quarantined, o que adiciona um aviso a cada recuperação dele. O agente host ainda deve tratar a memória como dados.

Um modelo de embeddings por cofre. O SHA-256 do modelo é registrado no cofre e verificado na abertura, para que as pontuações de similaridade permaneçam comparáveis. Para mudar o modelo, execute compartment reindex --re-embed.

Sem LLM interno. Os embeddings são executados localmente com um modelo ONNX int8 de 384 dimensões incluído, em um único processo compartilhado de cerca de 70 MB que todos os agentes na máquina usam. O modelo host decide o que armazenar e esquecer; Compartment captura, criptografa e recupera. Essa divisão mantém a garantia offline absoluta e cada decisão reproduzível. Com um LLM offline, todo o agente roda sem rede.

Veja o que ele aprendeu. compartment recent lista as memórias mais recentes, ocultando os fatos de referência para que suas próprias memórias fiquem visíveis. compartment status relata organic_records ao lado do total. memory_recent é a mesma visão via MCP.

O aplicativo e o painel

The macOS panel: vault state, settings, connected agents, the last five memories

O mesmo painel em cada sistema: a barra de menus no macOS, a área de notificação no Windows e uma janela comum no Linux, listada no menu de aplicativos. O Linux recebe uma janela de propósito: um ícone de bandeja pode nunca aparecer no GNOME ou Wayland, e o controle que desbloqueia suas memórias não deve falhar silenciosamente.

O painel mostra se o cofre está aberto, quantas memórias ele contém e quantas você armazenou, as três configurações que valem a pena mudar (hook de captura, se fatos de referência aparecem na busca, bloqueio automático), quais agentes estão conectados com botões para conectar Claude, Hermes Agent ou OpenClaw, e as últimas cinco memórias. Você pode desbloquear, bloquear e mudar sua frase secreta lá sem terminal. O painel abre instantaneamente com o que leu por último e atualiza em segundo plano, apenas quando algo realmente mudou. Enquanto você o usa, um processo auxiliar mantém o cofre aberto somente leitura e lê apenas as novas memórias conforme os agentes as adicionam; após dez minutos ociosos, ele sai, então um aplicativo ocioso não mantém cofre nem chave. Olhar nunca bloqueia, desbloqueia ou reescreve o cofre. Ele é feito para ser um dos muitos aplicativos no seu computador, não algo que você precisa aprender: cada função é um botão ou um interruptor, e os padrões foram escolhidos por medição.

O botão Painel abre o cofre inteiro no seu navegador: crescimento ao longo do tempo, o grafo de relações com cada entidade nomeada, tags, contagens por agente e busca ao vivo. Ele é servido da RAM apenas em 127.0.0.1, somente leitura, sem requisições de saída.

compartment dash: namespaces, memories per agent, relation types, top tags and search

compartment dash on a 51,000-memory vault: growth over time and the relation graph

A matemática

Tudo abaixo está em um único arquivo, src/compartment/ranking.py, usado pelo vault, pelo dashboard e pelo benchmark. Uma pontuação de benchmark, portanto, mede o próprio produto.

Armazenamento: memórias longas são incorporadas em janelas

O codificador lê 512 tokens. Texto além disso não é visto de forma alguma, então uma memória longa costumava ser pesquisável apenas pela sua abertura. Em um vault real com 6.705 memórias, 40% dos registros excediam a janela e 57,6% do texto era invisível para a busca semântica.

Então cada registro é incorporado como janelas sobrepostas de W = 448 tokens com um passo de S = 384, dando 64 tokens de sobreposição para que nenhum fato seja cortado pela metade, e o registro é pontuado pela sua melhor janela:

windows(d) = ceil( max(0, tokens(d) - W) / S ) + 1        capped at 64

s_vec(d)   = max over windows w of d :  cos(q, w)

Máximo, não média: uma memória é relevante se qualquer parte dela for, e uma média penalizaria uma memória longa pelas suas outras partes. Com uma janela por registro, isso é idêntico ao comportamento antigo, então memórias curtas não são afetadas. A maioria das memórias é curta: 6.705 registros produziram 6.785 janelas. As janelas são medidas em tokens do modelo, não em caracteres, porque um orçamento de caracteres erra por um fator de três entre prosa e um digest hexadecimal.

Recuperação: dois canais, combinados como evidência

Dois índices respondem a perguntas diferentes. O índice vetorial responde o que uma memória significa; o índice de palavras-chave responde o que ela diz. Suas pontuações não estão na mesma escala, e combiná-los é o problema central.

Até a versão 4.7, o Compartment os somava. Somar permite que uma correspondência semântica apenas razoável supere evidência literal conclusiva: buscar em um vault real por um SHA de commit que aparece em exatamente uma memória retornava essa memória abaixo de dez paráfrases dela, porque a soma enterrava um resultado de palavra-chave em primeiro lugar.

Os dois canais são alternativas, não adendos: qualquer um deles sozinho pode estabelecer relevância. Isso é um OR suave sobre evidências independentes,

P(relevant) = 1 - (1 - p_vec)(1 - p_lex)

e a pontuação é o seu logaritmo, que classifica de forma idêntica, mas mantém espalhando os resultados perto do topo em vez de saturar em 1:

score(d) = - w_vec · log(1 - p_vec(d))  -  w_lex · log(1 - p_lex(d))

w_vec = 0.75      w_lex = 0.25

Qualquer canal próximo da certeza carrega a memória sozinho; nenhum pode vetar o outro.

Transformando um cosseno em uma probabilidade. Um codificador normalizado por L2 fornece cossenos que são comparáveis entre consultas, então limites fixos os mapeiam. A normalização min-max por consulta reescalaria o melhor resultado de uma consulta sem esperança para 1.0 e descartaria essa informação.

p_vec(d) = clamp( (cos(q, d) - 0.25) / (0.85 - 0.25),  0,  0.88 )

O teto de 0.88 importa. Um cosseno é uma similaridade, nunca uma identidade: um codificador pode dizer isto é sobre a mesma coisa, nunca este é o registro que você nomeou. Uma correspondência literal em uma string única para uma memória pode. Então o canal semântico é limitado abaixo do que o canal literal pode alcançar, e o limite é forçado pelos pesos: o canal literal atinge o máximo em 0.25 · -log(1 - 0.999) = 1.727, então 0.75 · -log(1 - cap) < 1.727, dando cap < 0.90.

Transformando um resultado de palavra-chave em uma probabilidade, sem BM25. BM25 mede quão bem um documento corresponde, o que não resolve um confronto contra um resultado semântico. O que resolve é quão improvável a correspondência foi por acaso. Cada termo de consulta carrega sua auto-informação sobre o vault, e uma memória pontua a fração da informação da consulta que ela cobre:

I(t)     = log( N / (1 + df(t)) )                     N = records in the vault

p_lex(d) = ( Σ I(t) for query terms t present in d ) / ( Σ I(t) for all t )

Um termo único para uma memória é quase conclusivo; um termo em um décimo do vault é quase nada, seja qual for seu BM25. É isso que torna resultados literais e semânticos comparáveis.

O índice de palavras-chave é consultado como AND primeiro, porque uma frase exata é o sinal mais forte. O AND implícito do FTS5 exige que uma pergunta de nove palavras apareça palavra por palavra, então quando o AND não encontra nada, ele recai para OR sobre os termos informativos apenas: qualquer coisa em mais de 10% dos registros é descartada. Esse limiar é medido do vault, não retirado de uma lista de stopwords em inglês, então funciona da mesma forma para código, nomes ou outros idiomas.

Um pequeno termo de concordância de classificação é adicionado, a única coisa que a fusão de classificação recíproca faz bem, dimensionado para desempatar:

+ w_rrf · k · [ 1/(k + rank_vec) + 1/(k + rank_lex) ]      w_rrf = 0.10, k = 20

Importância e recência reordenam a pontuação

evidence(d) = aged( vec term, q(d) ) + lex term + rank residue
final(d)    = evidence(d) · ( 1 + w_imp · (2·importance(d) - 1) + w_op )

aged(s, q)  = log( 1 + 2^( -q / half_life_share ) · (e^s - 1) )

q(d)             = share of the vault's own memories written after this one
half_life_share  = 0.5, so the median memory is worth half the odds
w_imp            = 0.15, for facts and opinions alike
w_op             = 0.30 · 2^( -age_days / 30 ) for an opinion, from the last
                   re-affirmation (`affirmed`); 0 for a fact

Multiplicativo, então um prior só pode reordenar memórias que já corresponderam. Um prior aditivo deixaria uma memória importante aparecer para uma pergunta não relacionada. Uma memória que não correspondeu a nada pontua zero e permanece assim.

Centrado no padrão 0.5, daí 2·importance - 1. Cada memória sem peso carrega 0.5, incluindo os milhares de fatos de referência, então sem centralização todos receberiam o mesmo impulso e a importância não faria nada. Centrado, uma memória sem peso é neutra e apenas um peso deliberado a move.

A idade de uma memória é contada em memórias, não em dias. Um fato não fica menos verdadeiro em seis meses; o que torna uma memória antiga a resposta errada é que o vault avançou, e o quanto avançou é uma questão sobre quanto foi escrito. Então uma memória é tão antiga quanto a parcela do vault escrita depois dela. Duas memórias adicionadas em uma quinzena deixam uma memória de quinze dias intocada; quinhentas adicionadas na mesma quinzena reduzem pela metade as chances por trás de sua evidência semântica. A população contada são as memórias vivas do próprio vault nos namespaces sendo pesquisados: não os fatos de referência e não um pacote instalado, que chegam aos milhares em um instante e não têm idade nesse sentido.

A mudança é aplicada apenas ao canal semântico, e em chances, então uma correspondência forte é ajustada e uma fraca é reduzida. Um identificador literal é deixado sozinho: um SHA de commit que aparece em exatamente uma memória nomeia essa memória quer tenha sido escrito ontem ou no ano passado. E os pisos de relevância leem a pontuação sem idade, então a recência escolhe a ORDEM dos resultados e nunca quais voltam. Uma consequência: o score relatado de uma memória retornada é o envelhecido e pode ficar abaixo do piso absoluto que passou, então o piso é um corte que o vault faz e não uma propriedade do número que ele devolve.

Uma opinião carrega um segundo prior além disso, e esse está no relógio: ele reduz pela metade a cada 30 dias desde quando foi reafirmada pela última vez, com peso suficiente para que a opinião mais recente sobre um assunto vença.

Ordem de recuperação

Filtros de namespace, tag, data e fatos de referência são executados após a classificação, então um pool dimensionado para o número solicitado de resultados pode ser esvaziado por eles enquanto memórias correspondentes ficam logo após o corte. O pool começa em 200 por canal e se amplia até três vezes quando a filtragem deixa poucos. Abaixo de 20.000 registros, a busca vetorial é exata (matemática de matriz SIMD, recall 1.0); acima disso, HNSW com cerca de 99% de recall.

Segurança e o modelo de bloqueio

Os primitivos: criptografia XChaCha20-Poly1305 em tudo em repouso, incluindo vetores de incorporação, porque vetores podem ser invertidos de volta para texto · slots de chave Argon2id, estilo LUKS · uma chave por registro, então forget --shred destrói a chave e o conteúdo é irrecuperável em vez de marcado como excluído · um diário selado com fsync, compactação atômica e recuperação testada com kill -9 · um log de auditoria encadeado por hash (compartment audit verify) · manifests de vault assinados e pacotes · transporte stdio sem portas abertas; o único socket local é o socket Unix do processo de incorporação compartilhado, no mesmo diretório privado que a credencial de desbloqueio, carregando texto para dentro e vetores para fora e nunca uma chave · uma proteção em tempo de execução que aborta em qualquer tentativa de socket de rede (--assert-offline), com CI executando toda a suíte sob ela no Linux, macOS e Windows. O modelo de ameaça completo, incluindo o que o Compartment não pode proteger, está em SECURITY.md.

Pelo aplicativo

Tudo o que você faz no dia a dia é um botão. Desbloquear pede sua frase secreta; Bloquear fecha o vault e limpa toda credencial armazenada; Alterar senha recriptografa; Bloqueio automático escolhe 15, 30 ou 60 minutos ociosos, ou nunca. O Compartment nunca gera uma senha, semente ou frase de recuperação, e não guarda nenhuma credencial que você não tenha.

Após um desbloqueio, o vault permanece aberto entre processos, logouts e logins pelo tempo que você deixar, até um reinício ou perda de energia, até o timer de bloqueio automático disparar, ou até você bloqueá-lo. Um reinício ou perda de energia sempre o bloqueia: a credencial de desbloqueio é a chave mestra envolvida com um segredo aleatório por inicialização que vive apenas na memória do kernel e nunca é escrito em disco, então uma nova inicialização não pode abri-lo. Uma cópia do arquivo de credencial sozinha é inútil.

Pela linha de comando

Os mesmos controles, mais dois que só existem aqui:

  • compartment unlock e compartment lock fazem o que os botões fazem. Agentes podem bloquear com a ferramenta memory_lock. (Vaults de versões mais antigas que receberam uma frase de recuperação ainda a aceitam.)
  • compartment 2fa enable adiciona um segundo fator: sua frase secreta mais um arquivo de chave, por exemplo em um pendrive USB. Ambos alimentam o Argon2id juntos, então o requisito é imposto pela criptografia, não por uma configuração; um arquivo de vault roubado mais sua frase secreta não abre nada sem o arquivo de chave. A localização do arquivo de chave é lembrada, então desbloquear parece o mesmo enquanto ele estiver presente.
  • compartment unlock --keychain no macOS é uma adesão explícita que sobrevive a reinicializações.

A ferramenta MCP memory_unlock existe, mas está desativada por padrão, porque ativá-la coloca a frase secreta no contexto do modelo.

Um vault, muitos agentes, qualquer máquina

Sem a linha de comando

Cada agente na máquina usa o mesmo vault, e nada disso precisa de configuração: os botões Conectar um agente do aplicativo conectam Claude, Hermes Agent e OpenClaw, e o que um agente armazena os outros recuperam. Claude, Hermes Agent, Cursor e a CLI podem usar o vault ao mesmo tempo: escritas são serializadas por um bloqueio de arquivo, cada processo percebe escritas de outros e recarrega, e cada agente tem sua própria identidade e namespace. Seus servidores compartilham um processo de incorporação também, então dez agentes custam um modelo em RAM, e ele sai alguns minutos depois que o último deles sai.

Um vault bloqueado é um arquivo, memory.vault na pasta .compartment do seu diretório pessoal. Para mover para outra máquina, bloqueie o vault, copie o arquivo para lá, instale o Compartment e desbloqueie-o no aplicativo com sua frase secreta.

Pela linha de comando

O mesmo movimento, assinado para que o destinatário possa verificá-lo, mais as saídas de emergência:

compartment lock --sign
scp ~/.compartment/memory.vault other-machine:
compartment --vault memory.vault unlock     # your passphrase (+ keyfile if 2FA)

lock --sign adiciona um manifest Ed25519 que o destinatário pode verificar com compartment verify e nenhuma credencial. export --plaintext escreve o vault como JSONL e import o lê de volta, então você nunca fica preso. FORMAT.md especifica os arquivos .vault e .mpack byte por byte. Namespaces por agente aceitam concessões rw, ro ou none no arquivo de configurações, então um agente de rascunho pode ler sem escrever.

Pacotes de memória são pacotes assinados e somente leitura de memórias curadas (compartment pack build | install | remove | list | export). Eles instalam sob packs/<name>, somente leitura para todos os chamadores, e include_packs_in_search os alterna. A assinatura de um pacote é verificada contra uma chave que você confia, nunca contra a chave dentro do pacote. Os fatos de referência são o único pacote que vive em main como memórias comuns. PACKS.md cobre a autoria.

compartment setup airgap-bundle prepara uma instalação para uma máquina sem rede; setup download-model e setup download-longmemeval buscam o que os benchmarks opcionais precisam.

Medido, em um laptop básico de 8 GB

Cada número abaixo é reproduzível na sua máquina com compartment selftest and compartment bench (--longmemeval executa o benchmark de recuperação); compartment embed-daemon status relata o tamanho do próprio processo compartilhado.

MétricaMedido
Instalação limpa → abrir cofre, offlinesegundos, zero rede
Busca vetorial, 20 mil registros (HNSW)p95 0,68 ms
Busca híbrida completa (embed + janelas + palavras-chave + fusão de evidências)mediana 11,6 ms, p95 14,7 ms
Processo de incorporação compartilhado, modelo carregado, uma vez por máquina68 MB residentes
O mesmo após dois lotes de 64 janelas de texto longo71 MB; antes da 4.9.6, o servidor de cada agente mantinha 1,5 GB, depois 3 GB
Um processo de servidor MCP com seu modelo no daemon compartilhado60 MB, mais seu cofre e índice
Armazenar uma memória (embed + criptografar + journal fsync)~40 ms
Tamanho do wheel, modelo incluído~30 MB
Suíte de testes (cripto, adulteração, falha, offline, concorrência, 2FA, grafo, painel, ranqueamento)800+ testes, guarda offline ativa

Instalação

Nenhuma linha de comando necessária. Em um Mac, baixe o Compartment.pkg do último lançamento e abra-o. Python, o modelo de incorporação e todas as dependências estão dentro dele. Ele pede que você escolha uma frase secreta, cria o cofre e coloca o Compartment na sua barra de menus, onde os botões Conectar um agente fazem o resto.

Pela linha de comando, em qualquer sistema:

pip (macOS, Linux, Windows)pip install compartment && compartment init
pipx / uvpipx install compartment ou uv tool install compartment, depois compartment init
Plugin Claude Codeapós pip install compartment && compartment init: /plugin marketplace add MaxFreedomPollard/Compartment, depois /plugin install compartment@maxfreedompollard. O Codex lê o mesmo arquivo de marketplace
Dockerdocker build -t compartment . a partir de um checkout; veja Conectando cada agente

A rota pip precisa de Python 3.11 ou mais recente. O aplicativo roda no macOS 13 ou mais recente, no Windows com o runtime Microsoft Visual C++ instalado, e em qualquer desktop Linux.

init pede que você escolha uma frase secreta, cria o cofre, carrega os fatos de referência, conecta o Claude Code, Hermes Agent ou OpenClaw se estiverem instalados, e inicia o aplicativo: um item na barra de menus no macOS, um ícone na bandeja no Windows, uma janela no Linux. Reinicie seu agente e ele terá uma memória.

Para conectar um agente depois, ou qualquer outro cliente:

compartment integrate claude      # Claude Code + Claude Desktop
compartment integrate hermes      # Hermes Agent
compartment integrate openclaw    # OpenClaw
compartment integrate --list      # the 28 MCP clients it can wire: Cursor, VS Code, Cline, Roo Code, Zed, OpenCode, Codex CLI, Gemini CLI, Oh My Pi, LM Studio, AnythingLLM, BoltAI ...
compartment integrate --all       # every one of them that is installed here

claude, hermes e openclaw também recebem a habilidade /compartmentalize instalada em seus diretórios de habilidades. Qualquer outro cliente MCP usa este bloco (transporte stdio, sem variáveis de ambiente):

{ "mcpServers": { "compartment": { "command": "compartment", "args": ["serve"] } } }

Conectando cada agente

Nada disso precisa de terminal: os botões Conectar um agente no aplicativo executam os mesmos passos para Claude, Hermes Agent e OpenClaw. Os comandos abaixo são para quem os prefere, e para conectar um cliente que o aplicativo não lista. No Windows, execute-os no PowerShell com py -m pip install compartment no lugar de pip install compartment.

Claude (Code + Desktop)

pip install compartment && compartment init && compartment integrate claude

Registra o servidor MCP com a CLI do Claude Code (escopo do usuário, todos os projetos), importa as memórias que o Claude Code já escreveu em seus arquivos de memória (somente cópia e repetível; --no-import pula isso), instala o hook de captura (--no-hooks pula isso), instala a habilidade /compartmentalize, escreve um bloco gerenciado em CLAUDE.md e imprime o bloco de configuração do Claude Desktop. O servidor também se descreve no handshake do MCP, dizendo ao modelo para recordar antes de responder e para armazenar fatos duráveis, credenciais, nomes e decisões, então o Claude usa o Compartment como sua memória sem nenhuma instrução manual.

Hermes Agent

pip install compartment && compartment init && compartment integrate hermes

Instala o plugin de provedor no ambiente Hermes e executa hermes memory setup compartment; verifique com hermes memory status. Hermes Agent 0.20.0 e mais recentes também leem o formato portátil Agent Plugins, e este repositório é um deles. Essa rota instala o servidor MCP e a habilidade /compartmentalize do GitHub:

pip install compartment && compartment init
hermes plugins install MaxFreedomPollard/Compartment
hermes plugins enable compartment

O provedor é a integração mais completa, porque recorda e armazena em cada turno; o pacote portátil funciona apenas quando o modelo chama suas ferramentas. No macOS e Windows, ambos instalam no mesmo nome de diretório de plugin, então use um ou outro.

OpenClaw

pip install compartment && compartment init && compartment integrate openclaw

Escreve a entrada mcpServers em ~/.openclaw/openclaw.json, com um backup. Depois execute openclaw gateway restart e verifique com openclaw mcp list.

Qualquer cliente MCP

compartment integrate <client> conecta qualquer um dos 28 clientes em --list. Cada escrita de configuração faz um backup byte-exato primeiro, mescla em vez de substituir, escreve atomicamente e se recusa a tocar em um arquivo que não consegue analisar (ele imprime o bloco para colar em vez disso). Para fazer manualmente, use o bloco em Instalação; VS Code usa a chave servers com "type": "stdio", Zed usa context_servers, Codex usa TOML em [mcp_servers.compartment]. --vault e --caller são opcionais; os padrões são ~/.compartment/memory.vault e chamador user. Passo a passo por cliente estão em docs/INTEGRATIONS.md.

Docker

docker build -t compartment . a partir de um checkout constrói uma imagem headless: somente stdio, sem porta, usuário sem privilégios, cofre em um bind mount em /data. Crie o cofre no host primeiro com compartment init, porque esse passo solicita a frase secreta.

Configuração

Nada aqui é obrigatório. O Compartment instala já configurado; esta é toda a superfície se você quiser mudar algo.

No aplicativo

O painel atrás do ícone: Desbloquear e Bloquear, Alterar senha, Criar memórias automaticamente (o hook de captura), Buscar fatos iniciais, Bloqueio automático (15, 30, 60 minutos ou nunca), os botões CONECTAR UM AGENTE para Claude, Hermes Agent e OpenClaw, Atualizar e Sair.

Comandos

Flags globais, antes do comando: --vault PATH, --caller NAME, --keyfile PATH, --assert-offline, --version.

ComandoO que faz
initcria o cofre. --passphrase, --creator, --keychain, --no-session, --no-app
unlock / lockabre ou fecha ele. --passphrase-stdin, --keyfile, --keychain, --once; lock --sign --identity
status / verify / selftesto que há nele, está intacto, funciona
store / get / forgetuma memória. --source (obrigatório), --discovered, --expires, --namespace, --tag, --importance, --kind fact|opinion, --supersedes ID, --keep-both, --quarantined, --raw; forget --shred
search / recentencontra coisas. --namespace, --tag, --top-k, --limit, --all, --json
expireremove memórias expiradas
atomizelista memórias blob acima do limite como JSONL (--out + --plaintext), aplica um plano de divisão escrito por agente (--apply)
opinions auditpreenche kind em registros com formato de opinião, agrupa opiniões ativas sobrepostas, resolve com --keep-newest. --threshold, --no-backfill, --json
link / relations / unlinko grafo de relações, com janelas de validade (--from, --to, --as-of)
panel (menubar, tray)o aplicativo. --show, --self-check, --render, --login
integrate <agent>conecta claude, hermes, openclaw ou qualquer cliente listado, e instala /compartmentalize. --list, --all, --no-import, --no-hooks; integrate --refresh atualiza as instruções que uma instalação anterior escreveu nos arquivos do agente e nada mais
hooko hook de captura do Claude Code: install --pin-vault, uninstall, status, capture
import-claudepuxa o que o Claude Code já escreveu. --dir, --namespace, --dry-run
serveo servidor MCP, via stdio
embed-daemono processo de incorporação compartilhado que todo agente usa: status, stop, run
dashlê o cofre em um navegador: 127.0.0.1, token de uso único, somente GET
export / importexport --plaintext escreve sem criptografia; import lê de volta
rekeyaltera a frase secreta. --new-passphrase-stdin
2faenable, disable, status: um arquivo de chave como segundo fator
auditverify, repair o histórico encadeado por hash
retagrecalcula tags do cofre atual (--dry-run, --prune); nunca altera o texto da memória
reindexreconstrói o índice e dá aos registros longos as janelas de incorporação que estão faltando. --int8, --f32, --re-embed, --model
packbuild, install, remove, list, export pacotes de memória assinados (--trusted-key)
bench--records, --longmemeval, --variant, --limit
setupdownload-model, download-longmemeval, airgap-bundle
updateatualiza no lugar e depois atualiza as instruções nos arquivos do agente. --source pega o main do GitHub, --no-app pula o reinício
uninstallremove ele. O cofre é mantido a menos que você passe --purge

compartment panel --login on | off | status controla iniciar no login (no Linux, a entrada do menu de aplicativos). init --no-app pula o aplicativo em máquinas headless e em CI.

compartment dash é o botão do Painel pelo terminal: o cofre inteiro no seu navegador, crescimento ao longo do tempo, o grafo de relações com cada entidade nomeada, tags, contagens por agente, busca ao vivo. Ele serve a partir da RAM em 127.0.0.1 apenas, atrás de um token de URL aleatório, somente leitura, sem requisições de saída e sem configuração. Ctrl-C fecha ele.

A habilidade /compartmentalize

compartment integrate <agent> escreve um arquivo no diretório de habilidades do próprio agente, e compartment uninstall o remove:

AgenteCaminho
Claude Code~/.claude/skills/compartmentalize/SKILL.md
Hermes Agent$HERMES_HOME ou ~/.hermes/skills/compartmentalize/SKILL.md
OpenClaw$OPENCLAW_HOME ou ~/.openclaw/skills/compartmentalize/SKILL.md

Todos os três usam o mesmo layout de Agent Skills, então é um único arquivo. Apenas o usuário o executa. Digite antes de compactar, ou a qualquer momento, e o agente armazena a conversa inteira no cofre: pessoas e contatos, credenciais e onde elas vivem, URLs e hosts, decisões e as razões para elas, e um registro da própria sessão. Ele faz muitas chamadas memory_store. Você pode editar sua cópia; uma instalação posterior faz backup de uma cópia alterada em vez de sobrescrevê-la.

Arquivo de configurações

<vault>.config.json, ao lado do cofre, contendo permissões por chamador e:

ConfiguraçãoPadrãoSignificado
auto_lock_minutes30tempo ocioso antes de bloquear. 0 nunca bloqueia
search_starter_factstruese os fatos semeados entram nos resultados de busca
include_packs_in_searchtrueo mesmo, para pacotes instalados
recency_half_life_share0.5o quanto do cofre precisa ser mais novo que uma memória antes que sua evidência semântica valha metade das probabilidades. 0 desativa o prior de recência
expire_memoriestrueremover memórias expiradas automaticamente
duplicate_threshold0.97similaridade de cosseno na qual um armazenamento é duplicado
max_memory_chars200o limite de comprimento de uma única afirmação para memórias autorais. 0 desativa as verificações de comprimento e layout
opinion_update_threshold0.80similaridade na qual uma nova opinião é uma atualização de uma ativa e precisa de uma decisão de substituição
opinion_reaffirm_threshold0.97similaridade na qual uma opinião reformulada reafirma o registro ativo em vez de armazenar
retag_interval_hours6com que frequência a passagem em segundo plano recalcula tags. 0 desativa isso
retag_prunefalsese essa passagem também pode remover tags
index_precision"f32""int8" usa um quarto da RAM
embed_daemontruepedir ao processo de incorporação compartilhado da máquina por vetores em vez de carregar o modelo neste processo
unlock_tool_enabledfalsepermite que um agente desbloqueie o cofre. Desativado porque a frase secreta cruzaria o contexto do modelo

Ambiente

COMPARTMENT_VAULT qual cofre usar, COMPARTMENT_PASSPHRASE para scripts e CI, COMPARTMENT_SESSION_DIR onde a credencial de desbloqueio vive, COMPARTMENT_UI_SCALE escala do painel, COMPARTMENT_ASSERT_OFFLINE abortar em qualquer tentativa de rede. COMPARTMENT_EMBED_DAEMON=0 mantém o modelo de incorporação dentro de cada processo em vez do compartilhado, COMPARTMENT_EMBED_SOCKET move o socket desse processo, COMPARTMENT_EMBED_IDLE é quantos segundos ele sobrevive ao seu último cliente (300). HERMES_HOME, OPENCLAW_HOME e XDG_DATA_HOME são lidos onde se aplicam. Qualquer coisa exportada como ENGRAM_* ainda funciona.

Ferramentas MCP

Cada ferramenta tem um título e uma anotação somente leitura ou destrutiva, para que um cliente possa distinguir as sete ferramentas somente leitura das que escrevem antes de chamar qualquer coisa. memory_search, memory_store, memory_store_many, memory_get, memory_recent, memory_forget, memory_link, memory_relations, memory_unlink, memory_list_namespaces, memory_status, memory_lock, memory_selftest. memory_unlock existe, mas está desativado, a menos que você o ative acima.

Documentação

docs/MEMORY.mdcomo a memória é armazenada, o que é lembrado e o design de classificação
docs/INTEGRATIONS.mdselecionando Compartment no Hermes Agent, OpenClaw, Claude, e todo o resto
docs/COMPARISON.mdoutros servidores de memória, com fontes
SECURITY.mdo modelo de ameaça completo e seus limites
FORMAT.mdespecificações de .vault e .mpack em nível de byte (agnósticas de linguagem)
PACKS.mdcriação e envio de pacotes de memória assinados
CONTRIBUTING.mdconfiguração, boas issues e as garantias a manter
RELEASING.mdcomo um lançamento é feito

Política de Privacidade

O Compartment não coleta dados: sem telemetria, sem análises, sem conta e sem rede em tempo de execução. As memórias são armazenadas apenas na sua máquina, criptografadas com AEAD em repouso com uma frase secreta que nunca a deixa, e nada é compartilhado com ninguém. A política completa, cobrindo coleta, armazenamento, acesso à rede, compartilhamento com terceiros, retenção e contato, está em https://maxfreedompollard.github.io/Compartment/privacy.

Onde encontrá-lo

O Compartment está listado no PyPI, no registro oficial de MCP, no Cursor Directory, Glama, LobeHub, MCP Toplist, MCP Market, mcpservers.org, TensorBlock, no registro toolsdk.ai, Libraries.io, Snyk Advisor e deps.dev, e nas listas curadas abordage/awesome-mcp, TensorBlock/awesome-mcp-servers e Jenqyang/Awesome-AI-Agents.

MCP Toplist LobeHub

Compartment MCP server

Bugs e solicitações de recursos: Issues. Suporte e perguntas: Discussions; relatórios de segurança: SECURITY.md. Perguntas e ideias: Discussions.


mcp-name: io.github.MaxFreedomPollard/compartment