
O agente de terminal é ótimo até a sessão acabar. Na seguinte, ele redescobre o mesmo bug, relê o mesmo README e pergunta de novo se a API usa JWT. O Engram é um cérebro local para isso: um binário em Go, um SQLite com FTS5 em ~/.engram/engram.db, e o mesmo banco para Claude Code, Codex, Cursor, Grok e qualquer outro cliente MCP.
Não é lixeira de transcript. O agente decide o que vale a pena lembrar — decisão, bug, convenção — e grava com mem_save. Na sessão seguinte, mem_search e mem_context devolvem o pedaço certo. O mapa das alternativas (mnemo, Leteo, Subcog…) está em Alternativas ao Claude-Mem em Go, Rust e C; o mapa dos agentes no terminal, em Assistentes de IA no terminal Linux. Este post é o passo a passo do Engram no Linux: instalar, ligar nos agentes, acertar o nome do projeto e deixar o daemon no boot.
O que é — e o que não é
Engram (/ˈen.ɡræm/, o traço físico de uma memória no cérebro) é um binário Go com SQLite embutido via modernc.org/sqlite — puro Go, sem CGO, sem Node, sem Python, sem Docker para o uso diário. Licença MIT. A linha estável em julho de 2026 é a v1.20.0.
Quatro portas para o mesmo banco:
| Porta | Comando | Para quê |
|---|---|---|
| MCP stdio | engram mcp --tools=agent |
O agente fala com a memória (Claude, Grok, Codex…) |
| CLI | engram search, save, context |
Você consulta e grava na mão |
| TUI | engram tui |
Navegar sessões e observações no terminal |
| HTTP local | engram serve (porta 7437) |
API JSON. Não é página de navegador |
O dashboard HTML (/dashboard) é o Engram Cloud — outro processo, Postgres, opcional. Sem Cloud, o visualizador local é o TUI.
A filosofia, explícita no README: o agente já tem o LLM e o contexto. Em vez de capturar cada tool call e comprimir depois (o modelo do claude-mem), o Engram pede que o agente grave só o que dura. Resultado: busca FTS5 limpa, zero chamada extra de API, um arquivo que você controla.
Instalar no Ubuntu/Linux
Não existe pacote apt nem .deb nas releases. O que a documentação de produção pede é o binário. Um arquivo, zero runtime: sem Node, sem Python, sem Docker. A linha estável em julho de 2026 é a v1.20.0.
Os releases oferecem binários Linux prontos para amd64 e arm64. O executável oficial é estaticamente ligado, sem dependências de runtime; escolha apenas o arquivo da arquitetura da máquina. Para compilar do código-fonte, o requisito é Go 1.24+.
Ubuntu amd64 e arm64
sudo apt-get update
sudo apt-get install -y curl ca-certificates
VER=1.20.0
case "$(dpkg --print-architecture)" in
amd64) FILE=engram_${VER}_linux_amd64.tar.gz ;;
arm64) FILE=engram_${VER}_linux_arm64.tar.gz ;;
*) echo "sem binário pronto para $(dpkg --print-architecture)"; exit 1 ;;
esac
cd /tmp
curl -fsSL -O "https://github.com/Gentleman-Programming/engram/releases/download/v${VER}/${FILE}"
curl -fsSL -O "https://github.com/Gentleman-Programming/engram/releases/download/v${VER}/checksums.txt"
sha256sum -c checksums.txt --ignore-missing
mkdir -p ~/.local/bin
tar -xzf "$FILE" engram
install -m 755 engram ~/.local/bin/engram
# o ~/.profile do Ubuntu só acrescenta ~/.local/bin no próximo login,
# e só se o diretório já existir
export PATH="$HOME/.local/bin:$PATH"
hash -r
engram version
A saída esperada é engram 1.20.0. O tarball traz o executável na raiz, mais README, LICENSE e CHANGELOG. Banco padrão: ~/.engram/engram.db.
Para o PATH ficar permanente, abra um terminal novo depois da instalação. O ~/.profile padrão do Ubuntu já tem o bloco if [ -d "$HOME/.local/bin" ] — por isso o mkdir vem antes do install.
go install
Se você já tem Go 1.24+ (o da documentação). O pacote golang-go do Ubuntu 24.04 é 1.22 e o do 22.04 é 1.18 — não dá para go install por aí; use o binário da release ou instale o Go pelo site:
go install github.com/Gentleman-Programming/engram/cmd/engram@latest
# cai em $(go env GOPATH)/bin — em geral ~/go/bin/
go install carimba a versão como dev. Se quiser o git-describe no engram version, clone e passe -ldflags — um go install e um go build no mesmo PATH deixam dois binários e a versão “dev” ganha. Há uma linha v2 (github.com/Gentleman-Programming/engram/v2/cmd/engram) para release candidates; produção continua na v1.
Homebrew no Linux
brew install gentleman-programming/tap/engram
O tap cobre a linha estável v1.20.0. Upgrade: brew update && brew upgrade engram. Trocar o binário mata um engram serve solto — por isso o serviço systemd, mais abaixo.
Primeiro contato
engram version
engram stats
engram projects list
engram tui
Banco padrão: ~/.engram/engram.db. Override: ENGRAM_DATA_DIR. No TUI, j/k navega, Enter abre, / busca, Esc volta. Tema Catppuccin Mocha.
A API local, se você subir o daemon:
engram serve # 127.0.0.1:7437
curl -s http://127.0.0.1:7437/health
# {"service":"engram","status":"ok","version":"0.1.0"}
/ e /dashboard nessa porta devolvem 404. É JSON, não site. GET /project/current usa o cwd do processo do serve — no systemd com WorkingDirectory=%h, isso vira o basename da home, não o repo em que você está editando.
Ligar nos agentes
engram setup <agente> escreve o MCP no formato de cada cliente. Não configura Cloud. Reinicie o agente depois.
| Agente | Comando |
|---|---|
| Claude Code | claude plugin marketplace add Gentleman-Programming/engram e claude plugin install engram — ou engram setup claude-code |
| Codex | engram setup codex |
| OpenCode | engram setup opencode |
| Cursor | engram setup cursor |
| Gemini CLI | engram setup gemini-cli |
| VS Code Copilot | engram setup vscode-copilot |
| Windsurf, Qwen, Kiro, Kilo, Pi, Antigravity | engram setup <nome> — lista em engram --help |
Perfis MCP: agent (o conjunto que o agente usa no dia a dia), admin, ou all. O default do engram mcp sem flag é all. Para o agente, use --tools=agent.
Grok Build (manual)
Não há engram setup grok. Em ~/.grok/config.toml:
[mcp_servers.engram]
command = "/home/SEU_USER/.local/bin/engram"
args = ["mcp", "--tools=agent"]
enabled = true
Confira com grok mcp doctor engram — handshake ok e as tools do perfil agent. Recarregue a sessão do Grok: o MCP só entra na que sobe depois da config. O banco é o mesmo do Claude. O nome do projeto, não: cada processo detecta pelo próprio cwd.
Qualquer cliente MCP
{
"mcpServers": {
"engram": {
"command": "engram",
"args": ["mcp", "--tools=agent"]
}
}
}
O cliente dispara um processo stdio por sessão. Isso não substitui o engram serve do systemd — são coisas diferentes. MCP lê e grava o SQLite direto; o serve é a API HTTP (e o autosync Cloud, se você ligar).
Como o Engram escolhe o projeto
Ele não indexa o path. Resolve um nome e filtra o SQLite por esse nome. Precedência:
- argumento explícito (
mem_contextcomproject,engram context teste); - override de processo (
engram mcp --project …ouENGRAM_PROJECT); - detecção pelo cwd.
A detecção do diretório, em ordem:
| # | source | O que usa |
|---|---|---|
| 0 | config |
.engram/config.json com project_name |
| 1 | git_remote |
repo com origin — nome do remote, gravado num binding privado do clone |
| 2 | git_root |
git sem origin — basename da raiz |
| 3 | git_child |
cwd tem exatamente um filho git — promove esse |
| 4 | ambiguous |
vários filhos git — não escolhe sozinho |
| 5 | dir_basename |
último recurso: filepath.Base(cwd) |
Pasta sem git vira o basename. Claude gravando em /home/você/teste e Grok em …/site-linuxpro são dois projetos. A memória não aparece “do outro lado” até você buscar com o nome certo ou all_projects=true.
Lock estável na raiz do repo:
{
"project_name": "site-linuxpro"
}
O Engram usa o config mais próximo abaixo da raiz git — dá para ter backend/.engram/config.json e frontend/.engram/config.json no monorepo. Fora de git, só vale o config do diretório atual: ~/.engram/config.json não vaza para os filhos. Primeira chamada útil de qualquer sessão: mem_current_project — devolve project, project_source e, se for o caso, available_projects.
Se a escrita voltar ambiguous_project, o agente não pode chutar. Você escolhe um nome da lista e a tool retenta com project_choice_reason=user_selected_after_ambiguous_project.
Subir o serve no boot
Esta seção é opcional. Claude Code, Codex e os demais clientes MCP via stdio usam engram mcp e não precisam de engram serve. Suba o serviço se precisar da API HTTP local, do autosync do Cloud ou de integrações HTTP, como OpenCode e Pi.
Quando ele for necessário, um supervisor evita que engram serve morra no reboot ou durante a troca do binário.
Unit de usuário, no template oficial:
# ~/.config/systemd/user/engram.service
[Unit]
Description=Engram Memory Server
After=network.target
[Service]
WorkingDirectory=%h
ExecStart=%h/.local/bin/engram serve
Restart=always
RestartSec=3
Environment=ENGRAM_DATA_DIR=%h/.engram
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=default.target
mkdir -p ~/.engram ~/.config/systemd/user
systemctl --user daemon-reload
systemctl --user enable --now engram.service
curl -s http://127.0.0.1:7437/health
journalctl --user -u engram -f
enable amarra no login. Para subir no boot sem sessão gráfica, o usuário precisa de linger:
loginctl enable-linger "$USER"
loginctl show-user "$USER" -p Linger
Se a 7437 já estiver ocupada por um serve órfão, a unit falha no bind. Mate o processo antigo (ss -tlnp | grep 7437) e systemctl --user restart engram.
O contrato de memória
O README trata o Engram como memória curada, não como dump. O ciclo:
- Orientar —
mem_current_project, depoismem_context/mem_search. - Buscar antes de repetir — decisão, bug, convenção que já podem estar no banco.
- Revelar por camadas —
mem_searchdevolve preview (~300 caracteres);mem_get_observationtraz o texto inteiro;mem_timelinemostra o antes/depois na sessão. - Gravar o que dura —
mem_savecom título curto, tipo (decision,bugfix,config,architecture…) e corpo What / Why / Where / Learned. Não grave saída crua de ferramenta. - Assunto que evolui —
topic_keyestável (architecture/auth-model). Mesmo projeto + scope + topic vira upsert, não uma linha nova. - Fechar a sessão —
mem_session_summarycom Goal, Discoveries, Accomplished, Next Steps, Files.
Scope: project (default), personal ou global. Um personal no mesmo topic_key não sobrescreve o de projeto.
O que não vai para o SQLite: senha, token, dump de journalctl. O git continua sendo o registro — a história está em A história do Git. Tags <private> são removidas em duas camadas no Engram; mesmo assim, não grave o que não pode vazar.
O Cloud é replicação opcional + UI. SQLite local continua autoritativo. Caminho smoke com Docker, no clone do repositório:
docker compose -f docker-compose.cloud.yml up -d
engram cloud config --server http://127.0.0.1:18080
engram cloud enroll meu-projeto
engram sync --cloud --project meu-projeto
Dashboard local: http://127.0.0.1:18080/dashboard. No compose smoke, /dashboard/login redireciona sem pedir token. Rotas úteis: /dashboard/browser, /dashboard/projects, /dashboard/activity.
Para o dia a dia num laptop, Cloud é extra. TUI + MCP bastam.
Dicas que evitam dor
- Um cérebro, nomes certos. Claude, Grok e Codex só compartilham memória se o
projectfor o mesmo. Coloque.engram/config.jsonno repo no primeiro dia. - Não instale três servidores de memória no mesmo agente. Eles competem pelo contexto. Um de sessão (Engram) + o grafo do código (codebase-memory-mcp) já é o teto útil — o encaixe no fluxo está em Vibe coding no Linux.
- MCP ≠ serve. O Grok/Claude sobe
engram mcpvia stdio. O systemd sobeengram servena 7437. Os dois podem coexistir; um não substitui o outro. - Cwd do serve. Unit com
WorkingDirectory=%hfaz/project/currentresponder o basename da home. Para leitura de projeto, use o MCP do agente (cwd do repo) ou passe--project. - Busca FTS5 é AND por padrão.
match_mode=anyalarga. Preview não é o registro completo — abra o id. - Doctor.
engram doctor(oumem_doctor) checa lock do SQLite, mismatch de sessão e binding. Quatro checks ok é o estado saudável. - Linger. Sem
loginctl enable-linger, a unit de usuário só vive enquanto houver sessão. Com linger, sobrevive ao reboot headless. - Upgrade do binário. Homebrew ou um
installpor cima mata o processo se não houver systemd comRestart=always. - Não misture autosync nativo e wrappers de cron. A documentação pede um modo só.
- HTTP token.
ENGRAM_HTTP_TOKENprotege delete/export/import na API local. Sem ele, essas rotas ficam abertas em 127.0.0.1 — ok no laptop, ruim se você publicar a 7437 na LAN.
Engram ou claude-mem?
O Engram nasceu inspirado no claude-mem, com decisões opostas: binário único, qualquer agente MCP, FTS5 em vez de worker + ChromaDB, o agente comprime na hora em vez de um pipeline à parte. Se a sua vida é só Claude Code e você já está no ecossistema de hooks dele, o original continua válido. Se Claude, Codex e Grok precisam lembrar a mesma decisão, comece pelo Engram. Comparação lado a lado e as outras opções em Go/Rust/C: Alternativas ao Claude-Mem.
Fechando
Instale o binário da release, trave o nome do projeto num .engram/config.json, ligue o MCP em cada agente e deixe o engram serve no systemd de usuário. O resto é disciplina: gravar o que dura, buscar antes de repetir, fechar a sessão com um resumo. O agente da manhã seguinte já sabe que a autenticação é JWT — e você não paga um segundo modelo só para lembrar disso.
Para continuar: assistentes de IA no terminal, Ollama se a inferência também for local, e a história do Go — a língua em que o Engram é um arquivo só.
Links oficiais: github.com/Gentleman-Programming/engram · releases · engram.gentlemanprogramming.com · Installation · Agent Setup