bulhufas
Servidor MCP que ingere documentações de projetos uma vez e permite que o Claude pesquise por significado em vez de ler tudo — economizando tokens em bases de código grandes.
Documentação
bulhufas
Gerenciamento de projetos com RAG que captura o que as ferramentas de PM não capturam.
Começando · Como Funciona · API · Self-Host · Contribuindo
Por que "bulhufas"?
Bulhufas é uma gíria do português brasileiro para "nada", "coisa nenhuma", "bupkis" — absolutamente nada.
Como em: "Quanto o Claude sabe sobre aquela decisão que seu time tomou no WhatsApp na quinta-feira passada?" Bulhufas.
"E aquele bloqueio que alguém mencionou na daily?" Bulhufas.
"E aquela decisão de arquitetura de dois sprints atrás?" Você adivinhou. Bulhufas.
Agora ele sabe.
Times tomam decisões no Slack, WhatsApp e reuniões — e nada disso chega à ferramenta de PM. bulhufas captura conversas brutas, extrai artefatos estruturados de projeto (decisões, itens de ação, bloqueios, mudanças de escopo) e os torna pesquisáveis via embeddings semânticos.
Binário único. Sem dependências externas. Embeddings rodam no processo.
Recursos
- Conversa para Estrutura — Cole conversas brutas e obtenha blocos estruturados: decisões, itens de ação, bloqueios, requisitos, mudanças de escopo
- Memória de Agente — Armazene memórias de trabalho, episódicas, semânticas e procedurais em namespaces isolados com proveniência, confiança, importância e janelas de validade
- Busca Semântica — Encontre contexto pelo significado, não por palavras-chave. "O que decidimos sobre autenticação?" encontra o bloco certo mesmo que "autenticação" não esteja no texto
- Recall Compacto — Retorne um pacote de contexto limitado com IDs de memória e referências de origem para que qualquer LLM possa recuperar apenas o que precisa
- CRUD no Conhecimento — Atualize status, adicione contexto, arquive blocos desatualizados. Sua base de conhecimento permanece atualizada
- Binário Único — Um binário Go com armazenamento vetorial embutido (chromem-go) e modelo de embeddings (hugot/all-MiniLM-L6-v2). Sem Ollama, sem Docker, sem processos externos
- Self-Hostable — Implante em qualquer lugar: Coolify, Railway, Hetzner, AWS, GCP. Roda em um VPS de 2GB
Como Funciona

You paste a conversation into your AI assistant
|
The LLM extracts structured chunks with metadata
|
bulhufas stores chunks + generates embeddings in-process (hugot)
|
Later: "what's pending from last week?" -> semantic search returns relevant chunks
O Que É Capturado
| Tipo de Bloco | Exemplo |
|---|---|
decision | "Escolhemos WebSockets em vez de polling para atualizações em tempo real" |
action_item | "Hugo criará credenciais de banco somente leitura até sexta-feira" |
blocker | "Não dá para fazer deploy até o certificado SSL ser renovado" |
requirement | "O cliente precisa de exportação CSV para o relatório financeiro" |
scope_change | "Módulo de autenticação expandido para incluir SSO" |
context | "A API legada retorna XML, não JSON" |
research_finding | "pgvector supera pinecone para o nosso tamanho de dataset" |
status_update | "Integração de pagamento está ativa em staging" |
Instalação
1. Compile a partir do código-fonte
# Requires Go 1.22+ with CGO enabled
git clone https://github.com/HugoluizMTB/bulhufas.git
cd bulhufas
make build
2. Adicione ao Claude Code
claude mcp add --transport stdio --scope user bulhufas -- /absolute/path/to/bulhufas/bin/bulhufas --mcp
Substitua
/absolute/path/topelo caminho real onde você clonou o repositório. Use--scope userpara disponibilizá-lo em todos os seus projetos. Use--scope projectpara restringi-lo apenas ao projeto atual.
3. Reinicie o Claude Code e verifique
Execute /mcp dentro do Claude Code. Você deve ver bulhufas conectado com 10 ferramentas:
| Ferramenta | Descrição |
|---|---|
save_conversation | Salvar uma conversa com blocos estruturados extraídos |
remember | Salvar um registro de memória com escopo e metadados de proveniência e ciclo de vida |
search | Busca semântica em todos os blocos armazenados |
recall | Recuperar um pacote de contexto isolado por namespace e consciente de tokens |
observe_turn | Aprender automaticamente uma virada significativa como memória episódica |
list_chunks | Listar blocos com filtros opcionais de tipo/status |
update_status | Atualizar status de bloco por ID |
delete_chunk | Excluir um bloco por ID |
list_actions | Listar todos os itens de ação pendentes |
consolidate_memory | Visualizar ou executar consolidação episódica-para-semântica/procedural |
Na primeira execução, o modelo de embeddings (all-MiniLM-L6-v2, ~80MB) é baixado automaticamente para ./data/models/.
Executar como Servidor HTTP (opcional)
./bin/bulhufas
Inicia uma API HTTP na porta 8420. Use a flag --mcp para o modo MCP stdio.
Gateway automático para qualquer LLM compatível com OpenAI
Para capturar viradas automaticamente no Claude Code sem depender do modelo chamar observe_turn, registre o hook Stop em integrations/claude-code-hook.mjs. Veja docs/claude-code-sessions.md.
Para provedores que não suportam MCP, execute o proxy de memória sem dependências:
LLM_UPSTREAM_URL=https://api.openai.com \
LLM_UPSTREAM_API_KEY="$OPENAI_API_KEY" \
BULHUFAS_NAMESPACE=project:bulhufas \
make proxy
Aponte o cliente para http://127.0.0.1:8421/v1. O proxy recupera memória com escopo antes de cada conclusão de chat e captura viradas substantivas após a resposta. Funciona com endpoints compatíveis com OpenAI, como Ollama, vLLM e LM Studio; veja integrations/README.md.
Com Docker Compose, use docker compose --profile proxy up -d após definir LLM_UPSTREAM_URL, LLM_UPSTREAM_API_KEY e BULHUFAS_NAMESPACE no ambiente.
Variáveis de Ambiente
| Variável | Padrão | Descrição |
|---|---|---|
PORT | 8420 | Porta do servidor |
DATA_DIR | ./data | Diretório de armazenamento persistente (banco SQLite, arquivos de modelo, índice vetorial) |
MEMORY_LLM_BASE_URL | não definido | Endpoint /v1 compatível com OpenAI usado para consolidação automática |
MEMORY_LLM_API_KEY | não definido | Chave de API opcional para o provedor de consolidação |
MEMORY_LLM_MODEL | gpt-4o-mini | Modelo usado pelo gerenciador de memória em segundo plano |
MEMORY_CONSOLIDATION_INTERVAL | 15m | Intervalo para promover memórias episódicas quando MEMORY_LLM_BASE_URL está definido |
MEMORY_NAMESPACE | default | Namespace processado pelo consolidador automático |
BULHUFAS_API_KEY | não definido | Chave de API opcional exigida por clientes da API HTTP |
BULHUFAS_ALLOWED_NAMESPACE | não definido | Limite de namespace rígido opcional para esta instância do servidor |
BULHUFAS_TLS_CERT_FILE | não definido | Caminho do certificado; habilita HTTPS junto com o arquivo de chave |
BULHUFAS_TLS_KEY_FILE | não definido | Caminho da chave privada para HTTPS |
API
Salvar uma conversa com blocos
curl -X POST http://localhost:8420/api/conversations \
-H "Content-Type: application/json" \
-d '{
"source": "whatsapp",
"summary": "Discussion about database access",
"participants": ["renan", "hugo"],
"chunks": [
{
"content": "Renan needs read-only access to PostgreSQL",
"type": "decision",
"tags": ["infra", "postgres"],
"people": ["renan"],
"status": "pending",
"action_item": "Create read-only credentials"
}
]
}'
Busca semântica
curl -X POST http://localhost:8420/api/search \
-H "Content-Type: application/json" \
-d '{"text": "database access", "limit": 5}'
Salvar e recuperar memória de agente
curl -X POST http://localhost:8420/api/memories \
-H "Content-Type: application/json" \
-d '{
"content": "The payments service uses idempotency keys for retries",
"memory_kind": "procedural",
"namespace": "project:bulhufas",
"source": "architecture-review",
"source_ref": "meeting:2026-08-01",
"confidence": 0.95,
"importance": 0.8,
"tags": ["payments", "reliability"]
}'
curl -X POST http://localhost:8420/api/recall \
-H "Content-Type: application/json" \
-d '{
"text": "How should payment retries work?",
"namespace": "project:bulhufas",
"memory_kinds": ["semantic", "procedural"],
"limit": 5,
"max_chars": 3000
}'
recall retorna tanto results estruturado quanto uma string context limitada. Namespaces, IDs de projeto/tenant/sessão e tipos de memória são filtros rígidos, para que contextos de agentes não relacionados não sejam concatenados acidentalmente.
Quando MEMORY_LLM_BASE_URL está configurado, um gerenciador em segundo plano consolida periodicamente memórias episódicas em registros semânticos/procedurais conservadores. Também pode ser acionado ou visualizado explicitamente:
curl -X POST http://localhost:8420/api/consolidate \
-H "Content-Type: application/json" \
-d '{"namespace":"project:bulhufas","limit":32,"dry_run":true}'
Aprendizado ambiente
No uso normal do agente, o cliente pode chamar recall no início da tarefa e observe_turn após viradas substantivas. Estas são chamadas de ferramenta internas: você não precisa digitar "lembre disso" para aprendizado comum. As ferramentas explícitas remember, atualização e exclusão permanecem disponíveis para correções, promoções, esquecimento e controle exato. Para gateways de chat que podem encaminhar cada mensagem automaticamente, POST /api/turns fornece o mesmo caminho de captura sem depender do modelo para iniciar a chamada.
Listar blocos com filtros
curl "http://localhost:8420/api/chunks?type=blocker&status=pending"
Listar itens de ação pendentes
curl http://localhost:8420/api/actions
Atualizar status de bloco
curl -X PATCH http://localhost:8420/api/chunks/{id}/status \
-H "Content-Type: application/json" \
-d '{"status": "resolved"}'
Excluir um bloco
curl -X DELETE http://localhost:8420/api/chunks/{id}
Verificação de saúde
curl http://localhost:8420/healthz
Métricas estão disponíveis em GET /metrics no formato de texto Prometheus. Defina BULHUFAS_API_KEY para proteger rotas da API; coloque o serviço atrás de um proxy reverso TLS ou defina ambas as variáveis de arquivo TLS diretamente.
Arquitetura
cmd/server/ -> entrypoint, wires everything together
internal/
domain/ -> core types: Conversation, Chunk, WorkItem, Relation
mcp/ -> HTTP server, handlers, request/response logic
store/ -> persistence interface + SQLite implementation
vectorstore/ -> embedded vector search via chromem-go
embedder/ -> in-process embeddings via hugot (all-MiniLM-L6-v2)
scripts/ -> test scripts
macos/BulhufasMac/ -> native macOS app: Dynamic Island + menu bar (GPL-3.0)
Todas as dependências externas estão atrás de interfaces. Troque SQLite por Postgres, ou chromem-go por pgvector — sem tocar na lógica de negócio.
Stack
| Componente | Biblioteca | Roda no processo? |
|---|---|---|
| Embedding | hugot + all-MiniLM-L6-v2 (384 dim) | Sim |
| Armazenamento vetorial | chromem-go | Sim |
| Banco de dados | SQLite (mattn/go-sqlite3) | Sim |
| Servidor HTTP | Go stdlib net/http | Sim |
| UI macOS | SwiftUI + AppKit NSPanel | App nativo |
Sem Ollama. Sem Docker. Sem bancos de dados externos. Um binário.
O backend local é deliberadamente o primeiro nível de um design de memória maior. SQLite/chromem é o armazenamento offline padrão; o app macOS nativo conversa com ele pela API HTTP local, enquanto o adaptador Postgres opcional pode usar pgvector HNSW mais busca em texto completo do PostgreSQL. Quantização vetorial como TurboQuant é uma otimização opcional de índice e deve ser validada contra recall antes de ser habilitada.
O adaptador opcional PostgreSQL/pgvector está documentado em docs/pgvector.md. A pesquisa mais profunda sobre LLM e memória está resumida em docs/research-landscape.md.
Self-Hosting
Binário
CGO_ENABLED=1 GOOS=linux go build -o bulhufas ./cmd/server
scp bulhufas your-server:/opt/bulhufas/
ssh your-server '/opt/bulhufas/bulhufas'
Docker
docker build -t bulhufas .
docker run -d --name bulhufas -p 8420:8420 -v bulhufas-data:/data bulhufas
Docker Compose
git clone https://github.com/HugoluizMTB/bulhufas.git
cd bulhufas
docker compose up -d
Funciona com Coolify, Railway, Hetzner, AWS, GCP, Oracle Cloud — qualquer coisa que rode Docker.
App macOS nativo
O app macOS não tem janela regular. Ele vive em dois lugares: uma Dynamic Island que fica pendurada no notch, e um painel na barra de menu.
make macos-open
Dynamic Island. Fechada, ela tem exatamente o tamanho do notch e, portanto, é invisível. Passar o mouse abre; clicar fixa aberta. Quando novas memórias chegam, ela se alarga brevemente em uma prévia. O estado aberto mostra a sessão ativa do Claude Code e memórias recentes ou a lista de sessões. Em telas sem notch, a mesma forma fica pendurada na borda superior.
Barra de menu. Um painel com a contagem de memórias, atividade de captura ao longo do tempo e uma divisão do que foi capturado por tipo de bloco.
Sessões do Claude Code. O app lista sessões lendo metadados de arquivos de $CLAUDE_CONFIG_DIR/projects, ~/.claude/projects e ~/.claude-pessoal/projects — apenas horários de modificação e nomes de arquivos. O conteúdo das transcrições nunca é aberto e nenhuma credencial é lida. A captura de memória em si ainda acontece pelo servidor MCP; veja docs/claude-code-sessions.md.
O app usa por padrão http://127.0.0.1:8420. Defina BULHUFAS_URL antes de iniciá-lo para usar outro endpoint HTTP local ou remoto. A fórmula Homebrew está documentada em docs/homebrew.md.
Nota de licença: o app macOS em
macos/é GPL-3.0, porque contém código derivado de Atoll e, através dele, boring.notch. O servidor Go e todo o resto neste repositório permanecem Apache-2.0 — são programas separados que se comunicam por uma API HTTP local. Veja macos/NOTICE.
Roadmap
- Tipos de domínio principais e interfaces
- API HTTP com salvar/buscar/atualizar/excluir
- Implementação de armazenamento SQLite
- Embeddings no processo via hugot (all-MiniLM-L6-v2)
- Armazenamento vetorial chromem-go
- Busca semântica com enriquecimento SQLite
- Endpoint de itens de ação
- Protocolo de servidor MCP (transporte stdio via mcp-go)
- Imagem Docker
- App macOS nativo: Dynamic Island + barra de menu
- Lista de sessões do Claude Code a partir de metadados de transcrições locais
- Plugin Slack
- MCP remoto via transporte SSE
Contribuindo
Veja CONTRIBUTING.md para instruções de configuração, estilo de código e processo de PR.
Licença
Apache License 2.0 — use livremente, até comercialmente. Proteção de patente incluída.
Criado por @HugoluizMTB