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
Servidor MCP de memoria a largo plazo para OpenCode: almacena preferencias, lecciones e historial de uso en un único archivo SQLite local (100% local, sin API externa) para que la IA pueda "recordar y adaptarse" al usuario mediante aprendizaje basado en contexto.
Estado: v2.2.2 — un motor de memoria temporal, consciente de conflictos y con recuperación híbrida. 16 herramientas MCP, 20 suites de pruebas que pasan. Migración de esquema no destructiva desde v1 (todos los datos v1 se conservan). Nuevo en v2: 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.
Requisitos
- Node.js >= 20 — el servidor utiliza APIs exclusivas de Node (la compilación nativa de
better-sqlite3y la resolución deimport.meta.url) y el SDK de MCP requiere un runtime moderno. CI prueba en Node 20.x y 22.x. - npm — para instalar dependencias y ejecutar los scripts de compilación/prueba (
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_PATHes más fácil de configurar consetx; en macOS/Linux usaexporten 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).
Instalar 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).
# 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"
- 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" }
}
}
}
- (Opcional) Captura automática: copia
src/plugin/learning-capture.ts→~/.config/opencode/plugins/ - Reinicia OpenCode
- 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 hosts
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 de fondo de prompts/herramientas/errores + inyección de perfil) necesita un runtime de hooks — OpenCode lo tiene integrado; Claude Code lo obtiene a través de nuestro puente de hooks; Codex y Cursor usan las herramientas manualmente (aún sin runtime de hooks).
| Característica | OpenCode | Claude Code | Qwen Code | Codex | Cursor |
|---|---|---|---|---|---|
| 16 herramientas MCP | ✅ | ✅ | ✅ | ✅ | ✅ |
| Captura automática (fondo) | ✅ plugin | ✅ hooks | ⚠️ adaptador | ❌ manual | ❌ Rules |
| Inyección de perfil | ✅ compactación | ✅ UserPromptSubmit | ❌ get_profile | ❌ get_profile | ❌ get_profile |
| Búsqueda semántica local | ✅ (v2.0) | ✅ (v2.0) | ✅ (v2.0) | ✅ (v2.0) | ✅ (v2.0) |
- Claude Code: consulta CLAUDE_CODE_HOOKS.md — los hooks listos para usar replican el plugin de OpenCode (captura + inyección de perfil en
UserPromptSubmit/PreCompact, destilado basado en reglas enSessionEnd). - 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 hosts comparten un único archivo SQLite a través de 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_contextcombina búsqueda de palabras clave FTS5 con un embedding vectorial local sin dependencias (fusión RRF + puntuación), luego ensambla un contexto con presupuesto de tokens y 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 / i18n de primera clase — 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-host — se ejecuta en OpenCode, Claude Code, Codex y Cursor compartiendo una sola base de datos; captura automática + inyección de perfil mediante plugin de OpenCode o 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
| Comando | Descripción |
|---|---|
npm run build | compila TypeScript → dist/ |
npm start | ejecuta el servidor MCP (stdio) desde dist/index.js |
npm run distill | destilado basado en reglas: interacciones → secciones de perfil + poda de datos antiguos (env RETENTION_DAYS predeterminado 30) |
npm test | suite completa: captura, destilado, ciclo de vida, temporal, conflictos, recuperación, grafo, contexto, consolidación, benchmark, seguridad, tools_v21, smoke, e2e_transport, retrieval_benchmark, recall_regression, scope, profile, entity_extraction, conflict_benchmark |
node test/capture.test.mjs | prueba capture-core (filtro de secretos, deduplicación, truncado, inserción SQL) |
node test/distill.test.mjs | prueba distill-core (tokenización tailandesa, estadísticas, secciones de perfil, poda) |
node test/lifecycle.test.mjs | prueba el motor de ciclo de vida (estados, decaimiento, superación) |
node test/temporal.test.mjs | prueba el modelo temporal (validez, recuperación histórica) |
node test/conflict.test.mjs | prueba la resolución de conflictos y deduplicación |
node test/retrieval.test.mjs | prueba la recuperación híbrida FTS+vectorial+RRF |
node test/graph.test.mjs | prueba el grafo de memoria (entidades, relaciones, recorrido) |
node test/context.test.mjs | prueba el ensamblaje de contexto + presupuesto de tokens |
node test/consolidation.test.mjs | prueba la agrupación + memorias derivadas |
node test/benchmark.test.mjs | benchmark de latencia sobre 300 memorias |
node test/security.test.mjs | comprobaciones de inyección / seguridad |
node test/smoke.mjs | prueba de humo de extremo a extremo sobre JSON-RPC (16 herramientas) |
Herramientas (16)
| Herramienta | Descripción |
|---|---|
remember | upsert de preferencia (categoría+clave) — volver a guardar la misma clave aumenta la confianza en 0.1 (máx. 1.0) |
recall | buscar preferencias + lecciones (FTS5) + interacciones coincidentes recientes. Úsalo antes de comenzar una nueva tarea |
get_profile | resumen del perfil de usuario: secciones de perfil + preferencias principales + 5 lecciones más recientes |
save_lesson | registrar una lección aprendida de una corrección (situación / error / corrección) |
search_history | buscar prompts de usuario anteriores por palabra clave (fragmentos de 200 caracteres por fila) |
forget | eliminar una fila de memoria (preferencia/lección/interacción) por id (+tipo evita choque de id entre tablas) |
memory_stats | estadísticas de memoria: recuentos por tipo, tamaño de la base de datos, interacción más antigua/más reciente, secciones de perfil |
get_recent_interactions | listar interacciones crudas recientes (filtrar por tipo) — materia prima para Smart Distill |
export_memory | exportar memoria a JSON bajo data/exports/ solamente (nombre de archivo auto-saneado) |
get_context | ensamblar memorias relevantes para la tarea actual mediante recuperación híbrida (+ expansión opcional del grafo) con presupuesto de tokens |
consolidate | agrupar memorias similares mediante similitud de embeddings; opcionalmente crear memorias derivadas/consolidadas vinculadas vía derived_from |
link_memory | crear una relación tipada entre dos memorias en el grafo (supports/contradicts/supersedes/derived_from/related_to/caused_by/depends_on) |
merge_memory | fusionar un duplicado/casi duplicado en una memoria canónica (la fuente se vuelve superada, procedencia en metadata.merged_from) |
update_memory | actualizar campos mutables en el lugar, o crear una memoria superadora cuando content cambia (establece supersede=false para editar en el lugar) |
import_memory | importar memorias desde JSON (valida tipo, deduplica contra existentes, nunca sobrescribe a ciegas); dry-run por defecto, apply=true para insertar |
extract_memories | escanear interacciones capturadas recientes en busca de frases con intención de memoria y proponer candidatos de memoria (determinista, sin LLM); dry-run por defecto, apply=true para crear (fuente=capturada) |
Instalar con OpenCode
- Fusiona la sección
mcpdeopencode.example.jsonen tuopencode.json(global o a nivel de proyecto)- Importante: establece
MEMORY_DB_PATHal 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
environmentde mcp (ver ejemplo) — cubre solo el servidor MCP - o establécelo como variable de entorno a nivel de sistema/usuario (por ejemplo,
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
- defínelo en el
- Importante: establece
- Adjunta las reglas de memoria globales — agrega a
opencode.json:
(el contenido de ejemplo de reglas está en"instructions": ["C:/Users/<user>/.config/opencode/memory-protocol.md"]AGENTS.memory.example.md— se puede adjuntar a nivel de proyecto en su lugar) - (Opcional) Despliega el plugin de captura automática: copia
src/plugin/learning-capture.ts→~/.config/opencode/plugins/learning-capture.ts - Reinicia OpenCode (la configuración se carga solo al inicio)
- Prueba: "Recuerda que prefiero pnpm" → abre una nueva sesión y pregunta de vuelta
Uso diario
La IA acepta tailandés e inglés indistintamente — puedes cambiar de idioma en cualquier momento sin previo aviso.
| Comando de ejemplo | Herramienta / efecto |
|---|---|
| "Recuerda que..." | remember — guarda una preferencia |
| "Resumir memoria" / "destilar memoria" | Destilación Inteligente — la IA lee get_recent_interactions, encuentra patrones y guarda información por sí misma |
| "¿Cómo está mi memoria?" / "estado de la 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 eliminar 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
Licencia
MIT © 2026 worakorn-prince
Este proyecto está licenciado bajo la Licencia MIT — consulta el archivo LICENSE para el texto completo.