Ir al contenido

Guía de Migración

Si usas el servidor MCP Memory de Anthropic, tu knowledge graph vive en un único archivo JSONL. mcp-memory almacena los mismos datos en SQLite con indexación adecuada, soporte de concurrencia y embeddings vectoriales — pero el formato de datos es idéntico.

La tool migrate lee tu archivo JSONL existente e importa cada entidad, observación y relación en la base de datos SQLite. Es idempotente, tolerante a fallos y segura para ejecutar múltiples veces.

El servidor MCP Memory de Anthropic almacena datos en formato JSONL — un objeto JSON por línea. Hay exactamente dos tipos de registro:

Una entidad representa un nodo en el knowledge graph con nombre, tipo y una lista de observaciones:

{"type": "entity", "name": "Session 2026-03-21", "entityType": "Session", "observations": ["Decision: build MCP Memory v2", "Uses FastMCP framework"]}

Campos obligatorios:

CampoTipoDescripción
typestringDebe ser "entity"
namestringIdentificador único de la entidad
entityTypestringTipo de entidad (por defecto "Generic" si se omite)
observationsstring[]Lista de cadenas de observación (puede estar vacía)

Una relación conecta dos entidades con un arco tipado:

{"type": "relation", "from": "MCP Memory v2", "to": "FastMCP", "relationType": "uses"}

Campos obligatorios:

CampoTipoDescripción
typestringDebe ser "relation"
fromstringNombre de la entidad origen
tostringNombre de la entidad destino
relationTypestringTipo de relación

Un archivo típico mezcla ambos tipos de registro. Las entidades deben aparecer antes de las relaciones que las referencian:

{"type": "entity", "name": "Project Alpha", "entityType": "Project", "observations": ["Started in March 2026", "Uses Python 3.12"]}
{"type": "entity", "name": "SQLite", "entityType": "Technology", "observations": ["Used for persistence"]}
{"type": "entity", "name": "FastMCP", "entityType": "Framework", "observations": ["MCP server framework"]}
{"type": "relation", "from": "Project Alpha", "to": "SQLite", "relationType": "uses"}
{"type": "relation", "from": "Project Alpha", "to": "FastMCP", "relationType": "built_with"}

La migración se ejecuta en cuatro fases secuenciales:

El archivo JSONL se lee línea por línea. Cada línea se parsea como un objeto JSON independiente:

  • Si la línea se parsea correctamente, el registro se clasifica como entidad o relación según su campo type.
  • Si el parseo JSON falla (línea corrupta, problema de codificación), se registra un warning y la línea se omite. La línea se cuenta en el total de errors.
  • Las líneas en blanco se ignoran.

Esta fase es puramente en memoria — no se escribe en la base de datos aún. Los registros parseados se encolan para las siguientes fases.

Cada registro de entidad se procesa mediante upsert_entity, que usa ON CONFLICT(name) DO UPDATE de SQLite:

  • Entidad nueva: se inserta en la tabla entities.
  • Entidad existente: las observaciones se fusionan — solo se añaden las observaciones que no existen. El tipo de entidad se actualiza si difiere.

Esto permite ejecutar la migración sobre un archivo que se solapa parcialmente con datos ya existentes en la base de datos.

Cada registro de relación se valida antes de la inserción:

  1. Ambas entidades from y to deben existir en la base de datos.
  2. Todos los campos obligatorios (from, to, relationType) deben estar presentes.
  3. La relación no debe existir ya (restricción UNIQUE sobre (from_entity, to_entity, relation_type)).

Si alguna comprobación falla, la relación se omite y se cuenta como skipped. Si la relación es válida, se inserta mediante create_relation, que captura IntegrityError en restricciones duplicadas por seguridad.

Si el motor de embeddings está disponible (modelo descargado — consulta Primeros Pasos), los embeddings se generan para todas las entidades importadas en un único batch al final de la migración.

Esto es significativamente más eficiente que generar embeddings uno a uno durante la importación. El enfoque batch:

  • Agrupa todo el texto de entidades en una única pasada de inferencia ONNX.
  • Usa INSERT OR REPLACE sobre rowid — los embeddings existentes se sobrescriben con vectores nuevos.
  • Si el motor de embeddings no está disponible, esta fase se omite silenciosamente. La migración se completa correctamente y los embeddings se generarán más tarde cuando las entidades se accedan mediante search_semantic.

Tienes dos opciones: mediante la tool MCP (recomendada para la mayoría de usuarios) o mediante script Python (para acceso programático).

Si usas un cliente MCP (OpenCode, Claude Desktop, etc.), llama a la tool migrate con la ruta a tu archivo JSONL:

{
"source_path": "~/.config/opencode/mcp-memory.jsonl"
}

La tool expande ~ al directorio home automáticamente. La ruta debe apuntar a un archivo existente y legible.

La tool retorna un resultado JSON (consulta Formato del resultado más abajo).

Para scripting o pipelines de CI, importa la función de migración directamente:

from mcp_memory.storage import MemoryStore
from mcp_memory.migrate import migrate_jsonl
store = MemoryStore()
store.init_db()
result = migrate_jsonl(store, "~/.config/opencode/mcp-memory.jsonl")
print(result)

La función migrate_jsonl acepta la misma ruta con expansión de ~. Retorna un diccionario con los mismos campos que la respuesta de la tool MCP.

También puedes ejecutarlo como una línea desde la raíz del repositorio:

Ventana de terminal
uv run python -c "
from mcp_memory.storage import MemoryStore
from mcp_memory.migrate import migrate_jsonl
store = MemoryStore()
store.init_db()
result = migrate_jsonl(store, '~/.config/opencode/mcp-memory.jsonl')
print(result)
"

La migración es idempotente: ejecutarla múltiples veces produce el mismo resultado sin duplicar datos. Esto es seguro porque cada operación de escritura incluye un mecanismo de resolución de conflictos:

OperaciónMecanismoEfecto en ejecuciones repetidas
Insertar entidadON CONFLICT(name) DO UPDATELas entidades existentes se actualizan; las observaciones nuevas se fusionan
Añadir observaciónComprobación de existencia antes de insertarLas observaciones duplicadas se descartan silenciosamente
Crear relaciónIntegrityError capturado en restricción UNIQUELas relaciones duplicadas se ignoran
Almacenar embeddingINSERT OR REPLACE sobre rowidEl vector de embedding existente se sobrescribe con uno nuevo

La migración está diseñada para ser tolerante a fallos — procesa tantos registros como sea posible en lugar de fallar en el primer error:

Condición de errorComportamientoContado como
Línea corrupta (JSON inválido)Omitida con warningerrors
Entidad sin campo nameOmitidaskipped
Relación con campos faltantes (from, to o relationType)Omitidaskipped
Relación que referencia entidad inexistenteOmitidaskipped
Tipo de registro desconocido (no "entity" ni "relation")Omitidoskipped
Fallo individual de embeddingRegistrado como warning, la migración continúaNo se cuenta

La migración nunca lanza una excepción por fallos de registros individuales. Todos los problemas se capturan en los contadores del resultado.

La tool migrate retorna un objeto JSON con cuatro campos:

{
"entities_imported": 32,
"relations_imported": 37,
"errors": 0,
"skipped": 2
}
CampoTipoDescripción
entities_importedintRegistros de entidad procesados correctamente (insertados o actualizados)
relations_importedintRelaciones creadas efectivamente en la base de datos
errorsintLíneas que fallaron el parseo JSON o lanzaron excepciones inesperadas
skippedintRegistros omitidos por campos faltantes, entidades destino inexistentes o tipo desconocido

Tras completar la migración, verifica que los datos se importaron correctamente:

Usa search_nodes para verificar las entidades importadas y confirmar que los datos se migraron correctamente:

{
"query": ""
}

Si descargaste el modelo de embeddings, verifica que se generaron los embeddings ejecutando una consulta semántica:

{
"query": "tu término de búsqueda aquí",
"limit": 10
}

Si los resultados incluyen campos limbic_score y distance, los embeddings funcionan. Si obtienes un error sobre el modelo, consulta Primeros Pasos para las instrucciones de descarga.

Usa open_nodes para verificar entidades individuales por nombre:

{
"names": ["Session 2026-03-21", "Project Alpha"]
}

Confirma que las observaciones se fusionaron correctamente y no se perdió datos.

Migrar desde una instalación predeterminada de Anthropic

Sección titulada «Migrar desde una instalación predeterminada de Anthropic»

La ubicación predeterminada del archivo JSONL de Anthropic MCP Memory depende de tu configuración:

Ventana de terminal
# OpenCode
~/.config/opencode/mcp-memory.jsonl
# Claude Desktop (macOS)
~/Library/Application Support/Claude/claude_memory.jsonl
# Claude Desktop (Linux)
~/.config/Claude/claude_memory.jsonl

Pasa la ruta correcta a la tool migrate o a la función Python.

Si tu archivo JSONL sigue recibiendo escrituras (por ejemplo, ejecutas ambos servidores en paralelo durante un periodo de transición), puedes ejecutar la migración periódicamente. Al ser idempotente, cada ejecución solo importa entidades y observaciones nuevas que no estaban presentes.

La migración procesa el archivo línea por línea — nunca carga el archivo completo en memoria. Un archivo con miles de entidades y relaciones se importará sin problemas. La fase de generación batch de embeddings es la parte más lenta, pero procesa los embeddings en lotes en lugar de todos a la vez.


  • Siguiente: Referencia de Tools — parámetros, respuestas y casos extremos para las 10 tools
  • Ver también: Primeros Pasos — instalación, configuración y primeros pasos