Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Second Brain Worker

БесплатноНе проверен

Provides tools to retrieve, ingest, and reindex a serverless personal knowledge base built from Obsidian wiki and external files, with hybrid semantic + keyword

GitHubEmbed

Описание

Provides tools to retrieve, ingest, and reindex a serverless personal knowledge base built from Obsidian wiki and external files, with hybrid semantic + keyword search via the Model Context Protocol.

README

Un knowledge base personale serverless su Cloudflare Workers che indicizza la tua wiki Obsidian e file esterni, con ricerca ibrida (semantica + keyword) accessibile via MCP (Model Context Protocol) direttamente dal tuo IDE.

Cos'è

Second Brain Worker è un Cloudflare Worker che:

  • Indicizza file markdown dalla wiki Obsidian e file esterni (PDF, articoli, testo)
  • Chunka il contenuto rispettando la struttura delle sezioni (##/###), preservando frontmatter e wikilink
  • Genera embedding semantici via Workers AI (@cf/baai/bge-base-en-v1.5, 768 dim)
  • Memorizza tutto in R2 (raw), D1 (metadata + FTS5 keyword search), e Vectorize (embedding)
  • Espone 5 tool MCPretrieve, ingest, reindex, read, grep — accessibili dal tuo IDE via OAuth GitHub
  • Sincronizza automaticamente la wiki via GitHub webhook: quando fichi push su main, i file .md cambiati vengono re-indicizzati

Tutto entro il free tier di Cloudflare.


Architettura

                    ┌─────────────────────────────────────────────┐
                    │              Cloudflare Worker               │
                    │                                              │
   GitHub Webhook ──▶  /webhook/github  ──▶  fetch .md  ──▶  R2   │
                    │                                  │           │
   REST API ────────▶  /api/ingest      ──▶  chunker    │           │
                    │  /api/retrieve    ──▶  embedder   │           │
                    │  /api/reindex     ──▶  D1 + Vectorize        │
                    │  /api/health      │           │               │
                    │                   │           │               │
   MCP Client ─────▶  /mcp (OAuth)      │           │               │
                    │  /authorize       │           │               │
                    │  /callback        │           │               │
                    └─────────────────────────────────────────────┘
                           │         │           │
                    ┌──────▼──┐ ┌───▼────┐ ┌────▼──────┐
                    │   R2    │ │   D1   │ │ Vectorize │
                    │ (raw)   │ │(meta + │ │ (embedding│
                    │         │ │  FTS5) │ │  vectors) │
                    └─────────┘ └────────┘ └───────────┘

Componenti

  • R2 (RAW_BUCKET) — storage del contenuto raw dei file
  • D1 (DB) — database SQLite con tabelle files, chunks, e tabella virtuale FTS5 chunks_fts per keyword search
  • Vectorize (VECTORIZE) — indice di embedding semantici (768 dimensioni)
  • Workers AI (AI) — modello bge-base-en-v1.5 per generazione embedding
  • KV (OAUTH_KV) — storage di stato/CSRF token per il flow OAuth
  • Durable Object (SECOND_BRAIN_MCP) — McpAgent che mantiene la sessione MCP
  • OAuth Provider — integrazione @cloudflare/workers-oauth-provider con GitHub OAuth

MCP Tools

Il server MCP espone 5 tool accessibili dal tuo IDE:

retrieve

Ricerca ibrida nel knowledge base: query semantica via Vectorize + query keyword via D1 FTS5. I risultati vengono fusi (merge) con pesi 50/50, ordinati per score combinato, e arricchiti con metadata dal D1.

Parametri:

  • query (string, required) — query in linguaggio naturale o keyword
  • limit (number, default 10, max 50) — numero massimo di risultati
  • file_type ("wiki_page" | "ingested", optional) — filtra per tipo di file
  • section_prefix (string, optional) — filtra per prefisso sezione (es. ## Architecture)
  • file_key_prefix (string, optional) — filtra per prefisso file key (es. wiki/concepts/)

ingest

Carica un file nel knowledge base: il contenuto viene chunkato, embeddato, e salvato in R2 + D1 + Vectorize. Se il file esiste già, i vecchi chunk e vector vengono sostituiti.

Parametri:

  • file_key (string, required) — identificatore univoco. Per wiki page: path relativo (es. wiki/concepts/Tool Attention.md). Per file esterni: filename:uuid
  • content (string, required) — contenuto testuale completo
  • file_type ("wiki_page" | "ingested", required) — tipo di file
  • title (string, optional) — titolo del file
  • source (string, optional) — URL o path sorgente

reindex

Re-indicizza un file specifico o tutti i file. Legge il raw da R2, re-esegue chunking + embedding, aggiorna Vectorize e D1.

Parametri:

  • file_key (string, optional) — file da re-indicizzare. Se omesso, re-indicizza tutti i file

read

Legge il testo raw di un file indicizzato da R2 con offset/limite opzionali. Utile per leggere il contesto completo attorno a un chunk trovato via retrieve.

Parametri:

  • file_key (string, required) — file key del file da leggere
  • offset (number, optional, default 0) — offset in caratteri da cui iniziare
  • max_chars (number, optional, default 2000, max 10000) — numero massimo di caratteri da restituire

grep

Cerca un pattern regex nel testo raw di un file indicizzato. Restituisce i match con contesto opzionale. Utile per estrarre dati strutturati (date, importi, ID) dai documenti.

Parametri:

  • file_key (string, required) — file key del file in cui cercare
  • pattern (string, required) — pattern regex JavaScript
  • max_matches (number, optional, default 10, max 50) — numero massimo di match
  • context (number, optional, default 40, max 200) — caratteri di contesto attorno a ogni match

REST API

Oltre ai tool MCP, il Worker espone endpoint REST (non autenticati, utili per script e setup):

Metodo Endpoint Descrizione
GET /api/health Stato del Worker: file indicizzati, chunk totali
POST /api/ingest Ingest di un file (stesso formato del tool MCP)
POST /api/retrieve Retrieve ibrido (stesso formato del tool MCP)
POST /api/reindex Reindex di un file o di tutti
POST /api/read Leggi raw text da R2 con offset/limit
POST /api/grep Ricerca regex sul contenuto indicizzato
GET /api/metrics Metriche aggregate di retrieve (latency, score, zero-result rate)
POST /webhook/github Webhook GitHub per sync automatico

Prerequisiti

  • Node.js 22+
  • Account Cloudflare (free tier sufficiente)
  • GitHub OAuth App — per l'autenticazione MCP
  • Wiki Obsidian in un repo GitHub (se vuoi usare il sync automatico)

Setup completo

1. Clona e installa

git clone https://github.com/50R1Paps/second-brain-worker.git
cd second-brain-worker
npm install

2. Crea le risorse Cloudflare

Esegui questi comandi con wrangler per creare le risorse necessarie:

# Crea R2 bucket
npx wrangler r2 bucket create second-brain-raw

# Crea D1 database
npx wrangler d1 create second-brain
# Annota il database_id dal output

# Crea KV namespace per OAuth
npx wrangler kv namespace create OAUTH_KV
# Annota l'id dal output

# Crea Vectorize index (768 dim per bge-base-en-v1.5)
npx wrangler vectorize create second-brain-embeddings --dimensions 768 --metric cosine

3. Configura wrangler.toml

Copia il file di esempio e compila i valori reali:

cp wrangler.toml.example wrangler.toml

Modifica wrangler.toml sostituendo <your-d1-database-id> e <your-kv-namespace-id> con i valori ottenuti al passo 2.

4. Applica la migration D1

# Locale (per dev)
npm run db:migrate

# Remoto (per produzione)
npm run db:migrate:remote

5. Crea una GitHub OAuth App

  1. Vai su GitHub Settings > Developer settings > OAuth Apps > New OAuth App
  2. Compila:
    • Application name: Second Brain MCP
    • Homepage URL: https://second-brain.<tuo-subdomain>.workers.dev
    • Authorization callback URL: https://second-brain.<tuo-subdomain>.workers.dev/callback
  3. Annota il Client ID e genera un Client Secret

6. Imposta i segreti

# OAuth
npx wrangler secret put GITHUB_CLIENT_ID
npx wrangler secret put GITHUB_CLIENT_SECRET
npx wrangler secret put COOKIE_ENCRYPTION_KEY

# GitHub webhook sync (opzionale, solo se usi il sync automatico)
npx wrangler secret put WEBHOOK_SECRET
npx wrangler secret put GITHUB_TOKEN
npx wrangler secret put GITHUB_TOKEN_EXPIRY

Per COOKIE_ENCRYPTION_KEY puoi generare una stringa casuale con:

openssl rand -hex 32

Per GITHUB_TOKEN, crea un Personal Access Token con scope repo (per leggere i file .md via API).

Per WEBHOOK_SECRET, genera un'altra stringa casuale e usala anche come secret del webhook GitHub.

Per GITHUB_TOKEN_EXPIRY, inserisci la data di scadenza del PAT in formato ISO (es. 2026-09-25T00:00:00Z). Il Cron Trigger giornaliero controlla questa data e apre automaticamente una issue su second-brain-worker 2 giorni prima della scadenza come promemoria.

7. Deploy

npm run deploy

Annota l'URL del Worker (es. https://second-brain.<tuo-subdomain>.workers.dev).

8. Inizializza il knowledge base (setup script)

Se hai la wiki Obsidian in locale, puoi ingerire tutti i file .md con lo script di setup:

# Locale (durante dev)
npm run setup -- --wiki-dir /path/to/wiki --url http://localhost:8787

# Remoto (dopo deploy)
npm run setup -- --wiki-dir /path/to/wiki --url https://second-brain.<tuo-subdomain>.workers.dev

# Dry run (lista file senza ingerire)
npm run setup:dry -- --wiki-dir /path/to/wiki

9. Configura il webhook GitHub (opzionale)

Per sincronizzare automaticamente la wiki quando fichi push su main:

  1. Vai su GitHub > Your Repo > Settings > Webhooks > Add webhook
  2. Compila:
    • Payload URL: https://second-brain.<tuo-subdomain>.workers.dev/webhook/github
    • Content type: application/json
    • Secret: lo stesso valore di WEBHOOK_SECRET
    • Trigger: "Just the push event"
  3. Salva

Da ora, ogni push su main che modifica file .md in wiki/ triggera la re-indicizzazione automatica.


Gestione dei secret

I secret sono gestiti via wrangler secret put e stored nella dashboard Cloudflare (mai nel codice). Ecco quando aggiornarli:

Secret Scade? Quando aggiornare
GITHUB_TOKEN — scade in base alla configurazione del PAT Quando il Personal Access Token scade: npx wrangler secret put GITHUB_TOKEN e incolla il nuovo token
GITHUB_TOKEN_EXPIRY — da aggiornare insieme al token Quando aggiorni GITHUB_TOKEN: npx wrangler secret put GITHUB_TOKEN_EXPIRY con la nuova data di scadenza
GITHUB_CLIENT_ID No Solo se revochi/ricrei l'OAuth App su GitHub
GITHUB_CLIENT_SECRET No Solo se revochi/ricrei l'OAuth App su GitHub
COOKIE_ENCRYPTION_KEY No Mai (a meno che tu non voglia invalidare tutte le sessioni attive)
WEBHOOK_SECRET No Mai (deve coincidere con il secret configurato nelle impostazioni webhook su GitHub)

Rotazione del GITHUB_TOKEN

Il GITHUB_TOKEN (Personal Access Token con scope repo) è l'unico secret con scadenza. Un Cron Trigger giornaliero controlla GITHUB_TOKEN_EXPIRY e apre automaticamente una issue su second-brain-worker 2 giorni prima della scadenza come promemoria.

Quando ricevi la notifica (o quando il token è già scaduto):

  1. Crea un nuovo token su GitHub Settings > Tokens con scope repo
  2. Aggiorna i secret su Cloudflare:
npx wrangler secret put GITHUB_TOKEN
npx wrangler secret put GITHUB_TOKEN_EXPIRY
  1. Incolla il nuovo token e la nuova data di scadenza (formato ISO, es. 2026-09-25T00:00:00Z)
  2. Chiudi la issue di promemoria su GitHub

Nessun altro secret o configurazione su Cloudflare deve essere aggiornato.


Configurare il client MCP nel IDE

Windsurf / Cursor

Crea o modifica il file mcp_config.json nel tuo IDE (in Windsurf: Settings > MCP Servers):

{
  "mcpServers": {
    "second-brain": {
      "command": "npx",
      "args": [
        "workers-mcp",
        "proxy",
        "https://second-brain.<tuo-subdomain>.workers.dev/mcp"
      ]
    }
  }
}

Sostituisci <tuo-subdomain> con il tuo subdomain reale.

Al primo utilizzo, il IDE aprira il browser per l'autenticazione GitHub. Dopo il login, i 5 tool (retrieve, ingest, reindex, read, grep) saranno disponibili nell'AI assistant.

Claude Desktop

Aggiungi al file claude_desktop_config.json:

{
  "mcpServers": {
    "second-brain": {
      "command": "npx",
      "args": [
        "workers-mcp",
        "proxy",
        "https://second-brain.<tuo-subdomain>.workers.dev/mcp"
      ]
    }
  }
}

Sviluppo

Comandi disponibili

Comando Descrizione
npm run dev Avvia il Worker in locale con wrangler dev
npm run deploy Deploy su Cloudflare
npm test Esegue i test (vitest)
npm run test:watch Test in watch mode
npm run typecheck Type checking con tsc --noEmit
npm run db:migrate Applica migration D1 in locale
npm run db:migrate:remote Applica migration D1 in remoto
npm run setup Script di ingest della wiki
npm run setup:dry Dry run dello script di setup

Struttura del progetto

src/
├── worker.ts          # Entry point: OAuthProvider + routing
├── mcp.ts             # SecondBrainMCP (McpAgent) con i 5 tool
├── types.ts           # Tipi condivisi: Env, request/response interfaces
├── http.ts            # Utility HTTP: jsonResponse, handleCORS
├── health.ts          # Health check endpoint
├── ingest.ts          # Ingestion: chunking, embedding, R2+D1+Vectorize, GitHub push
├── retrieve.ts        # Retrieve ibrido: semantic + keyword search, merge, metrics
├── metrics.ts         # Metriche aggregate di retrieve (latency, score, zero-result)
├── reindex.ts         # Reindex singolo file o tutti i file
├── read.ts            # Read raw text da R2 con offset/limit
├── grep.ts            # Grep regex sul contenuto indicizzato
├── chunker.ts         # Markdown chunker (split su ##/###, overlap, wikilink-safe)
├── github-handler.ts  # Hono app: REST API + OAuth flow (/authorize, /callback)
├── oauth-utils.ts     # Utility OAuth: state, CSRF, cookie, approval dialog
├── webhook.ts         # GitHub webhook handler per sync automatico
├── cron.ts            # Cron Trigger: reminder scadenza GITHUB_TOKEN via GitHub Issue
└── setup.ts           # Logica del setup script (ingest bulk)

migrations/
├── 0001_initial_schema.sql       # Schema D1: files, chunks, chunks_fts + trigger
└── 0002_retrieve_metrics.sql     # Tabella retrieve_metrics per observability

scripts/
└── setup.ts           # CLI entry point per il setup script

test/                  # Test suite (vitest + @cloudflare/vitest-pool-workers)

Test

npm test           # tutti i test
npm run typecheck  # type checking

I test usano @cloudflare/vitest-pool-workers per simulare l'ambiente Workers con D1, R2, e AI bindings.


Operazioni di manutenzione

Deploy del Worker

Dopo aver modificato il codice:

npm run typecheck   # verifica tipi
npm test            # verifica test
npx wrangler deploy # deploy su Cloudflare

Non serve reindicizzare dopo un deploy che non cambia la logica di ingest/retrieve.

Applicare una nuova migration D1

Quando aggiungi una migration (es. 0002_retrieve_metrics.sql):

# Locale (per dev)
npm run db:migrate

# Remoto (per produzione)
npx wrangler d1 migrations apply second-brain --remote

La migration va applicata prima del deploy se il codice dipende dalla nuova tabella.

Reindicizzare i documenti (popolare Vectorize)

Se i vettori sono mancanti o vuoi rigenerare gli embeddings:

# Reindex di un singolo file
curl -X POST https://second-brain.<tuo-subdomain>.workers.dev/api/reindex \
  -H "Content-Type: application/json" \
  -d '{"file_key": "wiki/concepts/Esempio.md"}'

# Reindex di tutti i file (attenzione: può hit rate limit su Workers AI)
curl -X POST https://second-brain.<tuo-subdomain>.workers.dev/api/reindex \
  -H "Content-Type: application/json" \
  -d '{}'

Nota: il reindex di tutti i file (113+) può fallire per rate limiting di Workers AI. Se semantic_hits è 0 dopo un reindex completo, reindicizza i file singolarmente con una pausa di ~1 secondo tra ogni chiamata. Verifica lo stato con:

npx wrangler d1 execute second-brain --remote \
  --command "SELECT COUNT(*) as total, COUNT(vector_id) as with_vectors FROM chunks"

Verificare le metriche di retrieve

Dopo aver fatto qualche retrieve, controlla le metriche aggregate:

# Ultime 24 ore (default)
curl https://second-brain.<tuo-subdomain>.workers.dev/api/metrics

# Ultima ora
curl https://second-brain.<tuo-subdomain>.workers.dev/api/metrics?period=1h

# Ultimi 7 giorni
curl https://second-brain.<tuo-subdomain>.workers.dev/api/metrics?period=7d

# Ultimi 30 giorni
curl https://second-brain.<tuo-subdomain>.workers.dev/api/metrics?period=30d

Periodi validi: 1h, 24h, 7d, 30d.

Le metriche includono: total queries, zero-result rate, avg/p50/p95 latency, score distribution, e search type breakdown (semantic/keyword/hybrid).


Documenti


Limiti e note

  • Il chunker e ottimizzato per markdown con frontmatter YAML e wikilink [[Nome]] (formato Obsidian)
  • L'embedding model bge-base-en-v1.5 produce vettori a 768 dimensioni — assicurati che il Vectorize index sia creato con --dimensions 768
  • Il retrieve ibrido usa pesi 50% semantico + 50% keyword, con top-K = 20 per ciascuna modalita
  • Il content dei risultati viene troncato a 2000 caratteri per chunk
  • L'OAuth flow supporta solo GitHub come identity provider
  • Il webhook sync processa solo file .md nella cartella wiki/ su push a main
  • I commit automatici del Worker su GitHub includono [skip ci] per non triggerare la pipeline di lint
  • Le metriche di retrieve sono best-effort: se la persistenza su D1 fallisce, il retrieve non viene interrotto

from github.com/50R1Paps/second-brain-worker

Установка Second Brain Worker

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/50R1Paps/second-brain-worker

FAQ

Second Brain Worker MCP бесплатный?

Да, Second Brain Worker MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Second Brain Worker?

Нет, Second Brain Worker работает без API-ключей и переменных окружения.

Second Brain Worker — hosted или self-hosted?

Доступен hosted-вариант: Unyly запускает сервер в облаке, локальная установка не обязательна.

Как установить Second Brain Worker в Claude Desktop, Claude Code или Cursor?

Открой Second Brain Worker на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Second Brain Worker with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development