th-memory-mcp

Servidor MCP de memoria a largo plazo para OpenCode y otros entornos: almacena preferencias, lecciones e historial de uso en un único archivo local SQLite (100% local, sin API externa) para que la IA pueda "recordar y adaptarse" al usuario mediante aprendizaje basado en contexto.

Documentación

th-memory-mcp

npm version npm downloads License: MIT Node CI Version Sync Listed on mcpservers.org

th-memory-mcp MCP server

Estado: v2.3.0 — un motor de memoria temporal, consciente de conflictos y con recuperación híbrida. 16 herramientas MCP, 25 suites de pruebas aprobadas. Migración de esquema no destructiva desde v1 (todos los datos de v1 se conservan). Nuevo en v2.2: estados de ciclo de vida, validez temporal, resolución de conflictos/deduplicación con alcance USER/SESSION/PROJECT/GLOBAL, recuperación híbrida FTS+vectorial (RRF), grafo de memoria, ensamblaje de get_context, consolidación periódica y link_memory / merge_memory / update_memory / import_memory / extract_memories. Nuevo en v2.2.3: recuperación con alcance forzado, aislamiento de alcance en el grafo, ida y vuelta de exportación/importación, ruta de importación endurecida (realpath), validación estricta de importación, eliminación de consultas N+1, punto de referencia en frío/ablación e interruptor MEMORY_RETRIEVAL_MODE. Nuevo en v2.2.7: filtro de secretos sincronizado entre el hook de Claude y capture-core (redacción de 6 patrones en lugar de eliminar líneas), corrección de err() para devolver isError:true según la especificación MCP, corrección de la rotación de copias de seguridad (copia solo cuando hay migraciones pendientes + poda a 5 archivos) y registro de errores de hook para el destilado de SessionEnd. Nuevo en v2.2.8: corrección de contaminación de alcance 0.75→0 (crítico) y falso conflicto 0→1 (fuga GLOBAL), corrección de grafo hop1 0.52→1.0 mediante includeGraph, y reescalado de perfiles de referencia a 5K/20K/100K/500K/1M (pre-commit ahora rápido 5K + normal 20K solamente). Nuevo en v2.2.9: extensión de exportación a entidades/usuarios/relaciones, forget ahora elimina enlaces asociados, migración con cierre ante fallos con helper ISO compartido, eliminación de N+1 en FTS, inclusión de smoke en el script de pruebas y sincronización del visor con perfiles reescalados 5K/20K/100K/500K/1M. Nuevo en v2.3.0: CLI th-memory + subrayado de resaltado.

Requisitos

  • Node.js >= 20 — el servidor utiliza APIs exclusivas de Node (la compilación nativa de better-sqlite3 y la resolución de import.meta.url) y el SDK de MCP requiere un runtime moderno. Las pruebas de CI se ejecutan en Node 20.x y 22.x.
  • npm — para instalar dependencias y ejecutar los scripts de compilación/pruebas (npm install, npm run build, npm test).
  • OpenCode — el host que carga este servidor MCP y el plugin de captura automática. Cualquier compilación que admita MCP sobre stdio + plugins funciona; el plugin se ejecuta en el runtime Bun incluido de OpenCode.
  • SO: Windows / macOS / Linux — el servidor es multiplataforma (Node). El plugin de captura automática se ejecuta dondequiera que se ejecute el runtime Bun de OpenCode. Nota para Windows: MEMORY_DB_PATH es más fácil de configurar con setx; en macOS/Linux usa export en tu perfil de shell.

No se requieren servicios externos, cuentas ni claves API — todo vive en un único archivo SQLite local.

Inicio rápido

Ruta más rápida: después de clonar, ejecuta npm run quickstart — compila, conecta opencode.json, despliega el plugin y configura MEMORY_DB_PATH por ti en un solo comando. Los pasos a continuación muestran exactamente lo que hace (úsalos si prefieres control manual).

Instalación vía npm (alternativa): instala el servidor globalmente con npm install -g th-memory-mcp (o ejecútalo bajo demanda con npx th-memory-mcp), luego apunta el mcp command en opencode.json a th-memory-mcp en lugar del dist/index.js compilado. El plugin de captura automática aún proviene de este repositorio (copia src/plugin/learning-capture.ts como se describe en el paso 4 a continuación).

Nota: ya no se publica en GitHub Packages — instala desde npmjs con npm i -g th-memory-mcp.

# 1. Clone and build
git clone https://github.com/worakorn-prince/th-memory-mcp.git
cd th-memory-mcp
npm install
npm run build

# 2. Share one DB between the server and the plugin
#    Windows (PowerShell):
setx MEMORY_DB_PATH "$PWD/data/memory.db"
#    macOS / Linux (add to your shell profile, e.g. ~/.zshrc):
# export MEMORY_DB_PATH="$PWD/data/memory.db"
  1. Fusiona esto en tu ~/.config/opencode/opencode.json (reemplaza <REPO> con la ruta absoluta del clon):
{
  "instructions": ["<REPO>/AGENTS.memory.example.md"],
  "mcp": {
    "memory": {
      "type": "local",
      "command": ["node", "<REPO>/dist/index.js"],
      "enabled": true,
      "environment": { "MEMORY_DB_PATH": "<REPO>/data/memory.db" }
    }
  }
}
  1. (Opcional) Captura automática: copia src/plugin/learning-capture.ts → ~/.config/opencode/plugins/
  2. Reinicia OpenCode
  3. Pruébalo: "Recuerda que prefiero pnpm" → nueva sesión → "¿Qué gestor de paquetes prefiero?"

Arquitectura

OpenCode ──┬─ Plugin learning-capture (Bun)  ── auto-captures prompts/tool/error into DB
            │                                   └─ injects profile back into context on compaction
             └─ MCP th-memory-mcp (Node.js stdio)  ── 16 tools read/write the same SQLite DB
                                                      ▲
                               Global instructions (memory-protocol.md) teach the AI to use the tools

Consulta ARCHITECTURE_v2.md para la especificación completa de la arquitectura.

¿Por qué th-memory-mcp?

Los LLM no te recuerdan entre sesiones — cada nuevo chat comienza en blanco. th-memory-mcp le da a tu IA una memoria a largo plazo privada y local:

  • Aprendizaje basado en contexto, no fine-tuning — captura tus preferencias, correcciones y hábitos, luego los recupera en el contexto la próxima vez. El mismo mecanismo que las funciones de memoria de los principales productos de IA, sin enviar ningún dato fuera de tu máquina.
  • 100% local y privado — un único archivo SQLite, sin nube, sin API externa. Los secretos se filtran antes de almacenar cualquier cosa.
  • Baja sobrecarga — cada llamada de herramienta está limitada (latencia < 10 ms, tamaño de salida acotado) y la IA solo consulta la memoria cuando es realmente útil, por lo que nunca infla tu contexto.
  • Resiliente — cada herramienta se degrada con elegancia; si la base de datos no está disponible, la IA sigue funcionando en lugar de fallar.
  • Abierto y extensible — licencia MIT, 16 herramientas documentadas, un destilado basado en reglas y un plugin de captura automática que puedes adaptar.

Funciona con otros harnesses

th-memory-mcp es un servidor MCP estándar, por lo que las 9 herramientas se ejecutan en cualquier lugar donde se admita MCP sobre stdio. La captura automática completa (captura en segundo plano de prompts/herramientas/errores + inyección de perfil) necesita un runtime de hooks — OpenCode lo tiene integrado; Claude Code lo obtiene mediante nuestro puente de hooks; Codex y Cursor usan las herramientas manualmente (aún sin runtime de hooks).

FunciónOpenCodeClaude CodeQwen CodeCodexCursor
16 herramientas MCP✅✅✅✅✅
Captura automática (segundo plano)✅ plugin✅ hooks⚠️ adaptador❌ manual❌ Rules
Inyección de perfil✅ compactación✅ UserPromptSubmit❌ get_profile❌ get_profile❌ get_profile
Coincidencia difusa léxica✅ (v2.0)✅ (v2.0)✅ (v2.0)✅ (v2.0)✅ (v2.0)
  • Claude Code: consulta CLAUDE_CODE_HOOKS.md — los hooks de instalación directa replican el plugin de OpenCode (captura + inyección de perfil en UserPromptSubmit/PreCompact, destilado basado en reglas en SessionEnd).
  • Qwen Code: consulta QWEN_SETUP.md — MCP funciona completamente; los hooks usan el esquema de Gemini-CLI, por lo que la captura automática necesita un pequeño adaptador.
  • Codex: consulta CODEX_SETUP.md
  • Cursor: consulta CURSOR_SETUP.md

Todos los harnesses comparten un único archivo SQLite mediante MEMORY_DB_PATH, por lo que la memoria capturada en cualquier lugar es legible en todos.

Destacados

  • Memoria estructurada — preferencias con puntuación de confianza más registros dedicados de lesson (situación → error → corrección) para capturar correcciones, no solo hechos planos.
  • Ciclo de vida y temporal — cada memoria tiene un estado de ciclo de vida (activa/obsoleta/superada/archivada), puntuación de confianza/importancia/saliencia, decaimiento por tipo e intervalos de validez para que la IA pueda razonar sobre la verdad en un punto temporal y cadenas de superación.
  • Consciente de conflictos — detección de duplicados, detección de contradicciones y resolución de actualización/superación preservan ambos lados de la evidencia ambigua en lugar de sobrescribir silenciosamente.
  • Recuperación híbrida — get_context combina la búsqueda de palabras clave FTS5 con una coincidencia difusa léxica sin dependencias (similitud de n-gramas con hash, FNV-1a de 512 dimensiones) (fusión RRF + puntuación), luego ensambla un contexto con presupuesto de tokens con expansión opcional del grafo de memoria.
  • Consolidación — agrupación periódica de memorias similares en memorias derivadas con procedencia completa (enlaces derived_from).
  • Tailandés de primera clase / i18n — tokenización consciente del tailandés en el destilado; la IA acepta tailandés e inglés indistintamente.
  • Privado por defecto — un único archivo SQLite local, sin nube, sin claves API, con líneas secretas (api_key=, password:, token) filtradas antes del almacenamiento.
  • Multi-harness — se ejecuta en OpenCode, Claude Code, Codex y Cursor compartiendo una base de datos; captura automática + inyección de perfil mediante el plugin de OpenCode o los hooks de Claude.
  • Ligero y resiliente — Node + better-sqlite3, sin extensiones nativas adicionales; cada herramienta se degrada con elegancia para que la IA siga funcionando si la base de datos no está disponible.

Scripts

ComandoDescripción
npm run buildcompilar TypeScript → dist/
npm startejecutar el servidor MCP (stdio) desde dist/index.js
npm run distilldestilado basado en reglas: interacciones → secciones de perfil + poda de datos antiguos (env RETENTION_DAYS predeterminado 30)
npm testsuite completa: captura, destilado, ciclo de vida, temporal, conflictos, recuperación, grafo, contexto, consolidación, punto de referencia, seguridad, tools_v21, smoke, e2e_transport, retrieval_benchmark, recall_regression, scope, perfil, extracción de entidades, conflict_benchmark, security_regression, export_import_roundtrip
node test/capture.test.mjsprobar capture-core (filtrar secretos, deduplicar, truncar, insertar SQL)
node test/distill.test.mjsprobar distill-core (tokenización tailandesa, estadísticas, secciones de perfil, poda)
node test/lifecycle.test.mjsprobar el motor de ciclo de vida (estados, decaimiento, superación)
node test/temporal.test.mjsprobar el modelo temporal (validez, recuperación histórica)
node test/conflict.test.mjsprobar la resolución de conflictos y deduplicación
node test/retrieval.test.mjsprobar la recuperación híbrida FTS+vectorial+RRF
node test/graph.test.mjsprobar el grafo de memoria (entidades, relaciones, recorrido)
node test/context.test.mjsprobar el ensamblaje de contexto + presupuesto de tokens
node test/consolidation.test.mjsprobar la agrupación + memorias derivadas
node test/benchmark.test.mjspunto de referencia de latencia sobre 300 memorias
node test/security.test.mjscomprobaciones de inyección / seguridad
node test/smoke.mjsprueba de humo de extremo a extremo sobre JSON-RPC (16 herramientas)

Herramientas (16)

HerramientaDescripción
rememberinsertar o actualizar preferencia (categoría+clave) — volver a guardar la misma clave aumenta la confianza en 0.1 (máximo 1.0)
recallbuscar preferencias + lecciones (FTS5) + interacciones coincidentes recientes. Úsalo antes de comenzar una nueva tarea
get_profileresumen del perfil de usuario: secciones de perfil + preferencias principales + 5 lecciones más recientes
save_lessonregistrar una lección aprendida de una corrección (situación / error / corrección)
search_historybuscar prompts de usuario anteriores por palabra clave (fragmentos de 200 caracteres por fila)
forgeteliminar una fila de memoria (preferencia/lección/interacción) por id (+tipo evita choque de id entre tablas)
memory_statsestadísticas de memoria: conteos por tipo, tamaño de la base de datos, interacción más antigua/más reciente, secciones de perfil
get_recent_interactionslistar interacciones crudas recientes (filtrar por tipo) — materia prima para Smart Distill
export_memoryexportar memoria a JSON bajo data/exports/ solamente (nombre de archivo auto-saneado)
get_contextensamblar memorias relevantes para la tarea actual mediante recuperación híbrida (+ expansión opcional del grafo) con presupuesto de tokens
consolidateagrupar memorias similares mediante similitud de embeddings; opcionalmente crear memorias derivadas/consolidadas enlazadas mediante derived_from
link_memorycrear una relación tipada entre dos memorias en el grafo (supports/contradicts/supersedes/derived_from/related_to/caused_by/depends_on)
merge_memoryfusionar un duplicado/casi duplicado en una memoria canónica (la fuente se vuelve superada, procedencia en metadata.merged_from)
update_memoryactualizar campos mutables en el lugar, o crear una memoria superadora cuando content cambia (establece supersede=false para editar en el lugar)
import_memoryimportar memorias desde JSON (valida tipo, deduplica contra existentes, nunca sobrescribe a ciegas); simulación por defecto, apply=true para insertar
extract_memoriesescanear interacciones capturadas recientes en busca de frases con intención de memoria y proponer candidatos de memoria (determinista, sin LLM); simulación por defecto, apply=true para crear (fuente=capturada)

CLI (th-memory)

Dos binarios se incluyen en package.json (bin):

BinarioEntradaPropósito
th-memory-mcpdist/index.jsservidor MCP (stdio) — las 16 herramientas anteriores
th-memorydist/cli.jsCLI de memoria local (sin dependencias, comparte la misma base de datos mediante MEMORY_DB_PATH)

Uso: th-memory [--db <path>] [--json] [--plain] <command> [options] — ayuda por comando mediante th-memory <command> --help. Banderas globales (cada comando):

BanderasEfecto
--db <path>usar este archivo SQLite (establece MEMORY_DB_PATH)
--jsonimprimir JSON {ok,data} en lugar de texto plano
--plain / --no-colordesactivar colores
-h, --helpmostrar ayuda (global o por comando)
-V, --versionimprimir versión

Comandos:

ComandoUso
rememberremember --category <c> --key <k> --value <v|-> — guardar una preferencia (--value - lee desde stdin)
recallrecall <topic> [--limit <n>] [--highlight] — buscar en la memoria
forgetforget <id> [--type <t>] — eliminar por id (t: memory|preference|lesson|interaction)
exportexport [--include-interactions] [--filename <n>] — exportar a data/exports/*.json
importimport (--file <p>|--json <s>) [--apply] [--user-id <id>] — importar copia de seguridad (simulación por defecto)
statsstats — estadísticas de memoria
profileprofile — perfil de usuario destilado
historyhistory [--query <q>] [--limit <n>] — buscar prompts pasados (sin consulta = prompts recientes)
recentrecent [--limit <n>] [--kind <k>] — interacciones recientes (k: prompt|tool_call|error)
highlighthighlight [text...] -q <topic> [--limit <n>] — resaltar coincidencias de temas (texto vacío = tubería stdin)

Comportamiento de resaltado (comando highlight y recall --highlight): las coincidencias se envuelven con un subrayado (ESC[4m…ESC[24m) cuando stdout es una TTY con colores habilitados; cuando se canaliza, con --json, o con --plain/--no-color, las coincidencias se envuelven con marcadores [mem]…[/mem] en su lugar.

Ejemplos:

th-memory remember --category coding_pref --key package_manager --value pnpm
th-memory recall pnpm --limit 5
th-memory recall pnpm --highlight
echo "I prefer pnpm for installs" | th-memory highlight -q pnpm

Nota: --value - lee el valor desde stdin (p. ej. echo -n "pnpm" | th-memory remember --category coding_pref --key package_manager --value -).

Instalar con OpenCode

  1. Fusiona la sección mcp de opencode.example.json en tu opencode.json (global o a nivel de proyecto)
    • Importante: establece MEMORY_DB_PATH al MISMO archivo de base de datos tanto para el servidor como para el plugin (el ejemplo usa <ABSOLUTE_PATH>/th-memory-mcp/data/memory.db), de lo contrario el plugin de captura automática escribe en una base de datos diferente a la que lee la IA
    • Cómo configurarlo (elige uno):
      • defínelo en el environment de mcp (ver ejemplo) — cubre solo el servidor MCP
      • o establécelo como variable de entorno a nivel de sistema/usuario (p. ej. setx MEMORY_DB_PATH "D:/path/to/memory.db" en Windows) — cubre tanto el servidor como el plugin, ya que el plugin se ejecuta en el mismo proceso que OpenCode
  2. Adjunta las reglas de memoria globales — agrega a opencode.json:
    "instructions": ["C:/Users/<user>/.config/opencode/memory-protocol.md"]
    
    (el contenido de ejemplo de la regla está en AGENTS.memory.example.md — se puede adjuntar a nivel de proyecto en su lugar)
  3. (Opcional) Implementa el plugin de captura automática: copia src/plugin/learning-capture.ts → ~/.config/opencode/plugins/learning-capture.ts
  4. Reinicia OpenCode (la configuración se carga solo al inicio)
  5. Prueba: "Recuerda que prefiero pnpm" → abre una nueva sesión y pregunta de nuevo

Uso diario

La IA acepta tanto tailandés como inglés de manera intercambiable — puedes cambiar de idioma en cualquier momento sin aviso.

Comando de ejemploHerramienta / efecto
"Recuerda que..."remember — guardar una preferencia
"Resumir memoria" / "destilar memoria"Destilación inteligente — la IA lee get_recent_interactions, encuentra patrones y guarda conocimientos por sí misma
"¿Cómo está mi memoria?" / "estado de memoria"memory_stats
"Exportar memoria" / "respaldar memoria"export_memory
"Buscar historial..."search_history
"Olvidar..."forget

Cuidado a largo plazo: ejecuta npm run distill ocasionalmente para resumir estadísticas y podar interacciones de más de 30 días.

Estructura de data/

data/
├── memory.db          # SQLite (WAL mode) — main DB (+ .db-wal, .db-shm)
└── exports/           # JSON files from export_memory (writeable only in this dir)
  • La ruta de la base de datos se puede sobrescribir mediante la variable de entorno MEMORY_DB_PATH
  • todo en data/ está ignorado por git

Benchmark — autoinformado interno (no de terceros)

⚠️ Benchmark autoinformado interno — no es un benchmark de terceros

  • interno de muestra pequeña: 180 registros/30 temas (B.recuperación: 30 temas × 5 relevantes + 30 distractores = 180; la ejecución completa también usa subconjuntos de almacenamiento/temporal/contexto de muestra pequeña)
  • autoejecución en una sola máquina: máquina de desarrollo única, un solo SO/Node/compilación better-sqlite3 — no entre máquinas, no verificado de forma independiente
  • no es un benchmark de terceros: autoinformado, no verificado de forma independiente; no lo compares como si fuera de un evaluador externo
  • El conjunto de datos y el arnés están en repro/ (se puede confirmar) y benchmark/ (marco completo, ver TH_MEMORY_MCP_BENCHMARK_SPEC.md y benchmark/README.md).

Dos modos

ModoComandoDatosSuitesCaso de uso
Normalnpm run benchmark180 registros / 30 temasrecuperaciónverificación rápida (<5s)
Pesadonpm run benchmark:heavy600 registros / 100 temas + escala de 2ktodos (almacenamiento/recuperación/temporal/contexto/rendimiento/escalabilidad/en frío/ablación)estrés / regresión

Reproducir:

npm run build
# Normal — quick
npm run benchmark
npm run benchmark -- --k 10
npm run benchmark -- --out repro/results

# Heavy — full framework, more data
npm run benchmark:heavy
# or custom:
node benchmark/run.mjs --suite all --topics 100 --distractors 100 --scale 2000 --out benchmark/results

Visor — comparar las últimas 3 versiones (tabla + gráficos)

npm run benchmark:viewer
# or: npx serve . -l 3000
# open http://localhost:3000/benchmark/viewer/  or  http://localhost:3000/result/viewer.html

El visor carga benchmark/results/history.jsonl, agrupa por versión, toma la última ejecución de las 3 versiones más recientes (p. ej. 2.2.6 / 2.2.7 / 2.2.8) y muestra una tabla resaltada (1 fila por versión) + gráficos de barras para Recall@5 / MRR / NDCG@5 y Latency p95. Los resultados también se guardan por versión en result/v*_benchmark_result.md y benchmark/results/versions/<ver>/.

Última ejecución interna (v2.2.8, en caliente, perfil normal, a2dcbce — no de terceros): Recall@5=0.9060, Precision@5=0.9060, MRR=1, NDCG@5=0.9347 sobre 100 temas/600 registros. Ver result/v2.2.8_benchmark_result.md y repro/README.md para detalles y advertencias (interno, autoejecución en una sola máquina).

Limitaciones conocidas

  • Sin cifrado en reposo (texto plano en reposo) — data/memory.db (modo WAL, better-sqlite3) es un archivo SQLite plano y sin cifrar. 100% local & private significa sin exfiltración por nube o red — no significa cifrado en reposo. Cualquier persona con acceso al sistema de archivos (máquina compartida, copia de seguridad, malware, dispositivo robado) puede leer preferencias/lecciones/interacciones en texto plano. Para datos sensibles, usa cifrado de disco completo a nivel de SO (BitLocker / FileVault / LUKS) o una compilación SQLCipher opcional (requiere recompilación nativa y gestión de claves). No se aplica SQLCipher/cifrado en código por defecto y src/db/index.ts lo documenta explícitamente.
  • Proceso local de un solo usuario — sin capa de autenticación (Lote B-3) — userId / sessionId / projectId son cadenas proporcionadas por el llamador con sin autenticación ni verificación de autorización dentro del servidor. El aislamiento de alcance (recuperación, get_context, recorrido/expansión de grafo, consolidate, link_memory, merge_memory) se aplica solo contra los valores que envía el llamador, por lo que un llamador puede leer o escribir cualquier alcance pasando un id diferente. Esto es adecuado para un proceso local de un solo usuario (un operador, data/memory.db local). No compartas un servidor/base de datos entre usuarios que no se confían mutuamente sin una capa de autenticación al frente que autentique a cada llamador y fuerce el userId correcto (y projectId / sessionId permitidos). No se incorpora ningún sistema de autenticación nuevo en el servidor por diseño — esa capa pertenece al frente de él.

Licencia

MIT © 2026 worakorn-prince

Este proyecto está licenciado bajo la Licencia MIT — consulta el archivo LICENSE para el texto completo.