A scheduled multi-agent pipeline that reads before it recommends, with no API key and no public surface.
A personal agent pipeline that searches YouTube and the web, reads or transcribes each candidate before recommending it, writes Markdown notes to a knowledge base, and serves a private feed. Every model call goes through the headless Claude CLI on an existing subscription, with no API key.
- candidates gathered on the first run (8 read, 7 queued)
- 66
- candidates gathered on the first run (8 read, 7 queued)
- tokens of fixed overhead per model call
- ~2.5k
- tokens of fixed overhead per model call
- items queued by the verified scheduled production run
- 7
- items queued by the verified scheduled production run
- first run, first commit, and verified scheduled production
- Same day
- first run, first commit, and verified scheduled production
The problem
Good long-form videos, essays, and papers are hard to find, and recommendation feeds favor engagement over depth. The goal was a set of agents that find candidates, actually read or transcribe each one before recommending it, keep a Markdown knowledge base, and serve a short feed that works from a laptop or a phone.
Constraints
- Run on an existing Claude subscription instead of metered API keys, using the claude CLI in headless mode.
- Keep fixed per-call overhead small. Replacing the default system prompt and using a strict MCP config keeps it to about 2.5k tokens per call.
- Run unattended under launchd, where interactive logins go stale. Scheduled runs authenticate with a long-lived token read from a private file.
- YouTube's caption endpoint rate-limits bursts (HTTP 429), so caption requests are spaced 4 seconds apart, with backoff and a local Whisper fallback.
- Private by design: the feed is tailnet-only and never public, and downloaded audio exists only in a temporary directory until it has been transcribed.
What I built
- A staged pipeline: plan, gather, judge, pick, ingest, then refresh the queue. The planner writes about 8 YouTube searches (about 20% of them exploratory). yt-dlp runs the searches and checks followed channels over RSS, and a web scout uses WebSearch and WebFetch.
- A judge agent scores candidates 0 to 10 from metadata in batches of 40. A pick step keeps either videos or articles from taking more than 75% of the picks.
- An ingest step that reads captions, a Whisper transcript, or the extracted article text, then asks a summarizer for a verdict and writes an Obsidian-ready note. It runs on 3 worker threads.
- Each agent role has its own tool allowlist and a JSON-schema structured output (--json-schema), so every stage gets typed data back instead of free text.
- A SQLite store that records every candidate, including rejected ones, so nothing is judged twice. A small standard-library feed server has thumbs-up, thumbs-down, and done buttons, and those ratings feed into the next run's prompts.
- launchd jobs run the pipeline daily at 05:30 and keep the feed always on. A deploy script syncs the code, upgrades dependencies, runs the tests, and reloads the jobs.
How it's verified
- 7 unit tests cover the deterministic parts: caption VTT parsing and dedupe, paragraph grouping, video-ID parsing, URL dedupe, the one-retry rule, slugs, and durations. The deploy script runs them before reloading the scheduled jobs.
- Two quality gates: a judge score before reading and a verdict after reading, both with a threshold of 7.
- Production was verified end to end under launchd on 2026-10-31, including a run that queued two items through the Whisper fallback.
Results
- Running daily on a home machine with no API key and no public endpoint. The production queue held about 24 read-and-summarized items after its first day.
- Every recommendation comes with a note written from the full transcript or article, not from a title and thumbnail.
TODO (Matt): numbers to add
- TODO: Share of recommendations rated thumbs-up after a few weeks of use.
- TODO: An offline eval set for the judge and verdict gates; the thresholds are LLM judgments that haven't been measured yet.
How coding agents fit in
- Built with Claude Code in a single session on 2026-10-31. All 4 commits carry a Claude co-author trailer, and v1 landed as 22 files and 1,615 lines.
- The repo's agent notes record its rules and gotchas, such as the caption rate limit, no persistent downloads, and tailnet-only access, so later agent sessions don't relearn them.