bulhufas

Servidor MCP que ingiere documentación de proyectos una vez y permite a Claude buscar por significado en lugar de leer todo — ahorrando tokens en bases de código grandes

Documentación

bulhufas

Gestión de proyectos impulsada por RAG que captura lo que las herramientas de gestión de proyectos pasan por alto.

Build Go Reference Go Report Card License

Primeros pasos · Cómo funciona · API · Autoalojamiento · Contribuciones


¿Por qué "bulhufas"?

Bulhufas es una jerga del portugués brasileño que significa "nada", "ni pío", "cero" — absolutamente nada.

Por ejemplo: "¿Cuánto sabe Claude sobre esa decisión que tu equipo tomó en WhatsApp el jueves pasado?" Bulhufas.

"¿Y ese bloqueo que alguien mencionó en la reunión diaria?" Bulhufas.

"¿Y esa decisión de arquitectura de hace dos sprints?" Lo adivinaste. Bulhufas.

Ahora lo sabe.


Los equipos toman decisiones en Slack, WhatsApp y reuniones — y luego nada de eso llega a la herramienta de gestión de proyectos. bulhufas captura conversaciones en bruto, extrae artefactos estructurados del proyecto (decisiones, elementos de acción, bloqueos, cambios de alcance) y los hace buscables mediante incrustaciones semánticas.

Un solo binario. Sin dependencias externas. Las incrustaciones se ejecutan en el proceso.

Características

  • De conversación a estructura — Pega un chat en bruto y obtén fragmentos estructurados: decisiones, elementos de acción, bloqueos, requisitos, cambios de alcance
  • Memoria del agente — Almacena memorias de trabajo, episódicas, semánticas y procedimentales en espacios de nombres aislados con procedencia, confianza, importancia y ventanas de validez
  • Búsqueda semántica — Encuentra contexto por significado, no por palabras clave. "¿Qué decidimos sobre la autenticación?" encuentra el fragmento correcto incluso si "auth" no está en el texto
  • Recuperación compacta — Devuelve un paquete de contexto limitado con IDs de memoria y referencias de origen para que cualquier LLM pueda recuperar solo lo que necesita
  • CRUD sobre el conocimiento — Actualiza el estado, añade contexto, archiva fragmentos obsoletos. Tu base de conocimiento se mantiene al día
  • Un solo binario — Un binario de Go con almacén vectorial integrado (chromem-go) y modelo de incrustación (hugot/all-MiniLM-L6-v2). Sin Ollama, sin Docker, sin procesos externos
  • Autoalojable — Despliega en cualquier lugar: Coolify, Railway, Hetzner, AWS, GCP. Funciona en un VPS de 2GB

Cómo funciona

Ingestion and retrieval flow

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

Qué se captura

Tipo de fragmentoEjemplo
decision"Elegimos WebSockets en lugar de polling para actualizaciones en tiempo real"
action_item"Hugo creará credenciales de BD de solo lectura para el viernes"
blocker"No se puede desplegar hasta que se renueve el certificado SSL"
requirement"El cliente necesita exportación CSV para el informe financiero"
scope_change"El módulo de autenticación se amplió para incluir SSO"
context"La API heredada devuelve XML, no JSON"
research_finding"pgvector supera a pinecone para nuestro tamaño de conjunto de datos"
status_update"La integración de pagos está activa en staging"

Instalación

1. Compilar desde el código fuente

# Requires Go 1.22+ with CGO enabled
git clone https://github.com/HugoluizMTB/bulhufas.git
cd bulhufas
make build

2. Añadir a Claude Code

claude mcp add --transport stdio --scope user bulhufas -- /absolute/path/to/bulhufas/bin/bulhufas --mcp

Reemplaza /absolute/path/to con la ruta real donde clonaste el repositorio. Usa --scope user para que esté disponible en todos tus proyectos. Usa --scope project para restringirlo solo al proyecto actual.

3. Reinicia Claude Code y verifica

Ejecuta /mcp dentro de Claude Code. Deberías ver bulhufas conectado con 10 herramientas:

HerramientaDescripción
save_conversationGuarda una conversación con fragmentos estructurados extraídos
rememberGuarda un registro de memoria con alcance con procedencia y metadatos de ciclo de vida
searchBúsqueda semántica en todos los fragmentos almacenados
recallRecupera un paquete de contexto aislado por espacio de nombres y consciente de tokens
observe_turnAprende automáticamente un turno significativo como memoria episódica
list_chunksLista fragmentos con filtros opcionales de tipo/estado
update_statusActualiza el estado de un fragmento por ID
delete_chunkElimina un fragmento por ID
list_actionsLista todos los elementos de acción pendientes
consolidate_memoryVista previa o ejecución de la consolidación episódica a semántica/procedimental

En la primera ejecución, el modelo de incrustación (all-MiniLM-L6-v2, ~80MB) se descarga automáticamente a ./data/models/.

Ejecutar como servidor HTTP (opcional)

./bin/bulhufas

Inicia una API HTTP en el puerto 8420. Usa la bandera --mcp para el modo MCP stdio en su lugar.

Puerta de enlace automática para cualquier LLM compatible con OpenAI

Para capturar turnos automáticamente en Claude Code sin depender de que el modelo llame a observe_turn, registra el hook Stop en integrations/claude-code-hook.mjs. Consulta docs/claude-code-sessions.md.

Para proveedores que no admiten MCP, ejecuta el proxy de memoria sin dependencias:

LLM_UPSTREAM_URL=https://api.openai.com \
LLM_UPSTREAM_API_KEY="$OPENAI_API_KEY" \
BULHUFAS_NAMESPACE=project:bulhufas \
make proxy

Apunta el cliente a http://127.0.0.1:8421/v1. El proxy recupera la memoria con alcance antes de cada finalización de chat y captura turnos sustanciales después de la respuesta. Funciona con endpoints compatibles con OpenAI como Ollama, vLLM y LM Studio; consulta integrations/README.md.

Con Docker Compose, usa docker compose --profile proxy up -d después de configurar LLM_UPSTREAM_URL, LLM_UPSTREAM_API_KEY y BULHUFAS_NAMESPACE en el entorno.

Variables de entorno

VariablePredeterminadoDescripción
PORT8420Puerto del servidor
DATA_DIR./dataDirectorio de almacenamiento persistente (BD SQLite, archivos de modelo, índice vectorial)
MEMORY_LLM_BASE_URLsin configurarEndpoint /v1 compatible con OpenAI utilizado para la consolidación automática
MEMORY_LLM_API_KEYsin configurarClave API opcional para el proveedor de consolidación
MEMORY_LLM_MODELgpt-4o-miniModelo utilizado por el gestor de memoria en segundo plano
MEMORY_CONSOLIDATION_INTERVAL15mIntervalo para promover memorias episódicas cuando MEMORY_LLM_BASE_URL está configurado
MEMORY_NAMESPACEdefaultEspacio de nombres procesado por el consolidador automático
BULHUFAS_API_KEYsin configurarClave API opcional requerida por los clientes de la API HTTP
BULHUFAS_ALLOWED_NAMESPACEsin configurarLímite de espacio de nombres estricto opcional para esta instancia del servidor
BULHUFAS_TLS_CERT_FILEsin configurarRuta del certificado; habilita HTTPS junto con el archivo de clave
BULHUFAS_TLS_KEY_FILEsin configurarRuta de la clave privada para HTTPS

API

Guardar una conversación con fragmentos

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"
      }
    ]
  }'

Búsqueda semántica

curl -X POST http://localhost:8420/api/search \
  -H "Content-Type: application/json" \
  -d '{"text": "database access", "limit": 5}'

Guardar y recuperar memoria del 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 devuelve tanto el results estructurado como una cadena context limitada. Los espacios de nombres, los IDs de proyecto/tenant/sesión y los tipos de memoria son filtros estrictos, por lo que los contextos de agentes no relacionados no se concatenan accidentalmente.

Cuando MEMORY_LLM_BASE_URL está configurado, un gestor en segundo plano consolida periódicamente las memorias episódicas en registros semánticos/procedimentales conservadores. También se puede activar o previsualizar explícitamente:

curl -X POST http://localhost:8420/api/consolidate \
  -H "Content-Type: application/json" \
  -d '{"namespace":"project:bulhufas","limit":32,"dry_run":true}'

Aprendizaje ambiental

En el uso normal del agente, el cliente puede llamar a recall al inicio de la tarea y a observe_turn después de turnos sustanciales. Estas son llamadas internas de herramientas: no necesitas escribir "recuerda esto" para el aprendizaje ordinario. Las herramientas explícitas remember, actualización y eliminación siguen disponibles para correcciones, promociones, olvidos y control exacto. Para puertas de enlace de chat que pueden reenviar cada mensaje automáticamente, POST /api/turns proporciona la misma ruta de captura sin depender de que el modelo inicie la llamada.

Listar fragmentos con filtros

curl "http://localhost:8420/api/chunks?type=blocker&status=pending"

Listar elementos de acción pendientes

curl http://localhost:8420/api/actions

Actualizar el estado de un fragmento

curl -X PATCH http://localhost:8420/api/chunks/{id}/status \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved"}'

Eliminar un fragmento

curl -X DELETE http://localhost:8420/api/chunks/{id}

Comprobación de salud

curl http://localhost:8420/healthz

Las métricas están disponibles en GET /metrics en formato de texto Prometheus. Configura BULHUFAS_API_KEY para proteger las rutas de la API; coloca el servicio detrás de un proxy inverso TLS o configura ambas variables de archivo TLS directamente.

Arquitectura

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 las dependencias externas están detrás de interfaces. Cambia SQLite por Postgres, o chromem-go por pgvector — sin tocar la lógica de negocio.

Pila tecnológica

ComponenteBiblioteca¿Se ejecuta en el proceso?
Incrustaciónhugot + all-MiniLM-L6-v2 (384 dim)
Almacén vectorialchromem-go
Base de datosSQLite (mattn/go-sqlite3)
Servidor HTTPGo stdlib net/http
Interfaz de macOSSwiftUI + AppKit NSPanelAplicación nativa

Sin Ollama. Sin Docker. Sin bases de datos externas. Un solo binario.

El backend local es deliberadamente el primer nivel de un diseño de memoria más amplio. SQLite/chromem es el almacén offline predeterminado; la aplicación nativa de macOS se comunica con él a través de la API HTTP local, mientras que el adaptador Postgres opcional puede usar pgvector HNSW más la búsqueda de texto completo de PostgreSQL. La cuantización vectorial como TurboQuant es una optimización opcional del índice y debe validarse contra la recuperación antes de habilitarla.

El adaptador opcional PostgreSQL/pgvector está documentado en docs/pgvector.md. La investigación más profunda sobre LLM y memoria se resume en docs/research-landscape.md.

Autoalojamiento

Binario

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 con Coolify, Railway, Hetzner, AWS, GCP, Oracle Cloud — cualquier cosa que ejecute Docker.

Aplicación nativa de macOS

La aplicación de macOS no tiene ventana normal. Vive en dos lugares: una Dynamic Island que cuelga del notch y un panel de la barra de menú.

make macos-open

Dynamic Island. Cerrada, tiene exactamente el tamaño del notch y por lo tanto es invisible. Al pasar el cursor se abre; al hacer clic se fija abierta. Cuando llegan nuevas memorias se ensancha brevemente como una vista previa. El estado abierto muestra la sesión activa de Claude Code y ya sea las memorias recientes o la lista de sesiones. En pantallas sin notch, la misma forma cuelga del borde superior.

Barra de menú. Un panel con el recuento de memorias, la actividad de captura a lo largo del tiempo y un desglose de lo capturado por tipo de fragmento.

Sesiones de Claude Code. La aplicación lista las sesiones leyendo metadatos de archivos de $CLAUDE_CONFIG_DIR/projects, ~/.claude/projects y ~/.claude-pessoal/projects — solo tiempos de modificación y nombres de archivo. Los contenidos de las transcripciones nunca se abren y no se leen credenciales. La captura de memoria en sí sigue ocurriendo a través del servidor MCP; consulta docs/claude-code-sessions.md.

La aplicación usa por defecto http://127.0.0.1:8420. Configura BULHUFAS_URL antes de iniciarla para usar otro endpoint HTTP local o remoto. La fórmula Homebrew está documentada en docs/homebrew.md.

Nota de licencia: la aplicación de macOS en macos/ es GPL-3.0, porque contiene código derivado de Atoll y, a través de él, de boring.notch. El servidor Go y todo lo demás en este repositorio permanecen bajo Apache-2.0 — son programas separados que se comunican a través de una API HTTP local. Consulta macos/NOTICE.

Hoja de ruta

  • Tipos e interfaces del dominio central
  • API HTTP con guardar/buscar/actualizar/eliminar
  • Implementación del almacén SQLite
  • Incrustaciones en proceso mediante hugot (all-MiniLM-L6-v2)
  • Almacén vectorial chromem-go
  • Búsqueda semántica con enriquecimiento SQLite
  • Endpoint de elementos de acción
  • Protocolo de servidor MCP (transporte stdio mediante mcp-go)
  • Imagen Docker
  • Aplicación nativa de macOS: Dynamic Island + barra de menú
  • Lista de sesiones de Claude Code a partir de metadatos de transcripciones locales
  • Plugin de Slack
  • MCP remoto mediante transporte SSE

Contribuciones

Consulta CONTRIBUTING.md para instrucciones de configuración, estilo de código y proceso de PR.

Licencia

Apache License 2.0 — úsalo libremente, incluso comercialmente. Protección de patente incluida.


Creado por @HugoluizMTB