Claude Conversation Memory System

Proporciona almacenamiento local con capacidad de búsqueda para el historial de conversaciones de Claude, permitiendo la recuperación de contexto durante las sesiones.

Documentación

Quality Gate Status Bugs Vulnerabilities Code Smells Coverage Duplicated Lines (%)

Universal Memory MCP — Memoria de Conversaciones para IA

Un servidor de Protocolo de Contexto de Modelo (MCP) que proporciona memoria de conversaciones persistente y buscable en múltiples plataformas de IA. Almacena, busca y recupera el historial de conversaciones con búsqueda de texto completo rápida impulsada por SQLite FTS5.

Características

  • 🔍 Búsqueda de texto completo rápida mediante SQLite FTS5 con clasificación por relevancia — ~10 veces más rápida que un escaneo lineal (medido)
  • 🏷️ Extracción automática de temas — más de 574 temas únicos en más de 2,000 asociaciones
  • 📊 Resúmenes semanales con perspectivas y patrones
  • 🗃️ Almacenamiento de archivos organizado por fecha y tema
  • 🤖 Soporte multiplataforma — Claude, ChatGPT, Cursor AI y formatos personalizados
  • 🔌 Integración MCP para Claude Desktop y Claude Code

Inicio Rápido

Requisitos Previos

  • Python 3.10+ (CI ejecuta 3.14)
  • Un cliente MCP — Claude Code, Claude Desktop, Codex o cualquier otro que hable MCP sobre stdio

Instalación

uv tool install universal-memory-mcp   # or: pipx install universal-memory-mcp

No es pip install: esto es una aplicación, y en Debian/Ubuntu y otros sistemas PEP 668, instalar uno en el intérprete del sistema falla con error: externally-managed-environment. Dentro de un virtualenv que ya hayas activado, pip install universal-memory-mcp es correcto.

Luego apunta tu cliente al script de consola universal-memory-mcp:

claude mcp add --transport stdio universal-memory-mcp -- universal-memory-mcp

O escríbelo tú mismo en la configuración — Claude Code y Claude Desktop:

{ "mcpServers": { "universal-memory-mcp": { "command": "universal-memory-mcp" } } }

Codex (~/.codex/config.toml):

[mcp_servers.universal-memory-mcp]
command = "universal-memory-mcp"

El nombre del servidor es tu elección, pero establece el espacio de nombres de herramientas que tu cliente expone (mcp__<name>__*). Las conversaciones viven en ~/claude-memory/ independientemente, así que renombrar es seguro.

¿Actualizar una instalación que apunta a un checkout? scripts/switch_mcp_config.py reescribe ambos formatos de configuración en su lugar — ejecución en seco por defecto, --apply para escribir.

Desde el código fuente

git clone https://github.com/adamkwhite/universal-memory-mcp.git
cd universal-memory-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
python3 tests/validate_system.py     # optional: verify the install

Apunta tu cliente a <checkout>/.venv/bin/python3 -m universal_memory_mcp.server_fastmcp. El paquete usa importaciones relativas, por lo que ejecutar el archivo directamente no puede funcionar — python3 src/universal_memory_mcp/server_fastmcp.py fails with se intentó una importación relativa sin un paquete padre conocido.

Uso Básico

Modo Servidor MCP

Tu cliente inicia el servidor por ti; ejecútalo manualmente solo para depurar.

universal-memory-mcp                          # installed from PyPI
python3 -m universal_memory_mcp.server_fastmcp  # from source

Importación Masiva

# Import conversations from JSON export
python3 scripts/bulk_import_enhanced.py your_conversations.json

Herramientas MCP

search_conversations(query, limit=5)

Búsqueda de texto completo en todas las conversaciones almacenadas con clasificación por relevancia. El texto de la consulta se trata como términos Unicode literales, por lo que la puntuación y los operadores FTS5 no cambian la semántica de la consulta. Los resultados incluyen IDs de conversación para una recuperación exacta.

get_conversation(conversation_id, max_chars=12000)

Recupera una conversación almacenada por un ID devuelto por una herramienta de búsqueda. El contenido se lee del almacén JSON autoritativo y se trunca a max_chars para proteger el contexto del modelo. max_chars debe estar entre 1 y 50,000.

search_by_topic(topic, limit=10)

Encuentra conversaciones etiquetadas con un tema específico.

add_conversation(content, title, date)

Almacena una nueva conversación con extracción automática de temas e indexación FTS.

generate_weekly_summary(week_offset=0)

Genera perspectivas y patrones a partir de conversaciones recientes.

get_search_stats()

Muestra estadísticas del motor de búsqueda — tamaño del índice, conteos de temas y estado del motor.

update_conversation(conversation_id, content=None, title=None, add_tags=None, remove_tags=None, set_tags=None, conversation_type=None, session_id=None, user_id=None, change_note=None, record_audit=True)

Actualiza campos de una conversación existente en su lugar. Pasa conversation_id más cualquier subconjunto de campos a cambiar; los campos no especificados se dejan intactos. Por defecto, la primera línea del contenido almacenado se reescribe con una línea de auditoría autodocumentada — [update <iso-timestamp> — <change_note>] — encadenada a través de actualizaciones repetidas. Si change_note se omite, se deriva de los campos cambiados.

Establece record_audit=False solo para importaciones autoritativas cuyo contenido debe permanecer como una réplica exacta del sistema fuente. Las actualizaciones interactivas normales deben conservar el registro de auditoría predeterminado.

Operaciones de etiquetas: set_tags reemplaza la lista completa de etiquetas y es mutuamente excluyente con add_tags/remove_tags (pasa set_tags=[] para borrar todas las etiquetas); add_tags/remove_tags mutan la lista existente.

Devuelve una cadena de estado. En caso de éxito: Status: success más un mensaje de resumen y, cuando está habilitado, la línea de auditoría. En caso de fallo (ID malformado, conversación no encontrada, sin cambios proporcionados, operaciones de etiquetas conflictivas o un error de E/S): Status: error más un mensaje que describe el problema.

search_by_tag(tag, limit=10)

Encuentra conversaciones etiquetadas con una etiqueta específica — un campo de metadatos universal poblado por importadores o establecido mediante update_conversation (por ejemplo, starred, archived, workspace:my-project). Coincidencia exacta, sensible a mayúsculas. Requiere SQLite FTS habilitado; sin él, devuelve un mensaje de error.

search_by_session_id(session_id, limit=10)

Encuentra todas las conversaciones que comparten un session_id, útil para reconstruir una sesión de múltiples turnos que abarca varios registros de conversación almacenados (por ejemplo, una sesión de trabajo de Cursor, un hilo de Claude continuado a lo largo de días). Los resultados se ordenan cronológicamente (más antiguos primero). Requiere SQLite FTS habilitado; sin él, devuelve un mensaje de error.

search_by_conversation_type(conversation_type, limit=10)

Encuentra conversaciones por conversation_type (por ejemplo, chat, code, analysis). Coincidencia exacta, más recientes primero. Requiere SQLite FTS habilitado; sin él, devuelve un mensaje de error.

Arquitectura

~/claude-memory/
├── conversations/
│   ├── 2025/
│   │   └── 06-june/
│   │       └── 2025-06-01_topic-name.md
│   ├── index.json          # Search index
│   └── topics.json         # Topic frequency
└── summaries/
    └── weekly/
        └── week-2025-06-01.md

Configuración

Integración con Claude Desktop

Agrega a tu configuración MCP de Claude Desktop:

{
  "mcpServers": {
    "universal-memory-mcp": {
      "command": "universal-memory-mcp"
    }
  }
}

¿Instalado desde el código fuente en lugar de PyPI? Apunta command al intérprete de tu virtualenv y ejecuta el módulo:

{
  "mcpServers": {
    "universal-memory-mcp": {
      "command": "/absolute/path/to/universal-memory-mcp/.venv/bin/python3",
      "args": ["-m", "universal_memory_mcp.server_fastmcp"]
    }
  }
}

Actualización desde antes del movimiento del paquete (#225): las configuraciones solían nombrar el script del servidor directamente (src/server_fastmcp.py). Eso ya no funciona de ninguna forma — los módulos se movieron bajo src/universal_memory_mcp/, y el paquete ahora usa importaciones relativas, por lo que ejecutar el archivo genera attempted relative import with no known parent package. Cambia al script de consola o a la forma -m anterior.

Precedencia de Configuración

La configuración se resuelve mediante src/universal_memory_mcp/config.py de Config.load(), consultada en este orden (la más alta gana):

  1. Variables de entorno (CLAUDE_MEMORY_* / CLAUDE_MCP_*)
  2. Archivo de configuración (por defecto ~/.claude-memory/config.json)
  3. Perfil de plataforma (default, claude, chatgpt o cursor — selecciona un conjunto parcial de valores predeterminados, por ejemplo, log_format)
  4. Valores predeterminados integrados

Variables de Entorno

VariablePropósitoValor Predeterminado
CLAUDE_MEMORY_PATHDirectorio de almacenamiento de conversaciones~/claude-memory
CLAUDE_MEMORY_DISABLE_SQLITEEstablece true para deshabilitar SQLite FTS y recurrir a la búsqueda lineal JSON. Alias inverso de CLAUDE_MCP_ENABLE_SQLITE; gana si ambos están establecidos.sin establecer (SQLite habilitado)
CLAUDE_MCP_LOG_FORMATFormato de salida de registros: text o jsontext
CLAUDE_MCP_LOG_LEVELNivel de registro: DEBUG, INFO, WARNING, ERROR, CRITICALINFO
CLAUDE_MCP_ENABLE_SQLITEHabilita/deshabilita la búsqueda SQLite FTS (booleano: true/false, 1/0, yes/no, on/off)true
CLAUDE_MCP_CONSOLE_OUTPUTEnvía registros a stdout además del archivo de registro (booleano)false
CLAUDE_MCP_PLATFORM_PROFILEPerfil de plataforma a aplicar: default, claude, chatgpt o cursordefault

Cuando CLAUDE_MEMORY_PATH se establece explícitamente, la ruta puede vivir fuera de tu directorio de inicio (por ejemplo, una unidad de datos separada en Windows: D:\claude-memory). Las rutas que no están configuradas explícitamente aún están restringidas al directorio de inicio o del proyecto por seguridad.

Archivo de Configuración

Como alternativa a las variables de entorno, la configuración se puede colocar en ~/.claude-memory/config.json. El archivo es opcional — un archivo faltante recurre a los valores predeterminados del perfil de plataforma/integrados. Ejemplo:

{
  "storage_path": "~/claude-memory",
  "log_format": "json",
  "log_level": "INFO",
  "enable_sqlite": true,
  "console_output": false,
  "platform_profile": "default"
}

Las claves desconocidas en el archivo generan un error de configuración en lugar de ser ignoradas silenciosamente. Las variables de entorno aún anulan cualquier cosa establecida aquí.

Deshabilitar SQLite

La búsqueda SQLite FTS5 está habilitada por defecto. En plataformas donde SQLite/FTS5 no está disponible (por ejemplo, algunas compilaciones de Python en Windows), deshabilítala para recurrir a la búsqueda lineal basada en JSON:

export CLAUDE_MEMORY_DISABLE_SQLITE=true

Configuración de Registros

Formato de Registro

Cambia entre registros de texto legibles por humanos (predeterminado) y registros JSON estructurados para producción:

# JSON format (for production log aggregation)
export CLAUDE_MCP_LOG_FORMAT=json

# Text format (default, for development)
export CLAUDE_MCP_LOG_FORMAT=text

Ejemplo de Registro JSON:

{
  "timestamp": "2025-01-15T10:30:45",
  "level": "INFO",
  "logger": "claude_memory_mcp",
  "function": "add_conversation",
  "line": 145,
  "message": "Added conversation successfully",
  "context": {
    "type": "performance",
    "duration_seconds": 0.045,
    "conversation_id": "conv_abc123"
  }
}

El registro JSON es ideal para:

  • Implementaciones de producción con agregación de registros (Datadog, ELK, CloudWatch)
  • Monitoreo y alertas automatizados
  • Análisis y consultas de registros estructurados
  • Seguimiento de rendimiento y depuración

Consulta docs/json-logging.md para documentación detallada sobre registros JSON.

Estructura de Archivos

universal-memory-mcp/
├── src/
│   ├── server_fastmcp.py       # Main MCP server
│   ├── conversation_memory.py  # Core memory engine + SQLite FTS5
│   ├── format_detector.py      # Auto-detect AI platform format
│   ├── validators.py           # Input validation
│   ├── logging_config.py       # Structured logging (text/JSON)
│   ├── importers/              # Platform-specific importers
│   │   ├── chatgpt_importer.py
│   │   ├── claude_importer.py
│   │   ├── cursor_importer.py
│   │   └── generic_importer.py
│   └── schemas/                # JSON schema validation
├── tests/                      # 435 tests, 98.68% coverage
├── data/                       # Consolidated app data
├── scripts/                    # Import and utility scripts
└── docs/                       # Documentation

Rendimiento

scripts/benchmark_search.py estaba roto (llamadas asíncronas sin espera, midiendo la construcción de corrutinas en lugar del tiempo real de búsqueda) desde octubre de 2025 hasta que se encontró y corrigió. Los números anteriores a continuación nunca se midieron realmente y se han reemplazado con los reales. Reproduce con:

python scripts/generate_test_data.py --conversations 159
python scripts/benchmark_search.py --storage-path ~/claude-memory-test --iterations 5

Medido en un conjunto de datos local de 159 conversaciones / 7.7MB (WSL2, Python 3.12) — trátalo como orden de magnitud, no como un SLA preciso, los resultados varían según la máquina:

  • Velocidad de búsqueda (SQLite FTS5): media 15–18ms, mediana 10–13ms por consulta, rango 0.5–82ms en 12 tipos de consulta (se afirmaba 0.2–0.5ms; esa cifra nunca se midió)
  • Búsqueda vs. escaneo lineal JSON: SQLite FTS5 es ~10 veces más rápido (media 14.7ms vs 154.2ms; mediana 10.5ms vs 152.0ms) — la afirmación anterior de "4.4x" tenía la dirección correcta pero tampoco se midió nunca
  • Búsqueda de temas: media 3.4ms, mediana 2.5ms (se afirmaba 0.3–0.4ms; esa cifra nunca se midió)
  • Velocidad de escritura: media 14ms, mediana 14ms por conversación de ~49KB, incluida la indexación SQLite (se afirmaba ~33ms; esa cifra nunca se midió)
  • Capacidad: 371 conversaciones en uso de producción durante 10 meses
  • Cobertura de pruebas: 98.68% (435 pruebas) — 0 olores de código, 0 puntos críticos de seguridad (verificado por SonarCloud)

Última evaluación comparativa: julio de 2026 | Informe Detallado

Nota para Desarrolladores: Las evaluaciones comparativas de rendimiento crean un directorio ~/claude-memory-test para pruebas aisladas. El uso normal de MCP solo usa ~/claude-memory/. Si ves ~/claude-memory-test, se puede eliminar de forma segura.

Ejemplos de Búsqueda

# Technical topics
search_conversations("terraform azure")
search_conversations("mcp server setup")
search_conversations("python debugging")

# Project discussions
search_conversations("interview preparation")
search_conversations("product management")
search_conversations("architecture decisions")

# Specific problems
search_conversations("dependency issues")
search_conversations("authentication error")
search_conversations("deployment configuration")

Desarrollo

Agregar Nuevas Características

  1. Extracción de Temas: Modifica _extract_topics() en ConversationMemoryServer
  2. Algoritmo de Búsqueda: Mejora el método search_conversations()
  3. Generación de Resúmenes: Mejora la lógica de generate_weekly_summary()

Pruebas

# Run validation suite
python3 tests/validate_system.py

# Run full test suite with coverage
python3 -m pytest tests/ --cov=src --cov-report=term

# Import test data
python3 scripts/bulk_import_enhanced.py test_data.json --dry-run

Almacenamiento de Datos de Prueba (Solo Desarrolladores): Si ejecutas evaluaciones comparativas de rendimiento o generadores de datos de prueba, crean un directorio ~/claude-memory-test para aislar los datos de prueba de tu directorio de producción ~/claude-memory. Esto es solo para desarrollo/pruebas — el uso normal de MCP no crea este directorio.

Para limpiar los datos de prueba después de ejecutar evaluaciones comparativas:

rm -rf ~/claude-memory-test

O usando el objetivo de limpieza del Makefile:

make clean-test-data

Solución de Problemas

Problemas Comunes

Errores de Importación de MCP: la dependencia mcp viene con el paquete, por lo que esto normalmente significa que el servidor se está ejecutando bajo un intérprete que no la tiene. Verifica cuál invoca tu configuración de MCP: el script de consola universal-memory-mcp de uv tool/pipx, o el python3 -m universal_memory_mcp.server_fastmcp de tu virtualenv — no un python3 del sistema sin envolver.

La Búsqueda No Devuelve Resultados:

  • Verifica la indexación de conversaciones: ls ~/claude-memory/conversations/index.json
  • Verifica los permisos de archivos
  • Ejecuta la validación: python3 tests/validate_system.py

Errores de Zona Horaria en el Resumen Semanal:

  • Asegúrate de que todos los objetos datetime usen un manejo de zona horaria consistente
  • La corrección reciente aborda la comparación entre objetos con y sin zona horaria

Requisitos del Sistema

  • Python: 3.10+ (CI ejecuta 3.14)
  • Espacio en disco: ~10MB por cada 100 conversaciones
  • Memoria: <100MB de uso de RAM
  • SO: Linux/WSL y Windows están verificados en CI en cada PR (Ubuntu + windows-latest). Se espera que macOS funcione, pero no está cubierto por un runner de CI.

Contribuciones

  1. Haz un fork del repositorio
  2. Crea una rama de características: git checkout -b feature-name
  3. Realiza los commits: git commit -am 'Add feature'
  4. Sube la rama: git push origin feature-name
  5. Envía un Pull Request

Nota para PRs desde forks: GitHub no otorga a los forks acceso a los secretos del repositorio, por lo que el escaneo de SonarCloud y el comentario de resultados de rendimiento se omiten en tu PR en lugar de ejecutarse. Eso es esperado y no es algo que puedas o debas corregir: la suite de pruebas, el linting, CodeQL y la ejecución en Windows se ejecutan normalmente, y la cobertura de tus cambios se verifica cuando la rama llega a main. Si ves esos dos omitidos, no hay nada malo.

Publicación

La publicación está controlada por etiquetas y utiliza Trusted Publishing (OIDC): no hay token de PyPI almacenado en este repositorio. .github/workflows/publish.yml se activa solo con una etiqueta vX.Y.Z.

Configuración única en PyPI (ajustes de publicador para el proyecto, o un publicador pendiente mientras el nombre aún no está reclamado):

campovalor
Propietarioadamkwhite
Repositoriouniversal-memory-mcp
Workflowpublish.yml
Entornopypi

Para lanzar una versión:

# 1. bump `version` in pyproject.toml, commit, merge to main
# 2. tag the merged commit — the workflow refuses a tag that disagrees with pyproject
git tag v0.1.0 && git push origin v0.1.0

El workflow compila, ejecuta twine check, instala la rueda en un venv limpio y verifica que cada módulo se importe y que no se haya filtrado ningún nombre genérico de nivel superior, luego publica. Añade revisores requeridos al entorno pypi en la configuración del repositorio para una puerta de aprobación manual también.

Ensaya en TestPyPI antes de la primera subida real: la primera subida reclama el nombre permanentemente, y un número de versión nunca se puede reutilizar:

rm -rf dist && uv build
uv run --with twine --no-project twine upload --repository testpypi dist/*
# TestPyPI does not mirror mcp/jsonschema/aiofiles, so pull deps from real PyPI:
uv pip install --index-url https://test.pypi.org/simple/ \
               --extra-index-url https://pypi.org/simple/ universal-memory-mcp

Licencia

Licencia MIT: consulta el archivo LICENSE para más detalles

Agradecimientos


Estado: Listo para producción ✅ Última actualización: Abril 2026 Versión: 2.0.0