
The terminal agent is great until the session ends. In the next one, it rediscovers the same bug, rereads the same README, and asks again if the API uses JWT. The Engram is a local brain for this: a binary at Go, a SQLite with FTS5 at ~/.engram/engram.db, and the same database for Claude Code, Codex, Cursor, Grok, and any other MCP client.
It's not a transcript dump. The agent decides what's worth remembering — decision, bug, convention — and writes with mem_save. In the next session, mem_search and mem_context they return the right chunk. The map of alternatives (mnemo, Leteo, Subcog…) is at Claude-Mem alternatives in Go, Rust, and C; the map of terminal agents, at AI assistants on the Linux terminal. This guide walks through setting up Engram on Linux: installation, connecting to agents, configuring the project name, and enabling the daemon at boot.
What it is — and what it isn't
Engram (/ˈen.ɡræm/, the physical trace of a memory in the brain) is a Go binary with embedded SQLite via modernc.org/sqlite — pure Go, no CGO, no Node, no Python, no Docker for daily use. MIT license. The stable line in July of 2026 is the v1.20.0.
Four ports for the same database:
| Port | Command | What for |
|---|---|---|
| MCP stdio | engram mcp --tools=agent |
The agent talks with memory (Claude, Grok, Codex…) |
| CLI | engram search, save, context |
You manually query and save |
| TUI | engram tui |
Browse sessions and observations in the terminal |
| Local HTTP | engram serve (port 7437) |
JSON API. No is browser page |
The HTML dashboard (/dashboard) is the Engram Cloud — another process, Postgres, optional. Without Cloud, the local viewer is the TUI.
The philosophy, explicit in the README: the agent already has the LLM and the context. Instead of capturing every tool call and compressing afterward (the claude-mem model), Engram asks the agent to record only what lasts. Result: clean FTS5 search, zero extra API calls, one file you control.
Install on Ubuntu/Linux
There is no package apt neither .deb in the releases. What the production documentation asks for is the binary. One file, zero runtime: no Node, no Python, no Docker. The stable branch in July 2026 is the v1.20.0.
The releases provide ready-to-use Linux binaries for amd64 and arm64. The official executable is statically linked, with no runtime dependencies; just pick the file for your machine's architecture. To compile from source, the requirement is Go 1.24+.
Ubuntu amd64 and 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
The expected output is engram 1.20.0. The tarball contains the executable at the root, plus README, LICENSE, and CHANGELOG. Default database: ~/.engram/engram.db.
To make the PATH permanent, open a new terminal after installation. The ~/.profile Ubuntu's default already has the block if [ -d "$HOME/.local/bin" ] — so the mkdir comes before the install.
go install
If you already have Go 1.24+ (the one from the documentation). golang-go from Ubuntu 24.04 is 1.22 and the one from 22.04 is 1.18 — you can't go install that way; use the release binary or install Go from the website:
go install github.com/Gentleman-Programming/engram/cmd/engram@latest
# cai em $(go env GOPATH)/bin — em geral ~/go/bin/
go install stamps the version as dev. If you want the git-describe in engram version, clone and pass -ldflags — a go install and a go build in the same PATH leave two binaries and the “dev” version wins. There's a v2 line (github.com/Gentleman-Programming/engram/v2/cmd/engram) for release candidates; production continues on v1.
Homebrew on Linux
brew install gentleman-programming/tap/engram
The tap covers the v1 stable line.20.0. Upgrade: brew update && brew upgrade engram. Swapping the binary kills a engram serve loose — that's why the systemd service, below.
First contact
engram version
engram stats
engram projects list
engram tui
Default database: ~/.engram/engram.db. Override: ENGRAM_DATA_DIR. In the TUI, j/k navigates, Enter opens, / searches, Esc returns. Catppuccin Mocha theme.
The local API, if you start the 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"}
/ and /dashboard on this port they return 404. It's JSON, not a site. GET /project/current use the cwd of the serve process — on systemd with WorkingDirectory=%h, this becomes the basename of home, not the repo you're editing.
Connect to agents
engram setup <agente> writes MCP in the format of each client. Doesn't configure Cloud. Restart the agent afterwards.
| Agent | Command |
|---|---|
| Claude Code | claude plugin marketplace add Gentleman-Programming/engram and claude plugin install engram — or 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> — list in engram --help |
MCP Profiles: agent (the set that the agent uses on a daily basis), admin, or all. The default of engram mcp without flag is all. For the agent, use --tools=agent.
Grok Build (manual)
There is no engram setup grok. In ~/.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.
Any MCP client
{
"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).
How Engram chooses the project
Ele não indexa o path. Resolve um nome e filtra o SQLite por esse nome. Precedência:
- argumento explícito (
mem_contextwithproject,engram context teste); - override de processo (
engram mcp --project …orENGRAM_PROJECT); - detecção pelo cwd.
A detecção do diretório, em ordem:
| # | source | O que usa |
|---|---|---|
| 0 | config |
.engram/config.json with 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 and 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.
Start the server on 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 without 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.
The memory contract
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 or 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.
Tips to avoid pain
- 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 on 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 or 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.
Closing
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.
To continue: 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ó.
Official links: github.com/Gentleman-Programming/engram · releases · engram.gentlemanprogramming.com · Installation · Agent Setup