Memmy: memoria local compartida para agentes en un VPS
Instala Memmy desde código fuente en Ubuntu, ejecuta el servicio en el puerto 18960 y comparte una base SQLite local entre tus agentes de IA.
Qué es Memmy y qué almacena
Memmy es un centro de memoria local para agentes de IA que se ejecuta en tu propio VPS (servidor privado virtual). Mantiene una base de datos SQLite con lo que han aprendido tus agentes, y todos los agentes del servidor leen y escriben en ese mismo almacén. El proyecto es memmy-agent de MemTensor, tiene licencia MIT y está en la versión 1.0.4 en julio de 2026.
Solo una parte resulta relevante en un servidor. Memmy incluye un servicio de memoria que escucha en http://127.0.0.1:18960, una interfaz de línea de comandos (CLI) memmy-memory que se comunica con ese servicio y un entorno de trabajo de escritorio. El entorno de trabajo solo está disponible para macOS y Windows. Por tanto, en un VPS Linux ejecutas el servicio y la CLI. Esto basta para proporcionar una memoria compartida a Claude Code, Codex y Cursor.
Memmy clasifica lo que almacena en cuatro capas. L1 Trace es el turno sin procesar: la solicitud, la respuesta y las llamadas a herramientas. L2 Policy es un procedimiento derivado de trazas que ha demostrado ser útil. L3 World Model es conocimiento estable sobre un proyecto o un entorno. Skill es un procedimiento invocable cristalizado a partir de una política. El servicio asigna una capa al ingerir un turno, por lo que no tienes que crearlas manualmente.
Qué cambia un hub de memoria compartida frente a la memoria independiente de cada herramienta
Actualmente, cada agente incluye su propia memoria. Claude Code guarda los archivos de instrucciones en el repositorio. Cursor guarda las reglas en la base de datos de su espacio de trabajo. Codex guarda los registros de sesión en ~/.codex. Cada almacén pertenece a una sola herramienta, por lo que un dato que enseñaste el lunes en una herramienta se desconoce el martes en otra. Pagas ese coste dos veces: una vez en tokens para volver a explicar el mismo proyecto y otra por el trabajo incorrecto que realiza un agente basándose en una suposición que ya corregiste en otro lugar.
Un hub saca el almacén de la herramienta. Memmy también lee los almacenes existentes, por lo que no partes de una base de datos vacía. Su escáner conoce seis fuentes: Claude Code en ~/.claude/projects/**/*.jsonl, Codex en ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl, OpenCode en ~/.local/share/opencode/opencode.db, los archivos state.vscdb de Cursor, las bases de datos SQLite de OpenClaw en ~/.openclaw y Hermes en ~/.hermes. Puedes añadir una fuente manualmente con un nombre y una ruta local.
Los contadores de importación no coincidirán, y eso es normal. El escáner agrupa los mensajes por fuente y conversación y, después, escribe una memoria L1 por cada turno completo. Un turno se considera completo cuando tiene contenido de usuario no vacío y termina con un mensaje del asistente no vacío, por lo que una sesión interrumpida no aporta nada. Los mensajes se deduplican mediante puntos de control de conversación e identificadores de turno estables. El recuento escaneado, el recuento de mensajes importados y el recuento de memorias nuevas son diferentes en la misma ejecución.
Esta es la pieza que complementa cómo Claude Code gestiona el contexto dentro de una sesión. La gestión del contexto decide qué cabe en una sola ventana. Un hub de memoria decide qué permanece después de cerrar esa ventana.
Requisitos del VPS
- Node.js 22 o posterior. La documentación de Memmy lo requiere, y Ubuntu 24.04 incluye Node 18.
gity una cadena de herramientas de compilación, porquebetter-sqlite3es un módulo nativo que puede compilarse durante la instalación.- Aproximadamente 2 GB de RAM. La instalación en root descarga un espacio de trabajo grande y una cadena de compilación para el frontend.
- Varios GB de espacio libre en disco para
node_modulesy la base de datos.
sudo apt update
sudo apt install -y git build-essential python3 curl ca-certificates sqlite3
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node --versionnode --version debe mostrar v22 o posterior. Un valor v18 aquí significa que el paso de NodeSource no se aplicó y que la instalación fallará más adelante en la comprobación del motor del proyecto.
Instalar Memmy desde el código fuente en Ubuntu 24.04
git clone https://github.com/MemTensor/memmy-agent.git
cd memmy-agent
cp .env.example .env
npm install
npm run memory:buildnpm run memory:build compila el espacio de trabajo de @memmy/memory en Memory/dist. No es necesario compilar nada más del árbol para un servidor sin interfaz gráfica. Comprueba que el módulo nativo se haya cargado:
node -e "require('better-sqlite3'); console.log('better-sqlite3 loads')"Si esa línea genera un error en lugar de mostrar la salida, el módulo nativo no coincide con tu versión de Node. Ejecuta npm rebuild better-sqlite3, que es exactamente lo que hace el script de inicio del proyecto antes de iniciar cualquier proceso.
El README documenta bash scripts/dev-start.sh como un inicio mediante un solo comando. No lo ejecutes en un VPS sin interfaz gráfica. Inicia el shell de escritorio de Electron y un servidor de desarrollo de Vite en el puerto 19000 junto al servicio de memoria. Electron necesita una pantalla, por lo que en un servidor sin sesión gráfica el script se bloquea o finaliza.
Iniciar el servicio de memoria y comprobar que responde
npm run memory:serve:devEsta es la forma documentada de ejecutar el servicio de memoria desde el código fuente. Se enlaza a 127.0.0.1:18960, mantiene la base de datos en ~/.memmy/memory-service/memory.sqlite y lee la configuración desde ~/.memmy/config.yaml. El README especifica los mismos valores de forma explícita:
npm run memory:serve:dev -- \
--host 127.0.0.1 --port 18960 \
--db ~/.memmy/memory-service/memory.sqlite \
--config ~/.memmy/config.yamlDesde un segundo shell, pregunte al servicio si está activo:
curl -sS http://127.0.0.1:18960/api/v1/healthHealth es el único endpoint que nunca solicita un token, por lo que es la comprobación adecuada. Si curl termina con el código 7 y un mensaje Failed to connect to 127.0.0.1 port 18960, no hay ningún proceso escuchando. Lea el terminal donde se ejecuta el servicio, porque los errores de inicio se muestran allí. La causa habitual es que el módulo nativo de SQLite no se pueda cargar. ss -lntp | grep 18960 confirma el socket cuando el servicio ya está activo.
El resto de la API HTTP (interfaz de programación de aplicaciones) se encuentra bajo /api/v1.
POST /api/v1/memory/addescribe una memoria yPOST /api/v1/memory/searchrealiza consultas.GET /api/v1/memory/:idyDELETE /api/v1/memory/:idleen y eliminan una entrada.POST /api/v1/sessions/openyPOST /api/v1/sessions/:sessionId/closedelimitan una sesión de agente.POST /api/v1/turns/startyPOST /api/v1/turns/:turnId/completeregistran un turno.GET /api/v1/panel/overview,/api/v1/panel/analysisy/api/v1/panel/itemsproporcionan datos al dashboard.
Memmy reserva un bloque de puertos. En modo headless solo se usa el primero: 18960 para la memoria, 18970 para el estado de health del gateway, 18980 para la interfaz web y la administración HTTP, 18990 para la API compatible con OpenAI que inicia memmy serve, y después 19000 y 19010 para el servidor de desarrollo del frontend de escritorio. Si algo en su equipo ya utiliza uno de esos puertos, esa lista es el primer lugar que debe revisar.
De dónde procede realmente el comando memmy-memory
Aquí es donde suele fallar la primera instalación, así que léalo en el paquete en lugar de hacer suposiciones. El nombre del comando no tiene relación con el nombre del repositorio. Procede del campo bin del espacio de trabajo que lo define:
node -p "JSON.stringify(require('./Memory/package.json').bin)"Esto muestra {"memmy-memory":"./dist/src/cli/index.js"}. Por tanto, el punto de entrada compilado es Memory/dist/src/cli/index.js y solo existe después de npm run memory:build, porque la compilación crea dist y marca el archivo como ejecutable. Ejecútelo directamente:
node Memory/dist/src/cli/index.js healthSi quiere el nombre corto en su PATH, cree un enlace al mismo archivo:
sudo ln -s "$PWD/Memory/dist/src/cli/index.js" /usr/local/bin/memmy-memory
memmy-memory healthLa CLI usa http://127.0.0.1:18960 de forma predeterminada y acepta --url, --token, --config, --source y --user-id. Sus subcomandos son init, health, search, add, get y delete, además de las llamadas de sesión y turno que usan los agentes en lugar de las personas. memmy-memory search "deploy steps" y memmy-memory add "staging migrates on deploy" son los dos que ejecuta un agente con mayor frecuencia.
¿Cómo se conecta Claude Code con Memmy?
Claude Code no tiene una interfaz de complementos de memoria, por lo que Memmy no se integra directamente con él. La integración es más sencilla. Claude Code ejecuta memmy-memory como un comando de shell normal, y un archivo de instrucciones le indica cuándo hacerlo. El instalador documentado de Memmy escribe ese archivo por usted: memmy-memory init --agent coloca un archivo de instrucciones de memoria en el directorio de reglas del agente de destino.
Escriba la instrucción manualmente una vez para saber exactamente qué se indicó al agente. Claude Code lee CLAUDE.md desde la raíz del proyecto al inicio de cada sesión, por lo que una sección como esta constituye toda la integración:
## Memory
Before starting a task, run `memmy-memory search "<topic>"` and read what comes back.
When a task is done, run `memmy-memory add "<what you learned>"` for anything that will matter next session.Defina claramente qué permite esto. Es una integración en el nivel de instrucciones, por lo que funciona cuando el modelo decide ejecutar el comando, y no en otro caso. Nada fuerza la llamada. Si una sesión termina sin add, no se guarda nada, y la única señal es un resultado vacío la próxima vez que realice una búsqueda. Es la misma limitación que los propios archivos de memoria de Claude Code, con una diferencia: el almacén es compartido, por lo que la nota también está disponible para Codex y Cursor en la misma máquina.
La otra dirección no requiere ninguna configuración. El escáner de Memmy ya lee ~/.claude/projects/**/*.jsonl, que es donde Claude Code escribe las transcripciones de sus sesiones. Ejecute Memmy en el mismo servidor donde ejecuta Claude Code dentro de una sesión de tmux y el trabajo del día anterior se convertirá en memoria sin que tenga que configurar nada.
¿Funciona Memmy como servidor MCP para Claude Code?
No. Conocer esta dirección evita perder una tarde. MCP (model context protocol) tiene clientes y servidores. Memmy es un cliente. Se conecta a servidores MCP y ofrece sus herramientas a su propio entorno de ejecución del agente. No publica un endpoint MCP al que claude mcp add pueda conectarse. El único puente MCP del repositorio pertenece a la integración de Composio dentro de la API local de escritorio. Esa API se enlaza a un puerto aleatorio en 127.0.0.1 y usa su propio encabezado x-memmy-mcp-token.
El lado cliente se configura en ~/.memmy/config.yaml. El archivo MEMMY_CONFIG apunta a la configuración ubicada en tools.mcpServers:
tools:
mcpServers:
example:
type: stdio
command: npx
args:
- "-y"
- "your-mcp-server"
toolTimeout: 30
enabledTools:
- "*"type acepta stdio, sse y streamableHttp. Un servidor stdio se ejecuta como proceso secundario de Memmy. Por tanto, su comando debe existir en el mismo equipo y ejecutarse con el mismo usuario. Si ya mantiene servidores MCP en ejecución en un VPS, esos son los que debe enumerar aquí.
Mantener privado el almacén de memoria
Todo lo que posee Memmy se encuentra en ~/.memmy: config.yaml, el espacio de trabajo, memory-service/memory.sqlite y los archivos de ejecución. El análisis y la ingesta se realizan localmente, y las memorias se escriben en ese archivo SQLite local, por lo que la configuración predeterminada es realmente local.
Hay dos rutas que acceden a la red. MEMMY_CLOUD_SERVICE usa https://memmy-api.memtensor.cn de forma predeterminada y respalda el modo de cuenta con sus tokens de prueba, por lo que el modo de clave de API nunca lo utiliza. El programa de mejora de la memoria es un interruptor independiente en la configuración de privacidad y permanece desactivado hasta que lo active.
Hay una tercera ruta que es más fácil de pasar por alto. Si configura un proveedor de embeddings alojado, el texto de cada memoria se envía a ese proveedor para convertirlo en un vector. El almacenamiento local no evita este envío. Un endpoint de embeddings alojado por usted es la única forma de impedirlo.
Mantenga el puerto 18960 en la dirección de loopback. No necesita una regla de firewall, porque un servicio asociado a 127.0.0.1 no es accesible desde fuera del equipo. Acceda a él desde su laptop mediante SSH:
ssh -N -L 18960:127.0.0.1:18960 you@your-vpsSi alguna vez lo asocia a una dirección más amplia, establezca primero un token. Definir storage.token en la configuración, o la variable de entorno MEMMY_MEMORY_TOKEN o MEMORY_SERVICE_TOKEN, hace que todos los endpoints, excepto el de health, requieran un bearer token. Los valores de configuración admiten referencias ${ENV_NAME}, por lo que el token y las claves de API de sus modelos permanecen fuera del archivo. Es la misma práctica que mantener los secretos fuera de los agentes de IA en el resto del sistema, y una política ufw predeterminada de denegación ofrece una protección adicional si una versión futura cambia la dirección de asociación predeterminada.
Haz una copia de seguridad de ~/.memmy antes de confiar en él
memory.sqlite es todo el almacén. Los vectores se guardan en ese mismo archivo mediante la extensión sqlite-vec, por lo que un solo archivo es suficiente para la copia de seguridad. Copiarlo con cp mientras el servicio está escribiendo puede producir una base de datos inconsistente. Usa el comando de copia de seguridad propio de SQLite:
mkdir -p ~/memmy-backup
sqlite3 ~/.memmy/memory-service/memory.sqlite ".backup '$HOME/memmy-backup/memory.sqlite'"Esto crea una copia coherente mientras el servicio sigue ejecutándose. Transfiérela fuera del servidor de forma programada; para eso sirve restic para almacenamiento externo. Perder config.yaml implica volver a introducir la configuración del proveedor. Perder memory.sqlite implica perder todos los recuerdos, porque ningún otro elemento del equipo contiene una segunda copia.
Ejecutar el servicio de memoria con systemd
npm run memory:serve:dev en un shell termina con el shell. Un archivo de unidad mantiene el servicio activo después de los reinicios.
[Unit]
Description=Memmy memory service
After=network-online.target
[Service]
Type=simple
User=memmy
WorkingDirectory=/opt/memmy/memmy-agent
EnvironmentFile=/etc/memmy/memory.env
ExecStart=/usr/bin/npm run memory:serve:dev
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetMantenga el token fuera de la unidad. Colóquelo en /etc/memmy/memory.env, con root como propietario y permisos 600:
MEMMY_CONFIG=/home/memmy/.memmy/config.yaml
MEMMY_MEMORY_TOKEN=replace-this-with-a-long-random-stringsudo systemctl daemon-reload
sudo systemctl enable --now memmy-memory
systemctl status memmy-memory --no-pager
curl -sS http://127.0.0.1:18960/api/v1/healthstatus=203/EXEC en la salida de estado significa que systemd no pudo ejecutar ExecStart en absoluto. Por tanto, compruebe which npm: en una instalación de NodeSource es /usr/bin/npm y, con nvm, está en una ruta bajo el directorio personal del usuario, que systemd no encontrará. Si una unidad se inicia y se detiene de inmediato, el fallo se produjo dentro de npm. journalctl -u memmy-memory -n 50 muestra el motivo. El funcionamiento es el mismo que el de cualquier otro servicio de systemd en un VPS.
Lo que Memmy todavía no hace
- No existe una compilación de escritorio para Linux. Los scripts de empaquetado cubren macOS y Windows, por lo que el entorno de trabajo, el asistente de incorporación y el panel de memoria no están disponibles en el propio servidor.
memory:serve:devejecuta el punto de entrada de TypeScript mediantetsx, una ruta de desarrollo. El repositorio también incluyememory:servepara la salida compilada. Ejecutenpm runsin argumentos para ver qué scripts tiene realmente su copia de trabajo.- La recuperación crea su ventana de búsqueda a partir de las 2,000 filas vectoriales más recientes y, después, aplica la selección Top-K dentro de esa ventana. En un almacén muy grande, una memoria antigua puede quedar fuera de ella.
- La generación de embeddings ocurre después de la captura, y los errores se envían a una cola de reintentos en lugar de bloquear el turno del agente. Es posible que una memoria añadida hace poco todavía no se pueda encontrar mediante la búsqueda vectorial.
- Un solo archivo SQLite equivale a un solo nodo. No hay clustering, por lo que un segundo servidor tiene una memoria independiente.
La versión 1.0.4 y aproximadamente 329 estrellas a fecha de julio de 2026 describen un proyecto reciente. Los flags, las rutas y los nombres de los scripts cambian entre versiones. Consulte el campo bin y la salida de npm run en su propia copia de trabajo, en lugar de confiar en un comando copiado de cualquier sitio, incluido este documento.
FAQ
¿Por qué la comprobación de estado devuelve «connection refused»?
No hay ningún proceso escuchando en el puerto 18960. Un código de salida 7 de curl con Failed to connect to 127.0.0.1 port 18960 indica que el servicio de memoria no está en ejecución o que terminó durante el inicio. Lea el terminal o el journal donde se inició. Las dos causas habituales son un módulo nativo better-sqlite3 que no coincide con su versión de Node, lo que se corrige con npm rebuild better-sqlite3, y una versión de Node inferior a 22. Confirme el socket con ss -lntp | grep 18960 cuando el servicio esté activo.
¿De dónde procede el comando memmy-memory después de compilar desde el código fuente?
Procede del campo bin del paquete de workspace @memmy/memory, no del nombre del repositorio. Ejecute node -p "JSON.stringify(require('./Memory/package.json').bin)" dentro del checkout; mostrará {"memmy-memory":"./dist/src/cli/index.js"}. Ese archivo solo existe después de npm run memory:build, porque la compilación crea dist y marca el archivo como ejecutable. Ejecútelo como node Memory/dist/src/cli/index.js health o cree un enlace simbólico en /usr/local/bin para usar el nombre corto.
¿Puedo añadir Memmy a Claude Code con claude mcp add?
No. Memmy es un cliente MCP, no un servidor MCP. Se conecta a los servidores incluidos en tools.mcpServers dentro de ~/.memmy/config.yaml y ofrece sus herramientas a su propio entorno de ejecución. Claude Code accede a Memmy de la otra forma: ejecuta la CLI memmy-memory como un comando de shell, mediante un archivo de instrucciones que memmy-memory init --agent escribe en el directorio de reglas del agente.
¿Ejecutar Memmy envía mis memorias a un servicio en la nube?
El análisis y la ingesta se ejecutan localmente, y las memorias se escriben en ~/.memmy/memory-service/memory.sqlite en su propio disco. MEMMY_CLOUD_SERVICE apunta a https://memmy-api.memtensor.cn para el modo de cuenta y los tokens de prueba, y el programa de mejora de memorias permanece desactivado hasta que lo habilite. Debe prestar atención al proveedor de embeddings: un modelo de embeddings alojado recibe el texto de cada memoria que convierte en un vector. Si esto es importante, use un endpoint que administre usted mismo.