Automating My Notes
The hardest part of maintaining a second brain isnβt capturing ideas β itβs keeping the whole thing from slowly turning into a pile of loosely related files with inconsistent formatting, broken links, and folders nobody audits.
Hereβs the honest version: I tried manual upkeep for about three weeks and gave up. Notes landed from everywhere β quick captures on my phone, Telegram messages to myself, half-finished thoughts at 11pm β and the inbox quietly ballooned. Links rotted. The index drifted out of sync. The vault became less useful the more I put into it.
The fix isnβt discipline. Itβs automation.
Version 1 β Vault Maintenance with Claude Code
Initially, the design was to delegate most of the work to Claude Code β not as a chatbot I open when something breaks, but as an active collaborator that runs maintenance in the background.
Design of Claude Code
Three layers make this work:
Skills β slash commands that encode vault-specific workflows. /organize, /state-of-brain, /fix-links. Each one knows the vault structure, the right file formats, and what βcorrectβ looks like.
Hooks β shell scripts that fire automatically after Claude writes or edits files. The blog index enforcement hook means I never have to remember to update a Table of Contents β it happens the moment a file is created.
Styles β writing presets that activate based on file path. I want to enforce different writing styles for different
- Blog posts are more expressive & descriptive on the process
- Internal notes are more concise & technical for concepts & learning points
- Claude CLI responses uses a humorous, yet cost-effective β caveman mode to save tokens
Pipeline for Organising my Vault
/organize is the main maintenance pass. It routes loose inbox notes to their right home, rebuilds the _index.md map files that let Claude navigate without loading the full vault into context, and handles section-specific logic for blogs, calendar, and tasks.
Itβs split into focused sub-skills:
/organize-inboxβ drain04 Inbox/into the right vault section/organize-knowledgeβ sort and index01 Atlas/and03 Efforts//organize-blogsβ rebuild blog index files for the Quartz site/organize-calendarβ fix links, rebuild calendar indexes, trigger the weekly report/organize-tasksβ consolidate open tasks across06 Tasks/
Run /organize with no arguments and all five run in order. Or target a specific section when you only touched one area.
Weekly Review
Every week, /state-of-brain reads across the vault and writes a synthesis report. It surfaces emergent themes (notes that are connecting without me noticing), contradiction clusters (conflicting advice across old and new notes), and stale efforts (active project notes from two months ago that are now done or abandoned).
The stale efforts section alone is worth running it for. Left to itself, 03 Efforts/ fills up with in-progress notes that silently stop being in-progress. The weekly report flags them and tells me what to do with them.
Reports land at 02 Calendar/Obsidian/YYYY/Mmm_Week_N.md β so May Week 3 2026 is at 02 Calendar/Obsidian/2026/May_Week_3.md. Browsable by month without translating ISO week numbers.
The Result
Daily: hooks β passive, no manual trigger
On-demand: /organize β batch process and rebuild
Weekly: /state-of-brain β synthesis and review
The vault maintains itself between deliberate work sessions. I write, Claude handles structure. The inbox drains. Links stay current. The weekly report keeps the bigger picture visible.
A second brain that requires constant manual maintenance isnβt a second brain β itβs a second job.
Go Deeper
The full setup lives across five posts in the AI-Native World section:
- Overview of Claude Structure β CLAUDE.md, vault layout, how skills fit together
- Organizing my Vault β the organize sub-skills in detail
- Weekly State of the Mind β what the weekly report actually generates
- Leveraging Hooks β passive automation with PostToolUse hooks
- Customizing with Styles β three writing modes and why theyβre separate
Version 2 β MCP-first Architecture
Version 1 worked, but it had a fundamental flaw: LLMs are non-deterministic. Ask Claude to organize the inbox twice β you might get two different file placements. Thatβs fine for exploratory work, not fine for automation that runs unattended.
The fix was to push the structure-sensitive logic out of the LLM and into deterministic code.
Improved Design - MCP
iujinwee-vault-plugin is a Go MCP server that exposes vault operations as tools. The LLM decides what to do; the MCP server does the how β reproducibly, every time.
The server sits between the AI agent and the vault filesystem. LiveSync handles the sync layer separately, replicating changes to a self-hosted CouchDB instance and fanning them out to other devices (phone, desktop, NAS). The MCP server doesnβt touch sync β it just reads and writes files, and LiveSync picks up the changes.
Telegram β AI Agent β LLM β MCP Server β Vault Filesystem
β
LiveSync β CouchDB β Other devices
Key implementation Details
- Bounded Worker pool & Concurrency
- Bounded concurrency for vault walks
- No go-routine explosion as the vault expands
- Per-file Mutex Registry
- Serialises concurrent writes to the same path
- E-Tag / optimistic locking
- SHA-256 content hash validated on every write
- Write conflict trigger a retry strategy rather than silently clobbering changes
MCP Tools
Six tools cover the full maintenance surface:
| Tool | What it does |
|---|---|
scan_vault | Walks the vault and writes a {name, ref} index to links.json |
generate_index | Creates/updates _index.md in each directory; skips if content unchanged |
update_links | Rewrites wiki-links to standard markdown links using the scan index |
get_daily_note_schema | Returns note categories and template structure |
append_to_daily_note | Inserts structured content into the correct daily note section |
run_maintenance | Single call: scan_vault β update_links β generate_index |
run_maintenance is the main scheduled operation β one tool call, full vault pass, combined summary back to the agent.
Create/ Add to Daily Note
The use case that motivated the whole thing: send a Telegram message β it lands in todayβs daily note, in the right section, formatted correctly.
Sequence Flow
- User sends
/daily <free-form text with different topics>to Telegram Bot,iujinwee-hermes - Activates
daily-note-managementskill which is activated when:/dailycommand- When the userβs intention is related to daily note taking
daily-note-management- Invokes
get_daily_note_schematool to retrieve note categories from vault template - LLM breaks down the message into different bullet points based on context
- LLM classifies each bullet point based on note category
- Sends structure to
append_to_daily_note
- Invokes
append_to_daily_note- Creates the daily note from template if missing
- Validates E-Tag before writing
- Retries up to 3Γ on conflict
Bam! With this workflow, all Iβll need to do is to send my thoughts, notes, or any links to my Telegram Bot and iujin-hermes will handle the heavy-lifting for me!
Outcome
The LLM handles classification. The Go server handles file I/O. The result is automation that runs reliably whether triggered from Telegram at midnight or a scheduled cron at 3am β no surprising file placements, no silent clobbers.
The Quartz side of this β how the blog actually publishes β is in Core Architecture.