← Builds

Build · Internal

Nucleus Radio

A personal radio network built on the music I own. Eight stations, programmed and hosted by a local AI agent on my own hardware, that introduce their own songs, run their own shows, and know how the artists in my collection connect to one another.

Tune in to the station ↗

Eight stations · a local agent that programs them · TTS DJ · a generative show · a map of the collection

Challenge

A few years ago my family talked me into a streaming subscription. I came around slowly, then got hooked on the exploration, chasing one artist into the next. After a while Spotify started telling me, every week, how many times I'd played some band, as if I'd gone looking for it, when its own playlists had been rotating the same handful of names past me for days. The exploration dried up. The deep tracks and hidden gems I used to reach for had somehow been algorithmed away from me.

I self-host the rest of my infrastructure, media library included, so I started wondering how to play my own collection the right way, while honoring the music I'd found and worn out during my time renting songs from the streamers. I wanted a station, something with a schedule and a point of view, running on my own collection and my own hardware. And I wanted it to be a place where the rest of what I build could show up, the Tugboat briefings, the Feed and Thread reads, the text-to-speech work, and the generative writing, all of it airing between the songs like segments on a broadcast.

Build

So I built it a piece at a time, and that turned out to be the whole point. First it was just the music on an open port, streaming to a browser. Then a stream URL I could point a radio app at, so it went where I did. Then metadata and album covers, so it carried itself like a station. Then a schedule, with blocks of programming like Mellow Sunday and Overnight Open. Then a TTS DJ that names the songs as they land, and then the blocks too. Then time and weather on the hour. Then a show. Then, slowly, a DJ with a mind of its own, one that watches what plays and when, learns from my scrobbles and my skips, and starts making suggestions.

What started in May as one station shuffling my library became that same station with a schedule, then a schedule with a voice, and it kept going. There are eight stations now. Nucleus Radio is still the flagship, and alongside it sit Country, Classic Rock, New Wave, Alternative, Ambient, and Pop, each with its own identity, its own schedule, and its own place on the dial. Happy Accidents outgrew being a block and became a channel of its own. They all draw from one library of 56,042 tracks by 4,432 artists, and they have aired 239,584 plays between them since the middle of May.

The across-the-dial view: eight station cards, each with the station name, its dial number from 8000 to 8007, and the song playing on it right now
Across the dial, all eight stations and what each one is playing right now

None of that schedules itself, though, and it would be unfair to the machine to say it did. Behind every one of those decisions is Nucleus, the agent that runs my homelab, thinking with a 27-billion-parameter Qwen model on a single GPU in the next room. What I did not plan, and now like best, is that Nucleus ended up wearing a different hat for every job. It is the program director when it proposes next week's schedule for me to approve or send back. It is the DJ when it names a song on the way in. It is the staff writer when Happy Accidents needs an intro connecting a song to something that happened on the same date in another year. It is the one that turns up in Telegram to argue that an artist has earned an hour of their own. One agent, covering a small station's worth of shifts, in the WKRP sense where the same few people do everything.

Three Telegram messages from Nucleus: proposing next week's radio with a Review the week button, reporting a finished Happy Accidents episode, and asking whether 222 Ronnie Milsap tracks have earned a block of their own
One agent, three jobs: proposing the week, delivering a finished show, and making the case for an artist

All of the thinking is local. The writing runs on Qwen on my own GPU, the voice is a Qwen text-to-speech model on the studio box, and nothing about my listening is sent anywhere to be turned into a recommendation I did not ask for. That was the point of leaving the streamers, so it would be strange to rebuild the same arrangement with better manners.

The Nucleus Radio station page: a now-playing hero with album art for Pearl Jam's Rearviewmirror and a Listen Live button, an up-next queue, and a recently-played list, under an ON AIR light and 8000 on your dial
The station page: now playing, up next, and recently played

The schedule runs itself once Nucleus has set it. Each block holds a rule, and every time it comes up it reaches back into the same history the station is writing. The station learns from itself. When a Comeback Shuffle digs up a song I hadn't heard in years and airs it this morning, that play lands in the same table the pickers read, so by the afternoon it's back in the pool of recent favorites. What I play shapes what plays next.

Today's schedule on the New Wave station: a stack of blocks with start times and durations, from a NewWave: All backbone through a four-artist New Wave Mix to hour-long spotlights, with the block currently on air marked NOW
A day on New Wave: a backbone block, a four-artist mix, and spotlights, with the block on air marked NOW

One of the blocks writes itself, too. Happy Accidents picks a song with a known release date, digs up something that happened on that same calendar day in a different year, and asks Qwen to write a DJ intro that connects the two with total confidence. The stretch is the joke. If a pairing falls flat, it reaches for a different piece of history and tries again, so the host keeps its footing. A dozen of those become an hour-long episode, rendered ahead of time and aired on its slot, in the same measured voice every week.

A Happy Accidents episode page: a show-open intro, then numbered segments pairing a song with a same-day historical event and an AI-written DJ intro
Happy Accidents, a show that writes itself, each song paired with a same-day fact

The DJ side is where it got personal. Nucleus, the voice of the station, keeps a set of beliefs about what I like, weighted by how it learned them, my own words outranking a guess it drew from a skip. It proposes a week of programming for me to approve, rests the artists I've heard plenty of, and brings back the ones I love. It suggests which artists have earned a block of their own, and it builds blocks that run several related artists together, so a folk lane on Country can move between neighbours instead of sitting on one name.

The newest piece is a map of the collection. Every artist, album, genre, and band member is a node, and the lines between them are the things I actually wanted to see: who played in which band, who turned up on whose record, and which genres sit next to each other. It runs to 12,243 nodes and 17,535 edges, including 4,426 band memberships and 3,145 collaborations. It answers the question the streaming service never would, which is not what else sounds like this, but who else was in the room.

The music map with Indigo Girls as the central seed node, ringed by their albums and genres, with lines running out to band member Amy Ray and The Butchies, to Emily Saliers, and to the Alternative, Pop, Country, Classic Rock and Nucleus Radio stations
The map, with Indigo Girls at the centre: their albums and genres, the stations that play them, and the band members who lead off to other artists

Outcome

All of it comes together at station.gogomito.com, a page that shows what's playing now, what's coming up next, the day's schedule, and the week ahead, with the shows given their own blocks and their own descriptions. There's a Listen live button that plays the stream right on the page, and the same stream drops into any radio app. The collection has its own dashboard, so I can see what each station played most today, yesterday, this week, last week, or across the last month, and the map is there to wander through whenever I want to follow a band member into something I forgot I owned. The scrobbles are honest, too. The station reads the live stream's title and logs each song at the moment it hits the air, a few minutes after it was queued.

The collection dashboard: tracks, artists, albums and all-time plays as four figures, then top artists, albums and songs per channel, filterable by today, yesterday, this week, last week and the last 30 days
The collection dashboard, the shelves every station draws from, by channel and by window
The week-ahead grid on the Alternative station: seven day columns from Friday to Thursday, each stacked with blocks including Alternative Mix and Spotlight, with today's column outlined and the current block lit
The week ahead on Alternative, seven days of blocks with today outlined and the block on air lit

Small things that make it feel like a station

What makes it convincing is the small stuff, the things a real station does without thinking about it. Each one took an afternoon.

The whole look is documented as a living design system rendered from the production stylesheet, a dark broadcast field with a pulsing on-air light and 8000 on the dial. It started as music on an open port. It's a station now, and it's still the same project, still getting one more layer whenever I think of one.

The Nucleus Radio living design system: the masthead, a nine-token color palette, and the typography scale, rendered from the production stylesheet
The living design system, every component rendered from production code

The Stack