
El agente de terminal es genial hasta que termina la sesión. En la siguiente, redescubre el mismo bug, vuelve a leer el mismo README y pregunta otra vez si la API usa JWT. Engram es un cerebro local para eso: un binario en Go, un SQLite con FTS5 en ~/.engram/engram.db, y la misma base de datos para Claude Code, Codex, Cursor, Grox y cualquier otro cliente MCP.
No es un cubo de transcripts. El agente decide qué vale la pena recordar: decisión, bug, convención, y lo guarda con mem_save. En la siguiente sesión, mem_search y mem_context devuelven el trozo adecuado. El mapa de alternativas (mnemo, Leteo, Subcog…) está en Alternativas a Claude-Mem en Go, Rust y C; el mapa de los agentes en terminal, en Asistentes de IA en el terminal Linux. Este post es el paso a paso de Engram en Linux: instalar, conectarlo a los agentes, ajustar el nombre del proyecto y dejar el daemon en el arranque.
Qué es — y qué no es
Engram (/ˈen.ɡræm/, el rastro físico de un recuerdo en el cerebro) es un binario Go con SQLite integrado mediante modernc.org/sqlite: Go puro, sin CGO, sin Node, sin Python, sin Docker para el uso diario. Licencia MIT. La línea estable en julio de 2026 es la v1.20.0.
Cuatro puertas al mismo banco:
| Puerta | Comando | Para qué |
|---|---|---|
| MCP stdio | engram mcp --tools=agent |
El agente habla con la memoria (Claude, Grok, Codex…) |
| CLI | engram search, save, context |
Consultas y grabas a mano |
| TUI | engram tui |
Navegar sesiones y observaciones en el terminal |
| HTTP local | engram serve (puerto 7437) |
API JSON. No es una página de navegador |
El dashboard HTML (/dashboard) es el Engram Cloud, otro proceso, Postgres, opcional. Sin Cloud, el visor local es el TUI.
La filosofía, explícita en el README: el agente ya tiene el LLM y el contexto. En lugar de capturar cada tool call y comprimir después (el modelo de claude-mem), Engram pide al agente que registre solo lo que dura. Resultado: búsqueda FTS5 limpia, cero llamadas extra a la API, un archivo que tú controlas.
Instalar en Ubuntu/Linux
No existe paquete apt ni .deb en las releases. Lo que pide la documentación de producción es el binario. Un archivo, cero runtime: sin Node, sin Python, sin Docker. La línea estable en julio de 2026 es la v1.20.0.
Los releases ofrecen binarios Linux listos para amd64 e arm64. El ejecutable oficial está enlazado estáticamente, sin dependencias en tiempo de ejecución; elige únicamente el archivo de la arquitectura de la máquina. Para compilar desde el código fuente, el requisito es Go 1.24+.
Ubuntu amd64 y 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
La salida esperada es engram 1.20.0. El tarball trae el ejecutable en la raíz, además de README, LICENSE y CHANGELOG. Base de datos por defecto: ~/.engram/engram.db.
Para que el PATH quede permanente, abre una terminal nueva después de la instalación. El ~/.profile por defecto de Ubuntu ya trae el bloque if [ -d "$HOME/.local/bin" ] — por eso el mkdir va antes que el install.
go install
Si ya tienes Go 1.24+ (el de la documentación). El paquete golang-go de Ubuntu 24.04 es 1.22 y el de 22.04 es 1.18 — no se puede go install por ahí; usa el binario de la release o instala Go desde su web:
go install github.com/Gentleman-Programming/engram/cmd/engram@latest
# cai em $(go env GOPATH)/bin — em geral ~/go/bin/
go install estampa la versión como dev. Si quieres el git-describe en el engram version, clona y pasa -ldflags — un go install y un go build en el mismo PATH dejan dos binarios y gana la versión “dev”. Hay una línea v2 (github.com/Gentleman-Programming/engram/v2/cmd/engram) para release candidates; producción sigue en v1.
Homebrew en Linux
brew install gentleman-programming/tap/engram
El tap cubre la línea estable v1.20.0. Actualización: brew update && brew upgrade engram. Cambiar el binario mata un engram serve suelto — por eso el servicio systemd, más abajo.
Primer contacto
engram version
engram stats
engram projects list
engram tui
Banco por defecto: ~/.engram/engram.db. Override: ENGRAM_DATA_DIR. En el TUI, j/k navega, Enter abre, / busca, Esc vuelve. Tema Catppuccin Mocha.
La API local, si levantas el 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"}
/ y /dashboard en ese puerto devuelven 404. Es JSON, no un sitio. GET /project/current usa el cwd del proceso serve — en systemd con WorkingDirectory=%h, eso se convierte en el basename del home, no el repo en el que estás editando.
Conectar a los agentes
engram setup escribe el MCP en el formato de cada cliente. No configura Cloud. Reinicia el agente después.
| Agente | Comando |
|---|---|
| Claude Code | claude plugin marketplace add Gentleman-Programming/engram e claude plugin install engram — o 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 en engram --help |
Perfiles MCP: agent (el conjunto que usa el agente en el día a día), admin, o all. El valor por defecto de engram mcp sin flag es all. Para el agente, usa --tools=agent.
Grok Build (manual)
No hay engram setup grok. En ~/.grok/config.toml:
[mcp_servers.engram]
command = "/home/SEU_USER/.local/bin/engram"
args = ["mcp", "--tools=agent"]
enabled = true
Compruébalo con grok mcp doctor engram — handshake ok y las tools del perfil agent. Recarga la sesión de Grok: el MCP solo entra en la que sube después de la config. La base de datos es la misma que la de Claude. El nombre del proyecto, no: cada proceso detecta por su propio cwd.
Cualquier cliente MCP
{
"mcpServers": {
"engram": {
"command": "engram",
"args": ["mcp", "--tools=agent"]
}
}
}
El cliente lanza un proceso stdio por sesión. Esto no sustituye al engram serve de systemd — son cosas distintas. MCP lee y escribe el SQLite directamente; el serve es la API HTTP (y el autosync Cloud, si lo activas).
Cómo Engram elige el proyecto
No indexa el path. Resuelve un nombre y filtra el SQLite por ese nombre. Precedencia:
- argumento explícito (
mem_contextconproject,engram context teste); - override de proceso (
engram mcp --project …oENGRAM_PROJECT); - detección por cwd.
La detección del directorio, en orden:
| # | source | Qué usa |
|---|---|---|
| 0 | config |
.engram/config.json con project_name |
| 1 | git_remote |
repo con origin — nombre del remote, guardado en un binding privado del clon |
| 2 | git_root |
git sin origin — basename de la raíz |
| 3 | git_child |
cwd tiene exactamente un hijo git — promueve ese |
| 4 | ambiguous |
varios hijos git — no elige solo |
| 5 | dir_basename |
último recurso: filepath.Base(cwd) |
Carpeta sin git se convierte en el basename. Claude guardando en /home/você/teste y Grok en …/site-linuxpro son dos proyectos. La memoria no aparece “en el otro lado” hasta que la busques con el nombre correcto o all_projects=true.
Lock estable en la raíz del repo:
{
"project_name": "site-linuxpro"
}
Engram usa el config más cercano por debajo de la raíz git — se pueden tener backend/.engram/config.json y frontend/.engram/config.json en el monorepo. Fuera de git, solo vale el config del directorio actual: ~/.engram/config.json no se filtra a los hijos. Primera llamada útil de cualquier sesión: mem_current_project — devuelve project, project_source y, si procede, available_projects.
Si la escritura vuelve ambiguous_project, el agente no puede adivinar. Eliges un nombre de la lista y la herramienta reintenta con project_choice_reason=user_selected_after_ambiguous_project.
Iniciar el serve en el arranque
Esta sección es opcional. Claude Code, Codex y los demás clientes MCP a través de stdio usan engram mcp y no necesitan engram serve. Levanta el servicio si necesitas la API HTTP local, el autosync de la nube o integraciones HTTP, como OpenCode y Pi.
Cuando sea necesario, un supervisor evita que engram serve muera en el reinicio o durante el cambio del binario.
Unit de usuario, en la plantilla 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 se ata al login. Para arrancar en el boot sin sesión gráfica, el usuario necesita linger:
loginctl enable-linger "$USER"
loginctl show-user "$USER" -p Linger
Si el 7437 ya está ocupado por un serve huérfano, la unit falla en el bind. Mata el proceso antiguo (ss -tlnp | grep 7437) y systemctl --user restart engram.
El contrato de memoria
El README trata el Engram como memoria curada, no como volcado. El ciclo:
- Orientar —
mem_current_project, despuésmem_context/mem_search. - Buscar antes de repetir — decisión, error, convención que ya pueden estar en la base.
- Revelar por capas —
mem_searchdevuelve vista previa (~300 caracteres);mem_get_observationtrae el texto completo;mem_timelinemuestra el antes/después en la sesión. - Guardar lo que dura —
mem_savecon título corto, tipo (decision,bugfix,config,architecture…) y cuerpo What / Why / Where / Learned. No guarde salida cruda de herramienta. - Asunto que evoluciona —
topic_keyestable (architecture/auth-model). Mismo proyecto + scope + topic se convierte en upsert, no en una línea nueva. - Cerrar la sesión —
mem_session_summarycon Goal, Discoveries, Accomplished, Next Steps, Files.
Scope: project (por defecto), personal o global. Un personal en el mismo topic_key no sobrescribe el de proyecto.
Lo que no va al SQLite: contraseña, token, dump de journalctl. Git sigue siendo el registro — la historia está en El historial de Git. Las etiquetas se eliminan en dos capas en Engram; aun así, no guardes lo que no pueda filtrarse.
Cloud es replicación opcional + UI. SQLite local sigue siendo autoritativo. Ruta smoke con Docker, en el clon del repositorio:
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. En el compose smoke, /dashboard/login redirige sin pedir token. Rutas útiles: /dashboard/browser, /dashboard/projects, /dashboard/activity.
Para el día a día en un portátil, Cloud es extra. TUI + MCP bastan.
Consejos que evitan dolores
- Un cerebro, nombres correctos. Claude, Grok y Codex solo comparten memoria si el
projectes el mismo. Coloque.engram/config.jsonen el repo el primer día. - No instale tres servidores de memoria en el mismo agente. Compiten por el contexto. Uno de sesión (Engram) + el grafo del código (codebase-memory-mcp) ya es el techo útil — el encaje en el flujo está en Vibe coding en Linux.
- MCP ≠ serve. Grok/Claude arranca
engram mcpvía stdio. systemd arrancaengram serveen 7437. Ambos pueden coexistir; uno no sustituye al otro. - Cwd del serve. Unit con
WorkingDirectory=%hhace/project/currentresponder el basename del home. Para lectura de proyecto, usa el MCP del agente (cwd del repo) o pasa--project. - Búsqueda FTS5 es AND por defecto.
match_mode=anyamplia. La preview no es el registro completo — abre el id. - Doctor.
engram doctor(omem_doctor) verifica el bloqueo de SQLite, el desajuste de sesión y el binding. Cuatro comprobaciones correctas indican el estado saludable. - Linger. Sin
loginctl enable-linger, la unidad de usuario solo vive mientras haya sesión. Con linger, sobrevive al reinicio sin interfaz. - Actualización del binario. Homebrew o un
installencima mata el proceso si no hay systemd conRestart=always. - No mezcles el autosync nativo y los wrappers de cron. La documentación pide un único modo.
- Token HTTP.
ENGRAM_HTTP_TOKENprotege delete/export/import en la API local. Sin él, esas rutas quedan abiertas en 127.0.0.1 — bien en el portátil, mal si publicas la 7437 en la LAN.
Engram o claude-mem?
Engram nació inspirado en claude-mem, con decisiones opuestas: binario único, cualquier agente MCP, FTS5 en lugar de worker + ChromaDB, el agente comprime en el momento en vez de un pipeline aparte. Si tu vida es solo Claude Code y ya estás en el ecosistema de hooks de este, el original sigue siendo válido. Si Claude, Codex y Grok necesitan recordar la misma decisión, empieza por Engram. Comparación lado a lado y las demás opciones en Go/Rust/C: Alternativas a Claude-Mem.
Cerrando
Instala el binario de la release, fija el nombre del proyecto en un .engram/config.json, conecta el MCP en cada agente y deja el engram serve en systemd de usuario. El resto es disciplina: guardar lo que dura, buscar antes de repetir, cerrar la sesión con un resumen. El agente de la mañana siguiente ya sabe que la autenticación es JWT — y no pagas un segundo modelo solo para recordar eso.
Para continuar: asistentes de IA en el terminal, Ollama si la inferencia también es local, y la historia de Go — el lenguaje en el que Engram es un único archivo.
Enlaces oficiales: github.com/Gentleman-Programming/engram · releases · engram.gentlemanprogramming.com · Installation · Agent Setup