claude-music
PLAYLISTS · MUSICBRAINZ · SOULSEEK · YOUR OWN NICOTINE+
No. 1 · MMXXVI

GET THE PLAYLIST ONTO DISK. NOT INTO SOMEBODY ELSE'S CLOUD.

A Claude Code plugin that takes a playlist from TIDAL, Deezer, YouTube Music or an export file (or just the songs and albums you name), works out which of its tracks you already own, canonicalises the rest against MusicBrainz, and fetches what is missing from Soulseek through the Nicotine+ client already running on your machine. One Soulseek identity, your shares intact, an M3U in the original order at the end. Nothing is queued until you have seen the count, the size and the users involved and said yes. No telemetry, no hosted service, no account but the ones you already have.

HOW IT RUNS
XIMPORT. A TIDAL playlist through the official API with your own app, a public Deezer playlist by link, your YouTube Music library, or a file: Spotify data export, Exportify CSV, plain CSV, M3U, JSPF, XSPF. Each playlist becomes a JSPF file with MusicBrainz ids.
XRESOLVE. ISRC first, then artist, title and duration against MusicBrainz. One request a second, cached, a proper User-Agent.
XDIFF. Your library is indexed with mutagen. Matches by MusicBrainz id, then ISRC, then normalised text within a duration tolerance.
XMATCH. A background job searches Soulseek per track, scores every result, keeps the best few. Three or more missing tracks of one release become an album search, folder inspected, track count checked.
XAPPROVE. Review candidates with the reason each one scored as it did. Approve, skip, or hand a long list to the matcher agent.
XQUEUE. Totals first. Then, and only then, the transfers go to Nicotine+.
XWRITE. An M3U in the playlist's own order. Tracks still missing are listed, never dropped.
XTIDY. Once the downloads have landed: tags normalised, lossy copies of FLACs dropped, every file shelved as Artist/Album/NN - Title. Dry run, then your yes.
CLAUDE CODE │ ├─ library server ─── playlists · MusicBrainz │ local index · matching │ └─ nicotine server ── Unix socket, 0600 │ ▼ MCP BRIDGE PLUGIN inside Nicotine+
FIG. 1 — TWO SERVERS, ONE CLIENT
Soulseek bans a user for thirty minutes after too many searches in a short window. The plugin enforces thirty-four per two hundred and twenty seconds, for every client, and says so instead of blocking.
— A LESSON TAKEN FROM SOCKSEEK
NO DOWNLOAD
WITHOUT YOUR YES
INSTALL
# in Claude Code
/plugin marketplace add h-3303/claude-music
/plugin install claude-music@claude-music

# in a shell: the bridge that runs inside Nicotine+
sudo pacman -S --needed nicotine+ uv
bash ~/.claude/plugins/marketplaces/claude-music/install.sh

The marketplace add clones the repository; the script copies the bridge into Nicotine+'s plugin folder and builds the library server's venv. Then tick MCP Bridge in Nicotine+ → Preferences → Plugins, and say /playlist-sync in Claude Code. Any distro with Nicotine+ 3.3 or newer and uv works; a git clone and ./install.sh does both halves at once. Always-on context cost: about 320 tokens a session.

The tools, in the order you use them.
  • import_playlist_file · import_remote_playlistfile or service link in, playlist_id out; connect_service logs in to TIDAL (PKCE, loopback) or stores YouTube Music headers, 0600, on your disk
  • resolve_playlistMusicBrainz ids, release track counts, durations the export did not carry
  • scan_library · diff_librarywhat you already own, and how it was matched
  • match_playlistthe background job; poll playlist_status, which shows rate-limit waits
  • review_candidates · approveconfidence 0–1 with a documented formula and a tested table of examples
  • queue_approvedtotals without confirm; transfers only with it
  • sync_downloads · write_m3udone, downloading, failed and retried from the next candidate; then the file
  • tidy_analyse · tidy_applythe library put in order; a report and a plan first, writes only with confirm
  • nicotine_status · search · browse_folderthe bridge on its own: search, inspect, browse a folder without downloading, queue, manage
THE SHELVES, AFTERWARDS

A download folder is not a library. /music-tidy reads every FLAC, MP3, M4A, Ogg and Opus under the music folder, computes the whole plan, and writes it to .tidy/report.txt before a single tag is touched. The rules it applies on its own are small and dull: trim whitespace, write feat. one way, set ALBUMARTIST, spell an album the same on every track, carry the date across its siblings, turn 3/12 into a track number and a total, prefer the FLAC to the m4a of the same song, file everything as Artist/Album/NN - Title.ext, sweep the download reports out, prune what is empty.

Everything else is a question, not a rule. Two spellings of one band, an album nobody dated, a folder of twelve artists that is probably a playlist dump, two edits of one song: each is put to you, and the answer goes into .tidy/approved.py, a plain file that remembers. The next run does not ask again.

TARGET STATE
Built To Spill/
  Keep It Like a Secret/
    01 - The Plan.flac
    02 - Center of the Universe.flac
    03 - Carry the Zero.flac
    booklet.pdf
.tidy/
  approved.py     your decisions
  report.txt      last dry run
  backups/        raw tags, before every write
  tag_changes.log every change, with its rule

Refuses to apply while a file was written in the last three minutes: a download is still landing. Refuses on path clashes. Deletes only what the plan listed by name.

WHAT THE SKILLS WILL NOT DO.

They will not queue a transfer before you have seen the totals and agreed in the same conversation. They will not raise the search rate limit, or suggest it, without asking. They will not dump a whole tracklist into the conversation. They will not touch the Spotify API: their terms forbid feeding platform data to a model, so the data export is the route. They will not delete a file the plan did not list, nor write a tag without a backup of the old one. They will not send anything anywhere but MusicBrainz, your own Nicotine+, and a streaming service you have connected yourself.

— playlist-sync and music-tidy, guardrails sections

Tested against Nicotine+ 3.3.10, 3.3.11 and master. 152 tests: a headless Nicotine+ core in-process, fake Soulseek peers, both MCP servers over stdio, a synthetic run from export to M3U, a synthetic library tidied end to end, the service connectors on recorded fixtures. Nothing touches the network.

everything stays on your machine

github.com/h-3303/claude-music · llms.txt · GPL-3.0-or-later