Tailorlist MCP
Fills in genre information for artists where Spotify has none, using MusicBrainz as a supplemental genre source during collection analysis.
Allows reading and analyzing a user's own Spotify library and playlists, including loading playlists, viewing dashboards and stats, searching tracks, finding duplicates, comparing playlists, grouping tracks into draft playlists by decade/genre/sound, and writing organized results back as Spotify playlists without deleting existing playlists.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Tailorlist MCPfind duplicate tracks across my playlists and show me a cleanup preview"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Tailorlist MCP
Work in progress. Phases 1, 2a and 2b work: load playlists, dashboards, stats, searches, duplicates, comparison, grouping into drafts.
An MCP server that lets Claude read, analyze and reorganize your own Spotify library: find duplicates across playlists, group thousands of tracks by genre family or by sound, compare playlists, and write the result back to Spotify as playlists with the exact tracks.
Why
Claude's official Spotify connector has five tools: search (up to 20 results),
generate_playlist (from a text prompt only), save_to_library, remove_from_library and
get_currently_playing. It can't read the full contents of a playlist, and it can't create a
playlist from an exact list of tracks. Reorganizing a collection you already have needs both.
Related MCP server: Spotify MCP Server
How it works
Runs locally (stdio) and works with Claude Desktop and Claude Code.
Uses your own Spotify app (free to register at developer.spotify.com, needs Spotify Premium). Your app, your token, your machine: nothing goes through a third-party server.
Caches your collection in a local SQLite file. Claude only sees summaries and IDs, so a 5,000-track library doesn't flood the conversation.
Genres come from Spotify, filled in from MusicBrainz where Spotify has none. Audio features come from ReccoBeats.
It previews every change before writing, and never deletes a playlist.
Setup (for now, from source)
Create an app at https://developer.spotify.com/dashboard (needs Spotify Premium). Add
http://127.0.0.1:8888/callbackas a Redirect URI and tick "Web API".Install:
uv venv && uv pip install -e .Put your app's Client ID in
~/.tailorlist-mcp/.env(see.env.example). No client secret needed.Log in once:
.venv/bin/tailorlist-mcp login(or ask Claude to callconnect_spotify).Add it to Claude Code:
claude mcp add -s user tailorlist -- /path/to/.venv/bin/tailorlist-mcp. For Claude Desktop, add it undermcpServersinclaude_desktop_config.json.
Tools so far: connect_spotify, list_my_playlists, load_playlists (shows the overview
dashboard after loading), show_overview, show_playlist, get_playlist_tracks,
collection_stats (counts and averages by decade, artist, genre, playlist, month...),
find_tracks, find_duplicates, compare_playlists, fill_genres (MusicBrainz genres for
artists Spotify leaves empty, in the background, about 1 request per second), group_tracks (draft playlists by decade / genre family / chosen genres), show_draft, edit_draft, organize_progress, reset_progress (clears your progress), unload_playlists, forget_my_data. The
dashboard opens in your browser (~/.tailorlist-mcp/overview.html; set
TAILORLIST_OPEN_BROWSER=0 to turn that off) and is also an MCP App, which Claude Desktop can
show inside the chat. Everything is stored in ~/.tailorlist-mcp (TAILORLIST_HOME to change it).
Spotify's terms
Spotify's Developer Terms forbid using Spotify content "to train a machine learning or AI model or otherwise ingest Spotify Content into a machine learning or AI model". This tool trains nothing, but it does show your track and artist names to Claude, and Spotify hasn't said whether that counts. You use it with your own Spotify app, under your own developer account, for personal use. Read the Developer Terms and decide for yourself.
Origin
The analysis code (src/tailorlist_mcp/analysis/) is ported from the Tailorlist Streamlit app.
License
MIT
Available Tools
18 toolscollection_statsA
Counts and averages of the loaded playlists grouped by one dimension (optionally also split by a second one), as a small table you can chart. Examples: decade x playlist, top 20 artists, tracks per genre family, additions per month, one artist's albums (filters.artist).
Args: group_by: decade, year, artist (primary), album, genre (exact tags), genre_family, playlist, month_added or popularity_bin (steps of 5). split_by: optional second dimension from the same list; one row per group x split value. metrics: any of unique_tracks, entries, hours, avg_popularity, share (% of the selection's unique tracks). Default: unique_tracks and share. filters: narrow the tracks first (same filters as find_tracks). limit: groups to return, biggest first (default 50, max 500). Time dimensions and popularity bins are returned in order.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| filters | No | ||
| metrics | No | ||
| group_by | Yes | ||
| split_by | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
compare_playlistsA
One row per playlist (or only the ones given): size, followers, hours, average, shortest and longest duration, average popularity, genre diversity, release era (median, oldest, newest year), first and last added, and the unique tracks that are in no other playlist; then how many tracks each pair of playlists shares. A data tool: draw charts from it yourself.
Args: playlists: names, IDs or links; default all loaded playlists.
| Name | Required | Description | Default |
|---|---|---|---|
| playlists | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
connect_spotifyA
Connect Tailorlist to the user's Spotify account (only needed once).
Returns who is connected, or a login link the user has to open in their browser. After they approve access, call this again to confirm.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
edit_draftA
Change a draft, then refresh its page. All the changes are applied in order, or none if one fails. Only the draft (and the organize progress it touches) changes; nothing is written to Spotify.
Args:
draft: the draft ID ("d3").
changes: a list of operations, each with an "op":
rename {group, to}; move {tracks, to, from_group?, create_if_missing?} between groups;
assign {tracks, to} puts unmatched tracks in a group (saved as manual progress, like the
original's "Save assignments"); drop_group {group} (its tracks stay in the pool, listed as
left out); merge {groups, into?}; keep_visible {group, on?} (its tracks aren't marked done
when written); skip_unmatched {} (marks the unmatched tracks without data as done, so they
leave the pool); reopen {group} (a done group counts as not done).
tracks picks tracks by artist, text (in the name), genre, genre_family, decade, year_from/to,
popularity, track_ids, reason (unmatched only) or all=true. Group names accept a unique part.
| Name | Required | Description | Default |
|---|---|---|---|
| draft | Yes | ||
| changes | Yes |
fill_genresA
Fill in the genres Spotify leaves empty, using MusicBrainz (free, about 1 request per second).
Runs in the background and returns at once; call it again to see progress (it never starts a second run). Only primary artists with no Spotify genres are looked up, the most-used first; results are saved as they arrive, so every other tool uses them right away and a stopped run resumes where it left off. Takes a few minutes per hundred artists. Start it only if the user agrees.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
find_duplicatesA
Duplicates among the loaded playlists (or only the ones given): exact duplicates (the same Spotify ID saved more than once, inside or across playlists) and different versions (same song name and primary artist under different IDs), each with the playlists it is in and the IDs.
Args: playlists: names, IDs or links; default all loaded playlists. kind: "all", "exact" or "versions". limit: rows per list (default 50, max 500).
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | all | |
| limit | No | ||
| playlists | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
find_tracksA
List unique tracks of the loaded playlists that pass the filters: track, artist, album, year,
duration, popularity, first date added and the playlists it is in. Capped at limit rows (the
header says how many match), so narrow the filters instead of asking for everything.
Args:
filters: playlists, artist, album, genre (exact tag), genre_family, decade, year_from/to,
popularity_min/max, added_from/to, duration_min/max (minutes), text (in the name).
sort: popularity, year, added, duration, name or artist. Default order is descending
(ascending for name and artist) unless ascending says otherwise.
limit: rows to return (default 50, max 500).
include_links: add each track's Spotify link (longer output).
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | popularity | |
| limit | No | ||
| filters | No | ||
| ascending | No | ||
| include_links | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
forget_my_dataA
Delete the local cache of the user's playlists. With also_log_out, delete the saved Spotify login too. Nothing on Spotify is changed.
| Name | Required | Description | Default |
|---|---|---|---|
| also_log_out | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
get_playlist_tracksA
Every track of a loaded playlist, in playlist order: track, artist (with featured artists), album, year, duration, popularity and date added. Reads the local cache, so it always has the full playlist.
Args: playlist: the playlist's name (or a unique part of it), ID or Spotify link. include_links: add each track's Spotify link (longer output).
| Name | Required | Description | Default |
|---|---|---|---|
| playlist | Yes | ||
| include_links | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
group_tracksA
Group the loaded tracks into a draft of new playlists, and open the draft dashboard.
Workflow: narrow the pool with filters, call with preview_only=true to see the counts, then
run it. The draft is saved (ID like "d3") and nothing is written to Spotify. Tracks already
organized ("done", see organize_progress) are left out unless include_done=true.
Args: mode: "category" (one group per decade and/or genre family) or "genres" (one group per chosen genre tag). "kmeans" (by audio similarity) comes with audio features, later. filters: playlists, decades and genre_families to narrow the pool before grouping. by: category mode only: "decade", "genre_family" or "both" (e.g. "Rock · 1990s"). A track in several families goes to the first one. Tracks without a genre or a release decade (when that dimension is used) are listed as unmatched, with the reason. genres: genres mode: exact genre tags to make groups for (a track with several chosen tags is in each group). If omitted, filters.genre_families picks every tag of those families; with neither, you get the list of genres in the pool (nothing is saved). also_by_decade: genres mode: also split each genre group by decade ("rock · 1980s"). include_done: include tracks already organized. preview_only: don't save a draft; return the pool counts and how many groups/unmatched.
| Name | Required | Description | Default |
|---|---|---|---|
| by | No | both | |
| mode | Yes | ||
| genres | No | ||
| filters | No | ||
| include_done | No | ||
| preview_only | No | ||
| also_by_decade | No |
list_my_playlistsA
The user's Spotify playlists: id, name, track count, whether they own it, its link, and whether it is already in the local cache ("current", "changed" since loading, or null).
Show the list to the user and ask which playlists they want to load before calling load_playlists.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
load_playlistsA
Copy playlists from Spotify into the local cache and show the overview dashboard.
Only load the playlists the user chose. If they haven't said which ones, ask them first (list_my_playlists shows the options); don't load all of them unless they ask for that.
Args: playlists: playlist IDs or Spotify playlist links of the playlists the user chose. force: re-read playlists even if they haven't changed since the last load.
Playlists that haven't changed are skipped. The dashboard covers everything in the cache.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | ||
| playlists | Yes |
organize_progressA
How much of the collection is organized: tracks already placed in a playlist built from a draft ("done", or skipped on purpose) or assigned to a group by hand ("manual") count toward the % of the library organized. Done tracks are left out of the next group_tracks. Reads the cache only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
reset_progressA
DESTRUCTIVE for the user's organize progress: forgets which tracks are organized (done and manual), so every track is back in the pool and the % goes to 0. Only the progress is cleared: drafts, the cache and Spotify are untouched. Ask the user first; with confirm=false it only says what would be cleared.
Args: confirm: true only after the user agreed to clear their progress.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
show_draftA
Show a draft of new playlists as a dashboard (Cluster Results): one card per group with its size, hours, top artists, genres and decades and sample tracks, the unmatched tracks with the reason, and the overall progress bar. The full track lists are on the web page it opens.
Args: draft: the draft ID ("d3"). Default: the latest one; the text lists the other drafts.
| Name | Required | Description | Default |
|---|---|---|---|
| draft | No |
show_overviewA
Show the overview dashboard of the loaded playlists again: KPIs, oldest/newest track, playlists, top artists, decades, popularity, albums, genres, additions over time and duplicates. load_playlists already shows it after loading.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
show_playlistA
Show the dashboard of one loaded playlist: header numbers, track highlights, averages, top artists, duplicates inside it, era by decade and year, top genres, growth over time and all its tracks. Opens in the user's browser (and inside the chat where the app supports it).
Args: playlist: the playlist's name (or a unique part of it), ID or Spotify link.
| Name | Required | Description | Default |
|---|---|---|---|
| playlist | Yes |
unload_playlistsA
Take one or more playlists out of the local cache, so they leave the analysis, and show the overview of what remains. Nothing changes on Spotify: the playlists stay in the user's account and load_playlists brings them back.
Tracks and artists that no other loaded playlist has leave the cache too, and leave any draft that had them.
Args: playlists: names (or a unique part of the name), IDs or Spotify links of loaded playlists.
| Name | Required | Description | Default |
|---|---|---|---|
| playlists | Yes |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
18 tool updates
v0.0.1- First observed
collection_stats - First observed
compare_playlists - First observed
connect_spotify - First observed
edit_draft - First observed
fill_genres - First observed
find_duplicates - First observed
find_tracks - First observed
forget_my_data - First observed
get_playlist_tracks - First observed
group_tracks - First observed
list_my_playlists - First observed
load_playlists - First observed
organize_progress - First observed
reset_progress - First observed
show_draft - First observed
show_overview - First observed
show_playlist - First observed
unload_playlists
TDQS
Scored across 18 tools
Each tool targets a distinct stage or resource: cache loading, overview, single-playlist view, draft creation/editing, statistics, track search, duplicates, comparison, genre filling, and progress management. The detailed descriptions make the boundaries clear even where tools display related information, such as show_overview versus collection_stats.
Almost all names follow a snake_case verb_noun pattern (load_playlists, show_draft, find_tracks, reset_progress). A couple are noun phrases instead (collection_stats, organize_progress), which is readable but slightly breaks the otherwise consistent action-oriented convention.
18 tools is somewhat above the typical 3–15 range, but the server covers a fairly broad workflow (Spotify connection, cache management, analysis, drafts, progress). The tools mostly earn their place without obvious redundant aliases, though the surface is on the heavy side.
The set covers loading/cache management, analysis, draft creation and editing, progress tracking, and cleanup. However, there is no MCP tool to export or publish a draft back to Spotify, and no tool to delete a whole draft, which leaves a notable gap in the end-to-end draft lifecycle.
Maintenance
Related MCP Connectors
Spotify play counts, monthly listeners, charts, artist stats, albums, playlists and ISRC lookup.
Spotify play counts for any track, album, artist or playlist, plus monthly listeners and followers.
Find active Spotify playlists for a song and check a playlist's integrity. No curator contacts.
Full Spotify Web API coverage - albums, artists, playlists, player controls, and more.
Related MCP Servers
- FlicenseDqualityDmaintenanceEnables Claude to interact with Spotify by searching songs, creating playlists, getting recommendations, and managing your music through your Spotify account.73-
- AlicenseNot gradedqualityNot gradedmaintenanceConnects Claude to Spotify for music discovery, playlist creation, and collection analysis through natural language. Enables searching songs, analyzing music diversity, creating playlists, and getting recommendations using Spotify's API.-
- AlicenseAqualityDmaintenanceIntegrates Spotify with Claude to enable voice-controlled music playback, playlist management, and personalized recommendations through conversational AI. It provides comprehensive tools for searching tracks, managing liked songs, and analyzing listening habits.151MIT
- AlicenseNot gradedqualityDmaintenanceConnects Claude to Spotify, enabling play control, playlist management, lyrics retrieval, and music recommendations through natural language.1MIT