All posts

Introducing MusicSeed

Your music library has a discovery problem. Naturally, I wrote more software.

You know the moment. Somebody drops a track into the conversation and your brain immediately files a feature request: more of this, for the next hour, please.

You open Plex. Somewhere in your lovingly maintained collection is the perfect follow-up. Unfortunately, retrieving it requires querying the least reliable index in your infrastructure: your own memory.

You try a genre filter. Maybe a year range. Congratulations, you’ve implemented a WHERE clause. The vibe remains unresolved.

So I built MusicSeed — a local-first, open-source recommendation engine for your Plex music library. Give it a seed track, or a handful that occupy the same musical neighborhood, and it ranks candidates from your own collection using sonic similarity, metadata, popularity, and play history.

Preview the results. Tweak the knobs. Write the playlist back to Plex.

There is some pipeline bootstrapping before the dopamine: configuration, metadata ingestion, sonic analysis, and enrichment. We’ll get to that. The first-run experience includes actual work, a shocking regression from the industry’s preferred onboarding narrative.

Why I built it

Three threads have been running in my brain for a long time: recommendation systems, my music collection, and the conviction that open source is a pretty effective way to improve somebody else’s day.

MusicSeed is where those threads finally synchronized.

If it helps another collector rediscover an album they mentally garbage-collected years ago, keep a mood going, or assemble a playlist without manually traversing their entire catalog, I’ll consider that a useful contribution to the commons.

I’ve also had some spare cycles lately, which let me reconnect with something I’d allowed to bit-rot: the joy of writing software because I wanted it to exist.

No stakeholder alignment ceremony. No quarterly OKR requiring a defensible number of delighted users. Just an itch, a terminal, and the familiar suspicion that this should be a reasonably small project.

Experienced developers may now laugh.

Made for collectors, not streamers

MusicSeed is for the people who run Plex, maintain tags, make backups, and have opinions about directory structures that normal people would find medically concerning.

You know who you are.

Your library has provenance. It has obscure releases, alternate versions, and a suspiciously complete discography you acquired during a three-week hyperfixation. It also has the deep cut from 2007 that would absolutely belong in tonight’s playlist if you could remember its name.

That’s the discovery problem I care about.

Collectors keep music available, organized, and discoverable — for themselves, their friends, their families, and whoever eventually inherits the NAS and its undocumented operational requirements.

MusicSeed exists to make that collection easier to explore.

Before the first mix: bootstrap the pipeline

A recommendation engine needs signals. Installing the code does not cause useful data to materialize through dependency injection.

First, configure the Plex connection and database access. MusicSeed ingests your library’s metadata and play history into its own local SQLite store. If Plex runs on a NAS or another host, it can fetch consistent database snapshots over SSH.

Then comes sonic similarity. Plex analyzes the audio; MusicSeed imports the resulting vectors. These are separate stages in the pipeline. Dispatching the analysis job is not equivalent to receiving the finished artifact, regardless of how optimistically you stare at the progress indicator.

Popularity has its own enrichment pass: ListenBrainz, with Spotify as an optional fallback. External lookups introduce the usual distributed-systems seasoning — provider availability, matching coverage, and waiting.

On a large collection, analysis and enrichment can take a while. Your hardware, existing Plex analysis, and provider responses all affect the wall-clock time. The web UI exposes progress and coverage, and MusicSeed’s import and enrichment jobs are resumable.

You can start querying with whatever data is available. Just remember that incomplete signal coverage affects the ranking. An empty feature does not become informative because the interface looks confident.

What it does, through the eyes of a collector

Every feature started as a small, deeply personal bug report.

“I want to keep this exact mood going.”

Once the library is prepared, give MusicSeed one or more seed tracks. It scores candidates from your collection and produces a mix you can inspect, adjust, and save to Plex.

The recommendation loop gets shorter. Your internal playlist committee can finally stop holding meetings.

“I know I own something that sounds like this — I just can’t find it.”

MusicSeed uses Plex’s sonic analysis vectors to find sound-based similarity. Those vectors live in MusicSeed’s local store after import, ready for the recommendation engine to use.

This gives retrieval something more useful to work with than your increasingly speculative recollection of album artwork.

“This playlist is good. I just want more of it.”

Use an existing playlist as the starting point and ask MusicSeed for complementary tracks. Review the candidate additions, then append the ones you want.

Tracks already present are skipped when adding. Your playlist does not need an accidental multiset implementation.

“Why did you pick this track?”

Recommendations expose score breakdowns. Inspect them in the web UI or run the CLI with --explain to see which signals contributed to the ranking.

Useful debugging information, right there in the product. A bold architectural decision.

You can interrogate the result, adjust the parameters, and decide whether the engine’s reasoning matches your ears.

“I’ve heard everything I like a thousand times.”

The novelty signal uses play counts to favor less-played tracks. That gives the neglected corners of your collection a chance to escape cold storage.

Your five emotional-support songs will survive a brief reduction in production traffic.

“One signal is never enough.”

MusicSeed combines six signals: sonic similarity, popularity proximity, style, genre, era, and novelty.

Their weights feed a combined score. Tune them individually in the web UI or CLI, or start with a preset. You also get constraints such as year ranges and per-artist limits.

Yes, there are knobs. You’re running a self-hosted recommendation engine against a personal music archive. I assumed knobs were part of the acceptance criteria.

“I want to keep control of my library.”

The database and recommendation engine run locally. SQLite does the persistence work without requiring you to provision a database cluster to select the next song.

Optional enrichment contacts external services. If you connect a cloud AI agent, tool results containing track information may go to its provider.

That boundary matters. localhost somewhere in the architecture is not a universal privacy guarantee.

“Will it wreck my Plex?”

MusicSeed reads Plex metadata without editing its database files. Playlist mutations go through the Plex API, with previews so you can inspect the selection before saving.

The write paths handle retries: repeat the same playlist creation and you get the existing playlist; repeat an append and tracks already present are skipped.

Idempotency earns its keep whenever a response disappears and somebody decides to smash the button again.

Import and enrichment are resumable, too. Your carefully accumulated progress deserves better than being held hostage by one interrupted process.

“I’d rather just ask my assistant to make the mix.”

There’s an adapter for that.

MusicSeed now exposes musicseed-mcp, an MCP server with typed tools for library search, recommendation previews, and playlist creation and population.

Once the library is prepared and the agent is connected, you can ask:

Find ten complementary tracks for my Evening Mix playlist. Show me the recommendations before adding them.

The agent orchestrates calls to the same recommendation engine used by the web UI and CLI. Same prepared data, same signals, same coverage gaps.

MCP does not fast-forward Plex’s analysis queue or summon missing enrichment data. Adding an agent to the dependency graph leaves the underlying prerequisites stubbornly intact.

The intended workflow is search → preview → approve → write. The write carries the selected track IDs, and retries reconcile against existing playlist contents.

A conversational interface can be handy. The plumbing still has to work.

Honest, local, and yours

MusicSeed grew out of a very specific desire: get more enjoyment from a collection I’d already spent years maintaining.

There’s setup involved. The recommendations have room to improve. Occasionally, your ears will file a perfectly valid bug report against the ranking.

But then it surfaces a forgotten track that fits the moment, and the whole exercise makes sense again.

It’s MIT-licensed, built in the open, and available for tinkering, extending, and submitting the inevitable PR titled “small fix” that changes twelve files.

Use the web UI. Live in the terminal. Connect an agent once the pipeline is ready.

If you run Plex and care about what’s in your library, this was made for you.

Welcome home. Your backlog can wait until the track finishes.

Back to top ↑