Post

Stack Claude Code + Octopus + Obsidian + Qdrant: o cerebro externo definitivo para dev

Como montei uma stack pessoal com Claude Code, Octopus (multi-LLM), mem0 (memoria semantica), Qdrant (busca vetorial) e Obsidian como cerebro externo para desenvolvimento

Stack Claude Code + Octopus + Obsidian + Qdrant: o cerebro externo definitivo para dev

Imagina pedir ao Claude Code: “procure no vault sobre autenticacao JWT” e ele encontrar automaticamente as notas mais relevantes do seu Obsidian — mesmo que nenhuma delas tenha exatamente essas palavras no titulo.

Ou pedir “/octo:debate monorepo vs microservices” e 4 agentes de LLMs diferentes debaterem, com gate de 75% de consenso antes de qualquer output chegar a producao.

Ou simplesmente abrir uma sessao nova e o Claude ja saber suas preferencias, decisoes passadas, e contexto do projeto — sem voce reexplicar nada.

Esse artigo documenta a stack completa que uso no dia a dia. Nao e teoria — roda em producao, todo dia, nos meus projetos reais.

Arquitetura completa

flowchart TD
    U["Voce (input)"] --> CC["Claude Code (Terminal)"]
    CC --> OCTO["Octopus (Smart Router)"]
    OCTO --> CODEX["Codex"]
    OCTO --> GEMINI["Gemini"]
    OCTO --> COPILOT["Copilot"]
    OCTO --> QWEN["Qwen"]
    OCTO --> OLLAMA["Ollama (local)"]
    CODEX --> GATE["Gate 75% consenso"]
    GEMINI --> GATE
    COPILOT --> GATE
    QWEN --> GATE
    OLLAMA --> GATE
    GATE --> MEM["Camada de Memoria"]
    MEM --> MEM0["mem0 + Qdrant\n(fatos/prefs automatico)"]
    MEM --> VAULT["Obsidian Vault\n(documentos/conhecimento)"]
    MEM --> QVAULT["Qdrant vault-memory\n(busca semantica 384 dims)"]
    MEM --> OUTPUT["Output (codigo/docs)"]

    style U fill:#7c3aed,color:#fff
    style OCTO fill:#f97316,color:#fff
    style GATE fill:#dc2626,color:#fff
    style MEM0 fill:#2563eb,color:#fff
    style QVAULT fill:#dc2626,color:#fff
    style VAULT fill:#8b5cf6,color:#fff

O que cada camada faz

Componente Funcao Automatico?
Claude Code CLI com acesso ao filesystem, git, terminal Sim
Octopus Orquestra multiplos LLMs, Double Diamond, 32 personas Sim
mem0 + Qdrant Memoria semantica de fatos e preferencias Sim
Obsidian MCP Leitura/escrita de documentos no vault Manual
Qdrant vault-memory Busca semantica em todos os .md do vault Indexacao diaria
CLAUDE.md Protocolos e regras carregados em toda sessao Sim

Por que esse stack funciona

Nenhum modelo tem pontos cegos

Todo LLM tem limitacoes — Codex e otimo em codigo mas fraco em pesquisa de seguranca. Gemini pesquisa bem mas gera codigo fragil. O Octopus resolve isso com um gate de 75% de consenso: se os modelos discordarem, o sistema trava antes de prosseguir. Nenhum output suspeito chega a producao.

Tres camadas de memoria que se complementam

1
2
3
mem0          -> "voce prefere TypeScript strict mode"     (fato, automatico)
Qdrant vault  -> "como implementei auth no demiurgo"       (semantico, indexado)
Obsidian      -> "arquitetura completa do demiurgo.md"     (documento, navegavel)

mem0 captura fatos automaticamente durante a conversa. O Qdrant indexa o vault inteiro para busca por significado. O Obsidian e a interface visual onde voce navega e conecta conhecimento com wikilinks.

Vault que cresce como conhecimento real

A cada sessao: features implementadas, tecnicas descobertas, bugs resolvidos, decisoes arquiteturais — tudo vira nota no vault. Em 6 meses voce tem uma base de conhecimento real sobre como voce trabalha.

Busca semantica, nao keyword

Com Qdrant indexando o vault, o Claude nao busca por nome de arquivo — busca por significado. “Como implementei rate limiting?” encontra os trechos certos mesmo que a nota se chame “backend-patterns.md”.

Providers gratuitos por padrao

  • Codex: incluido na assinatura OpenAI
  • Gemini: incluido na conta Google
  • Qwen: 1.000-2.000 requests/dia gratuitos
  • Copilot: incluido na assinatura GitHub
  • Ollama: 100% local, sem custo
  • Perplexity/OpenRouter: unicos que exigem API key paga

Instalacao completa do zero

Pre-requisitos

1
2
3
node --version     # >= 18
python3 --version  # >= 3.10
docker --version   # qualquer versao recente

Passo 1 — Claude Code

1
2
npm install -g @anthropic-ai/claude-code
claude login

Passo 2 — Octopus (multi-LLM)

1
2
claude plugin marketplace add https://github.com/nyldn/claude-octopus.git
claude plugin install octo@nyldn-plugins

Passo 3 — Providers do Octopus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Codex (OpenAI)
npm install -g openai-codex && codex login

# Gemini (Google)
npm install -g gemini-cli && gemini auth

# Qwen (gratuito, 1-2k req/dia)
npm install -g @qwen-code/qwen-code && qwen

# Copilot (GitHub)
npm install -g @github/copilot-cli && github-copilot-cli auth

# Ollama (100% local)
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull llama3.2

Depois, dentro do Claude Code:

1
/octo:setup

Detecta todos os providers instalados automaticamente.

Passo 4 — MCP do Obsidian

1
2
3
4
5
6
# IMPORTANTE: usar npm, nao pip. A versao pip tem bug com fastmcp.
npm install -g mcp-obsidian

# Testar
mcp-obsidian "/mnt/c/Users/SEU_USUARIO/Documents/brain/mymind"
# Deve mostrar: "MCP Obsidian Server running on stdio"

Passo 5 — Qdrant (Docker)

1
2
3
4
5
6
7
8
9
10
docker run -d \
  --name qdrant \
  -p 6333:6333 \
  -v qdrant_data:/qdrant/storage \
  --restart unless-stopped \
  qdrant/qdrant:latest

# Verificar
curl http://localhost:6333/health
# {"status":"ok"}

Passo 6 — FastEmbed (embeddings locais)

1
pip install fastembed qdrant-client --break-system-packages

Critico: FastEmbed precisa estar instalado globalmente (nao so via uv run), pois o MCP precisa importa-lo quando inicia. Sem isso, o MCP conecta mas retorna vazio silenciosamente.

Passo 7 — Criar colecao no Qdrant

Aqui esta o primeiro ponto critico. A colecao precisa usar named vectors, nao unnamed:

1
2
3
4
5
6
7
8
9
# ERRADO - unnamed vectors (nao funciona com o MCP)
curl -X PUT http://localhost:6333/collections/vault-memory \
  -H "Content-Type: application/json" \
  -d '{"vectors": {"size": 384, "distance": "Cosine"}}'

# CORRETO - named vectors
curl -X PUT http://localhost:6333/collections/vault-memory \
  -H "Content-Type: application/json" \
  -d '{"vectors": {"fast-all-minilm-l6-v2": {"size": 384, "distance": "Cosine"}}}'

O nome fast-all-minilm-l6-v2 nao e arbitrario — e exatamente o que o mcp-server-qdrant espera quando usa EMBEDDING_PROVIDER=fastembed. Internamente, ele chama get_vector_name() que retorna esse nome.

Passo 8 — mem0 MCP (memoria automatica)

1
2
3
4
5
6
7
claude mcp add --scope user --transport stdio mem0 \
  --env MEM0_QDRANT_URL=http://localhost:6333 \
  --env MEM0_EMBED_URL=http://localhost:11434 \
  --env MEM0_EMBED_MODEL=bge-m3 \
  --env MEM0_EMBED_DIMS=1024 \
  --env MEM0_USER_ID=seu-usuario \
  -- uvx --from git+https://github.com/elvismdev/mem0-mcp-selfhosted.git mem0-mcp-selfhosted

mem0 usa Ollama com bge-m3 (1024 dims) para sua propria colecao de memorias. Isso e separado do vault-memory que usa FastEmbed (384 dims). Sao colecoes diferentes no mesmo Qdrant.

Passo 9 — Qdrant MCP para busca semantica no vault

1
2
3
4
5
claude mcp add --scope user --transport stdio qdrant-vault \
  --env QDRANT_URL=http://127.0.0.1:6333 \
  --env COLLECTION_NAME=vault-memory \
  --env EMBEDDING_PROVIDER=fastembed \
  -- uvx mcp-server-qdrant

Porta 6333 direto, sem proxy. Se usar um proxy HTTP na frente (tipo porta 6334), o httpx envia Accept-Encoding: gzip e o proxy corrompe os headers. Resultado: zlib: incorrect header check.

Passo 10 — ~/.claude.json final

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
  "mcpServers": {
    "obsidian": {
      "command": "mcp-obsidian",
      "args": ["/mnt/c/Users/SEU_USUARIO/Documents/brain/mymind"]
    },
    "qdrant-vault": {
      "command": "uvx",
      "args": ["mcp-server-qdrant"],
      "env": {
        "QDRANT_URL": "http://127.0.0.1:6333",
        "COLLECTION_NAME": "vault-memory",
        "EMBEDDING_PROVIDER": "fastembed"
      }
    },
    "mem0": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/elvismdev/mem0-mcp-selfhosted.git",
        "mem0-mcp-selfhosted"
      ],
      "env": {
        "MEM0_QDRANT_URL": "http://localhost:6333",
        "MEM0_EMBED_URL": "http://localhost:11434",
        "MEM0_EMBED_MODEL": "bge-m3",
        "MEM0_EMBED_DIMS": "1024",
        "MEM0_USER_ID": "seu-usuario"
      }
    }
  }
}

Script de indexacao do vault

Crie ~/index-vault.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python3
"""Indexa vault Obsidian no Qdrant para busca semantica."""

import os
import hashlib
from pathlib import Path

from fastembed import TextEmbedding
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct

# Estes valores DEVEM coincidir com o MCP
VAULT_PATH   = "/mnt/c/Users/SEU_USUARIO/Documents/brain/mymind"
QDRANT_URL   = "http://localhost:6333"
COLLECTION   = "vault-memory"
EMBED_MODEL  = "sentence-transformers/all-MiniLM-L6-v2"
VECTOR_NAME  = "fast-all-minilm-l6-v2"
EMBED_DIM    = 384
CHUNK_SIZE   = 500

client = QdrantClient(url=QDRANT_URL)
engine = TextEmbedding(model=EMBED_MODEL)

def chunk_text(text, size=CHUNK_SIZE):
    paragraphs = text.split("\n\n")
    chunks, current = [], ""
    for p in paragraphs:
        if len(current) + len(p) > size and current:
            chunks.append(current.strip())
            current = p
        else:
            current += "\n\n" + p if current else p
    if current.strip():
        chunks.append(current.strip())
    return chunks

def file_to_id(path, chunk_idx):
    h = hashlib.md5(f"{path}:{chunk_idx}".encode()).hexdigest()
    return int(h[:15], 16)

def index_vault():
    vault = Path(VAULT_PATH)
    md_files = sorted(vault.rglob("*.md"))
    print(f"Indexando {len(md_files)} arquivo(s)...")

    points = []
    for f in md_files:
        rel_path = str(f.relative_to(vault))
        text = f.read_text(encoding="utf-8", errors="ignore")
        if len(text.strip()) < 50:
            continue

        chunks = chunk_text(text)
        embeddings = list(engine.embed(chunks))

        for i, (chunk, emb) in enumerate(zip(chunks, embeddings)):
            points.append(PointStruct(
                id=file_to_id(rel_path, i),
                vector={VECTOR_NAME: emb.tolist()},
                payload={
                    "document": chunk[:500],
                    "metadata": {"file": rel_path},
                },
            ))

    BATCH = 100
    for i in range(0, len(points), BATCH):
        client.upsert(collection_name=COLLECTION, points=points[i:i+BATCH])

    print(f"Indexados {len(points)} chunks de {len(md_files)} arquivos.")

if __name__ == "__main__":
    index_vault()
1
python3 ~/index-vault.py

Reindexacao automatica diaria:

1
(crontab -l 2>/dev/null; echo "0 0 * * * python3 ~/index-vault.py >> ~/vault-index.log 2>&1") | crontab -

Script de busca manual

Para testar sem o Claude Code, crie ~/search-vault.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env python3
"""Busca semantica no vault via Qdrant."""

import sys
from fastembed import TextEmbedding
from qdrant_client import QdrantClient

QDRANT_URL   = "http://localhost:6333"
COLLECTION   = "vault-memory"
EMBED_MODEL  = "sentence-transformers/all-MiniLM-L6-v2"
VECTOR_NAME  = "fast-all-minilm-l6-v2"

client = QdrantClient(url=QDRANT_URL)
engine = TextEmbedding(model=EMBED_MODEL)

def search(query, limit=5):
    embedding = list(engine.embed([query]))[0].tolist()
    results = client.query_points(
        collection_name=COLLECTION,
        query=embedding,
        using=VECTOR_NAME,
        limit=limit,
        with_payload=True,
    ).points

    for i, r in enumerate(results, 1):
        file_path = r.payload.get("metadata", {}).get("file", "N/A")
        content = r.payload.get("document", "N/A")
        print(f"\n[{i}] {file_path}  (score: {r.score:.3f})")
        print(f"    {content[:200].strip()}...")

if __name__ == "__main__":
    query = " ".join(sys.argv[1:]) or input("Query: ")
    search(query)
1
2
3
python3 ~/search-vault.py "autenticacao JWT"
# [1] projetos/demiurgo/features/auth.md  (score: 0.852)
#     Implementei JWT com refresh tokens...

Estrutura do vault Obsidian

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mymind/
├── memory/
│   ├── session.md              <- contexto da sessao atual
│   └── decisions.md            <- decisoes permanentes (nunca reprocessar)
├── projetos/
│   └── [nome-projeto]/
│       ├── overview.md         <- visao geral, stack, objetivos
│       ├── arquitetura.md      <- decisoes arquiteturais
│       ├── features/           <- uma nota por feature
│       └── bugs-resolvidos.md
├── conhecimento/
│   ├── tecnicas/               <- padroes reutilizaveis
│   ├── snippets/               <- codigo por linguagem
│   │   └── typescript/
│   ├── research/               <- outputs de /octo:research
│   └── licoes.md               <- licoes entre projetos
└── tasks/
    └── queue.md                <- backlog global

Regra de wikilinks: sempre conectar notas relacionadas. Feature usa tecnica: [[tecnicas/clean-architecture]] Tecnica aplicada em: [[projetos/demiurgo/features/auth]]


CLAUDE.md — o contexto que carrega em toda sessao

Crie ~/.claude/CLAUDE.md:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# Claude Code --- [Seu Nome]

## Vault Obsidian
**Path:** `/mnt/c/Users/SEU_USUARIO/Documents/brain/mymind`
**MCP:** `obsidian` (leitura/escrita) + `mem0` (memoria semantica) + `qdrant-vault` (busca semantica)

## Busca no Vault --- REGRA CRITICA
Quando pedir para "buscar", "procurar" ou "achar" algo "no vault",
SEMPRE usar `qdrant-vault` (ferramenta `qdrant-find`) PRIMEIRO.
Ordem: qdrant-vault -> mem0 -> leitura direta de arquivos.

## Protocolo de Inicio de Sessao
1. Buscar memorias relevantes via `search_memories`
2. Ler `memory/session.md`
3. Ler `memory/decisions.md`

## Protocolo de Encerramento
1. Atualizar `memory/session.md` com resumo e proximos passos
2. Persistir decisoes novas em `memory/decisions.md`
3. Salvar memorias via `add_memory`

## Construcao de Conhecimento
A cada sessao, o vault deve crescer.

| Tipo | Onde salvar |
|---|---|
| Feature implementada | `projetos/[projeto]/features/[nome].md` |
| Decisao arquitetural | `projetos/[projeto]/arquitetura.md` + `memory/decisions.md` |
| Tecnica descoberta | `conhecimento/tecnicas/[nome].md` |
| Snippet reutilizavel | `conhecimento/snippets/[linguagem]/[nome].md` |
| Research | `conhecimento/research/[tema].md` |
| Bug dificil resolvido | `projetos/[projeto]/bugs-resolvidos.md` |

## Orquestracao (Octopus)
- `/octo:auto` --- smart router
- `/octo:develop` --- codigo (Codex primario)
- `/octo:research` --- pesquisa -> salvar em conhecimento/research/
- `/octo:debate` --- decisoes -> salvar em projetos/[proj]/arquitetura.md
- `/octo:embrace` --- pipeline completo feature
- `/octo:factory` --- pipeline autonomo spec->output

## Preferencias
- TypeScript com strict mode
- Clean Architecture
- Dependency Injection

Comandos do Octopus

Comando O que faz
/octo:auto Smart router — entrada padrao para qualquer task
/octo:develop Implementacao de codigo (Codex primario)
/octo:research Pesquisa multi-fonte (Gemini + Perplexity)
/octo:debate Debate entre 4 agentes + consenso
/octo:embrace Pipeline completo: Discover -> Define -> Develop -> Deliver
/octo:factory Pipeline autonomo: spec -> software pronto
/octo:review Code review multi-agente
/octo:parallel Execucao paralela em worktrees git

Modos de autonomia do /octo:embrace:

  • supervised — aprova cada fase
  • semi-auto — intervem so em falhas
  • autonomous — roda tudo, voce revisa o output final

Os 3 tipos de memoria — quando usar cada um

1
2
3
4
5
6
7
8
9
SITUACAO                              DESTINO
---------------------------------------------------------------
Preferencia pessoal                 -> mem0 (automatico)
Decisao rapida de sessao            -> mem0 (automatico)
Feature implementada                -> vault projetos/
Tecnica ou padrao descoberto        -> vault conhecimento/
Research de tecnologia              -> vault conhecimento/research/
Decisao arquitetural critica        -> vault + memory/decisions.md
Bug dificil resolvido               -> vault bugs-resolvidos.md

Na maioria das sessoes voce nao escreve nada manualmente. O mem0 captura fatos automaticamente. O vault voce alimenta com o que quer ler depois no Obsidian.


Os 3 requisitos criticos do Qdrant + MCP

Depois de muito debugging, descobri que o mcp-server-qdrant com EMBEDDING_PROVIDER=fastembed tem 3 requisitos nao-obvios. Se qualquer um falhar, a busca quebra com erros genericos.

1. Named vectors (nao unnamed)

O MCP chama get_vector_name() que retorna fast-all-minilm-l6-v2. Se a colecao usar unnamed vectors:

1
Not existing vector name error: fast-all-minilm-l6-v2

2. Campo document no payload (nao text)

O MCP acessa result.payload["document"]. Se o script indexou com campo text:

1
KeyError: 'document'

3. Porta 6333 direta (sem proxy)

Se usar proxy na frente do Qdrant, o httpx envia Accept-Encoding: gzip e o proxy corrompe os headers:

1
Error -3 while decompressing data: incorrect header check

Tabela rapida de erros

Erro Causa Fix
zlib: incorrect header check Proxy corrompendo headers Usar porta 6333
Not existing vector name Colecao com unnamed vectors Recriar com named vectors
'document' (KeyError) Payload usa text Reindexar com campo document
expected 384, got 1024 Modelo errado Usar all-MiniLM-L6-v2
MCP conectado mas vazio FastEmbed nao instalado pip install fastembed --break-system-packages

Descobri isso lendo o codigo fonte do MCP:

1
2
# Instalado via uvx, o codigo fica em:
~/.cache/uv/archive-v0/.../mcp_server_qdrant/qdrant.py

Linhas relevantes:

  • vector_name = self._embedding_provider.get_vector_name() — retorna fast-all-minilm-l6-v2
  • vector={vector_name: embeddings[0]} — usa named vectors
  • content=result.payload["document"] — espera campo document

Reset completo (quando nada funciona)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. Verificar Qdrant
curl http://localhost:6333/health

# 2. Deletar e recriar colecao
curl -X DELETE http://localhost:6333/collections/vault-memory
curl -X PUT http://localhost:6333/collections/vault-memory \
  -H "Content-Type: application/json" \
  -d '{"vectors":{"fast-all-minilm-l6-v2":{"size":384,"distance":"Cosine"}}}'

# 3. Reindexar
python3 ~/index-vault.py

# 4. Reiniciar Claude Code
exit
claude

Por que FastEmbed para o vault e Ollama para mem0?

Sao colecoes diferentes com propositos diferentes:

  vault-memory (busca no vault) mem0 (memoria semantica)
Provider FastEmbed Ollama
Modelo all-MiniLM-L6-v2 bge-m3
Dimensoes 384 1024
Latencia ~10ms ~50-100ms
RAM ~60MB ~1.2GB
Por que Velocidade para busca em tempo real Precisao para fatos/preferencias

FastEmbed e ideal para o vault: rapido, leve, sem dependencia de servidor. mem0 usa bge-m3 via Ollama porque precisa de mais precisao para extrair e comparar fatos semanticos.

Comparando com alternativas pagas:

Criterio FastEmbed OpenAI Ollama bge-m3
Custo Gratuito $0.02/1M tokens Gratuito
Privacidade 100% local Dados vao para API 100% local
Dependencia pip install API key + rede Servidor rodando

Fluxo de trabalho diario

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Inicio --- Claude carrega tudo automaticamente
cd ~/meu-projeto
claude
# -> le CLAUDE.md global + local
# -> mem0 busca memorias relevantes
# -> carrega memory/session.md e decisions.md

# Pesquisa rapida
procure no vault sobre rate limiting
# -> qdrant-find retorna chunks relevantes

# Trabalho com multi-LLM
/octo:auto refatora o modulo de pagamento
# -> Octopus roteia, executa com consenso 75%
# -> mem0 salva decisoes automaticamente

# Research profundo
/octo:research "comparativo Redis vs Valkey 2026"
# -> Gemini + Perplexity pesquisam
# -> resultado salvo em conhecimento/research/

# Debate arquitetural
/octo:debate "monorepo vs polyrepo para microsservicos"
# -> 4 agentes debatem com argumentos
# -> gate de consenso antes do output

# Feature completa
/octo:embrace "implementar webhook de pagamento"
# -> Discover -> Define -> Develop -> Deliver
# -> com gates entre cada fase

# Resultado importante? Salva no vault
salve essa decisao em projetos/demiurgo/arquitetura.md

# Fim do dia
atualize memory/session.md com o que fizemos hoje

Verificacao do stack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 1. Qdrant rodando?
curl -s http://localhost:6333/health

# 2. Colecao com named vectors?
curl -s http://localhost:6333/collections/vault-memory | \
  python3 -c "import sys,json; v=json.load(sys.stdin)['result']['config']['params']['vectors']; print('Named vectors:', list(v.keys()))"

# 3. Ollama + bge-m3 (para mem0)?
ollama list | grep bge-m3

# 4. FastEmbed (para vault)?
python3 -c "from fastembed import TextEmbedding; print('FastEmbed OK')"

# 5. MCPs configurados?
python3 -c "
import json
with open('$HOME/.claude.json') as f:
    c = json.load(f)
print('MCPs:', list(c.get('mcpServers',{}).keys()))"
# Esperado: ['obsidian', 'qdrant-vault', 'mem0']

# 6. Dentro do Claude Code:
/mcp              # lista MCPs ativos (devem estar verdes)
/octo:setup       # lista providers ativos

Problemas comuns

mcp-obsidian falha com ImportError (fastmcp):

1
2
pip uninstall obsidian-mcp -y  # remover versao pip
npm install -g mcp-obsidian    # instalar versao npm

Qdrant nao inicia apos reboot WSL:

1
2
3
4
# Adicionar ao ~/.zshrc:
if ! docker ps | grep -q qdrant; then
  docker start qdrant 2>/dev/null
fi

Providers nao detectados pelo Octopus:

1
2
which codex && which gemini  # verificar PATH
/octo:setup                  # rodar novamente

mem0 retorna vazio:

1
2
3
# Verificar Ollama rodando
curl http://localhost:11434/api/tags
# Se nao: systemctl start ollama

Glossario

Termo O que e
Claude Code CLI da Anthropic com acesso ao filesystem
Octopus Plugin de orquestracao multi-LLM para Claude Code
Double Diamond Discover -> Define -> Develop -> Deliver com gates
Consensus Gate Bloqueia output se < 75% dos agentes concordam
mem0 Memoria semantica automatica — extrai e armazena fatos
Qdrant Banco vetorial — armazena embeddings para busca semantica
FastEmbed Embeddings locais rapidos (all-MiniLM-L6-v2, 384 dims)
vault-memory Colecao Qdrant com chunks do vault indexados
MCP Model Context Protocol — padrao para LLMs acessarem ferramentas
CLAUDE.md Contexto carregado automaticamente em toda sessao
wikilinks [[links]] do Obsidian que criam grafo de conhecimento

Conclusao

Com essa stack, cada sessao de trabalho:

  • Comeca com contexto completo (sem reexplicar nada)
  • Usa o melhor LLM para cada tarefa (nao depende de um so)
  • Acumula conhecimento real no vault (nao perde nada)
  • Busca por significado, nao por keyword
  • Lembra suas preferencias e decisoes passadas

O custo: Docker rodando Qdrant (~200MB RAM), FastEmbed (~60MB), Ollama quando precisar (~1GB). Tudo local, sem API keys pagas obrigatorias.

Funciona. Em producao. Todo dia.

Esta postagem está licenciada sob CC BY 4.0 pelo autor.