mem0-mcp-selfhosted

Servidor MCP mem0 auto-hospedado para Claude Code. Execute um servidor de memória completo contra Qdrant + Neo4j + Ollama auto-hospedados enquanto usa o Claude como LLM principal.

Documentação

mem0-mcp-selfhosted

mem0-mcp-selfhosted MCP server

Servidor MCP mem0 auto-hospedado para Claude Code. Execute um servidor de memória completo contra Qdrant + Neo4j + Ollama auto-hospedados, com sua escolha de Anthropic (Claude) ou Ollama como LLM principal.

Usa o pacote mem0ai diretamente como biblioteca, suporta tanto o token OAT do Claude quanto configurações totalmente locais com Ollama, e expõe 11 ferramentas MCP para gerenciamento completo de memória.

Pré-requisitos

ServiçoObrigatórioFinalidade
QdrantSimArmazenamento e busca de memória vetorial
OllamaSimGeração de embeddings (bge-m3) e opcionalmente LLM local
Neo4j 5+OpcionalGrafo de conhecimento (relações entre entidades)
Chave da API GoogleOpcionalNecessária apenas para provedores de grafo gemini/gemini_split

Python >= 3.10 e uv.

Autenticação: A configuração padrão usa Claude (Anthropic) como LLM para extração de fatos. Nenhuma chave de API é necessária, o servidor usa automaticamente o token da sua sessão do Claude Code. Para configurações totalmente locais, defina MEM0_PROVIDER=ollama. Consulte Autenticação para opções avançadas.

Início Rápido

Padrão (Anthropic)

Adicione o servidor MCP globalmente (disponível em todos os projetos):

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 os padrões funcionam imediatamente: Qdrant em localhost:6333, embeddings Ollama em localhost:11434 com bge-m3 (1024 dimensões). Substitua qualquer padrão via --env (consulte Configuração).

uvx baixa, instala e executa automaticamente o servidor em um ambiente isolado, sem necessidade de instalação manual. O Claude Code o inicia sob demanda quando a conexão MCP começa.

O servidor lê automaticamente seu token OAT de ~/.claude/.credentials.json, sem necessidade de configuração manual de token.

Totalmente Local (Ollama)

Para uma configuração totalmente local sem dependências de nuvem, use Ollama tanto para o LLM principal quanto para 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 propaga para ambos os provedores de LLM principal e de grafo. Os mesmos padrões de infraestrutura se aplicam (Qdrant em localhost:6333, embeddings bge-m3). Substituições por serviço (ex.: MEM0_LLM_URL, MEM0_EMBED_URL) ainda funcionam quando necessário.

Ou adicione-o a um único projeto criando .mcp.json na raiz do projeto:

{
  "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"
      }
    }
  }
}

Experimente

Reinicie o Claude Code e então:

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

Integração com CLAUDE.md

Adicione estas regras ao CLAUDE.md do seu projeto (ou ~/.claude/CLAUDE.md para uso global) para que o Claude Code use proativamente as ferramentas de memória durante toda a sessão:

# 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.

Isso dá ao Claude Code instruções comportamentais para buscar e salvar memórias ativamente durante a sessão. Para melhores resultados, combine com Claude Code Hooks: as regras do CLAUDE.md dizem ao Claude como usar as ferramentas de memória no meio da sessão, enquanto os hooks lidam com a injeção e salvamento automáticos nos limites da sessão.

Claude Code Hooks

Hooks de sessão automatizam a memória nos limites da sessão, injetando memórias na inicialização e salvando resumos na saída. Isso acontece automaticamente sem chamadas manuais de ferramentas.

HookEventoO que faz
mem0-hook-contextSessionStart (startup, compact)Busca no mem0 memórias relevantes ao projeto e as injeta como additionalContext
mem0-hook-stopStopLê as últimas ~3 trocas de usuário/assistente da transcrição e salva um resumo no mem0 via infer=True

Ambos os hooks não são fatais; se o mem0 estiver inacessível ou ocorrer qualquer erro, o Claude Code continua normalmente.

Instalação

Instale os hooks no seu projeto:

mem0-install-hooks

Ou instale globalmente (todos os projetos):

mem0-install-hooks --global

Isso adiciona as entradas de hook ao .claude/settings.json. O instalador é idempotente; executá-lo duas vezes não criará duplicatas.

Como funciona

Na inicialização da sessão, o hook de contexto busca no mem0 com duas consultas (arquitetura do projeto + resumos recentes de sessão), deduplica por ID de memória e formata os resultados como linhas numeradas sob um cabeçalho # mem0 Cross-Session Memory. Eles são injetados via o campo de resposta additionalContext do hook.

Na parada da sessão, o hook de parada lê a transcrição JSONL, extrai as últimas 6 mensagens de usuário/assistente (uma janela deslizante via deque limitado), constrói um prompt de resumo e chama memory.add(infer=True) para extrair fatos atômicos. O grafo é forçadamente desabilitado nos hooks para permanecer dentro dos orçamentos de tempo limite de 15s/30s.

Pontos de entrada

ComandoFunçãoRegistrado em pyproject.toml
mem0-hook-contexthooks:context_mainHook SessionStart
mem0-hook-stophooks:stop_mainHook Stop
mem0-install-hookshooks:install_mainInstalador CLI

Hooks + CLAUDE.md

Hooks e CLAUDE.md são camadas complementares que funcionam melhor juntas:

CamadaPapelQuando
HooksFluxo de dados automatizado, injeta memórias armazenadas na inicialização, salva resumos de sessão na saídaLimites da sessão (início/parada)
CLAUDE.mdInstruções comportamentais, diz ao Claude para buscar e salvar memórias ativamente durante a sessãoDurante toda a sessão

Somente hooks dão a você recordação passiva (memórias aparecem na inicialização) e salvamento passivo (resumos salvos na saída). As instruções do CLAUDE.md adicionam comportamento ativo no meio da sessão: o Claude busca memórias relevantes ao encontrar novos tópicos e salva descobertas importantes imediatamente, em vez de esperar o fim da sessão.

Para a melhor experiência, use ambos. Os hooks garantem que as memórias fluam para dentro e para fora automaticamente nos limites da sessão, enquanto o CLAUDE.md garante que o Claude se envolva ativamente com as ferramentas de memória durante a sessão.

Autenticação

O servidor resolve um token Anthropic usando uma cadeia de fallback priorizada:

PrioridadeFonteDetalhes
1Variável de ambiente MEM0_ANTHROPIC_TOKENExplícita, controlada pelo usuário
2~/.claude/.credentials.jsonLê automaticamente o token OAT do Claude Code (zero configuração)
3Variável de ambiente ANTHROPIC_API_KEYChave de API padrão paga por uso
4DesabilitadoAvisa e desabilita os recursos LLM da Anthropic

No Claude Code, a prioridade 2 sempre vence, o arquivo de credenciais existe enquanto você estiver conectado. Isso significa que ANTHROPIC_API_KEY (prioridade 3) nunca é alcançada. Para substituir o token OAT no Claude Code, use MEM0_ANTHROPIC_TOKEN (prioridade 1). ANTHROPIC_API_KEY só é útil para implantações fora do Claude Code (Docker, CI, standalone).

Tokens OAT (sk-ant-oat...) usam sua assinatura do Claude. O servidor detecta automaticamente o tipo de token e configura o SDK de acordo. Tokens OAT são renovados automaticamente antes da expiração: o servidor verifica proativamente o tempo de vida do token e renova via o endpoint OAuth da Anthropic quando se aproxima da expiração (padrão: 30 minutos). Em falhas de autenticação, uma estratégia defensiva de 3 etapas entra em ação, aproveitando o arquivo de credenciais do Claude Code, auto-renovação via OAuth e espera-e-tenta, para que sessões longas sobrevivam à rotação de tokens sem interrupção.

Chaves de API (sk-ant-api...) usam cobrança padrão paga por uso.

Ferramentas

Ferramentas de Memória (9 principais)

FerramentaDescrição
add_memoryArmazena texto ou histórico de conversa como memórias. Suporta enable_graph, infer, metadata.
search_memoriesBusca semântica com filters, threshold, rerank, enable_graph opcionais.
get_memoriesLista/filtra memórias (sem busca). Suporta limit e filtros de escopo.
get_memoryBusca uma única memória por UUID.
update_memorySubstitui o texto de uma memória. Re-embedda e re-indexa no Qdrant.
delete_memoryExclui uma única memória por UUID.
delete_all_memoriesExclusão em massa de todas as memórias em um escopo.
list_entitiesLista usuários/agentes/execuções com contagens de memória. Usa a API Facet do Qdrant.
delete_entitiesExclusão em cascata de uma entidade e todas as suas memórias.

Ferramentas de Grafo

FerramentaDescrição
search_graphBusca entidades Neo4j por substring de nome. Retorna entidades + relacionamentos de saída.
get_entityObtém todos os relacionamentos de uma entidade (bidirecional: entrada + saída).

Prompt

O servidor registra um prompt MCP memory_assistant que fornece ao Claude um guia de início rápido para usar as ferramentas de memória de forma eficaz.

Parâmetros

Todas as ferramentas usam Annotated[type, Field(description=...)] Pydantic para esquemas de parâmetros autodocumentados. Padrões comuns:

  • user_id usa como padrão a variável de ambiente MEM0_USER_ID quando não fornecida
  • enable_graph substitui o MEM0_ENABLE_GRAPH padrão por chamada
  • filters suporta operadores estruturados: {"key": {"eq": "value"}}, {"AND": [...]}
  • Todas as respostas são strings JSON via json.dumps(result, ensure_ascii=False)

Configuração

Toda a configuração é feita via variáveis de ambiente. Crie um arquivo .env ou defina-as na sua configuração MCP.

Autenticação

VariávelPadrãoDescrição
MEM0_ANTHROPIC_TOKEN--Token OAT ou API da Anthropic (prioridade 1)
ANTHROPIC_API_KEY--Chave de API padrão da Anthropic (prioridade 3)
MEM0_OAT_HEADERSautoCabeçalhos de identidade OAT: auto ou none
MEM0_OAT_REFRESH_THRESHOLD_SECONDS1800Segundos antes da expiração para acionar a renovação proativa do token OAT

LLM

VariávelPadrãoDescrição
MEM0_PROVIDERanthropicProvedor de nível superior (anthropic ou ollama). Propaga para MEM0_LLM_PROVIDER e MEM0_GRAPH_LLM_PROVIDER quando não definidos. Não afeta MEM0_EMBED_PROVIDER.
MEM0_LLM_PROVIDER(MEM0_PROVIDER)Provedor LLM principal: anthropic ou ollama. Herda de MEM0_PROVIDER quando não definido.
MEM0_OLLAMA_URLhttp://localhost:11434URL base compartilhada do Ollama. Propaga para MEM0_LLM_URL, MEM0_EMBED_URL e MEM0_GRAPH_LLM_URL quando não definidos.
MEM0_LLM_MODEL(por provedor)Modelo para o provedor LLM selecionado. Usa como padrão claude-opus-4-6 para Anthropic, qwen3:14b para Ollama
MEM0_LLM_URL(propaga)URL base do Ollama para o LLM principal. Propagação: MEM0_LLM_URL → MEM0_OLLAMA_URL → http://localhost:11434. Usado apenas quando MEM0_LLM_PROVIDER=ollama
MEM0_LLM_MAX_TOKENS16384Máximo de tokens para respostas do LLM (somente Anthropic)
MEM0_GRAPH_LLM_PROVIDER(MEM0_PROVIDER)Provedor LLM de grafo (anthropic, anthropic_oat, ollama, gemini, gemini_split). Herda de MEM0_PROVIDER quando não definido.
MEM0_GRAPH_LLM_URL(propaga)URL base do Ollama para LLM de grafo. Propagação: MEM0_GRAPH_LLM_URL → MEM0_LLM_URL → MEM0_OLLAMA_URL → http://localhost:11434
MEM0_GRAPH_LLM_MODEL(varia)Modelo de grafo. Herda MEM0_LLM_MODEL para anthropic/ollama; usa como padrão gemini-2.5-flash-lite para gemini/gemini_split
GOOGLE_API_KEY--Chave da API Google (necessária para provedores de grafo gemini/gemini_split)
MEM0_GRAPH_CONTRADICTION_LLM_PROVIDERanthropicProvedor LLM de contradição no modo gemini_split (anthropic, anthropic_oat, ollama)
MEM0_GRAPH_CONTRADICTION_LLM_MODEL(ciente do provedor)Modelo de contradição no modo gemini_split. Usa como padrão claude-opus-4-6 para provedores anthropic/anthropic_oat; herda MEM0_LLM_MODEL para outros.
MEM0_OLLAMA_KEEP_ALIVE30mQuanto tempo o Ollama mantém o modelo na VRAM entre chamadas (ex.: 1h, 5m). Evita o descarregamento do modelo durante pipelines de grafo com múltiplas chamadas
MEM0_OLLAMA_THINKfalseDefina como true para reativar o modo de pensamento qwen3 (desabilitado por padrão para evitar colisão <think> + format:"json")

Embedder

VariávelPadrãoDescrição
MEM0_EMBED_PROVIDERollamaProvedor de embeddings (ollama ou openai)
MEM0_EMBED_MODELbge-m3Nome do modelo de embeddings
MEM0_EMBED_URL(em cascata)URL do Ollama para embeddings. Em cascata: MEM0_EMBED_URL → MEM0_OLLAMA_URL → http://localhost:11434
MEM0_EMBED_DIMS1024Dimensões do vetor de embeddings

Armazenamento de Vetores (Qdrant)

VariávelPadrãoDescrição
MEM0_QDRANT_URLhttp://localhost:6333URL da API REST do Qdrant
MEM0_QDRANT_API_KEY--Chave da API do Qdrant (para Qdrant Cloud)
MEM0_QDRANT_ON_DISKfalseArmazenar vetores em disco (reduz RAM, busca mais lenta)
MEM0_QDRANT_TIMEOUT(padrão do cliente)Tempo limite da API REST do Qdrant em segundos (ex.: 30). Defina apenas se encontrar ReadTimeout durante operações de coleção
MEM0_COLLECTIONmem0_mcp_selfhostedNome da coleção do Qdrant

Armazenamento de Grafos (Neo4j)

VariávelPadrãoDescrição
MEM0_ENABLE_GRAPHfalseAtivar memória de grafo (extração de entidades para Neo4j)
MEM0_NEO4J_URLbolt://127.0.0.1:7687Endpoint Bolt do Neo4j
MEM0_NEO4J_USERneo4jNome de usuário do Neo4j
MEM0_NEO4J_PASSWORDmem0graphSenha do Neo4j
MEM0_NEO4J_DATABASE--Nome do banco de dados Neo4j (configurações com múltiplos bancos)
MEM0_NEO4J_BASE_LABEL--Rótulo base personalizado do Neo4j para agrupamento por tipo de nó
MEM0_GRAPH_THRESHOLD0.7Limiar de similaridade de embeddings para correspondência de nós

Servidor

VariávelPadrãoDescrição
MEM0_TRANSPORTstdioTransporte: stdio, sse ou streamable-http
MEM0_HOST0.0.0.0Host para transportes SSE/HTTP
MEM0_PORT8081Porta para transportes SSE/HTTP
MEM0_USER_IDuserID de usuário padrão para escopo de memória
MEM0_LOG_LEVELINFONível de registro (DEBUG, INFO, WARNING, ERROR)
MEM0_HISTORY_DB_PATH--Caminho do SQLite para histórico de alterações de memória

Arquitetura

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

Memória de Grafo e Cota

A memória de grafo está desativada por padrão (MEM0_ENABLE_GRAPH=false) para proteger sua cota do Claude. Cada add_memory com grafo ativado aciona 3 chamadas adicionais de LLM para extração de entidades, geração de relacionamentos e resolução de conflitos.

Usando Ollama para Operações de Grafo

Para eliminar o uso da cota do Claude em operações de grafo, use um modelo Ollama local:

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

Qwen3:14b tem F1 de chamada de ferramentas de 0,971 (quase igualando o 0,974 do GPT-4) e roda em ~7-8GB de VRAM com quantização Q4_K_M.

Usando Gemini para Operações de Grafo

O Gemini 2.5 Flash Lite do Google é a opção mais barata para operações de grafo, mantendo forte precisão na extração 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

Usando Modelo Dividido para Melhor Precisão

O provedor gemini_split roteia chamadas do pipeline de grafo para diferentes LLMs com base na operação. A extração de entidades (Chamadas 1 e 2) vai para o Gemini por velocidade e custo; a detecção de contradições (Chamada 3) vai para o Claude por precisão.

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 em 248 casos de teste: Gemini pontua 85,4% na extração de entidades (vs. 79,1% do Claude), enquanto Claude pontua 100% na detecção de contradições (vs. 80% do Gemini). O modelo dividido combina o melhor de ambos.

Modos de Transporte

ModoCaso de UsoConfiguração
stdio (padrão)Integração com Claude CodeMEM0_TRANSPORT=stdio
sseClientes remotos legadosMEM0_TRANSPORT=sse
streamable-httpClientes remotos modernosMEM0_TRANSPORT=streamable-http

Para implantações remotas, MCP SDK >= 1.23.0 ativa a proteção contra rebinding de DNS por padrão.

Desenvolvimento

# 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

Estrutura de Testes

  • tests/unit/ -- Testes unitários puros com dependências simuladas (env, auth, config, matriz de configuração, concorrência, protocolo MCP, helpers, hooks, provedores de LLM, ferramentas de grafo, roteador de LLM, servidor)
  • tests/contract/ -- Valida suposições sobre os internos do mem0ai (invariante de detecção de esquema, caminho de acesso vector_store.client, idempotência de registro LlmFactory)
  • tests/integration/ -- Testes de infraestrutura ao vivo (ciclo de vida de memória, operações de grafo, operações em lote, hooks) contra Qdrant + Neo4j + Ollama reais. Marcados com @pytest.mark.integration.

Testes de contrato detectam mudanças que quebram compatibilidade em atualizações de mem0ai antes de chegarem à produção.

Telemetria

Toda telemetria do mem0ai é suprimida. os.environ["MEM0_TELEMETRY"] = "false" é definido no momento da importação do pacote, antes de qualquer módulo mem0 ser carregado. Nenhum evento PostHog é enviado.

Licença

MIT