mem0-mcp-selfhosted

Servidor MCP mem0 autoalojado para Claude Code. Ejecuta un servidor de memoria completo contra Qdrant + Neo4j + Ollama autoalojados mientras usas Claude como LLM principal.

Documentación

mem0-mcp-selfhosted

mem0-mcp-selfhosted MCP server

Servidor MCP de mem0 autoalojado para Claude Code. Ejecuta un servidor de memoria completo contra Qdrant + Neo4j + Ollama autoalojados, con tu elección de Anthropic (Claude) u Ollama como LLM principal.

Utiliza el paquete mem0ai directamente como biblioteca, admite tanto el token OAT de Claude como configuraciones totalmente locales con Ollama, y expone 11 herramientas MCP para la gestión completa de memoria.

Prerrequisitos

ServicioRequeridoPropósito
QdrantSíAlmacenamiento y búsqueda de memoria vectorial
OllamaSíGeneración de embeddings (bge-m3) y opcionalmente LLM local
Neo4j 5+OpcionalGrafo de conocimiento (relaciones entre entidades)
Clave API de GoogleOpcionalRequerida solo para los proveedores de grafo gemini/gemini_split

Python >= 3.10 y uv.

Autenticación: La configuración predeterminada usa Claude (Anthropic) como LLM para la extracción de hechos. No se necesita clave API, el servidor usa automáticamente el token de sesión de Claude Code. Para configuraciones totalmente locales, establece MEM0_PROVIDER=ollama. Consulta Autenticación para opciones avanzadas.

Inicio Rápido

Predeterminado (Anthropic)

Agrega el servidor MCP globalmente (disponible en todos los proyectos):

claude mcp add --scope user --transport stdio mem0 \
  --env MEM0_USER_ID=your-user-id \
  -- uvx --from git+https://github.com/elvismdev/mem0-mcp-selfhosted.git mem0-mcp-selfhosted

Todos los valores predeterminados funcionan de inmediato: Qdrant en localhost:6333, embeddings de Ollama en localhost:11434 con bge-m3 (1024 dimensiones). Anula cualquier valor predeterminado mediante --env (consulta Configuración).

uvx descarga, instala y ejecuta automáticamente el servidor en un entorno aislado, sin necesidad de instalación manual. Claude Code lo inicia bajo demanda cuando comienza la conexión MCP.

El servidor lee automáticamente tu token OAT desde ~/.claude/.credentials.json, sin necesidad de configuración manual de token.

Totalmente Local (Ollama)

Para una configuración totalmente local sin dependencias en la nube, usa Ollama tanto para el LLM principal como para los embeddings:

claude mcp add --scope user --transport stdio mem0 \
  --env MEM0_PROVIDER=ollama \
  --env MEM0_LLM_MODEL=qwen3:14b \
  --env MEM0_USER_ID=your-user-id \
  -- uvx --from git+https://github.com/elvismdev/mem0-mcp-selfhosted.git mem0-mcp-selfhosted

MEM0_PROVIDER=ollama se propaga tanto al LLM principal como a los proveedores de LLM de grafo. Se aplican los mismos valores predeterminados de infraestructura (Qdrant en localhost:6333, embeddings de bge-m3). Las anulaciones por servicio (p. ej., MEM0_LLM_URL, MEM0_EMBED_URL) siguen funcionando cuando se necesitan.

O agrégalo a un solo proyecto creando .mcp.json en la raíz del proyecto:

{
  "mcpServers": {
    "mem0": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/elvismdev/mem0-mcp-selfhosted.git", "mem0-mcp-selfhosted"],
      "env": {
        "MEM0_PROVIDER": "ollama",
        "MEM0_LLM_MODEL": "qwen3:14b",
        "MEM0_USER_ID": "your-user-id"
      }
    }
  }
}

Pruébalo

Reinicia Claude Code y luego:

> Search my memories for TypeScript preferences
> Remember that I prefer Hatch for Python packaging
> Show me all entities in my knowledge graph

Integración con CLAUDE.md

Agrega estas reglas al CLAUDE.md de tu proyecto (o ~/.claude/CLAUDE.md para uso global) para que Claude Code use proactivamente las herramientas de memoria durante toda la sesión:

# MCP Servers

- **mem0**: Persistent memory across sessions. At the start of each session, `search_memories` for relevant context before asking the user to re-explain anything. Use `add_memory` whenever you discover project architecture, coding conventions, debugging insights, key decisions, or user preferences. Use `update_memory` when prior context changes. Save information like: "This project uses PostgreSQL with Prisma", "Tests run with pytest -v", "Auth uses JWT validated in middleware". When in doubt, save it, future sessions benefit from over-remembering.

Esto le da a Claude Code instrucciones de comportamiento para buscar y guardar memorias activamente durante la sesión. Para mejores resultados, combínalo con Claude Code Hooks: las reglas de CLAUDE.md le indican a Claude cómo usar las herramientas de memoria a mitad de sesión, mientras que los hooks manejan la inyección y el guardado automáticos en los límites de la sesión.

Claude Code Hooks

Los hooks de sesión automatizan la memoria en los límites de la sesión, inyectando memorias al inicio y guardando resúmenes al salir. Esto ocurre automáticamente sin llamadas manuales a herramientas.

HookEventoQué hace
mem0-hook-contextSessionStart (startup, compact)Busca en mem0 memorias relevantes al proyecto y las inyecta como additionalContext
mem0-hook-stopStopLee los últimos ~3 intercambios usuario/asistente de la transcripción y guarda un resumen en mem0 mediante infer=True

Ambos hooks no son fatales; si mem0 no está disponible o ocurre cualquier error, Claude Code continúa normalmente.

Instalación

Instala los hooks en tu proyecto:

mem0-install-hooks

O instala globalmente (todos los proyectos):

mem0-install-hooks --global

Esto agrega las entradas de hook a .claude/settings.json. El instalador es idempotente; ejecutarlo dos veces no crea duplicados.

Cómo funciona

Al iniciar la sesión, el hook de contexto busca en mem0 con dos consultas (arquitectura del proyecto + resúmenes de sesiones recientes), deduplica por ID de memoria y formatea los resultados como líneas numeradas bajo un encabezado # mem0 Cross-Session Memory. Se inyectan mediante el campo de respuesta additionalContext del hook.

Al detener la sesión, el hook de detención lee la transcripción JSONL, extrae los últimos 6 mensajes usuario/asistente (una ventana deslizante mediante deque acotado), construye un prompt de resumen y llama a memory.add(infer=True) para extraer hechos atómicos. El grafo está deshabilitado por fuerza en los hooks para mantenerse dentro de los presupuestos de tiempo de 15s/30s.

Puntos de entrada

ComandoFunciónRegistrado en pyproject.toml
mem0-hook-contexthooks:context_mainHook SessionStart
mem0-hook-stophooks:stop_mainHook Stop
mem0-install-hookshooks:install_mainInstalador CLI

Hooks + CLAUDE.md

Los hooks y CLAUDE.md son capas complementarias que funcionan mejor juntos:

CapaRolCuándo
HooksFlujo de datos automatizado, inyecta memorias almacenadas al inicio, guarda resúmenes de sesión al salirLímites de sesión (inicio/detención)
CLAUDE.mdInstrucciones de comportamiento, le indica a Claude buscar y guardar memorias activamente durante la sesiónDurante toda la sesión

Solo los hooks te dan recuperación pasiva (las memorias aparecen al inicio) y guardado pasivo (los resúmenes se guardan al salir). Las instrucciones de CLAUDE.md agregan comportamiento activo a mitad de sesión: Claude busca memorias relevantes al encontrar nuevos temas y guarda descubrimientos importantes de inmediato en lugar de esperar al final de la sesión.

Para la mejor experiencia, usa ambos. Los hooks aseguran que las memorias fluyan automáticamente en los límites de la sesión, mientras que CLAUDE.md asegura que Claude interactúe activamente con las herramientas de memoria durante la sesión.

Autenticación

El servidor resuelve un token de Anthropic usando una cadena de respaldo priorizada:

PrioridadFuenteDetalles
1Variable de entorno MEM0_ANTHROPIC_TOKENExplícita, controlada por el usuario
2~/.claude/.credentials.jsonLee automáticamente el token OAT de Claude Code (configuración cero)
3Variable de entorno ANTHROPIC_API_KEYClave API estándar de pago por uso
4DeshabilitadoAdvierte y deshabilita las funciones LLM de Anthropic

En Claude Code, la prioridad 2 siempre gana: el archivo de credenciales existe mientras estés conectado. Esto significa que ANTHROPIC_API_KEY (prioridad 3) nunca se alcanza. Para anular el token OAT en Claude Code, usa MEM0_ANTHROPIC_TOKEN (prioridad 1). ANTHROPIC_API_KEY solo es útil para implementaciones fuera de Claude Code (Docker, CI, independiente).

Tokens OAT (sk-ant-oat...) usan tu suscripción de Claude. El servidor detecta automáticamente el tipo de token y configura el SDK en consecuencia. Los tokens OAT se renuevan automáticamente antes de expirar: el servidor verifica proactivamente la vida útil del token y lo renueva mediante el endpoint OAuth de Anthropic cuando se acerca la expiración (predeterminado: 30 minutos). Ante fallos de autenticación, se activa una estrategia defensiva de 3 pasos: aprovechar el archivo de credenciales de Claude Code, auto-renovación mediante OAuth y esperar y reintentar, para que las sesiones de larga duración sobrevivan a la rotación de tokens sin problemas.

Claves API (sk-ant-api...) usan facturación estándar de pago por uso.

Herramientas

Herramientas de Memoria (9 principales)

HerramientaDescripción
add_memoryAlmacena texto o historial de conversación como memorias. Admite enable_graph, infer, metadata.
search_memoriesBúsqueda semántica con filters, threshold, rerank, enable_graph opcionales.
get_memoriesLista/filtra memorias (sin búsqueda). Admite limit y filtros de alcance.
get_memoryObtiene una sola memoria por UUID.
update_memoryReemplaza el texto de una memoria. Re-embediza y re-indexa en Qdrant.
delete_memoryElimina una sola memoria por UUID.
delete_all_memoriesElimina en masa todas las memorias en un alcance.
list_entitiesLista usuarios/agentes/ejecuciones con conteos de memoria. Usa la API Facet de Qdrant.
delete_entitiesElimina en cascada una entidad y todas sus memorias.

Herramientas de Grafo

HerramientaDescripción
search_graphBusca entidades de Neo4j por subcadena de nombre. Devuelve entidades + relaciones salientes.
get_entityObtiene todas las relaciones de una entidad (bidireccional: entrantes + salientes).

Prompt

El servidor registra un prompt MCP memory_assistant que proporciona a Claude una guía de inicio rápido para usar las herramientas de memoria de manera efectiva.

Parámetros

Todas las herramientas usan Annotated[type, Field(description=...)] de Pydantic para esquemas de parámetros autodocumentados. Patrones comunes:

  • user_id usa por defecto la variable de entorno MEM0_USER_ID cuando no se proporciona
  • enable_graph anula el MEM0_ENABLE_GRAPH predeterminado por llamada
  • filters admite operadores estructurados: {"key": {"eq": "value"}}, {"AND": [...]}
  • Todas las respuestas son cadenas JSON mediante json.dumps(result, ensure_ascii=False)

Configuración

Toda la configuración es mediante variables de entorno. Crea un archivo .env o establécela en tu configuración MCP.

Autenticación

VariablePredeterminadoDescripción
MEM0_ANTHROPIC_TOKEN--Token OAT o API de Anthropic (prioridad 1)
ANTHROPIC_API_KEY--Clave API estándar de Anthropic (prioridad 3)
MEM0_OAT_HEADERSautoEncabezados de identidad OAT: auto o none
MEM0_OAT_REFRESH_THRESHOLD_SECONDS1800Segundos antes de la expiración para activar la renovación proactiva del token OAT

LLM

VariablePredeterminadoDescripción
MEM0_PROVIDERanthropicProveedor de nivel superior (anthropic o ollama). Se propaga a MEM0_LLM_PROVIDER y MEM0_GRAPH_LLM_PROVIDER cuando no están establecidos. No afecta a MEM0_EMBED_PROVIDER.
MEM0_LLM_PROVIDER(MEM0_PROVIDER)Proveedor LLM principal: anthropic o ollama. Hereda de MEM0_PROVIDER cuando no está establecido.
MEM0_OLLAMA_URLhttp://localhost:11434URL base compartida de Ollama. Se propaga a MEM0_LLM_URL, MEM0_EMBED_URL y MEM0_GRAPH_LLM_URL cuando no están establecidos.
MEM0_LLM_MODEL(por proveedor)Modelo para el proveedor LLM seleccionado. Usa por defecto claude-opus-4-6 para Anthropic, qwen3:14b para Ollama
MEM0_LLM_URL(se propaga)URL base de Ollama para el LLM principal. Propagación: MEM0_LLM_URL → MEM0_OLLAMA_URL → http://localhost:11434. Solo se usa cuando MEM0_LLM_PROVIDER=ollama
MEM0_LLM_MAX_TOKENS16384Máximo de tokens para respuestas LLM (solo Anthropic)
MEM0_GRAPH_LLM_PROVIDER(MEM0_PROVIDER)Proveedor LLM de grafo (anthropic, anthropic_oat, ollama, gemini, gemini_split). Hereda de MEM0_PROVIDER cuando no está establecido.
MEM0_GRAPH_LLM_URL(se propaga)URL base de Ollama para LLM de grafo. Propagación: MEM0_GRAPH_LLM_URL → MEM0_LLM_URL → MEM0_OLLAMA_URL → http://localhost:11434
MEM0_GRAPH_LLM_MODEL(varía)Modelo de grafo. Hereda MEM0_LLM_MODEL para anthropic/ollama; usa por defecto gemini-2.5-flash-lite para gemini/gemini_split
GOOGLE_API_KEY--Clave API de Google (requerida para los proveedores de grafo gemini/gemini_split)
MEM0_GRAPH_CONTRADICTION_LLM_PROVIDERanthropicProveedor LLM de contradicción en modo gemini_split (anthropic, anthropic_oat, ollama)
MEM0_GRAPH_CONTRADICTION_LLM_MODEL(según proveedor)Modelo de contradicción en modo gemini_split. Usa por defecto claude-opus-4-6 para proveedores anthropic/anthropic_oat; hereda MEM0_LLM_MODEL para otros.
MEM0_OLLAMA_KEEP_ALIVE30mCuánto tiempo mantiene Ollama el modelo en VRAM entre llamadas (p. ej., 1h, 5m). Evita la descarga del modelo durante pipelines de grafo de múltiples llamadas
MEM0_OLLAMA_THINKfalseEstablecer en true para re-habilitar el modo de pensamiento qwen3 (deshabilitado por defecto para prevenir la colisión <think> + format:"json")

Embedder

VariablePor defectoDescripción
MEM0_EMBED_PROVIDERollamaProveedor de embeddings (ollama o openai)
MEM0_EMBED_MODELbge-m3Nombre del modelo de embeddings
MEM0_EMBED_URL(en cascada)URL de Ollama para embeddings. En cascada: MEM0_EMBED_URL → MEM0_OLLAMA_URL → http://localhost:11434
MEM0_EMBED_DIMS1024Dimensiones del vector de embeddings

Almacén de vectores (Qdrant)

VariablePor defectoDescripción
MEM0_QDRANT_URLhttp://localhost:6333URL de la API REST de Qdrant
MEM0_QDRANT_API_KEY--Clave de API de Qdrant (para Qdrant Cloud)
MEM0_QDRANT_ON_DISKfalseAlmacenar vectores en disco (reduce RAM, búsqueda más lenta)
MEM0_QDRANT_TIMEOUT(predeterminado del cliente)Tiempo de espera de la API REST de Qdrant en segundos (p. ej., 30). Solo configúralo si encuentras ReadTimeout durante operaciones de colección
MEM0_COLLECTIONmem0_mcp_selfhostedNombre de la colección de Qdrant

Almacén de grafos (Neo4j)

VariablePor defectoDescripción
MEM0_ENABLE_GRAPHfalseHabilitar memoria de grafos (extracción de entidades a Neo4j)
MEM0_NEO4J_URLbolt://127.0.0.1:7687Endpoint Bolt de Neo4j
MEM0_NEO4J_USERneo4jUsuario de Neo4j
MEM0_NEO4J_PASSWORDmem0graphContraseña de Neo4j
MEM0_NEO4J_DATABASE--Nombre de la base de datos de Neo4j (configuraciones multi-base de datos)
MEM0_NEO4J_BASE_LABEL--Etiqueta base personalizada de Neo4j para agrupar tipos de nodos
MEM0_GRAPH_THRESHOLD0.7Umbral de similitud de embeddings para coincidencia de nodos

Servidor

VariablePor defectoDescripción
MEM0_TRANSPORTstdioTransporte: stdio, sse o streamable-http
MEM0_HOST0.0.0.0Host para transportes SSE/HTTP
MEM0_PORT8081Puerto para transportes SSE/HTTP
MEM0_USER_IDuserID de usuario predeterminado para el alcance de memoria
MEM0_LOG_LEVELINFONivel de registro (DEBUG, INFO, WARNING, ERROR)
MEM0_HISTORY_DB_PATH--Ruta de SQLite para el historial de cambios de memoria

Arquitectura

Claude Code
  |
  ├── MCP stdio/SSE/streamable-http
  │     |
  │     ├── env.py               ← Centralized env var readers (whitespace-safe)
  │     ├── auth.py              ← Hybrid token fallback chain + OAT self-refresh
  │     ├── llm_anthropic.py     ← Custom Anthropic LLM provider (OAT + structured outputs)
  │     ├── llm_ollama.py        ← Custom Ollama LLM provider (restored tool-calling)
  │     ├── config.py            ← Env vars → MemoryConfig dict (provider + URL cascades)
  │     ├── helpers.py           ← Error wrapper, concurrency lock, safe bulk-delete, monkey-patches
  │     ├── graph_tools.py       ← Direct Neo4j Cypher queries (lazy driver)
  │     ├── llm_router.py        ← Split-model graph LLM router (gemini_split)
  │     ├── __init__.py          ← Telemetry suppression (before any mem0 import)
  │     └── server.py            ← FastMCP orchestrator (11 tools + prompt)
  │           |
  │           ├── mem0ai Memory class
  │           │     ├── Vector: LLM fact extraction → Ollama embed → Qdrant
  │           │     └── Graph: LLM entity extraction (tool calls) → Neo4j
  │           |
  │           └── Infrastructure
  │                 ├── Qdrant          ← Vector store
  │                 ├── Ollama          ← Embeddings
  │                 ├── Neo4j           ← Knowledge graph (optional)
  │                 └── Anthropic/Ollama ← Main LLM (configurable)
  |
  └── Session Hooks (subprocess, not MCP)
        |
        └── hooks.py             ← Cross-session memory (SessionStart + Stop hooks)
              ├── context_main()   → Injects memories as additionalContext on startup/compact
              ├── stop_main()      → Saves session summary to mem0 on exit
              └── install_main()   → CLI to patch .claude/settings.json

Memoria de grafos y cuota

La memoria de grafos está deshabilitada por defecto (MEM0_ENABLE_GRAPH=false) para proteger tu cuota de Claude. Cada add_memory con grafos habilitados genera 3 llamadas adicionales al LLM para extracción de entidades, generación de relaciones y resolución de conflictos.

Uso de Ollama para operaciones de grafos

Para eliminar el uso de la cuota de Claude en operaciones de grafos, usa un modelo local de Ollama:

MEM0_ENABLE_GRAPH=true
MEM0_GRAPH_LLM_PROVIDER=ollama
MEM0_GRAPH_LLM_MODEL=qwen3:14b

Qwen3:14b tiene un F1 de llamada a herramientas de 0.971 (casi igualando el 0.974 de GPT-4) y se ejecuta en ~7-8GB de VRAM con cuantización Q4_K_M.

Uso de Gemini para operaciones de grafos

El Gemini 2.5 Flash Lite de Google es la opción más económica para operaciones de grafos manteniendo una alta precisión en la extracción de entidades:

MEM0_ENABLE_GRAPH=true
MEM0_GRAPH_LLM_PROVIDER=gemini
MEM0_GRAPH_LLM_MODEL=gemini-2.5-flash-lite
GOOGLE_API_KEY=your-google-api-key

Uso de modelo dividido para mayor precisión

El proveedor gemini_split enruta las llamadas del pipeline de grafos a diferentes LLMs según la operación. La extracción de entidades (llamadas 1 y 2) va a Gemini por velocidad y costo; la detección de contradicciones (llamada 3) va a Claude por precisión.

MEM0_ENABLE_GRAPH=true
MEM0_GRAPH_LLM_PROVIDER=gemini_split
GOOGLE_API_KEY=your-google-api-key
MEM0_GRAPH_CONTRADICTION_LLM_PROVIDER=anthropic
MEM0_GRAPH_CONTRADICTION_LLM_MODEL=claude-opus-4-6

Resultados de benchmark en 248 casos de prueba: Gemini obtiene 85.4% en extracción de entidades (vs 79.1% de Claude), mientras que Claude obtiene 100% en detección de contradicciones (vs 80% de Gemini). El modelo dividido combina lo mejor de ambos.

Modos de transporte

ModoCaso de usoConfiguración
stdio (predeterminado)Integración con Claude CodeMEM0_TRANSPORT=stdio
sseClientes remotos heredadosMEM0_TRANSPORT=sse
streamable-httpClientes remotos modernosMEM0_TRANSPORT=streamable-http

Para despliegues remotos, MCP SDK >= 1.23.0 habilita la protección contra rebinding de DNS por defecto.

Desarrollo

# Install with dev dependencies
pip install -e ".[dev]"

# Run unit tests
python3 -m pytest tests/unit/ -v

# Run contract tests (validates mem0ai internal API assumptions)
python3 -m pytest tests/contract/ -v

# Run integration tests (requires live Qdrant + Neo4j + Ollama)
python3 -m pytest tests/integration/ -v

# Run all tests
python3 -m pytest tests/ -v

Estructura de pruebas

  • tests/unit/ -- Pruebas unitarias puras con dependencias simuladas (env, auth, config, matriz de configuración, concurrencia, protocolo MCP, helpers, hooks, proveedores de LLM, herramientas de grafos, enrutador de LLM, servidor)
  • tests/contract/ -- Valida suposiciones sobre los internals de mem0ai (invariante de detección de esquema, ruta de acceso vector_store.client, idempotencia de registro LlmFactory)
  • tests/integration/ -- Pruebas de infraestructura en vivo (ciclo de vida de memoria, operaciones de grafos, operaciones masivas, hooks) contra Qdrant + Neo4j + Ollama reales. Marcadas con @pytest.mark.integration.

Las pruebas de contrato detectan cambios incompatibles en las actualizaciones de mem0ai antes de que lleguen a producción.

Telemetría

Toda la telemetría de mem0ai está suprimida. os.environ["MEM0_TELEMETRY"] = "false" se establece al importar el paquete, antes de que se cargue cualquier módulo mem0. No se envían eventos de PostHog.

Licencia

MIT