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
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ço | Obrigatório | Finalidade |
|---|---|---|
| Qdrant | Sim | Armazenamento e busca de memória vetorial |
| Ollama | Sim | Geração de embeddings (bge-m3) e opcionalmente LLM local |
| Neo4j 5+ | Opcional | Grafo de conhecimento (relações entre entidades) |
| Chave da API Google | Opcional | Necessá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.
| Hook | Evento | O que faz |
|---|---|---|
mem0-hook-context | SessionStart (startup, compact) | Busca no mem0 memórias relevantes ao projeto e as injeta como additionalContext |
mem0-hook-stop | Stop | Lê 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
| Comando | Função | Registrado em pyproject.toml |
|---|---|---|
mem0-hook-context | hooks:context_main | Hook SessionStart |
mem0-hook-stop | hooks:stop_main | Hook Stop |
mem0-install-hooks | hooks:install_main | Instalador CLI |
Hooks + CLAUDE.md
Hooks e CLAUDE.md são camadas complementares que funcionam melhor juntas:
| Camada | Papel | Quando |
|---|---|---|
| Hooks | Fluxo de dados automatizado, injeta memórias armazenadas na inicialização, salva resumos de sessão na saída | Limites da sessão (início/parada) |
| CLAUDE.md | Instruções comportamentais, diz ao Claude para buscar e salvar memórias ativamente durante a sessão | Durante 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:
| Prioridade | Fonte | Detalhes |
|---|---|---|
| 1 | Variável de ambiente MEM0_ANTHROPIC_TOKEN | Explícita, controlada pelo usuário |
| 2 | ~/.claude/.credentials.json | Lê automaticamente o token OAT do Claude Code (zero configuração) |
| 3 | Variável de ambiente ANTHROPIC_API_KEY | Chave de API padrão paga por uso |
| 4 | Desabilitado | Avisa 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)
| Ferramenta | Descrição |
|---|---|
add_memory | Armazena texto ou histórico de conversa como memórias. Suporta enable_graph, infer, metadata. |
search_memories | Busca semântica com filters, threshold, rerank, enable_graph opcionais. |
get_memories | Lista/filtra memórias (sem busca). Suporta limit e filtros de escopo. |
get_memory | Busca uma única memória por UUID. |
update_memory | Substitui o texto de uma memória. Re-embedda e re-indexa no Qdrant. |
delete_memory | Exclui uma única memória por UUID. |
delete_all_memories | Exclusão em massa de todas as memórias em um escopo. |
list_entities | Lista usuários/agentes/execuções com contagens de memória. Usa a API Facet do Qdrant. |
delete_entities | Exclusão em cascata de uma entidade e todas as suas memórias. |
Ferramentas de Grafo
| Ferramenta | Descrição |
|---|---|
search_graph | Busca entidades Neo4j por substring de nome. Retorna entidades + relacionamentos de saída. |
get_entity | Obté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_idusa como padrão a variável de ambienteMEM0_USER_IDquando não fornecidaenable_graphsubstitui oMEM0_ENABLE_GRAPHpadrão por chamadafilterssuporta 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ável | Padrão | Descriçã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_HEADERS | auto | Cabeçalhos de identidade OAT: auto ou none |
MEM0_OAT_REFRESH_THRESHOLD_SECONDS | 1800 | Segundos antes da expiração para acionar a renovação proativa do token OAT |
LLM
| Variável | Padrão | Descrição |
|---|---|---|
MEM0_PROVIDER | anthropic | Provedor 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_URL | http://localhost:11434 | URL 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_TOKENS | 16384 | Má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_PROVIDER | anthropic | Provedor 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_ALIVE | 30m | Quanto 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_THINK | false | Defina como true para reativar o modo de pensamento qwen3 (desabilitado por padrão para evitar colisão <think> + format:"json") |
Embedder
| Variável | Padrão | Descrição |
|---|---|---|
MEM0_EMBED_PROVIDER | ollama | Provedor de embeddings (ollama ou openai) |
MEM0_EMBED_MODEL | bge-m3 | Nome 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_DIMS | 1024 | Dimensões do vetor de embeddings |
Armazenamento de Vetores (Qdrant)
| Variável | Padrão | Descrição |
|---|---|---|
MEM0_QDRANT_URL | http://localhost:6333 | URL da API REST do Qdrant |
MEM0_QDRANT_API_KEY | -- | Chave da API do Qdrant (para Qdrant Cloud) |
MEM0_QDRANT_ON_DISK | false | Armazenar 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_COLLECTION | mem0_mcp_selfhosted | Nome da coleção do Qdrant |
Armazenamento de Grafos (Neo4j)
| Variável | Padrão | Descrição |
|---|---|---|
MEM0_ENABLE_GRAPH | false | Ativar memória de grafo (extração de entidades para Neo4j) |
MEM0_NEO4J_URL | bolt://127.0.0.1:7687 | Endpoint Bolt do Neo4j |
MEM0_NEO4J_USER | neo4j | Nome de usuário do Neo4j |
MEM0_NEO4J_PASSWORD | mem0graph | Senha 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_THRESHOLD | 0.7 | Limiar de similaridade de embeddings para correspondência de nós |
Servidor
| Variável | Padrão | Descrição |
|---|---|---|
MEM0_TRANSPORT | stdio | Transporte: stdio, sse ou streamable-http |
MEM0_HOST | 0.0.0.0 | Host para transportes SSE/HTTP |
MEM0_PORT | 8081 | Porta para transportes SSE/HTTP |
MEM0_USER_ID | user | ID de usuário padrão para escopo de memória |
MEM0_LOG_LEVEL | INFO | Ní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
| Modo | Caso de Uso | Configuração |
|---|---|---|
stdio (padrão) | Integração com Claude Code | MEM0_TRANSPORT=stdio |
sse | Clientes remotos legados | MEM0_TRANSPORT=sse |
streamable-http | Clientes remotos modernos | MEM0_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 acessovector_store.client, idempotência de registroLlmFactory)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