Enhanced Memory MCP Server
Servidor de Memoria Mejorada MCP
Memoria persistente y buscable para agentes de IA, sobre el Model Context Protocol. Las entidades y sus observaciones residen en una base de datos SQLite comprimida con sumas de verificación e historial de versiones; sobre ella se asientan un almacén por niveles y un pipeline de recuperación multiestrategia; y todo se expone a tu cliente como herramientas MCP.
La cantidad de herramientas depende de lo que hayas instalado, y la diferencia no es un error:
una herramienta cuyo backend falta no se registra en absoluto. Una instalación básica
(requirements.txt) registra 186; añadir los backends opcionales
(requirements-optional.txt) la eleva a 204. Si contaste 186 después de un
simple pip install -r requirements.txt, nada está roto.
Ambas cifras se midieron en Python 3.11.11 mediante tools/list sobre stdio,
con AGENTIC_SYSTEM_PATH sin definir. Esta última condición no es pedantería. Si esa
variable apunta al sistema separado descrito en
GraphRAG, se registran siete herramientas más y
obtienes 193 y 211 en su lugar. Borradores anteriores de este archivo indicaban 188 y 206
porque se midieron en máquinas que lo tenían exportado, y dos de nosotros
reproducimos el mismo número incorrecto sin notar que compartíamos la causa. Defínela como vacía
antes de volver a medir.
Todo lo básico funciona localmente sin claves API ni red. La pila vectorial opcional (Qdrant más ollama) mejora la recuperación de coincidencia de palabras clave a basada en significado, y su ausencia degrada con elegancia en lugar de romper.
Lo primero que debes saber
Esto son dos procesos, no uno. Casi todas las preguntas de soporte sobre este proyecto provienen de ejecutar solo la mitad.
your MCP client (Claude Code, Claude Desktop, an SDK, curl)
|
| stdio JSON-RPC, one server process per client session
v
+-------------------------------------------------------+
| MCP server server.py |
| start with setup/bin/mcp-server.sh |
+-------------------------------------------------------+
|
| JSON over a Unix socket: $MEMORY_DB_SOCKET_PATH
| (default /tmp/memory-db.sock)
v
+-------------------------------------------------------+
| memory-db daemon memory_db_service.py |
| start with setup/bin/memory-db-daemon.sh |
| REQUIRED. Owns the database file exclusively so that |
| several clients can share it without corrupting it. |
+-------------------------------------------------------+
|
v
memory.db (SQLite, default ~/.claude/enhanced_memories/)
optional, off to the side:
Qdrant http://localhost:6333 vector index for semantic recall
ollama http://127.0.0.1:11434 local embeddings that feed that indexEl daemon no es opcional y el servidor MCP no lo inicia por ti. Sin él, el servidor igual se inicia, responde y devuelve objetos como estos:
{"query": "anything", "count": 0, "results": [],
"error": "Memory-DB service error: [Errno 2] No such file or directory"}
{"error": "Memory-DB service error: ...", "entities": {"total": 0},
"compression": {"ratio": "N/A"}}Bien formados, analizables y vacíos. Un agente que lee eso concluye que tu memoria
está vacía en lugar de sorda. ./healthcheck.sh existe para diferenciar ambas situaciones.
Related MCP server: Strata Memory MCP Server
Requisitos previos
Python 3.11 o más reciente. En algunos macOS, un simple
python3sigue siendo 3.9, por lo que el instalador busca primero nombres versionados.git y espacio en disco para el entorno virtual. Medido en macOS arm64 con Python 3.11: 83 MB para una instalación básica, 964 MB con los backends opcionales, ya que estos incluyen sentence-transformers y torch. En Linux x86_64 la cifra básica es 131 MB (medido en un contenedor python:3.11-slim) — las ruedas difieren según la plataforma, así que espera que el número varíe con la tuya. El repositorio en sí pesa 5 MB.
Opcional: podman o docker, si quieres la ruta del contenedor o un Qdrant local.
Opcional: ollama, para incrustaciones locales.
No se requiere sudo en ningún momento. No se instala nada a nivel de sistema.
¿Ya tienes un sistema de memoria mejorada en ejecución?
Lee esto antes del paso 2 a continuación si esta máquina podría tener ya uno: un checkout
anterior, un segundo clon, un servicio que instalaste hace meses. Por defecto, cada
instalación quiere las mismas dos cosas — el socket /tmp/memory-db.sock y la
base de datos ~/.claude/enhanced_memories/memory.db — y no se pueden compartir.
Verifica primero:
lsof /tmp/memory-db.sock # macOS or Linux
ss -xl | grep memory-db.sock # Linux
pgrep -af memory_db_service.pyCualquier elemento listado significa que hay una instalación activa. Iniciar un segundo daemon en un socket ocupado es rechazado: sale con código distinto de cero e imprime la ruta del socket y la base de datos que el daemon respondedor está usando, en lugar de tomar el control del socket. Eso es una protección, no una coexistencia — el segundo daemon no se ejecuta en absoluto.
Para ejecutar dos instalaciones lado a lado, dale a esta su propio todo en .env:
ENHANCED_MEMORY_DIR=/home/you/.enhanced-memory-second
MEMORY_DB_SOCKET_PATH=/tmp/memory-db-second.sock
# Only if you want the Neural Memory Fabric somewhere else again; by default it
# follows ENHANCED_MEMORY_DIR:
# NMF_SQLITE_PATH=/home/you/.enhanced-memory-second/nmf.db
# NMF_FILES_ROOT=/home/you/.enhanced-memory-second/nmf_filesENHANCED_MEMORY_DIR es el que se olvida. Dos daemons en dos
sockets compartiendo un memory.db no es coexistencia: son dos propietarios exclusivos
de un archivo, que es exactamente lo que el daemon existe para evitar.
Inicio rápido
git clone <this-repo> enhanced-memory-mcp
cd enhanced-memory-mcp
# 1. venv, dependencies, .env, database directory. Idempotent, re-runnable.
setup/setup.sh
# 2. start the daemon (foreground). Leave it running, or install it as a
# background service: setup/service/install-services.sh
setup/bin/memory-db-daemon.sh &
# 3. prove the install works before you trust it
./healthcheck.shUna ejecución saludable termina con Required checks passed. y código de salida 0. Cualquier otra cosa
es un problema real: consulta Solución de problemas.
La configuración reside en .env, que el paso 1 crea a partir de .env.example solo cuando
.env está ausente. Editar ese archivo es cómo persiste una configuración; volver a ejecutar
setup/setup.sh nunca lo sobrescribe.
Luego registra el servidor con tu cliente MCP. En ~/.claude.json:
{
"mcpServers": {
"enhanced-memory": {
"command": "/absolute/path/to/enhanced-memory-mcp/setup/bin/mcp-server.sh"
}
}
}Apunta el cliente al lanzador, no a python server.py. El lanzador
aplica el .env de este checkout, que es lo que garantiza que el servidor MCP y el
daemon resuelvan el mismo archivo de base de datos. Un cliente que ejecuta python directamente
hereda solo el entorno que ese cliente tenía, y los dos procesos se desvían
silenciosamente. Consulta
la trampa del cerebro dividido.
En este punto, la instalación está completa y las herramientas funcionan cuando se llaman. Nada las llama por sí solo: cada sesión comienza fría, y no se escribe nada a menos que el agente decida hacerlo. Eso no es un fallo y ninguna verificación lo reporta, por lo que es fácil confundir una instalación funcional con una memoria funcional. docs/AUTOMATION.md cubre cómo cerrar esa brecha, comenzando con un gancho de recuperación que se ejecuta en cada mensaje.
La alternativa: un servidor HTTP compartido
stdio genera un proceso de servidor por sesión de cliente, que es lo que los clientes de escritorio esperan. Si prefieres ejecutar un único servidor compartido a través de HTTP, usa el transporte SSE:
MCP_TRANSPORT=sse setup/bin/mcp-server.sh # or setup/bin/mcp-server-sse.sh{
"mcpServers": {
"enhanced-memory": { "type": "sse", "url": "http://127.0.0.1:9106/sse" }
}
}No hay autenticación en ese puerto. Mantén MCP_HOST en 127.0.0.1.
Configuración
La configuración son variables de entorno. setup/setup.sh escribe un .env a partir de
.env.example, que documenta cada variable en línea. Editar
.env es el mecanismo persistente: la copia ocurre solo cuando .env no existe,
por lo que tus ediciones sobreviven a cada re-ejecución del instalador (y, por la misma
razón, los valores predeterminados de una nueva versión no llegan por sí solos — compara los dos
archivos después de una actualización). Una variable ya definida en tu entorno prevalece sobre el
archivo para esa invocación:
MEMORY_DB_SOCKET_PATH=/tmp/other.sock ./healthcheck.shVariable | Default | Propósito |
|
| Directorio que contiene |
| (sin definir) | Ruta completa al archivo de base de datos. Sobrescribe la configuración del directorio. |
|
| Socket Unix entre los dos procesos. Manténgalo corto, consulte la nota AF_UNIX a continuación. Asigne uno propio a una segunda instalación en la misma máquina. |
|
| Opcional. La base de datos de Neural Memory Fabric. Sigue a |
|
| Opcional. El almacén de archivos NMF, misma regla. |
|
|
|
|
| Solo transportes HTTP. No exponga esto a una red. |
|
| Solo transportes HTTP. |
|
|
|
|
|
|
|
| Almacén de vectores opcional. |
|
| Proveedor de incrustaciones opcional. |
|
| Modelo de incrustación a descargar y usar. |
|
| Puntuación por debajo de la cual un resultado se marca como de baja confianza. |
| (sin definir) | Archivo JSON que declara qué otros servidores MCP puede llamar el código dentro de |
|
| Envía |
| (sin definir) | Solo habilita GraphRAG, cuya implementación no se incluye aquí. Configurarlo aumenta el recuento de herramientas de 186 a 193, o de 204 a 211 con los backends opcionales. |
| (sin definir) | Fija el recuento de herramientas que requiere |
ENHANCED_MEMORY_SURFACE y MEMORY_PROFILE cambian la cantidad de herramientas que devuelve tools/list, y también lo hacen las dependencias opcionales instaladas: las herramientas cuyo backend falta no se registran. Una instalación solo con el núcleo y una instalación con los extras opcionales reportan recuentos diferentes desde el mismo código. Un recuento esperado de herramientas solo tiene sentido junto a los tres.
Servicios opcionales, y qué se pierde sin ellos
Ninguno es obligatorio. Ambos merecen la pena tenerlos.
Presente | Ausente | |
Qdrant | La búsqueda clasifica por significado: una consulta sobre "control de permisos" puede mostrar una entidad que nunca usa esas palabras. | La búsqueda sigue funcionando y sigue devolviendo resultados, pero la clasificación recurre a la coincidencia léxica. No se produce ningún error, por lo que es fácil no notarlo. |
ollama | Genera las incrustaciones que indexa Qdrant. | Qdrant no tiene nada que indexar, por lo que la recuperación sigue siendo léxica incluso con Qdrant en ejecución. |
Aprovisione uno o ambos:
setup/setup.sh --with-qdrant # container on 127.0.0.1:6333, named volume
setup/setup.sh --with-ollama # verifies ollama, pulls the embedding model./healthcheck.sh reporta ambos como OPCIONALES y nunca falla la compuerta por su ausencia. Pase --require-optional si desea un contrato más estricto.
¿Ya tiene un Qdrant en ejecución? Apunte MEMORY_QDRANT_URL hacia él y omita --with-qdrant por completo; nada aquí necesita ser propietario de la instancia. El conflicto de puerto discutido en el perfil de contenedor a continuación es específico de ese perfil, que publica su propio contenedor en el 6333 y no puede vincular un puerto que ya esté ocupado por otra cosa. Una instalación en el host solo realiza solicitudes salientes.
GraphRAG es opcional y externo
Las herramientas de GraphRAG (graph_enhanced_search, get_entity_neighbors) no se incluyen aquí. graphrag_tools.py carga su implementación desde $AGENTIC_SYSTEM_PATH/scripts/graph-rag.py, un archivo que pertenece a un sistema separado y no forma parte de este paquete. AGENTIC_SYSTEM_PATH por defecto es el abuelo del directorio de trabajo, por lo que en una instalación independiente esa ruta no existe.
Nada se rompe. El registro está envuelto, el servidor registra GraphRAG integration skipped: ... e inicia sin esas herramientas. Si tiene ese sistema, apunte AGENTIC_SYSTEM_PATH a su raíz y se registrarán. Tenga en cuenta que el mensaje de omisión va al archivo de registro, no a su terminal, por lo que las herramientas ausentes parecen herramientas que nunca estuvieron allí.
Ejecución en un contenedor
La ruta de entrega para entornos compartidos. Podman primero, compatible con docker.
podman-compose up --build # core only
WITH_OPTIONAL=1 podman-compose --profile qdrant up # with a USABLE vector storeWITH_OPTIONAL=1 es crucial para el perfil qdrant. La imagen predeterminada instala solo requirements.txt, que no incluye qdrant-client, por lo que --profile qdrant sin él le brinda un Qdrant saludable, accesible y completamente sin usar: la verificación de salud informa que el servicio es accesible (verdadero) mientras que el servidor registra "qdrant-client not installed - vector search disabled" y cada búsqueda permanece léxica. Una señal verde junto a una capacidad inerte es exactamente el modo de fallo que este proyecto existe para eliminar, por lo que se menciona aquí en lugar de dejarlo para que lo descubra. WITH_OPTIONAL=1 construye la imagen con requirements-optional.txt y la ruta del vector realmente se activa. (Medido: una imagen central junto con el perfil qdrant respondió a /readyz con "all shards are ready" y no lo usó para nada).
Use el guión. En Fedora 44, podman compose (un espacio) se entrega a un proveedor externo, /usr/libexec/docker/cli-plugins/docker-compose, que necesita un socket de API compatible con Docker. Con podman.socket inactivo, que es el valor predeterminado, podman compose up falla:
failed to connect to the docker API at unix:///run/user/1000/podman/podman.sock:
connect: no such file or directorysystemctl --user start podman.socket soluciona eso, o simplemente usa podman-compose (aquí 1.6.0), que maneja podman directamente y no necesita socket. Medido en Fedora 44 con podman 5.8.4: podman compose up falló como arriba, podman-compose up -d levantó el stack y el contenedor reportó healthy.
La imagen ejecuta ambos procesos bajo container-entrypoint.sh, que inicia el daemon, espera a que el socket responda, y solo entonces inicia el servidor MCP en el transporte SSE. Si alguno de los procesos sale, el contenedor sale, porque un servidor MCP vivo junto a un daemon muerto es exactamente el estado que devuelve ceros bien formados para siempre.
Notas que te ahorrarán tiempo:
podman builddescarta elHEALTHCHECK. Podman por defecto usa el formato de imagen OCI, que no tiene campo para ello. Sí advierte, una vez, en tiempo de compilación:HEALTHCHECK is not supported for OCI image format and will be ignored. Must use `docker` formatOmite esa línea en la salida de compilación y nada lo vuelve a mencionar: la imagen no lleva healthcheck y
podman psnunca muestra estado de salud. Medido en podman 5.8.4, Fedora 44: el.HealthCheckde la imagen OCI inspecciona comonil, y reconstruir conpodman build --format dockerda[CMD /app/setup/lib/container-health.sh].Tres formas de evitarlo, todas verificadas: compilar con
--format docker; usar compose, cuyo healthcheck a nivel de servicio se define encompose.yamly aplica independientemente del formato de imagen (un contenedor gestionado por compose reportahealthydesde la misma imagen que inspecciona comonil); o verificar bajo demanda conpodman exec <name> /app/healthcheck.sh --skip-mcp.El puerto MCP se publica solo en loopback del host (
127.0.0.1:9106:9106). Dentro del contenedor el servidor se vincula a0.0.0.0, que es correcto allí y erróneo en una estación de trabajo.Los puertos del host de Qdrant son
${QDRANT_PORT:-6333}y${QDRANT_ADMIN_PORT:-6334}. Establécela en.envsi ya ejecutas Qdrant en el 6333, que de otro modo es un conflicto de bind que impide que el perfil se inicie.La imagen es una instalación base, por lo que el perfil qdrant no hace nada por sí solo.
podman-compose --profile qdrant upte da un Qdrant que se inicia, pasa su healthcheck y responde en su puerto, mientras que el servidor no tieneqdrant-clientpara comunicarse con él. Todo parece verde y no se indexa nada. Compila con el stack opcional para usarlo realmente:podman build --build-arg WITH_OPTIONAL=1 -t enhanced-memory:local -f Containerfile . # or, through compose: WITH_OPTIONAL=1 podman-compose up --build./healthcheck.shdistingue los dos casos: reporta Qdrant como alcanzable y utilizable solo cuando la biblioteca cliente es importable, y advierte cuando el servicio está levantado pero nada puede usarlo.La base de datos reside en el volumen nombrado
enhanced-memory-data. Sin un volumen, tu memoria muere con el contenedor.ollama se ejecuta en tu host, y un contenedor no puede alcanzarlo en
127.0.0.1. DescomentaMEMORY_OLLAMA_URLencompose.yaml(host.containers.internalpara podman,host.docker.internalpara docker).Verifica un contenedor en ejecución de la misma manera que verificas una instalación en el host. Usa la ruta absoluta: no todos los motores resuelven una relativa contra
WORKDIR.podman exec enhanced-memory /app/healthcheck.sh --skip-mcpTu
.envlocal no es configuración para el contenedor. La imagen incluye uno vacío a propósito, y todo lo real proviene del entorno de ejecución encompose.yaml..containerignorey.dockerignoreexcluyen el archivo, pero no todos los motores los respetan (elcontainer buildde Apple no lo hizo, verificado 2026-08-14), por lo que el Containerfile también lo vacía en una etapa de compilación descartada y luego falla la compilación si sobrevive uno poblado.
Ejecución como servicio en segundo plano
setup/service/install-services.sh # daemon only
setup/service/install-services.sh --with-sse # and a shared SSE server
setup/service/uninstall-services.shAgentes de usuario launchd en macOS (~/Library/LaunchAgents), unidades de usuario systemd en Linux (~/.config/systemd/user). Sin root, sin unidades del sistema. Cada ruta se renderiza desde la ubicación de este checkout, por lo que dos checkouts pueden coexistir si les das diferentes valores de --label-prefix, diferentes valores de MEMORY_DB_SOCKET_PATH y diferentes valores de ENHANCED_MEMORY_DIR. Los tres, no solo los dos primeros: sockets separados por sí solos dejan que ambos daemons abran el mismo memory.db, y cada uno está destinado a poseer ese archivo exclusivamente.
El instalador espera el socket y falla ruidosamente con un tail del log si el servicio no se levanta. Los logs se depositan en ~/Library/Logs/enhanced-memory o ${XDG_STATE_HOME:-~/.local/state}/enhanced-memory/log, deliberadamente no en el checkout: launchd no puede crear un archivo de log en un volumen externo al momento de lanzar el proceso y el trabajo muere con el código de salida 78 antes de que tu código se ejecute.
En Linux, las unidades de usuario se detienen al cerrar sesión a menos que habilites lingering:
loginctl enable-linger $USERVerifica tu instalación
Dos compuertas, en este orden.
./healthcheck.sh # the post-install gate
python3 comprehensive_test.py # the functional suite (needs the daemon running)Un tercer conjunto orientado a desarrolladores vive bajo tests/ y necesita pip install -r dev-requirements.txt primero — pytest deliberadamente no se incluye en ningún archivo de requisitos de ejecución, y las dos compuertas anteriores se ejecutan solo con la stdlib.
Juzga comprehensive_test.py por su código de salida, no por un conteo de aciertos. El número de comprobaciones depende del modo que seleccione: sin variables ENHANCED_MEMORY_* o MEMORY_DB_* establecidas, construye su propio sandbox y ejecuta todo; con ellas establecidas, se ejecuta contra tu despliegue y omite las comprobaciones que describen un sandbox que no creó. Medido en una máquina, un commit: 106 aisladas y 102 dirigidas por el operador, ambas con salida 0. La ejecución imprime su propio modo y nombra lo que omitió.
Instalar los backends opcionales cambia ese conteo en cero, medido de ambas maneras. Una revisión anterior de este archivo decía que los backends eran la causa. No lo son, y la misma suposición errónea se adjuntó al conteo de omisiones de pytest antes de que alguien lo probara; consulta la sección de suite de pruebas de RELEASE_NOTES.md para saber qué mueve realmente ese uno.
./healthcheck.sh está diseñado para poder fallar. Escribe una entidad de prueba a través del socket del daemon, la busca de nuevo y la elimina. Trata cualquier clave error o daemon en cualquier respuesta como fallo independientemente del resto del payload, y compara la ruta de la base de datos que reporta el daemon con la que resuelve tu entorno. Comprueba:
venv, versión del intérprete,
.env, longitud de la ruta del socket, fuentes presentesida y vuelta del daemon (estado, acuerdo de base de datos, escritura, lectura, limpieza) y una verificación de esquema: cada
INSERTliteral en los dos archivos que poseen esta base de datos se compara con las definiciones de tablas vivas, porque una columna que el esquema no tiene falla cada escritura mientras el daemon reporta el fallo por fila en lugar de lanzar una excepciónHandshake MCP sobre stdio, conteo de herramientas, y que nada contaminó stdout
Qdrant y ollama, marcados OPCIONALES, nunca fatales
Banderas útiles: --skip-mcp para una comprobación rápida solo del daemon, --expect-tools N para fijar el conteo, --require-optional para exigir el stack vectorial.
Dónde están los logs
/tmp/enhanced-memory-mcp.log, siempre, para toda instalación en el host.
El servidor MCP limpia todos los manejadores de logging al inicio y envía todo a ese archivo rotatorio (50 MB, dos copias de seguridad), porque en el transporte stdio cualquier cosa en stdout corrompe el protocolo. La información INFO de rutina solo vive allí, y la ruta es fija, por lo que dos checkouts en una misma máquina se intercalan en el mismo archivo con marcas de tiempo y pids como único separador.
WARNING y superior adicionalmente van a stderr, a menos que establezcas MEMORY_LOG_STDERR=0. Esto es deliberado: cada línea ... integración omitida: <reason> es una característica que no se cargó, y enrutar esas solo a un archivo bajo /tmp significaba que nadie las leía. Si tu cliente MCP trata cualquier salida de stderr como un error, establece la variable a 0 y lee el archivo en su lugar.
./healthcheck.sh también reporta esto, como una línea WARN mcp-startup que lista las advertencias distintas, de modo que una característica faltante aparece en la compuerta en lugar de solo en un log. Medido en esta rama: una instalación base produce 11 de ellas (numpy, qdrant-client, sentence-transformers, redis, neo4j y demás), una instalación completa 3. Ninguna de ellas falla la compuerta. Son el inventario de lo que tu instalación no tiene, que vale la pena leer una vez y luego ignorar.
Verificación de las firmas en esta versión
Los commits están firmados con SSH. Git no los verificará hasta que le digas qué claves confiar, y esa configuración no viaja con un clon:
git config gpg.ssh.allowedSignersFile .allowed_signers
git log --show-signature -1Sin la primera línea, git log --format=%G? reporta N para cada commit, que significa "no se puede verificar", no "sin firmar". Las firmas están presentes de cualquier manera: git cat-file commit HEAD muestra el bloque gpgsig.
Solución de problemas
Cada herramienta devuelve ceros, o un campo error
El daemon no se está ejecutando. Este es el caso común por un amplio margen.
{"count": 0, "results": [], "error": "Memory-DB service error: ..."}setup/bin/memory-db-daemon.sh # foreground, watch it
./healthcheck.sh --skip-mcp # confirm the round tripEl servidor y el daemon no están de acuerdo sobre la base de datos
Síntoma: las escrituras parecen tener éxito pero las búsquedas nunca las encuentran, o get_memory_status reporta un conteo que no coincide con lo que almacenaste. Los dos procesos resolvieron archivos diferentes, y ninguno reporta error.
./healthcheck.sh detecta esto directamente:
FAIL db-agreement SPLIT BRAIN: daemon holds /path/A/memory.db,
this environment resolves /path/B/memory.dbCausa: algo inició un proceso con un ENHANCED_MEMORY_DIR, ENHANCED_MEMORY_DB_PATH o HOME diferente al del otro. Generalmente un cliente MCP configurado para ejecutar python server.py directamente, omitiendo el lanzador que aplica .env. Corrige la configuración del cliente para usar setup/bin/mcp-server.sh, luego reinicia ambos procesos.
Las consultas de contenido devuelven cero mientras que las consultas de nombre funcionan
Desde e9ca30c esto no puede ocurrir silenciosamente: cuando la búsqueda no puede ver el contenido de la observación, la respuesta lo dice —
{"count": 0, "results": [], "degraded": "name-only (observations_fts missing)"}degraded significa que la base de datos es anterior al índice de texto completo y ningún daemon se ha inicializado contra ella desde la actualización. Reinicia el daemon: init_database() ahora crea el índice y retroalimenta cada fila existente. El otro valor, name-only (FTS query error), es por consulta y significa que el texto de la consulta rompió la sintaxis FTS después de la sanitización; la coincidencia de nombre/tipo aún se ejecutó.
Reimportar una semilla añade observaciones duplicadas
Corregido en e9ca30c: create_entities omite observaciones cuyo contenido exacto ya existe para esa entidad y reporta las omisiones como observations_deduped en su respuesta, por lo que las importaciones repetidas de semillas son idempotentes. Las observaciones genuinamente nuevas aún se añaden. Los duplicados creados por reimportaciones anteriores a la corrección no se eliminan por ti — el issue #8 tiene el SQL de limpieza único.
Las reimportaciones reformuladas (el mismo archivo de semilla ligeramente editado) también se detectan, mediante simhash determinista — sin LLM involucrado. Por defecto se almacenan y reportan en un campo de respuesta near_duplicates que nombra qué fila existente se parece cada una: una corrección ("62Gi" → "125Gi") es indistinguible de una reformulación en esta capa, y un almacén de memoria nunca debe descartar silenciosamente una corrección. Un pipeline de importación que sabe que está reimportando puede establecer ENHANCED_MEMORY_NEAR_DUP_POLICY=skip para descartarlas en su lugar; cualquier otro valor de esa variable cae en el comportamiento seguro de almacenar y reportar. El umbral de distancia y las bandas de calibración medidas viven en simhash_dedup.py.
OSError cuando el daemon se inicia, sin mensaje útil
La ruta del socket es demasiado larga. AF_UNIX limita la cadena de ruta a 104 bytes en macOS y 108 en Linux, y bind() falla con un error que no menciona ni el límite ni la ruta. Los checkouts profundos se topan con esto en cuanto el socket se coloca dentro de ellos.
Mantén MEMORY_DB_SOCKET_PATH corto y fuera del checkout, por ejemplo /tmp/em-myproject.sock. setup/setup.sh lo mide y se niega a continuar si es demasiado largo.
macOS: el servicio se instala pero el daemon nunca se inicia
Si el log muestra Operation not permitted en la ruta del lanzador, el checkout está en algún lugar donde launchd no tiene permiso para ejecutar. Verificado 2026-08-14: un checkout en un volumen externo bajo /Volumes se instala y carga bien, luego cada lanzamiento falla con EPERM, porque launchd se ejecuta sin el acceso al disco que tiene tu terminal.
Mueve el checkout a tu directorio personal u otra ruta local y reinstala, o concede Acceso Completo al Disco a launchd si la ubicación no es negociable. El instalador muestra esto en lugar de ocultarlo: espera el socket, falla después de 30 segundos e imprime la cola del log de error.
ConnectionRefusedError mientras el archivo del socket existe
Un daemon eliminado dejó el archivo atrás. Vuelve a iniciar el daemon y este eliminará el archivo por sí mismo, registrando removed stale socket <path>; el lanzador hace lo mismo antes de ejecutarse. No elimines un archivo de socket manualmente por costumbre — un archivo que aún está siendo servido se ve exactamente igual que uno obsoleto, y eliminarlo desconecta a todos los clientes del daemon que lo posee.
REFUSING TO START: another daemon is already serving ...
Funciona según lo previsto: algo más está respondiendo en esa ruta de socket. El mensaje nombra el socket y, cuando el otro daemon responde a una solicitud de estado, la base de datos que contiene. Detén ese daemon o asigna a este su propio MEMORY_DB_SOCKET_PATH y ENHANCED_MEMORY_DIR — consulta ¿Ya estás ejecutando un sistema de memoria mejorada?.
El cliente MCP falla en el handshake con un error de análisis JSON
Algo se imprimió en stdout, que pertenece exclusivamente al flujo JSON-RPC en el transporte stdio. La verificación 3 de ./healthcheck.sh reporta esto como FAIL mcp-stdout junto con la línea problemática.
python3 es 3.9
Común en macOS. Instala un intérprete compatible (brew install python@3.11) y vuelve a ejecutar setup/setup.sh, que prefiere nombres versionados. Para forzar uno: setup/setup.sh --python /path/to/python3.11.
Brechas y problemas conocidos
Escrito para ser revisado, no confiado.
La verificación de salud no ejercita el transporte SSE, no llama a herramientas individuales (las lista), no prueba el acceso concurrente desde varios clientes y no mide la calidad de recuperación con o sin la pila vectorial.
Las cifras de rendimiento citadas en revisiones anteriores de este README no se han reproducido aquí y se eliminaron en lugar de repetirse. Nada en este archivo afirma un rendimiento, una latencia o una relación de compresión.
La ruta del contenedor se verifica con podman 5.8.4 en Fedora 44, linux/amd64: construido, ejecutado, la verificación de salud completa en verde dentro de él, la prueba de supervisión produciendo
Exited (1)con el punto de entrada nombrando qué mitad falló, ypodman-composelevantando la pila saludable. También se construyó y ejecutó bajo elcontainerde Apple y bajo Docker en macOS/arm64 durante el desarrollo. No cubierto: cualquier distribución que no sea Fedora 44, y podman con privilegios (todo lo anterior fue sin privilegios).Las unidades de servicio son instaladas e iniciadas por el instalador, que espera el socket y falla ruidosamente si no aparece. La supervivencia después de un reinicio o cierre de sesión real no se ha probado.
El número de herramientas varía según la superficie, el perfil y qué dependencias opcionales están instaladas. Trata cualquier número único como específico de la configuración de una máquina.
Licencia
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides AI agents with persistent, searchable memory that survives across conversations using semantic search, temporal versioning, and smart organization. Enables long-term context retention and cross-session continuity for AI assistants.14
- AlicenseAqualityBmaintenanceEnables AI agents to manage hierarchical memory with Markdown-based storage, tiered architecture (L0-L3), and hybrid retrieval for transparent and persistent context.8MIT
- AlicenseNot gradedqualityDmaintenanceEnterprise-grade AI memory infrastructure with multi-agent support, providing 122 MCP tools for memory management, agent coordination, and cross-language SDKs.Apache 2.0
- AlicenseBqualityAmaintenanceEnables AI agents to maintain persistent, searchable two-layer memory with 37 tools, hybrid search, knowledge graphs, and enterprise features like authentication and backups.5MIT
Related MCP Connectors
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.
Universal memory for AI agents and tools. Save, organize and search context anywhere.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/marc-shade/enhanced-memory-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server