# claude-music > No longer updated as of 2026-09-17. Development continues in flacli (https://flacli.vercel.app, https://github.com/h-3303/flacli): the same engine, model-agnostic, as a command line and two MCP servers, with a thin Claude Code plugin over it. Use flacli for anything new. > A Claude Code plugin that gets a streaming playlist onto disk. It imports the playlist (from TIDAL, Deezer, YouTube Music, or an export file; or the user simply names songs and albums and request_music fetches them in one call), canonicalises it against MusicBrainz, finds which tracks the local library already has, fetches the rest from Soulseek through the user's own running Nicotine+ client with the user's approval, and writes an M3U in the original order. A second skill tidies the library afterwards: tags normalised, lossy duplicates of FLACs dropped, files shelved as Artist/Album/NN - Title. Everything runs locally; the only network traffic is MusicBrainz lookups, Soulseek through Nicotine+, and the streaming services the user connects. GPL-3.0-or-later. ## Install In Claude Code: /plugin marketplace add h-3303/claude-music /plugin install claude-music@claude-music Then, in a shell, the bridge plugin that runs inside Nicotine+ (requires Nicotine+ 3.3 or newer and uv; the marketplace add cloned the repository): bash ~/.claude/plugins/marketplaces/claude-music/install.sh Then tick "MCP Bridge" in Nicotine+ → Preferences → Plugins. Every Claude Code session then starts with a one-line health check of the bridge and the venv. Always-on context cost is about 320 tokens. Alternative, both halves at once: `git clone https://github.com/h-3303/claude-music && cd claude-music && ./install.sh`. For Claude Desktop or any other MCP client, the Nicotine+ server alone is registered as the stdio command `uv run --script ~/.local/bin/nicotine-mcp` (installed by install.sh). It is also published on its own as https://github.com/h-3303/nicotine-mcp. ## What the plugin contains - Skill `/playlist-sync` — import → resolve → diff → match → approve → queue → sync → write M3U. Triggers on a playlist file, "sync a playlist", "missing tracks", "get this album onto disk". - Skill `/music-tidy` — dry run, questions, then apply with confirm. Triggers on "tidy my music", "sort the new downloads", "organise my library", messy tags, duplicate m4a/flac copies. - Agent `matcher` — reviews Soulseek candidates for playlists over ~40 tracks in its own context and returns approve/skip/ask lists. - MCP server `library` — import_playlist_file, connect_service, service_status, disconnect_service, list_remote_playlists, import_remote_playlist, request_music, resolve_playlist, scan_library, diff_library, match_playlist, playlist_status, cancel_job, review_candidates, approve, skip_tracks, queue_approved, sync_downloads, write_m3u, list_playlists, delete_playlist, library_status, tidy_new (files newly arrived tracks, which sync_downloads also does by itself), tidy_analyse, tidy_apply, beets_status, beets_import (optional beets hand-off, dry run first), troi_status, troi_scan, troi_resolve (optional ListenBrainz content resolver for MusicBrainz-tagged collections). A plugin monitor reports finished and failed downloads as they happen. - MCP server `nicotine` — nicotine_status, search, get_search_results, list_searches, stop_search, browse_folder, get_folder_contents, download_files, download_folder, list_downloads, cancel_downloads, retry_downloads, clear_downloads. - Hook `SessionStart` — bridge reachability and venv check, stdlib only. - User config: music_dir (default ~/Music), mb_contact (MusicBrainz User-Agent contact), bridge_socket (only if changed in Nicotine+). ## Inputs accepted Direct: TIDAL (official API v2, Authorization Code + PKCE with the user's own app, loopback redirect on 127.0.0.1), Deezer (public playlists, no login), YouTube Music (ytmusicapi with browser request headers stored 0600 locally). Files: Spotify account data export (Playlist1.json, YourLibrary.json), Exportify CSV, generic CSV, M3U/M3U8, JSPF, XSPF. The Spotify Web API is deliberately not used: Spotify's developer terms forbid feeding platform data to an AI model, so the data export is the route. ## Guardrails - Nothing is queued on Soulseek until the user has seen track count, size and users and called queue_approved with confirm=True in the same conversation. - Nothing is deleted or retagged until tidy_analyse has written a plan, every deletion has been listed by name, and tidy_apply is called with confirm=True. Raw tags are backed up before every write. - The Nicotine+ bridge enforces a search rate limit (34 searches per 220 s by default) for every client, because Soulseek bans an account for 30 minutes when it is exceeded; clients back off on `rate_limited`. - The bridge listens on a 0600 Unix socket and rejects peers whose UID differs; there is no TCP listener. - No telemetry, no hosted services. ## Architecture Claude Code ─stdio─▶ library server (playlists · MusicBrainz · local index · matching) and ─stdio─▶ nicotine server ──Unix socket──▶ MCP Bridge plugin ──▶ Nicotine+ core. Tested against Nicotine+ 3.3.10, 3.3.11 and master with MCP Python SDK 2.x; 152 tests run a headless Nicotine+ core in-process with fake peers and never touch the network. ## Links - [Site](https://claude-music-liard.vercel.app/): this page, in full. - [Repository and README](https://github.com/h-3303/claude-music): install, the tool table, the security model, development and tests. - [Roadmap](https://github.com/h-3303/claude-music/blob/main/docs/ROADMAP.md): phases, verified external facts about streaming-service exports and APIs. - [nicotine-mcp](https://github.com/h-3303/nicotine-mcp): the Nicotine+ bridge and MCP server on their own, for any MCP client.