1
Connectors
atlas edited this page 2026-07-01 19:50:21 +00:00
Connectors & Setup Wizard
brain.py is the engine. Connectors + the setup wizard are the product layer that turns it
into a real "second brain" — plugging into the apps where your life actually lives, instead of
manually pointing at directories.
your apps ──▶ Connector ──▶ scrub() + _stage() ──▶ brain.db ──▶ recall
(mail, cloud, (auth+pull) (SAME engine path) (hybrid)
files, chat…) │
└── app credentials ──▶ encrypted vault (NEVER in brain.db)
Three-layer design (why it's built this way)
- Engine (
brain.py) — pure, connector-agnostic, unchanged. Still usable as a bare library. - Connectors — one per app. Each authenticates, pulls data, and feeds it through the engine's same scrub + dedup path — so secrets inside emails/files are redacted before storage too.
- Vault (
connectors/vault.py) — app logins are encrypted at rest (Fernet + PBKDF2, 390k iters,~/.secondbrain/vault.enc, chmod 600).brain.dbnever sees a credential.
This preserves SecondBrain's core promise — local-first, secrets-scrubbed — while adding real
onboarding. (Verified: a DB_PASSWORD=… inside a synced file is scrubbed out of brain.db.)
The setup wizard
python3 setup.py # pick apps → sign in → test connection → sync
python3 setup.py sync # re-sync all connected apps (cron/systemd timer)
python3 setup.py list # list available connectors
Set BRAIN_VAULT_PASS to run the sync non-interactively from a timer.
Connectors today
| Connector | Auth | Ingests as |
|---|---|---|
| Files & folders | path | files |
| Email (IMAP) | host + app password | events |
| Nextcloud / WebDAV | URL + app password | files |
Roadmap connectors
- Google & Microsoft (Gmail/Drive/Calendar, Outlook/OneDrive) — OAuth; needs the wizard's local-web variant for the redirect + a registered app client id/secret.
- WhatsApp (via Evolution API), Calendar (CalDAV), Paperless-ngx, Odoo (CRM/ERP), Obsidian (vault folder), Git/GitHub (repos + issues).
Writing a connector (~40 lines)
from .base import Connector, Field, register, feed
@register
class MyAppConnector(Connector):
id = "myapp"; name = "My App"; blurb = "Pull stuff from My App."
fields = [Field("host","Host"), Field("token","API token", secret=True)]
def test(self, cfg): ... # verify creds, raise on failure
def sync(self, cfg): # pull -> feed() -> engine scrub+stage
items = [{"text": "...", "ref": "...", "ts": "...", "project": "myapp"}]
return feed(items, "events")
Drop the file in connectors/; the wizard auto-discovers it. feed() runs everything through the
engine's credential scrub — you never have to think about redaction.