Building a second brain with Claude and D1
I’ve tried every note-taking app. Notion, Obsidian, Apple Notes, Roam, Logseq. They all have the same problem: they require me to organize things.
I don’t want to organize things. I want to dump my thoughts and have them magically become useful later. So I built exactly that.
The architecture
Three layers: capture, process, retrieve. Everything runs on Cloudflare’s free tier.
1. Capture — zero friction or it doesn’t happen
Two input channels:
- Pi CLI — type
/dumpin my terminal and start talking in natural language - WhatsApp — send a text or voice note to a dedicated number
That’s it. No app to open, no page to create, no folder to choose. Voice notes get transcribed by Whisper. Everything lands in Cloudflare D1 as an unprocessed session.
The WhatsApp channel was a game-changer. Walking to grab coffee, had a thought about a project? Voice note. Realized I need to follow up with someone? Text message. The barrier between “I had a thought” and “it’s captured” became essentially zero.
2. Processing — AI does the filing
When I run /process, Claude reads each unprocessed session and extracts entities into four categories — PPIA:
- People — who was mentioned, relationship context, pending follow-ups
- Projects — what I’m working on, status, next concrete action
- Ideas — sparks worth remembering
- Admin — tasks, deadlines, things that need doing
The key design decision: entity-level merge, not document-level. When Claude extracts “Anand” from a brain dump, it doesn’t create a new note — it finds the existing people/anand entity and appends a new note to it. One entity per slug, with an append-only history.
Each extraction gets a confidence score. Below 0.6, it gets flagged for manual review via /fix instead of auto-filed. This prevents the garbage-in-garbage-out problem — AI confidently filing vague mentions as concrete entities.
3. Retrieval — the data comes back
This is where most PKM systems fail. You capture things and never see them again. I built multiple retrieval channels:
/digest— daily summary of what’s active, what needs attention, recent ideas/weekly— weekly review with trends, stale projects, and suggestions/search— full-text search across all entities and notes- WhatsApp
?query— send?anandto instantly find everything about Anand
There’s also /nextactions (audit vague project actions into concrete ones), /tensions (surface system friction), and /duplicates (find entities that should be merged).
The schema is deliberately simple
items (slug, category, name, meta JSON, last_touched)
notes (item_id, content, noted_at)
sessions (status, source, raw_text, created_at)
Three tables. That’s the whole database. No graph structures, no tag taxonomies, no folder hierarchies. Just entities and their notes.
The meta field is a JSON blob with category-specific fields — status and nextAction for projects, context and followUps for people, oneLiner for ideas. Flexible enough to evolve without migrations.
The API layer
A Cloudflare Worker exposes a REST API: create sessions, list/query items, append notes, full-text search. Pi talks to it through a custom tool extension — every /dump, /process, /digest command is just an API call.
The WhatsApp integration uses the same Worker as a webhook endpoint. Meta’s Cloud API sends incoming messages, the Worker processes them (brain dump or search query), and responds in the same conversation.
Total infrastructure cost: $0/month. Cloudflare’s free tier covers Workers, D1, and the API. The only paid service is the Claude API for entity extraction, which is pennies per brain dump.
What actually works
Capture frequency went up 5–10x. Not because I’m more disciplined — because the friction disappeared. Voice notes while walking are the highest-bandwidth capture method I’ve found.
Things actually come back. /digest reminds me of follow-ups I would have forgotten. /weekly surfaces patterns I wouldn’t have noticed. This never happened with Notion.
The system gets smarter over time. More entities, more notes per entity, richer context for AI to work with. After a few weeks, /digest knows what my active projects are, who I’m working with, and what’s likely to need attention.
Zero maintenance. I don’t reorganize, re-tag, or clean up. The append-only model means I just keep adding, and the AI synthesizes the current state from the full history.
What I’d do differently
Start with WhatsApp earlier. I built the Pi CLI first and added WhatsApp later. In hindsight, WhatsApp should have been day one — it’s where most of my captures come from now.
The confidence threshold was essential from the start. My first version auto-filed everything. It took about two days of cleaning up false entities to add the 0.6 cutoff. Should have started with it.
Keep the schema boring. I considered graph databases, vector embeddings, semantic links. Glad I didn’t. A simple relational schema with full-text search covers 95% of retrieval needs. You can always add vectors later — you can’t easily undo premature complexity.
Stack
| Component | Technology |
|---|---|
| API | Cloudflare Workers |
| Database | Cloudflare D1 |
| AI | Claude API (entity extraction) |
| Voice | Whisper (transcription) |
| CLI | Pi (coding agent) |
| Messaging | WhatsApp Business API |
The whole thing — API, database, WhatsApp webhook, CLI commands — was built in a few sessions with AI as a collaborator. The .plan/ files have the full session-by-session build log if you’re curious about the process.