Back to Projects
Active Case study Featured

Muse: Content-Scouting Agents on a Claude Subscription

Python Claude Code CLI AI Agents Whisper SQLite launchd

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.