Capture
A message, image, PDF, or link lands in Discord #inbox. The bot enqueues a job, never blocks.
A personal open-brain that ingests everything I capture and makes it answerable by AI agents through MCP.
A personal AI second brain that doesn't ask me to organize anything. I drop things into a Discord channel and ask later. The system handles the capture, classification, embedding, and merge into a canonical memory — and exposes the answer surface to Claude Code, Codex, and a public chat through MCP.
The problem isn't capturing information — it's retrieving it when you need it and knowing what you know. Notes app, browser bookmarks, Apple Notes, Discord screenshots, git history — knowledge lives in eight places and I never find it again. Every tool I tried required manual organization I don't actually do.
Designer, engineer, operator. Solo build.
MCP changed the answer surface. Once Claude Code and Codex could call into a brain over MCP, the second-brain problem stopped being about UI and started being about pipelines, retrieval quality, and what the public surface should and should not say.
How a single Discord message becomes something the brain can answer with.
A message, image, PDF, or link lands in Discord #inbox. The bot enqueues a job, never blocks.
Worker routes by MIME type and pulls text from PDFs, images (vision OCR), Excel, DOCX, or web links.
Llama 3.1 8B returns strict JSON: category, confidence, entities, tags, suggested action. Below 0.75 → review queue.
Text chunked at 512 tokens with 64 overlap, embedded via nv-embedqa-e5-v5 into 1024d vectors.
Llama 3.3 70B decides: merge into an existing Note or create a new canonical one. Source artifacts are kept with provenance.
Same canonical store powers /brain chat, MCP tools for Claude Code & Codex, and the private dashboard.
Items below the 0.75 gate get a clarification question and a review-queue row instead of being silently dropped.
Every 20 merges, an on-demand synthesis pass runs across recent signals to surface threads I haven't seen.
Discord #inbox is the capture entry point. The bot enqueues into ARQ on Redis; the worker runs an async pipeline — extract (PDF/image/excel/docx/link), classify (Llama 3.1 8B → strict JSON), embed (nv-embedqa-e5-v5, 1024d), librarian merge (Llama 3.3 70B) into a canonical Note. Classification is gated at 0.75 confidence — below that, a review queue and clarification flow. Storage is a six-layer canonical memory (Evidence → Observation → Episode → Thread → Entity → Synthesis); story is presentation, not storage. FastMCP exposes search / ask / capture / context / protocol / story tools to Claude Code and Codex. A 5-page private Atlas dashboard sits on the same data — every page is one or two indexed SQL queries, no on-render LLM calls. The public surface is a separate, owner-approved snapshot — PublicFactRecord rows that only surface when I check the approval queue.
Five Docker services on one droplet; one canonical data store; two distinct answer surfaces.
Bot cog enqueues every message + attachment as an ARQ job.
Apple Notes, Chrome history, git, project files, life exports — periodic scans.
Five concurrent jobs max, 5-minute timeout, async throughout.
Strict JSON contracts at every step; failures stage to a review queue, not the dead-letter.
Canonical Notes + the six-layer memory (Evidence → Synthesis); vector search is project-aware.
Every LLM call logs model, tokens, cost, duration, trace_id.
search / ask / capture / context / protocol / story tools for Claude Code & Codex.
Five Atlas pages — What's New, Inbox, Library, Projects, Public Facts. No on-render LLM calls.
Owner-approved PublicFactRecord allowlist + scrubbed chat. The site you're reading.
0.75 separates auto-accept from owner-review. Below the line, the brain asks a clarification question instead of guessing.
The public site reads from a separate snapshot. Promoting anything to public is a manual approval — never an automatic derivation.