A personal music recommender where the brain lives in Markdown.
No recommendation logic in code — a handful of .md files turn
Claude Code into a music agent
that reads your real last.fm history every session and recommends
music grounded in what you actually listen to, not what an
algorithm thinks you should. A small set of Python helpers wrap the
data layer (last.fm API → compact text) for token efficiency. One
helper (make populate-mood) deliberately invokes Claude headless
to seed mood candidates on demand; everything else keeps the
reasoning in chat.
An antiphon is a sung response — a call answered with a counter-call. You ask; the library answers.
- Local-first. Your listening data is read from last.fm during a
session and used to produce recommendations on the spot. Nothing
is cached or logged on disk. The single exception is
make populate-mood, which sends mood context to Claude headless when you explicitly invoke it. - Markdown is the architecture. Antiphon stays in Markdown form
for as long as it can. The line at which it would graduate to
real software is documented in
WISHLIST.md§ 4. - The long tail matters. Antiphon is biased toward respecting the obscure half of your library, on the grounds that the mainstream half is well-served by every other recommender on earth.
- Every recommendation cites its reasoning. Picks should trace back to a specific signal in your listening data.
- Generated content is always labelled. If Claude produces a fake liner note or a hallucinated anecdote, it says so plainly.
New here? Walk through ONBOARDING.md.
What to type to get music: USING.md.
FEATURES.md— what's shipped.TODO.md— concrete near-term work.WISHLIST.md— full design space, including the unhinged. Section 4 explains the no-application-code stance.CLAUDE.md— operating instructions Claude reads every session.
MIT — do what you like with it.