SpotifyMCP
This server gives an AI assistant full control over Spotify: playback, search, library, playlists, and profile management via the Web API.
Playback: get now playing/current state, play/pause, skip/previous, seek, set volume/shuffle/repeat, view and add to queue, list and transfer devices.
Search & catalog: search tracks, artists, albums, playlists, shows, episodes; get details for tracks, artists, albums, shows, episodes, audiobooks, and chapters.
User profile & stats: get current user profile, top tracks/artists, and recently played.
Library management: get, save, remove, and check saved tracks, albums, shows, episodes, audiobooks; manage followed artists.
Playlists: list, create, update, get playlists, add/remove/reorder items, and manage cover images.
Convenience extras: search-and-play best match, pagination up to 500 items, dry-run previews, read-only mode, diagnostics, duplicate cleanup, and M3U/CSV import/export.
Provides tools for interacting with the Spotify Web API, enabling playback control, searching tracks, albums, artists, playlists, podcasts, and audiobooks, managing the user's library and playlists, and retrieving listening personalization data.
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., "@SpotifyMCPPlay my Discover Weekly playlist on my office speakers."
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.
SpotifyMCP
Spotify Web API MCP: playback, library, playlists, search, podcasts. Not affiliated with Spotify.
A broad Spotify Web API tool surface, plus extras most servers skip. Registration-gated wrappers are explained rather than hidden; see Registration-gated endpoints for the generated list.
What you get by default, and what to do about the rest. A server started with no environment registers a curated surface โ search, playback, playlists, library, following โ sized so the tool list does not dominate the context window before you have typed anything. SPOTIFY_MCP_TOOLSETS=all registers the entire registry instead, and the stats.fm tools are opt-in with SPOTIFY_MCP_STATSFM=1. Both are one line in docs/configuration.md.
A server started with no SPOTIFY_MCP_TOOLSETS registers 129 tools (148,378 bytes of schema) โ the curated default surface (#889). SPOTIFY_MCP_TOOLSETS=all registers all 560 tools, along with 17 fixed resources, 28 resource templates, and 14 prompts. Toolsets and production gates can trim a configured host further; both figures describe a real production tools/list after finalizers.
๐ง 3.0 is landing
3.0 is the release where the open issue list goes to zero โ every epic, every issue under it, every contradiction we turned up auditing ourselves. Most of that backlog was never "bugs" in the crashing sense; it was places where this server reported a value it had not actually checked, which is the only kind of wrong that is genuinely dangerous.
It also removes tools, because Spotify deleted the endpoints underneath them in February 2026 โ including artist follows, which have no migration target at all.
๐ค Paste this to your agent
Copy the block below into Claude Code, Cursor, OpenClaw, or any coding agent โ it will set SpotifyMCP up for you.
โ ๏ธ Never paste your Spotify credentials into a chat. Spotify's Developer Terms treat the Client ID as a credential: ยงVI.1.1 groups "I.D.s, client I.D.s, keys, passwords, security codes, or tokens" together as Security Codes, ยงVI.1.3 forbids disclosing them to any other party, and ยงVI.1.4 makes you responsible for their confidentiality. Anything you type into a conversation is retained by the model provider, written to shell history, and carried in the agent's context window. The Client ID is the only credential this server needs, and it is a Security Code rather than a public identifier โ treat it like a password.
Set up the Spotify MCP server from https://github.com/NovaLux12/spotify-mcp-server. 1. Walk me through creating a Spotify app at https://developer.spotify.com/dashboard with redirect URI http://127.0.0.1:8888/callback. Point me at where the dashboard shows the Client ID, then stop โ I will copy it myself. 2. Clone and build: git clone https://github.com/NovaLux12/spotify-mcp-server.git cd spotify-mcp-server && npm ci && npm run build 3. Show me which file my MCP host reads server environment from. The host's server config is the one that always works; a local .env is read only when you launch through this repo's npm run dev or npm start, which pass --env-file-if-exists on Node >=22.9 โ the published binary does not read it. Print the exact line to add. I will type the Client ID in myself. Do not ask me for it and never echo it back. 4. Start the server and run the auth command yourself, then finish the browser login when it opens. This server uses PKCE, so there is no client secret and no credential to fetch beyond the Client ID. 5. Verify with the read-only spotify_doctor tool and report its rows.
Why this one
Complete | Playback, search, catalog, library, playlists, following, plus extras like duplicate cleanup, M3U/CSV import-export, podcast sessions, snapshot diffing, listening analytics, market checks, stats.fm taste reads, and taste composite briefs, playlists, and reports. |
Safe |
|
Honest about the surface | Tools that turn your listening history into derived metrics โ hourly histograms, weekday profiles, discovery ratios โ are off unless you ask for them with |
Honest | No tool claims to work when it cannot. Gated endpoints keep their wrappers, read replacements where one exists, and explain the 403 in plain English instead of crashing โ see Registration-gated endpoints, generated from |
Polished | Paginated (up to 500), podcasts first-class, device-aware playback, |
Related MCP server: Spotify MCP Server
Quick start
1. Create a Spotify app
Spotify Developer Dashboard โ Create app โ add this Redirect URI exactly:
http://127.0.0.1:8888/callbackCopy the Client ID.
2. Authenticate
SPOTIFY_CLIENT_ID=your_client_id_here npx -y @novalux12/spotify-mcp@latest authOpens a browser, saves tokens to ~/.spotify-mcp/tokens.json, auto-refreshes after.
Windows (Command Prompt):
set SPOTIFY_CLIENT_ID=your_client_id_here && npx -y @novalux12/spotify-mcp@latest authWindows (PowerShell):
$env:SPOTIFY_CLIENT_ID="your_client_id_here"; npx -y @novalux12/spotify-mcp@latest authWindows is supported for install and everyday use, and is not covered by CI. The commands above are the supported path, but the test suite runs on Linux only, so a Windows-specific regression would not be caught before release. See docs/platform-support.md for exactly what is and is not verified there, and what the known gaps are.
Headless / remote host:
SPOTIFY_HEADLESS=1 SPOTIFY_CLIENT_ID=your_client_id_here npx -y @novalux12/spotify-mcp@latest auth
# prints a URL โ open it on any machine โ paste the redirect backCheck: npx -y @novalux12/spotify-mcp@latest doctor โ exit 0 means you're good.
3. Add to your MCP host
{
"mcpServers": {
"spotify": {
"command": "npx",
"args": ["-y", "@novalux12/spotify-mcp@latest"],
"env": { "SPOTIFY_CLIENT_ID": "your_client_id_here" }
}
}
}Restart the host. A hammer icon in the chat input means it's connected.
Claude Code (no JSON editing):
claude mcp add spotify -- npx -y @novalux12/spotify-mcp@latest
export SPOTIFY_CLIENT_ID=your_client_id_hereOpenClaw โ ~/.openclaw/openclaw.json โ mcp.servers:
"spotify": {
"command": "node",
"args": ["/path/to/spotify-mcp-server/dist/index.js"],
"cwd": "/path/to/spotify-mcp-server",
"env": { "SPOTIFY_CLIENT_ID": "your_client_id_here" }
}Any spec-compliant host works โ same command/args/env shape under mcpServers or servers. If the host can't pass env vars, authenticate once beforehand; the token cache persists.
What you can ask
"What are my top tracks this month?"
"Make a late-night driving playlist"
"Add Blinding Lights to my workout playlist"
"What podcasts have new episodes?"
"Clean duplicates across all my playlists"
"What does my taste look like? Build a playlist from it"
"Do my stats.fm lifetime genres match what I've played this month?"
Configuration
All via env vars โ no config file. Only SPOTIFY_CLIENT_ID is required.
Variable | Example | Purpose |
| unset | Trim by group for hosts that cap tool counts. Unset registers the curated default surface; |
|
| Register the 50 stats.fm-backed tools across four registration keys โ |
|
| Hide write-capable modules; read-only resources and prompts remain available. |
|
| Log mutations to JSONL for undo and audit. |
|
| Persist mutation receipts so |
|
| Turn off the "Music data supplied by Spotify" footer and the per-row |
Full reference: docs/configuration.md
spotify_doctor (CLI + in-server tool) diagnoses token state, scope gaps, Premium gating, rate-limit cooldowns, request/quota usage (cumulative + rolling-window counts, #904), and read-cache pressure (entries held, bytes retained, responses too large to cache, #894) without extra setup.
Upgrading to 2.0
2.0 is a contract release. One tool name is gone, four things moved, and one guarantee tightened:
get_show_episodesis removed. Uselist_show_episodes(same endpoint, same arguments, minus the drifted alias). It was the only name that changed; everything else in the surface keeps its name. The exact registry totals are generated at the top of this file, so this sentence deliberately carries no count of its own to fall behind.Destructive writes fail closed. Any confirmation-gated bulk write now refuses when the client cannot elicit, instead of proceeding unprompted.
archive_played_episodes'sconfirm: trueno longer authorises the delete (it is still accepted, and every result says it was ignored). For headless automation, setSPOTIFY_MCP_CONFIRM=neverdeliberately.Playlist set-operation inputs are canonical. A/B pairs are
playlist_a/playlist_b; ordered lists areplaylists;playlist_subtracttakes the base asbase_playlist_id. This was the 2.0 contract; the old spellings it was allowed to keep alongside it were withdrawn in 3.0 (#1287). They are no longer in any tool's schema, and a call that still sends one is refused before any Spotify request with avalidationerror whosereasonisretired_input, naming both what was sent and what to send instead. Each tool declared exactly one alias pair or one alias list, so the table below is a per-tool migration map rather than a bundle:family
canonical
the spelling that tool used to declare
A/B pair
playlist_a,playlist_ba/b, orplaylist_id_a/playlist_id_b, orplaylist_a_id/playlist_b_idโ one of them, per toolordered list
playlistsplaylist_ids, orsource_playlist_ids, orsourcesโ one of them, per toolsubtraction
base_playlist_id+playlistssubtract_playlist_ids, or the positional formplaylists: [base, ...sources]โ one of them, per toolbase_playlist_idis required again: with the positional form gone there is no longer a base for a caller to omit. A name the tool does not declare, and is not a retired spelling, is anunknown_paramerror โ a different claim fromretired_input, which says the server published that name until 3.0.Numeric caps have canonical names.
max_resultscaps what is returned;limitandscan_capcap how much of each source is read.Unknown arguments are rejected with a typed
unknown_paramerror rather than ignored, so a renamed parameter fails loudly instead of silently doing nothing.
Run spotify_doctor after upgrading: it reports the registered surface, the
gates that hid modules, and the granted scopes in one call.
Docs
docs/v3-roadmap.md โ what's coming in 3.0, and the one bug underneath all of it
docs/migration-v3.md โ every retired name in 3.0 and what replaced it, including the one operation with no replacement
SPEC.md โ every tool, resource & prompt
ARCHITECTURE.md โ how it's built
docs/configuration.md โ all env vars
docs/cli.md โ
tools,call,watch,export,init: the CLI as an MCP clientdocs/schema-budgets.md โ per-module schema budgets and registration order
docs/statsfm.md โ stats.fm second source: setup, tool cheat sheet, gotchas
docs/cookbook.md โ copy-paste agent recipes
docs/non-goals.md โ what v2 will not do, why, and what it offers instead
docs/taste.md โ anonymized taste showcase driving a playlist
docs/wave2-composites.md โ read-only taste composites
docs/distribution.md โ distribution and release notes
docs/faq.md โ auth, Premium, 403s, headless, tokens
docs/compliance.md โ brand marks, attribution & the outbound
User-AgentCONTRIBUTING.md โ dev setup & conventions
CHANGELOG.md โ release history
Requirements
Premium for playback control (play/pause/skip/seek/volume/queue). Free accounts can still use search, library & playlists.
Node 22.9+, Spotify app in dev mode (5 users until extended quota).
Audiobooks gated by Spotify to US/UK/CA/IE/NZ/AU.
A subset of endpoints is registration-gated โ 403 on current app registrations regardless of scopes or Premium. Whether a grandfathered registration still answers
200is unverified (#1338). This is a property of your app registration, not of the tool. See Registration-gated endpoints.
Registration-gated endpoints
Some Web API endpoints are denied at the app-registration level: on current Spotify app registrations they return 403 Forbidden no matter which OAuth scopes you grant or whether the account is Premium. This is Spotify-side gating, not a misconfiguration on your end.
Nothing here is simply "removed". Three sources describe this class and they do not agree, which is why the table below states the runtime behaviour instead of a verdict:
Spotify's February 2026 changelog marks a batch of operations
[REMOVED].The live OpenAPI schema still publishes most of those same paths, carrying
deprecated: truerather than deleting them โ/artists/{id}/top-tracksand all sevenGet Severalbatch paths among them.The runtime truth is neither document: it is what your app registration is allowed to read. A registration without the grant answers
403/404/410. Whether a grandfathered registration still answers200is unverified (#1338): no probe in this repository shows it, and the one probe artefact that was once cited for it records403on every such path.
So a 403 here is a property of the registration, not of the tool. No tool is hidden for being gated, no gated tool is a zombie: each one either reads a documented replacement and answers, or makes the call and explains the 403 in plain English. The authoritative list is the GATED_FAMILIES array in src/gating.ts โ GATED_PATH_PATTERNS is derived from it, so the classifier and this table cannot drift apart.
Endpoint family | Shipped tools that call it | On a current registration |
|
| 403 explained |
| (none โ no shipped tool reads this path) | Replaced; no call site |
|
| 403 explained |
|
| 403 explained |
|
| 403 explained |
| (none โ migrated to | Replaced; no call site |
| (none โ migrated to | Replaced; no call site |
|
| Replaced with per-id reads |
All 8 families above are operations Spotify's February 2026 changelog marks [REMOVED].
Confirm the list yourself against the source of truth:
grep -n "id: '" src/gating.ts # the families, with tools and fallback per rowNotes:
A family in that list is a runtime classifier, not a promise that a tool calls it. Three families (
browse-new-releases,me-type-contains,playlist-followers-contains) have no live call site left โ the tools that used them were migrated onto replacements โ and their patterns are retained so a future caller is still covered by the 403 contract rather than silently losing it.GET /me/library/containsis not gated (it returned 200 on the same probe) and backs the saved-state reads behindcheck_playlist_following,restore_library_snapshotand receipt verification. Thecontainsfamilies above are the documented per-type checks, which the changelog marks removed in favour of this one. (The playlist duplicate-cleanup tools are not in that set โ they page/playlists/{id}/items.)Batch fallback (#725). When a
Get Severalbatch endpoint answers 403,fetchSeveralretries through per-idGET /<kind>/{id}calls on the client's existing queue/backoff. Per-id paths are not in the gated class, so the read still succeeds. The response carriesdegraded: trueand a[degraded: batch endpoint returned 403; โฆ fetched individually]footer in prose, plusdegraded_reasoninstructuredContent, so a caller can tell a per-item round-trip from a clean batch read.Endpoints Spotify lists as removed that this server does not wrap at all (no shipped tool, so nothing to explain):
/recommendations,/recommendations/available-genre-seeds,/me/apps,/me/chapters, the/artists/{id}/related-artists,/audio-features,/audio-analysisand/browse/featured-playlistsreads, and the/playlists/{id}/tracksfamily (superseded by/playlists/{id}/items). These are absent from the table above because absence of a tool is the honest answer for them โ there is no 403 to explain.
"Not authenticated" โ re-run
auth; check~/.spotify-mcp/tokens.jsonexists and the redirect URI matches exactly (no trailing slash).Auth loop / S256 error โ open a private window, log into spotify.com first, then retry the auth URL there.
Port in use (8888) โ free the port, set
SPOTIFY_REDIRECT_URIto another port, or useSPOTIFY_HEADLESS=1. The message namesEADDRINUSEand the port because the usual cause is a previousauthstill holding it.Timed out waiting for the browser callback โ not a port conflict; the listener bound and has been closed. Retry, and check the redirect URI is registered exactly. Bound it with
SPOTIFY_AUTH_TIMEOUT_MS(default 5 min)."Premium required" on playback โ expected on Free accounts; no workaround.
Forbiddenon lookup tools (categories, markets, top-tracks, user profiles, the per-typecontainschecks) โ these endpoints are registration-gated by Spotify; see Registration-gated endpoints. (GET /me/library/containsis not one of them, so a 403 there is a real problem, not a gated registration.)Still stuck?
npx -y @novalux12/spotify-mcp@latest doctoror ask your agent to run the spotify-mcp-doctor skill.
What this server is not
v2 has a written non-goals list, so a request for something outside it gets an answer rather than a maybe. Each entry below carries its reasoning in SPEC ยง1, and docs/non-goals.md is the record behind both: what each one rules out, the source it rests on, and what the server offers instead.
Audio streaming, audio analysis, and offline playback
A web UI, a dashboard, or an MCP UI surface
Multi-tenant or hosted operation
Sharing one user's credentials across users
Lyrics
The Spotify Connect SDK and native client integration
Voice control
Training a model on Spotify data, or exporting derived profiles
A second third-party upstream, ad-tech, or monetization egress
Working around Spotify's own controls
Development
git clone https://github.com/NovaLux12/spotify-mcp-server.git && cd spotify-mcp-server
npm ci && npm run build
cp .env.example .env # add your Client ID
npm run auth # one-time login
npm run dev # run from source
npm test # unit + MCP smoke testsNot affiliated with Spotify. Use per the Spotify Developer Terms.
MIT ยฉ Carme99 and NovaLux12 contributors ยท Acknowledges calebWei/SpotifyMCP and varunneal/spotify-mcp.
Available Tools
129 toolsadd_to_playlistB
Add tracks or episodes to a playlist. Max 100 URIs per call.
| Name | Required | Description | Default |
|---|---|---|---|
| uris | Yes | Track or episode URIs to add | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| position | No | Insert at this index; appends if omitted. 0-based index into the playlist's current item order (0 = the first item). | |
| playlist_id | Yes | Playlist ID | |
| check_duplicates | No | Skip URIs that are already in the playlist instead of appending them (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is destructiveHint=false, so the safety profile is thin and the description carries most of the burden. It discloses the 100-URI ceiling, but says nothing about dedup defaults, ordering/position side effects on existing items, idempotency, or error behavior for invalid URIs. This is adequate but clearly short of full behavioral disclosure for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, the action front-loaded and the limit immediately after. Nothing wasted and nothing buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With five parameters, no output schema, and a mutation that can exceed a single-call limit, the description is thin: it omits how to handle more than 100 URIs, whether duplicates are skipped by default, and which sibling to use for bulk work. It is minimally viable but leaves a routing gap against batch_add_to_playlist.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents dry_run, position, check_duplicates, and the uris cap, so the baseline of 3 applies. The description's only parameter-relevant statement (max 100 URIs) duplicates maxItems: 100 in the schema, adding no meaning beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (add) and resource (playlist) plus the item types accepted (tracks or episodes). It does not distinguish itself from the sibling batch_add_to_playlist, which appears to serve the same purpose at a different scale, leaving the agent to guess which to call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no exclusions, and no mention of alternatives such as batch_add_to_playlist, add_to_queue, or replace_playlist_items. The only hint is the 100-URI cap, which implies a bulk boundary but doesn't state how to route around it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_to_queueA
Add a track or episode to the end of the playback queue.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes | Spotify track or episode URI (e.g. spotify:track:...) | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description carries most of the burden. 'To the end of the playback queue' usefully discloses append/ordering behavior, but it omits notable traits such as the need for an active playback device and the fact that this mutation is additive-but-persistent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single well-formed sentence with the resource and the placement constraint front-loaded; every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-required-param tool with no output schema and full schema coverage, this is mostly adequate, but the device targeting (device_id) and the active-device precondition are never surfaced, leaving a real behavioral gap for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so uri, dry_run, device_id, and response_format are all already documented in the schema, including the dry_run preview semantics and the response_format enum. The description adds nothing beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource ('Add a track or episode ... to the playback queue') and scopes it ('to the end'), which clearly separates it from play/pause/skip_next and get_queue siblings. It doesn't name an alternative explicitly, but the operation is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'to the end of the playback queue' hints at additive queuing versus immediate playback, but there is no explicit when-to-use/when-not clause and no sibling is named (e.g., play_from_search, play). An agent can infer intent but gets no routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
apply_sceneA
Apply a saved scene: resolve its device hint, transfer playback, then set volume/shuffle/repeat and start the saved context (in that order; missing targets are skipped)
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Scene name to apply | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint: false in annotations, the description adds meaningful behavioral context: it discloses the multi-step order (resolve device hint, transfer playback, set volume/shuffle/repeat, start context) and that missing targets are skipped. It does not discuss auth needs, reversibility, or rate limits, but it goes beyond the annotation without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action and execution order without wasted words. Every clause earns its place by conveying the operation or its sequencing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-step mutation tool with no output schema, the description is largely sufficient: it covers the execution order and skip behavior for missing targets. It could mention dry-run behavior explicitly, but that is already fully documented in the input schema, so the remaining gap is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters (name, dry_run, response_format) are already fully documented in the schema. The description adds no parameter-level detail beyond what is in the structured input schema, making the baseline of 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Apply') and resource ('a saved scene') and immediately distinguishes the operation from siblings like save_scene, list_scenes, and delete_scene. It also spells out the execution sequence, making the tool's scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: the tool is for applying a saved scene, and the sequence is described. However, there is no explicit guidance on when to choose this over manually calling transfer_playback, set_volume, set_shuffle, set_repeat, or play, nor any exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audiobook_progressA
Audiobook progress rollup: chapters total, played count, current chapter, percent complete. Walks every chapter page up to the shared fetch-all cap and reports scan coverage. Quota: 1 audiobook GET + chapter page GETs.
| Name | Required | Description | Default |
|---|---|---|---|
| market | No | Market, e.g. 'US' | |
| audiobook_id | Yes | Audiobook ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=false, so the description must supply behavioral context, and it does: it walks every chapter page up to a shared fetch-all cap, reports scan coverage, and discloses the quota cost (1 audiobook GET + chapter page GETs). It does not state error/not-found behavior, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight, front-loaded sentences with no filler; the output fields come first, then the scan behavior, then the quota cost. 'Shared fetch-all cap' is slightly jargon-y but informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by listing the returned metrics, and it covers the scanning/enumeration behavior and cost. Missing only edge-case behavior (e.g., audiobook not found) for a full 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including the response_format enum, so the parameters are fully documented structurally. The description adds no additional parameter-level meaning beyond the quota note, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (audiobook progress rollup) and enumerates the exact outputs: chapters total, played count, current chapter, percent complete. It is clearly distinguishable from all siblings, none of which report audiobook progress.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intent (fetch progress for an audiobook) is implied by the name and output list, but there is no explicit when-to-use or when-not-to-use guidance and no named alternative. Adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
backup_firstA
Create a pre-flight library snapshot before a destructive operation. Returns snapshot file path and counts for later restore. Read-only against Spotify.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Free-text note for the snapshot | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide destructiveHint=false; the description adds that the tool is read-only against Spotify, returns a snapshot file path and counts, and is intended as a pre-flight safety measure. This gives useful behavioral context beyond the annotation, though storage/retention details are not disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with no filler. The action and purpose are front-loaded, and each sentence adds a distinct piece of information: what it does, what it returns, and that it is safe against Spotify.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only snapshot tool with optional parameters and no output schema, the description gives enough to select and invoke it: purpose, usage timing, return shape, and safety. It could be more complete by clarifying what 'library' includes or how restore works, but that is not essential for calling this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add meaning beyond the schema for the two optional parameters; it only mentions return values generally, which is already implied by the tool's purpose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Create'), resource ('pre-flight library snapshot'), and purpose ('before a destructive operation'), which clearly distinguishes it from snapshot_playlist and backup_library. Also names the key return values (snapshot file path and counts), leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use this tool: before a destructive operation and for later restore. This provides clear context for choosing it, though it does not name alternatives or give exclusions, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
backup_libraryARead-onlyIdempotent
Snapshot your ENTIRE library to a local JSON file (read-only against Spotify): liked tracks, saved albums/shows/episodes/audiobooks, followed artists, and every playlist with its items. Walks capped at SPOTIFY_MCP_FETCH_ALL_CAP (500/category) and each playlist at SPOTIFY_MCP_PLAYLIST_ITEMS_CAP (500); the smaller wins, so a full backup of a large playlist needs both raised. Files land in SPOTIFY_MCP_BACKUP_DIR (default ~/.spotify-mcp/backups), mode 0600.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Free-text note stored in the snapshot _meta block | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| walk_cap | No | Cap on items per category walked for THIS call (default: SPOTIFY_MCP_FETCH_ALL_CAP). Bounds what is READ, not rows rendered โ use max_results to shrink the response. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description adds substantive context beyond that: read-only against Spotify, the two cap env vars and the 'smaller wins' interaction, the backup directory default, and file mode 0600. It does not describe failure modes or partial-write behavior, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the essential fact (full-library snapshot to local JSON) and then packs the operational caveats into compact clauses. Dense but every clause carries information; the long cap sentence is slightly heavy but justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully explains where files land, their mode, and the cap behavior, which covers what an agent needs to invoke and reason about the result. It stops short of describing the file's internal structure or how to locate a specific backup later.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented in the schema. The description reinforces the cap mechanics (walk_cap vs the env default, playlist cap interplay) but adds little that the schema does not already say. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (snapshot) and resource (entire library) plus the destination (local JSON file), and enumerates the categories captured. It does not explicitly contrast itself with siblings like export_library_json, export_all_playlists, or backup_first, so an agent must infer the distinction from the 'ENTIRE library' scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when it applies (full-library snapshot) and gives operational context about caps and env vars, but never says when to choose it over export_library_json, backup_first, or export_all_playlists, nor when-not to use it. Usage is inferred rather than directed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_add_to_playlistA
Add tracks from multiple source URIs (tracks, albums, artists, playlists) to a target playlist in one call. Dedupes within the batch and optionally against the existing playlist. Batches writes in groups of 100. Dry-run previews without writing. Elicitation for 100+ tracks. Target the playlist by ID/URI/URL or by lane name.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| dedupe | No | Deduplicate (within batch and against target). Default: true | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| source_uris | Yes | Source URIs: spotify:track:, spotify:album:, spotify:artist:, spotify:playlist: | |
| target_lane | No | Lane name from the lane registry; provide exactly one of target_playlist_id or target_lane | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| target_playlist_id | No | Target playlist ID, spotify:playlist: URI, or URL; provide exactly one of target_playlist_id or target_lane |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=false, so the description carries most of the behavioral weight and delivers: in-batch and against-target dedupe, write batching in groups of 100, dry-run preview semantics, and an elicitation trigger at 100+ tracks. These are non-obvious operational traits an agent could not infer from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five compact sentences, each earning its place, with the core action front-loaded and operational caveats (dedupe, batching, dry-run, elicitation) following in descending priority. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter mutation with no output schema, the description covers the behaviors an agent most needs: dedupe semantics, batching, dry-run, and the confirmation threshold. It does not describe result shape or partial-failure behavior across batched writes, a minor gap since no output schema exists to cover it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all nine parameters, setting the baseline at 3. The description echoes dedupe and target-selection semantics but adds no syntax or format detail beyond what the schema states, so it neither compensates for nor exceeds the structured data.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope: 'Add tracks from multiple source URIs (tracks, albums, artists, playlists) to a target playlist in one call.' The 'multiple source URIs ... in one call' framing distinguishes it cleanly from the single-item add_to_playlist sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives targeting guidance ('by ID/URI/URL or by lane name') and mentions dry-run and elicitation thresholds, which is useful context. However, it never explicitly states when to prefer this over add_to_playlist or how it relates to bulk siblings like merge_playlists or grow_playlist; the batch intent is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_wind_downA
Cancel the in-process wind-down ramp, if one is running
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Only cancel if the active wind-down targets this device id | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only include destructiveHint=false, which is minimal. The description discloses that it affects an in-process ramp and is conditional, but does not explain what happens to the ramp synchronization (e.g., devices return to original volume, whether any state is persisted) or any side effects beyond cancellation. Since annotations are sparse, the description carries more burden but still falls short of fully disclosing behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one sentence, front-loaded with the action and resource, and immediately states the condition. Every word earns its place and there is no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and minimal annotations, the description covers the essential purpose. It lacks details about scenarios (e.g., no ramp running), which might be handled by tool logic, but for a simple cancel operation it's sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are documented in the schema. The description adds no extra semantics beyond what's in the schema; device_id's purpose is already clear. For a simple tool, this is acceptable, but it doesn't add nuance like whether omitting device_id cancels all ramps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (cancel) and the resource (in-process wind-down ramp), and indicates the condition (if one is running). It differentiates from siblings like schedule_wind_down and wind_down_status, though it doesn't explicitly name them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it (when a wind-down is running and you want to stop it) and the conditionality is clear. However, it doesn't explicitly contrast with alternatives like 'wind_down_status' for checking state or 'schedule_wind_down' for starting. There is no explicit when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_following_artistsARead-onlyIdempotent
Check if the user follows specific artists โ this tests FOLLOW state, not library-saved state (for that use check_in_library). Accepts IDs or spotify:artist: URIs. Rows carry {id, uri, follows}; returns a boolean per ID. Max 50.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | Artist IDs, spotify:artist: URIs, or artist URLs; CSV accepted | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and idempotentHint, so the description's added value is describing the output shape ('Rows carry {id, uri, follows}; returns a boolean per ID') and accepted URI formats. It does not mention auth or error behavior, but those are less critical for a read-only, idempotent check.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero fluff. The core purpose is front-loaded, then the distinction from check_in_library, then input formats, then output behavior, then a limit. Every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with a well-populated schema, the description covers purpose, input, output, and a key alternative. The only gap is that 'Max 50' is ambiguous (input ids vs output count) and max_results can exceed 50, but the schema clarifies ids maxItems=50 and max_results maximum=2000, so it's a minor ambiguity rather than a completeness failure.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds no new parameter meaning beyond the schema โ it only partially restates the ids parameter's accepted formats ('IDs or spotify:artist: URIs') which the schema already documents fully. max_results and response_format semantics are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Check if the user follows specific artists') and explicitly distinguishes it from library-saved state by pointing to check_in_library. This clearly separates it from sibling tools like follow_artists, unfollow_artists, and check_playlist_following.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when not to use this tool ('this tests FOLLOW state, not library-saved state') and names the alternative tool (check_in_library). It also describes accepted input formats (IDs or URIs) and a practical limit, giving the agent enough to decide when to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_in_libraryARead-onlyIdempotent
Preferred. Accepts the widest URI mix (track, album, episode, show, audiobook, artist, user, playlist) in one request. Check whether items are saved in or followed by the user โ this tests LIBRARY-SAVED/FOLLOWED state, distinct from check_following_artists which only tests artist FOLLOW state. Returns a boolean per URI via Spotify's unified endpoint. Max 40. Following an artist is no longer expressible: Spotify's February 2026 changes removed PUT/DELETE /me/following, and this endpoint's save side does not accept spotify:artist: URIs, so there is no endpoint that can follow or unfollow an artist. This read still answers the question for artist URIs.
| Name | Required | Description | Default |
|---|---|---|---|
| uris | Yes | Spotify URIs to check (accepts tracks, albums, episodes, shows, audiobooks, artists, users, playlists) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint, and the description adds substantial value on top: per-URI boolean return, the 40-URI cap, the unified endpoint, and the February 2026 API change that removed artist follow/unfollow. That last point is non-obvious behavioral context an agent could not infer from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the decisive cue ('Preferred') and the capability in the first two sentences. The trailing explanation of the February 2026 following change is useful but somewhat discursive for a description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape (boolean per URI), the input ceiling, and the sibling routing. Nothing needed to invoke or interpret the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all three parameters are already documented in the schema. The description restates the accepted URI types but adds no syntax or format detail for max_results or response_format, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('check whether items are saved in or followed by the user') and explicitly scopes it against the sibling check_following_artists. An agent can distinguish it from every other check_* / get_saved_* tool without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with 'Preferred' and says it accepts the widest URI mix in one request, then names the alternative (check_following_artists) and the exact condition that separates them (library-saved/followed state vs artist follow state). It also explains the one case where the alternative is no longer usable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_playlist_followingARead-onlyIdempotent
Check if you follow 1โ50 playlists. Follow state: GET /me/library/contains?uris=spotify:playlist:,โฆ (40/req, 1โ2 GETs). Unreadable state reports unknown, never not-followed.
| Name | Required | Description | Default |
|---|---|---|---|
| playlists | No | Canonical ordered playlists (1โ50) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/idempotent, and the description adds real behavioral context beyond them: batching mechanics (40/req, 1โ2 GETs) and, importantly, the error semantics 'Unreadable state reports unknown, never not-followed' โ a valuable non-obvious contract. Lacks any note on output shape, but the key edge-case behavior is disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense and front-loaded: purpose first, then the operational detail and the safety guarantee. No padding; each clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does explain the returned state (followed / unknown) and the batch size, which is enough for correct invocation. Minor gap: it does not describe what fields accompany each playlist in the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description reinforces the array bound ('1โ50 playlists') but adds no format guidance for the ID/URI/URL items or the response_format enum beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Check if you follow 1โ50 playlists.' The scope (follow-state of playlists) is unambiguous and clearly distinct from the sibling check_following_artists, so an agent can select it without inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The batch size (1โ50) implies the intended use, but there is no explicit when-to-use/when-not guidance and no named alternative (e.g., the artist counterpart or follow_playlist). Usage must be inferred from the operation itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clean_all_playlistsADestructive
Scan every playlist in your library for duplicate items (repeated URIs, and on opt-in same-song copies under different URIs when match_by=name_artist). Reports per-playlist findings by default; pass apply=true to remove them (keeps the first occurrence of each group). Bulk removals ask for one confirmation before anything is deleted. See the duplicate-matching vocabulary in SPEC section 4.
| Name | Required | Description | Default |
|---|---|---|---|
| apply | No | Deprecated alias for dry_run โ prefer dry_run. false (default): report only. true: execute the cleanup across all playlists with duplicates. If both are given, dry_run wins. | |
| dry_run | No | Preview only โ when true, nothing is changed; when false via dry_run=false or apply=true, executes the cleanup | |
| match_by | No | Which rule decides that two items are the same: `uri` (exact URI, the default), `name_artist` (case-insensitive name + credited artists, catches relinks/remasters), or `name` (case-insensitive name only). The rule applied is echoed in the result as `match_by`. | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| include_relinked | No | Deprecated alias for `match_by`, kept for one release: true is `name_artist` and false is `uri`. It cannot express the `name` rule, which is why `match_by` replaced it. Sending both, where they mean different rules, is an error rather than a silent choice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=true, so the description usefully adds that the default is non-destructive, that the first occurrence of each duplicate group is preserved, and that bulk deletions require one confirmation. It could say more about irreversibility or whether an undo/receipt applies, but the safety-relevant behavior is well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences that front-load scope and default behavior before the mutation switch. The closing pointer to 'SPEC section 4' is an external dependency that costs a little self-containedness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does state what comes back (per-playlist findings, match_by echoed in results) and covers the confirmation flow for destructive runs. Complete enough for a library-wide cleanup tool, though return shape detail is thin.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter is already documented in the schema. The description reinforces match_by semantics and the deprecation of apply, but adds no syntax or format detail the schema lacks. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (scan/clean) plus resource (every playlist in your library) plus the object of interest (duplicate items), with the default behavior spelled out. It is clearly differentiated from single-playlist siblings like find_duplicates_in_playlist and remove_duplicate_playlist_items by the library-wide scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the default mode (report only) and the switch to mutation (apply=true), plus the confirmation gate for bulk removal. It does not explicitly name the single-playlist alternatives or say when a user should prefer them, so it falls short of a full when/when-not/alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clean_backup_artifactsADestructive
Delete the NON-library files sharing SPOTIFY_MCP_BACKUP_DIR with your library backups: closed listening sessions (listening-session-*.json), playlist write pre-images (playlistops-pre-*.json) and legacy or migrated playback bookmarks (playback-bookmark-*.json). Library backups and their .meta.json sidecars are never touched โ use delete_backup, and naming one here is refused. These files are local and gone for good once deleted. Preview by default; executing is confirmation-gated and refused when the client cannot prompt (SPOTIFY_MCP_CONFIRM=never bypasses). Ages are mtimes, and the default window is SPOTIFY_MCP_BACKUP_ARTIFACT_RETENTION_DAYS โ separate from the library window. Unrecognised files are listed, not deleted.
| Name | Required | Description | Default |
|---|---|---|---|
| files | No | File names to delete instead of a sweep. Each must be inside the backup directory and match a known family; `family` and `older_than_days` then do not apply. | |
| family | No | Which non-library family to act on. Default all. | |
| dry_run | No | Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit. | |
| older_than_days | No | Age floor in days. 0 = no age filter. Omit to use the retention window. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=true; the description adds substantial context beyond that: files are local and irrecoverable, preview-by-default, confirmation gating, SPOTIFY_MCP_CONFIRM=never bypass, age semantics based on mtimes, and that unrecognised files are listed rather than deleted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is dense and front-loads the destructive action and target scope before the caveats, with each sentence carrying distinct information. It runs long, but almost no clause is redundant given the number of behavioral guarantees it must convey.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description explains the PLAN/preview return, the listing of unrecognised files, and all safety gates. For a destructive file-deletion tool with zero required params, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: ages are mtimes and the default retention window comes from SPOTIFY_MCP_BACKUP_ARTIFACT_RETENTION_DAYS (separate from the library window). It also clarifies that `files` overrides `family`/`older_than_days`, though the schema already states this.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
It states a precise verb (delete) plus the exact resource scope (NON-library backup artifacts), enumerating the three file families by glob pattern. It also explicitly distinguishes itself from sibling `delete_backup` and names the files that belong to that other tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use routing (non-library artifacts vs. library backups via `delete_backup`), the safe default (preview), the commit path (dry_run=false, confirmation-gated), and refusal conditions (naming a library file, clients that cannot prompt). Alternatives and exclusions are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clone_playlist_coverB
Copy cover image from source playlist to target. Quota: GET images + PUT images (plus image fetch).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| image_index | No | Which cover image to copy. Default 0. 0-based index into the playlist's current item order (0 = the first item). | |
| source_playlist_id | Yes | Source playlist ID, URI, or URL | |
| target_playlist_id | Yes | Target playlist ID, URI, or URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds genuinely useful context not present in the schema or the single destructiveHint annotation: the quota cost (GET images + PUT images, plus an image fetch). However it does not say whether the target's existing cover is overwritten or what happens on failure, so the mutation behavior stays partly opaque.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, purpose front-loaded ahead of the quota note; nothing is wasted. The parenthetical 'plus image fetch' is slightly cryptic but does not bloat the text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple copy tool with a full-coverage schema and no output schema, the essentials are covered. The remaining gap is the effect on the target's existing cover and any failure/permission behavior, which an agent would want before invoking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including dry_run and image_index semantics, so the schema carries parameter meaning fully. The description adds nothing parameter-specific, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: copy the cover image from a source playlist to a target playlist. It is inherently distinguishable from nearby siblings like get_playlist_cover and upload_playlist_cover, though it never names them or explicitly disambiguates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance and no alternatives referenced. The quota note is operational cost information, not routing guidance, so an agent still infers on its own when cloning a cover is preferred over uploading one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_playlist_coversARead-onlyIdempotent
Compare two playlists covers: URL equality, dimensions. Quota: 2 GETs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| scan_cap | No | Maximum rows to read from each playlist; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| playlist_a | No | Canonical A playlist; provide with playlist_b | |
| playlist_b | No | Canonical B playlist; provide with playlist_a | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint and idempotentHint, so the safety profile is covered. The description adds genuine value beyond that by disclosing the cost ('Quota: 2 GETs') and the shape of the comparison (URL equality plus dimensions), which an agent cannot read off the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the action and resource, with the cost disclosure appended. Nothing is wasted and speed of scanning is high.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and six parameters, the description carries return-shape duty and does hint at it (URL equality, dimensions). It omits edge cases such as missing covers or mismatched sizes, but for a read-only comparison tool this is close to complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all six parameters (limit, scan_cap, playlist_a/b, max_results, response_format) are already documented in the schema. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('compare two playlists covers') and narrows the scope to URL equality and dimension checks, which separates it from one-cover tools like get_playlist_cover and clone_playlist_cover. It never names a sibling explicitly, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to reach for this versus get_playlist_cover or clone_playlist_cover, nor any precondition (e.g. both playlists must exist / have covers). The purpose is inferable but the selection guidance is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
copy_playlistA
Duplicate an existing playlist into a new playlist, preserving track order. Creates the new playlist then adds tracks in batches of 100. Dry-run reports what would be created.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| public | No | Public flag for the new playlist. Default: false | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| new_name | Yes | Name for the new playlist | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| description | No | Description for the new playlist (defaults to source description) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| collaborative | No | Collaborative flag. Default: false | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| source_playlist_id | Yes | Source playlist ID, spotify:playlist: URI, or URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is destructiveHint=false, so the description carries the burden of behavioral disclosure. It adds valuable transparency by stating that the tool creates the new playlist first, adds tracks in batches of 100, and supports a dry-run mode that reports what would be created. It does not cover rate limits, auth requirements, or failure modes, but the core behavior is well disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no filler. The first sentence states the purpose, the second explains the workflow, and the third covers the dry-run behavior. Every sentence earns its place and the key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 10 parameters and no output schema, and the description explains the main workflow well. However, it does not cover return values, response formats, or edge cases such as the interaction between limit, scan_cap, and max_results. It is adequate for a basic understanding but leaves gaps for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already fully documented. The description reinforces the 'batches of 100' behavior which relates to the limit parameter and mentions dry-run, but it does not add meaning beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Duplicate' and the resource 'existing playlist' into a new playlist, and adds a meaningful detail: preserving track order. It is specific enough to understand the tool's core function, but it does not explicitly disambiguate from sibling tools like clone_playlist_live or playlist_clone_snapshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives such as clone_playlist_live or playlist_clone_snapshot. The description implies usage for duplicating a playlist, but provides no exclusions, prerequisites, or distinguishing conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_playlistA
Create a new playlist for the current user. Set dry_run=true to preview without creating.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Playlist name | |
| public | No | Whether the playlist is public. Default: false | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| description | No | Playlist description | |
| collaborative | No | Whether the playlist is collaborative. Default: false |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=false, so the description need not restate safety. It adds the dry_run preview behavior, which is a useful nuance. However, it doesn't disclose other behavioral aspects like required authentication, rate limits, or the result payload on success. Since the create operation is inherently mutating but safe, the description provides moderate additional context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences convey both the primary function and a key usage tip without any filler. The description is front-loaded with the core action and includes the dry_run hint efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is a simple create operation with five documented parameters, but there is no output schema and the description doesn't mention what the tool returns (e.g., the created playlist object). Given the complexity is low and the schema covers inputs, this is adequate but leaves the return behavior unspecified. No prerequisites or side effects are described beyond dry_run.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters are documented in the schema. The description mentions dry_run, which reinforces the schema's description but doesn't add new meaning. It doesn't clarify any parameter semantics beyond what's already in the schema, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb ('Create') and resource ('a new playlist for the current user'), which clearly distinguishes it from read-only or update operations. It is concise and unambiguous, though it does not explicitly contrast with sibling playlist tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to prefer this tool over alternatives like update_playlist or add_to_playlist. The only usage hint is the dry_run flag for preview, but there is no explicit condition for when to use or avoid this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_smart_playlistA
Create a playlist from rules over your own listening data: top tracks (by time range), recently played, or saved tracks โ with optional artist-name filtering and a one-track-per-artist toggle. When source=saved_tracks the pool is the newest N saved tracks (N=scan_cap, default fetchAllCap=500) and truncation is reported. No deprecated recommendations endpoints involved. Every source has a pool ceiling (top_tracks 100, recently_played 50, saved_tracks scan_cap), reported as pool_capped with pool_cap โ a capped pool is a floor, not a complete scan. dry_run previews the exact track list without creating anything.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Playlist name | |
| limit | No | How many tracks the playlist should hold (after filters). Default 30. | |
| public | No | Whether the playlist is public | |
| source | No | Where candidates come from: your top tracks by time_range, your recently played history, or your saved (liked) tracks. | top_tracks |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| scan_cap | No | How many saved tracks to scan when source=saved_tracks; default SPOTIFY_MCP_FETCH_ALL_CAP (500). Reports truncation when hit. | |
| time_range | No | ~4 weeks / ~6 months / all time. Default: medium_term | |
| description | No | Playlist description | |
| artist_filter | No | Only include tracks whose artist name contains any of these substrings (case-insensitive), e.g. ["Radiohead", "Miles Davis"]. | |
| unique_artists | No | Keep at most one track per primary artist. Default false. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry destructiveHint=false, which is thin. The description compensates by disclosing real behavioral traits: pool ceilings per source, truncation reporting, the fact that a capped pool is 'a floor, not a complete scan', and that dry_run creates nothing. It also warns about truncation for saved_tracks. The one small gap: it doesn't state what happens to an existing playlist of the same name, or whether this mutates user state (creation is implied). Still, this is well beyond the annotation floor, so a 4 is fair.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph that front-loads the core purpose and then packs in constraints. It earns its sentences; every clause adds information. It could be split for readability, but there's no waste. Slightly long for a one-liner but appropriate for the tool's complexity (11 params, 3 sources). A 4 for tight content, minor ding for lack of visual structure.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters, 3 enum-based sources, no output schema, and sparse annotations, the description carries the full burden. It covers: what the tool creates, each source's behavior, pool ceilings, truncation, the dry_run preview, and the exclusion of deprecated endpoints. The parameter semantics dimension covers the rest. Nothing an agent needs to decide whether to call it or how to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning above the schema: it explains that limit applies 'after filters', clarifies that saved_tracks pool is the 'newest N saved tracks' with scan_cap defaulting to fetchAllCap=500, and defines source-specific pool ceilings. It also frames dry_run as 'previews the exact track list'. This is genuine added value beyond the property descriptions, so a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Create') and resource ('a playlist from rules over your own listening data'), then enumerates the exact rule dimensions (source, artist filter, unique artists). It clearly differentiates from the many playlist-creation siblings (e.g. create_playlist, taste_to_playlist, playlist_template_apply) by anchoring on rule-based creation from personal listening data and explicitly ruling out deprecated recommendations endpoints. An agent can tell this apart from siblings without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit 'when to use' context by naming the three data sources and their semantics, and it adds a crucial exclusion: 'No deprecated recommendations endpoints involved,' which tells the agent this is the modern replacement for a legacy flow. It also explains when dry_run is appropriate ('previews the exact track list without creating anything'). Combined with the sibling list (save_smart_playlist_rule, refresh_smart_playlist), an agent can select this over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_backupADestructive
Delete one library backup file (and its metadata sidecar) from SPOTIFY_MCP_BACKUP_DIR. Irreversible โ the library rows in the file cannot be recovered from anywhere else. Destructive and confirmation-gated: dry_run defaults to true, and executing is refused when the client cannot prompt (SPOTIFY_MCP_CONFIRM=never bypasses). Paths outside the backup directory are refused.
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Backup file name (e.g. backup-2026-01-02-1.json) or a path inside the backup directory | |
| dry_run | No | Preview only, and the default: pass dry_run: false to delete the snapshot. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the destructiveHint annotation, disclosing irreversibility, the sidecar deletion, confirmation-gating (dry_run default true, refusal when client can't prompt, SPOTIFY_MCP_CONFIRM=never bypasses), and path restrictions. This is rich, transparent behavioral context that an agent needs for a destructive operation. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is five sentences, with the core action front-loaded in the first sentence. Every sentence adds valueโsidecar deletion, irreversibility, confirmation gating, path restrictionsโwithout redundancy. It's concise and efficiently structured for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool, the description covers the critical aspects: what is deleted, irreversibility, confirmation steps, path safeguards. It does not describe the return format or error behavior for non-existent files, but for a mutation tool with a destructiveHint and full parameter documentation, the provided context is largely sufficient. A small gap remains around response/error details, hence 4.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so parameters (file, dry_run, response_format) are already fully documented in the schema. The description adds no new parameter-level semantics beyond what's in the schema, and the schema entries are themselves descriptive (e.g., dry_run explains default and how to override). Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (Delete), resource (library backup file and its metadata sidecar), and scope (from SPOTIFY_MCP_BACKUP_DIR). It clearly differentiates from list/restore/backup creation tools by emphasizing irreversibility and the sidecar. This leaves no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose is clear enough that an agent would know when to use it (to delete a backup), but the description does not explicitly name alternative tools or provide conditional guidance like 'use this only when you intend permanent removal' or point to restoration tools for recovery. It focuses on behavior rather than decision context, so it falls short of strong usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_sceneADestructive
Delete a saved playback scene from the local sidecar
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Scene name to delete | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true, so the description's confirmation that this deletes a saved scene adds clarity about what is destroyed. It also specifies 'from the local sidecar', which is a useful behavioral detail not present in the annotations. There is no contradiction, and the description provides enough context for the destructive action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with zero filler. Every word contributes to the meaning, and the structure immediately conveys the action and target. Nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter delete tool with destructive annotation and full schema coverage, the description is nearly sufficient. It clearly identifies the action, target, and storage location. The only minor gap is that it does not describe the return behavior or response_format effects, but that is partially covered by the schema and is not critical for a delete operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both 'name' and 'response_format' already documented. The tool description adds no additional meaning about the parameters or their relationships. This meets the baseline for schema-covered parameters but does not go beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Delete' and clearly identifies the resource: 'a saved playback scene from the local sidecar'. This distinguishes it from siblings like delete_playback_bookmark and aligns with the scene-related tools (save_scene, list_scenes, apply_scene). The scope is unambiguous and immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states the tool's function but provides no explicit guidance on when to use it versus alternatives such as delete_playback_bookmark or the other scene tools. Usage is implied by the name and resource, which is sufficient for a straightforward delete, but there is no stated exclusion or alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_playlistsARead-onlyIdempotent
Compare two playlists up to the configured source cap: tracks only in A, only in B (by track ID), and tracks present in both but at different positions. Rendered rows are capped by max_results; truncation metadata reports when source walks hit scan_cap.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| playlist_a | No | Canonical A playlist; provide with playlist_b | |
| playlist_b | No | Canonical B playlist; provide with playlist_a | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is a safe, repeatable read (readOnlyHint, idempotentHint), but the description adds real value beyond them: it discloses the source scan cap, that truncation metadata reports when source walks hit scan_cap, and that rendered rows are bounded by max_results. It stops short of describing output shape or how position comparison is computed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences, front-loaded with the operation and its result categories, followed by the capping/truncation semantics. No filler, restatement of the name, or redundant prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a comparison tool with no output schema and a fully documented parameter set, the description covers result categories, capping behavior, and truncation reporting, which is close to sufficient. It omits any note on empty/error cases or the fact that no parameters are required, but nothing critical to calling it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage the baseline is 3, but the description clarifies the non-obvious interplay between two similarly named caps: scan_cap bounds the source walk while max_results bounds rendered rows. That distinction is not obvious from the schema alone and materially helps correct invocation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Compare two playlists') and enumerates the three result classes (only in A, only in B by track ID, in both but at different positions), which is genuinely informative. However, it never distinguishes itself from the many closely related siblings such as playlist_symmetric_difference, overlap_playlists, or playlist_union, so an agent must infer which comparison tool to pick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no named alternative despite a dense field of overlapping comparison/union/subtract/symmetric-difference siblings. Usage is only implied by the behavioral description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
expand_mood_to_queriesA
Turn a free-text listening mood into search terms (genres, keywords, terms to avoid) for search. Uses the host model via MCP sampling when the host advertises the sampling capability; otherwise returns a built-in static map. Calls no Spotify endpoint and changes nothing. A model reply that cannot be parsed returns isError after one retry โ it is never replaced by a guess.
| Name | Required | Description | Default |
|---|---|---|---|
| mood | Yes | The mood or vibe to expand, in free text (e.g. "rainy afternoon", "late night coding") | |
| max_tokens | No | Token ceiling for the sampling call. Default: 512. Ignored on the static-map path | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the lone destructiveHint=false annotation: it discloses the sampling path vs. static-map fallback, that no Spotify endpoint is called, that nothing is mutated, and the exact failure contract (isError after one retry, never a guess). This is rich, high-value behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four front-loaded sentences, each carrying distinct information (purpose, execution path, side-effect profile, error semantics). Slightly dense but no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and a rich response_format parameter, the description carries the return-value burden and does describe the output fields. A brief note on which format actually gets returned on the static-map path would close the last gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so mood, max_tokens and response_format are fully documented in the schema. The description adds the output vocabulary but no parameter-specific semantics beyond the schema, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Turn a free-text listening mood into search terms') and enumerates the output shape (genres, keywords, terms to avoid). This is a unique utility with no equivalent among the siblings, so it is trivially distinguishable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for search' implies it is a pre-step to searching, but the description never states when to use this versus calling search/search_deep directly, nor any exclusions. Usage is implied rather than directed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_all_playlistsA
Export every owned (or all) playlist with metadata + items to a sidecar file. Quota: GET /me/playlists + NรGET /playlists/{id}/items; capped by fetchAllCap.
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | owned = only playlists you own | all |
| format | No | Output format | json |
| output_dir | No | Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it) | |
| include_items | No | Include track items per playlist | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
destructiveHint=false is already in annotations, and the description adds meaningful behavioral detail with the quota formula: GET /me/playlists + NรGET /playlists/{id}/items, capped by fetchAllCap. This helps the agent reason about cost and batch size, though auth requirements and sidecar-file naming are not disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, dense sentences front-load the core action and then add the quota constraint without any filler or repetition. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given five fully documented parameters, the description covers the operation, scope choice, output format, output directory, and quota behavior. Minor ambiguity remains around the exact meaning of 'all' and the shape of the returned result, but with no output schema and strong parameter docs this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage: all five parameters already carry descriptions, defaults, and enums. The description adds tool-level context like sidecar output and quota, but does not materially refine individual parameter meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The phrase 'Export every owned (or all) playlist with metadata + items to a sidecar file' names a specific verb, resource, and scope. The qualifier 'every' and the sidecar-file output clearly distinguish it from singular or JSON-specific export siblings, even though no sibling is named.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for the intended use case: bulk export of owned/all playlists, with scope selectable via the schema. It stops short of explicitly naming alternatives like export_playlist or sidecar_export_bundle or stating when not to use this tool, so the routing is left partly to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_followed_artistsA
Export your followed artists to a local directory as JSON or CSV. Fields: uri, name, genres. The file's exported_at is the export time, not a per-artist follow date (Spotify does not expose followed_at).
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Output format: json or csv | json |
| output_dir | No | Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only destructiveHint: false, so the description carries the behavioral burden. It discloses the file-writing side effect ('to a local directory'), the output field set, and โ most valuably โ that exported_at is the export time, not a follow date, because Spotify does not expose followed_at. This preempts a likely misinterpretation of the produced data, and none of it contradicts the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with the core purpose front-loaded in the first sentence and zero wasted words. The field list and the exported_at caveat each earn their place; the caveat preempts a data-interpretation error rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity tool (3 optional params, no output schema, non-destructive), the description plus schema cover purpose, destination, response mode (via response_format), field semantics, and the exported_at caveat. Minor gaps remain around overwrite behavior and directory creation, but nothing an agent needs to invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: all three parameters (format, output_dir, response_format) are documented with defaults, enums, and meaning, so the baseline is 3. The description adds marginal value by enumerating the exported fields (uri, name, genres), which clarifies what the chosen format will contain, but it doesn't deepen the meaning of any individual parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Export'), names the exact resource ('your followed artists'), the destination ('a local directory'), formats (JSON or CSV), and even the exported fields. Among the large sibling set of export_* tools, this uniquely targets followed artists, and it is clearly distinguishable from get_followed_artists by the explicit file-persistence behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the phrasing signals it is for creating a local file of followed artists. There is no explicit when/when-not guidance, and with retrieval siblings like get_followed_artists and broader exports like export_library_json in the sibling set, an agent gets no direct routing help. The exported_at caveat is informative but not usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_library_jsonA
Export your full library (saved tracks, albums, shows, episodes, audiobooks) to a local directory as JSON or CSV sidecar files. Respects SPOTIFY_MCP_FETCH_ALL_CAP per type; when capped, reports cap_reached + truncated and a prose footer ("first N of โฆ โ raise SPOTIFY_MCP_FETCH_ALL_CAP").
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Output format: json (single file) or csv (one file per type) | json |
| output_dir | No | Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only include destructiveHint=false, so the description carries the burden of behavioral disclosure. It explicitly discloses the SPOTIFY_MCP_FETCH_ALL_CAP behavior, reporting cap_reached, truncated, and a prose footer, which is valuable context beyond the annotation. However, it does not mention whether existing files are overwritten or how the output directory is created, but those are minor gaps given the export action is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences that front-load the core purpose and then add the cap behavior. Every word earns its place, with no redundancy or fluff. It efficiently conveys the tool's function and a key edge case without extra text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main export scope and the cap/truncation behavior, and the schema covers format and output details. However, it does not describe the return value for a successful export (only the cap case), and it omits details like whether the output directory is created automatically. Given the tool's complexity and lack of output schema, these are minor but notable gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides full descriptions for all three parameters (format, output_dir, response_format), including enums and defaults. The description adds no additional parameter-level meaning beyond what the schema covers. Since schema coverage is 100%, a baseline of 3 is appropriate; the description's cap explanation is not parameter-specific.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool exports the full library (saved tracks, albums, shows, episodes, audiobooks) to a local directory in JSON or CSV format, with a specific verb and resource. It also mentions the cap behavior, which distinguishes it from other export tools. The scope is explicit, making it easy to differentiate from siblings like export_playlist or export_followed_artists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus the many other export tools in the sibling list (e.g., export_all_playlists, export_followed_artists, export_profile_state). It does not mention alternatives or exclusions, leaving the agent to infer usage context. No when-not-to-use conditions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_listening_historyA
Export your listening history (recently played) to a JSON or CSV sidecar by walking /me/player/recently-played with before-cursor pagination. Respects SPOTIFY_MCP_FETCH_ALL_CAP; writes file 0600 and reports path + counts.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Cursor: only return items played after this timestamp (milliseconds since epoch or ISO string) | |
| limit | No | Alias for max_items | |
| before | No | Cursor: only return items played before this timestamp (milliseconds since epoch or ISO string) | |
| format | No | Output format: json or csv | json |
| max_items | No | Max history items to export (default: SPOTIFY_MCP_FETCH_ALL_CAP) | |
| output_dir | No | Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (non-destructive only), it discloses real behavioral details: it writes a file with 0600 permissions, respects SPOTIFY_MCP_FETCH_ALL_CAP, uses before-cursor pagination, and reports path plus counts. It does not fully spell out overwrite/append or error behavior, so not a 5, but it goes well beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler; the operation, target, mechanism, environment constraint, and result are all front-loaded and compact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and only a destructiveHint annotation, the description usefully states output (path + counts), file permissions, and cap behavior. The parameter details are already in the schema, and the description fills enough operational context; a brief return-format/overwrite note would make it fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds cross-cutting meaning that the schema lacks: the overall cap, pagination model, sidecar file behavior, and permission mode, which helps an agent understand how max_items/limit and before interact.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific operationโexporting listening history (recently played) to JSON or CSVโand adds the API endpoint and pagination strategy, so the tool's job is clear. It does not explicitly differentiate itself from the similar sibling listening_history_export or other export_* tools, which keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies when to use it (whenever a file-based export of recently played items is needed) and clarifies the pagination/fetch-cap behavior, but it never states when to prefer a sibling such as get_recently_played or listening_history_export, nor does it give exclusions. This is adequate but leaves routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_playlistA
Export a playlist's full item list as an M3U playlist file or a CSV spreadsheet. Pages every item; pass output_path to write a file (created with mode 0600) inside the configured output root, or omit it to get the document inline. CSV cells are formula-safe.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Output format: m3u (playable playlist) or csv (spreadsheet) | m3u |
| overwrite | No | Allow replacing an existing file at output_path (refused by default) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| output_path | No | Write the full document to this local file (relative paths resolve inside the output root, default ~/.spotify-mcp/exports) instead of returning it inline | |
| playlist_id | Yes | Playlist ID | |
| include_headers | No | Emit the #EXTM3U marker / CSV header row | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It adds genuinely useful behavioral detail beyond the annotations: internal pagination, mode 0600, output-root sandboxing, inline-vs-file behavior, and formula-safe CSV. However, the claim of a 'full item list' conflicts with the schema's max_results default of 50, so the transparency is incomplete and potentially misleading.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with the purpose front-loaded and no filler. Each sentence carries a distinct, useful fact: output formats, file-vs-inline behavior, and CSV security.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema fills in most parameter detail and the description covers output modes well, but the description would mislead an agent about default truncation unless max_results is raised, and it does not mention sibling export formats. For a 7-parameter tool with no output schema, these are notable gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds value on top by explaining output_path semantics (mode 0600, relative to the output root, inline when omitted) and CSV cell safety. Repeating the other parameters would be redundant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: exporting a playlist's full item list to M3U or CSV. It is clearly distinct from a generic get/list tool, but it does not explicitly differentiate itself from sibling exports like export_playlist_json, export_playlist_markdown, or export_all_playlists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear guidance on choosing between file output and inline return ('pass output_path... or omit it') and explains the output root and file mode. It stops short of naming when not to use this tool, such as pointing agents to JSON or Markdown export siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_profile_stateA
Export local sidecar stores (scenes, genre-tags, playback-ext, search-history, mutations, artist-watchlist) to a single schema-versioned JSON archive. artist-watchlist is ~/.spotify-mcp/artist-watchlist.json; SPOTIFY_MCP_DATA_DIR overrides that directory.
| Name | Required | Description | Default |
|---|---|---|---|
| output_dir | No | Directory to write the archive into, confined to the output root (default ~/.spotify-mcp/exports, set SPOTIFY_MCP_EXPORT_DIR to move it) | |
| include_history | No | Include mutation history JSONL (can be large) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide destructiveHint=false, so the description carries the burden of explaining behavior. It adds that the output is a single schema-versioned JSON archive and specifies the artist-watchlist location, which is useful. However, it does not disclose overwrite behavior, directory creation, or whether the operation has any side effects beyond writing the archive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the first states the core action and content scope, the second adds a useful file-path detail. Information is front-loaded and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple export operation, well-documented parameters, and clear content enumeration, the description is nearly complete for correct invocation. It does not describe the return value or file-naming behavior, but no output schema exists and the operation's intent is clear enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters (output_dir, include_history, response_format) are already fully documented. The description adds no parameter-level meaning beyond the schema, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'export local sidecar stores' to 'a single schema-versioned JSON archive', and enumerates exactly which stores are included (scenes, genre-tags, playback-ext, search-history, mutations, artist-watchlist). This clearly distinguishes it from export siblings like export_library_json or export_listening_history without needing to open the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for backing up or migrating local profile/sidecar state, but it never explicitly states when to use this tool over alternatives. With several nearby export tools (sidecar_export_bundle, export_library_json, mutation_log_export), the lack of exclusion or alternative guidance leaves some ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
filter_by_genreARead-onlyIdempotent
List URIs of your saved tracks or albums whose artists carry a given genre tag (case-insensitive tag-name match against your sidecar). Output is directly usable as create_playlist / add_to_playlist input. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | Which saved collection to filter | |
| genre | Yes | Genre tag to match (case-insensitive, e.g. "pop") | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the description's 'Read-only' line is redundant but not contradictory. It does add genuine beyond-annotation context: the tag match is case-insensitive and resolved against 'your sidecar' (a local data source), which tells the agent the filtering semantics differ from a live API query. It stops short of covering result limits or error behavior, but the annotation baseline is already met.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with zero filler, front-loading what is returned (URIs) and where they can be used before the read-only note. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description usefully explains the return value (URIs) and its downstream use, which the agent needs. It omits mention of the max_results cap behavior and result ordering, but for a filtered-list tool the essentials are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents kind, genre, max_results, and response_format including enums and the env-var default. The description only reinforces the case-insensitive genre matching already noted in the schema, adding little beyond it. Baseline 3 applies when the schema carries the full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List URIs of your saved tracks or albums') plus the filtering criterion (artists carrying a genre tag). The scope is narrow and clearly distinct from siblings like search_saved_tracks or library_genre_report, and it even names what the output feeds into (create_playlist / add_to_playlist).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by noting the output is 'directly usable as create_playlist / add_to_playlist input', which hints at a build-a-playlist workflow. However, it never states when to prefer this over alternatives such as search_saved_tracks or library_genre_report, leaving the routing decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_duplicate_saved_tracksARead-onlyIdempotent
Read-only duplicate detection over your saved (liked) tracks. Exact groups require the same non-null ISRC and album id with duration within ยฑ2s, and keep the oldest dated save. On opt-in, near-duplicate groups show same-title/artist tracks whose ISRC, release, or duration differs; these are distinct saved tracks and are review-only with no removals. Undated saves sort after dated saves. Optionally pass a playlist_id to cross-reference which group members also appear in that playlist. Never mutates your library.
| Name | Required | Description | Default |
|---|---|---|---|
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | No | Optional playlist ID to cross-reference: members of each duplicate group that also appear in this playlist are flagged, so cleanup or review decisions can account for where the track is already curated. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| include_near_duplicates | No | Also report same-title/artist groups with a different ISRC, release, or duration. Near duplicates are review-only and never recommend removal. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/idempotent annotations by disclosing the exact-match criteria (same non-null ISRC and album id, duration ยฑ2s, keeps oldest dated save), that near-duplicates are review-only with no removals, that undated saves sort last, and that it never mutates the library.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose and then layers matching semantics efficiently; every sentence carries information. A few sentences are dense and could be tighter, but there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining what comes back, and it does describe group types, exact vs. near distinction, and undated-save ordering. It stops short of describing the concise/detailed/json return shapes in depth, leaving a small gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: playlist_id denotes cross-referencing group members against a playlist for cleanup decisions, and include_near_duplicates is framed as an opt-in review-only mode. These enrich the parameters beyond their schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Read-only duplicate detection over your saved (liked) tracks.' The 'saved (liked) tracks' scope cleanly distinguishes it from sibling playlist duplicate tools like find_duplicates_in_playlist and find_duplicate_tracks_across_playlists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear conditions for the two modes (exact groups vs. opt-in near duplicates) and explains the optional playlist_id cross-reference use case. It never explicitly names an alternative sibling or states when NOT to use it, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_duplicates_in_playlistARead-onlyIdempotent
Find duplicate tracks in a playlist under one published matching rule. match_by selects the rule (uri โ the same track object twice; name_artist โ same name and credited artists, catching relinks and remasters; name โ same title only) and the rule is echoed back as match_by, so a group count is never unattributable. See the duplicate-matching vocabulary in SPEC section 4.
| Name | Required | Description | Default |
|---|---|---|---|
| match_by | No | Which rule decides that two items are the same: `uri` (exact URI, the default), `name_artist` (case-insensitive name + credited artists, catches relinks/remasters), or `name` (case-insensitive name only). The rule applied is echoed in the result as `match_by`. | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | Yes | Playlist ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds that the applied rule is echoed back as `match_by` so a group count is never unattributable, plus a pointer to SPEC section 4 vocabulary โ useful context beyond the annotations, though nothing about result shape or limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then rules; two sentences carry real information. The echo-of-`match_by` point is stated twice (once in prose, once in the schema description), a small redundancy that keeps it from being maximally tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does supply the key return-context detail (rule echoed in the result) and the matching-rule semantics. It omits result shape beyond group counts and limit behavior, but is otherwise sufficient for calling the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all four parameters including the enum semantics and the default. The description largely restates the `match_by` rules and its echo behavior, adding marginal value over the structured field, which is the expected baseline when the schema does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (find) plus resource (duplicate tracks) and an explicit scope ('in a playlist'), which separates it from siblings like find_duplicate_tracks_across_playlists and remove_duplicate_playlist_items. An agent can classify it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains which matching rule each `match_by` value selects and the real-world cases they catch (relinks, remasters), which is genuine usage guidance. It does not, however, explicitly route the agent away from the removal/clone siblings, so it stops short of the top mark.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_duplicate_tracks_across_playlistsARead-onlyIdempotent
Find tracks that appear in more than one of the given playlists (cross-playlist dupes). Quota: N GETs (one per playlist).
| Name | Required | Description | Default |
|---|---|---|---|
| playlists | No | Canonical ordered playlists (2โ20) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds the API-quota behavior (one GET per playlist, N total), which annotations do not convey, but it says nothing about how duplicates are reported, ordering, or truncation with max_results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the scope definition and the quota cost front-loaded. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, idempotent tool with three fully documented parameters and no output schema, the definition covers purpose and cost adequately. It could be slightly richer about what a duplicate match looks like, but nothing essential to invoking it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the playlist ID formats, the 2-20 bound, the max_results default, and the response_format enum are all documented in the schema. The description adds no syntax or semantic detail beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (find) and resource (tracks) plus the exact scope qualifier 'appear in more than one of the given playlists (cross-playlist dupes)'. The parenthetical explicitly disambiguates it from the within-playlist sibling find_duplicates_in_playlist/remove_duplicate_playlist_items without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives cost guidance (N GETs, one per playlist), which is genuinely useful, but never states when to prefer this over sibling overlap tools such as overlap_playlists, playlist_symmetric_difference, or playlist_union. Usage is implied by the purpose line rather than explicitly routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_toolARead-onlyIdempotent
Search the live tool registry by name or description substring โ the fastest way to discover which of the 500+ tools handles a job. Discovery set: find_tool/inspect_tool/toolset_report are always available (also via catalog). Use this first when unsure which verb to use (e.g., playlist vs snapshot vs search).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max matches to return (default 25) | |
| query | Yes | Case-insensitive substring to match against tool names and descriptions | |
| response_format | No | 'concise' (default) = prose bullet list; 'detailed' = the same prose; 'json' = the result payload as parseable JSON text, identical to structuredContent | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so safety and repeatability are covered by structured data. The description adds useful operational context โ the registry is live, 500+ tools, and the discovery set is always available via catalog โ but discloses nothing about result ordering, match behavior beyond 'case-insensitive substring', or limits. Adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero padding, with the core purpose front-loaded before the routing advice. The parenthetical about the discovery set is terse but earns its place by telling the agent these tools remain callable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety, an output schema covering return values, and full parameter documentation in the schema, the description only needed to supply purpose and routing โ both delivered. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with 3 parameters, each documented (query semantics, limit default/max, response_format enum meanings). The description adds no parameter guidance beyond the schema, so the baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource (live tool registry) with the matching mechanism (name or description substring). It also quantifies scope (500+ tools), which lets an agent distinguish it immediately from the domain-specific search_* siblings that search Spotify content rather than the tool registry.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use it first when unsure which verb applies, gives a concrete example of the ambiguity it resolves (playlist vs snapshot vs search), and names the sibling discovery tools (inspect_tool, toolset_report) plus the catalog as alternate access paths. Both the when and the alternatives are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
followed_playlists_auditB
Inventory of followed vs owned playlists: counts, collab, public, follower totals. Quota: GET /me/playlists paged.
| Name | Required | Description | Default |
|---|---|---|---|
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| only_followed | No | Only followed (not owned) playlists (default false) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=false, so the description must carry behavioral weight. It does add one useful operational fact โ the quota applies to the paged GET /me/playlists endpoint โ which hints at rate-limit and pagination costs. It says nothing about whether results are cached, how large the fetch can be, or how long it takes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact clauses with no filler, and the core inventory content is front-loaded before the quota note. The telegraphic list style ('counts, collab, public, follower totals') is dense but readable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden; it does list the reported dimensions, which is helpful. However it leaves the shape of the audit output, whether it covers owned playlists in the same call, and the effect of the response_format parameter unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so max_results, only_followed, and response_format are fully documented in the schema; the description adds essentially nothing parameter-specific. Baseline 3 applies when the schema does all the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (followed vs owned playlists) and enumerates what the audit reports: counts, collaborator status, public/private, and follower totals. This distinguishes it from siblings like get_user_playlists and following_analytics, though it never names those alternatives explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this tool versus get_user_playlists, get_user_playlists_by_id, or following_analytics, all of which overlap on playlist surface area. The word 'audit' and the followed/owned comparison imply a reporting use case, but the agent must infer it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
following_analyticsB
Followed-artist rollups from the tag sidecar; popularity/followers unavailable (Spotify no longer returns those fields). Quota: GET /me/following.
| Name | Required | Description | Default |
|---|---|---|---|
| top_n | No | Top N groups to show | |
| group_by | No | Rollup dimension; popularity/followers report 'unavailable' | genre |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint=false in annotations, the description carries real behavioral weight: it discloses the tag-sidecar data source, that popularity/followers are structurally unavailable (Spotify API change), and that a GET /me/following quota applies. These are non-obvious constraints an agent cannot infer from the schema. It stops short of 5 only because it doesn't say what happens when the sidecar is empty or stale.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences with the data-source caveat front-loaded before the quota note. No filler, though the 'Quota: GET /me/following' fragment is cryptic enough that its brevity borders on ambiguity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only rollup with no output schema, the description covers the data-source and availability caveats but never indicates the shape or grouping of results, nor how top_n interacts with max_results. Adequate but with a noticeable gap for an analytics tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all four parameters including the 'unavailable' behavior for popularity/followers. The description's note about unavailable fields is largely redundant with the enum description, so it adds little beyond the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and operation ('followed-artist rollups') plus the data source ('tag sidecar'), which is enough to distinguish it from get_followed_artists/check_following_artists. It does not explicitly name those siblings as alternatives, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance or routing against the many neighboring following/export tools. The quota note hints at cost but never tells the agent when this rollup is the right call versus get_followed_artists or export_followed_artists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
follow_playlistA
Follow a playlist โ save it to your Spotify library โ via PUT /me/library. Spotify removed the playlist-followers endpoints in Feb 2026; this is the only way to follow a playlist. Supports dry_run (default true); writes require confirmation unless SPOTIFY_MCP_CONFIRM=never.
| Name | Required | Description | Default |
|---|---|---|---|
| public | No | Must be true or omitted; the library endpoint has no visibility parameter. | |
| dry_run | No | Preview only (default): pass dry_run: false to execute the follow. | |
| playlist_id | Yes | Playlist ID to follow | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| dry_run | No | |
| receipt | No | |
| cancelled | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint: false in annotations, the description adds genuinely useful behavior: dry_run defaults to true, real writes require confirmation unless SPOTIFY_MCP_CONFIRM=never, and the underlying endpoint. It does not contradict the non-destructive hint, though it omits mention of auth scopes or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the action and endpoint, followed by the rationale and safety gating. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation. Endpoint, safety mode, confirmation policy, and API-version context are all covered, leaving nothing an agent needs missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and every parameter (including the public caveat and dry_run meaning) is already documented in the schema. The description reinforces dry_run's default but adds no syntax or format detail beyond the structured fields, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Follow a playlist') plus the precise mechanism (PUT /me/library). It clearly distinguishes itself from siblings like unfollow_playlist and check_playlist_following.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains why this tool is now the only path to follow a playlist (endpoints removed Feb 2026) and notes dry_run defaults to true while writes need confirmation. No explicit when-not-to-use or sibling alternative is named, though the alternatives are largely gone by construction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_currently_playingARead-onlyIdempotent
Lightweight poll of what is playing right now: the item and progress only. For full session state (shuffle/repeat mode, active device, volume) use get_now_playing instead.
| Name | Required | Description | Default |
|---|---|---|---|
| market | No | ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to SPOTIFY_MCP_MARKET | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| additional_types | No | Item types to include in the response. Default: ['track', 'episode'] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds real value beyond that by disclosing the scope of the response payload (item and progress only), letting the agent anticipate a lighter result set than the sibling. It does not mention auth or rate limits, but neither is critical for a poll.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences with zero filler; the payload scope is front-loaded immediately followed by the routing instruction. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only poll with no output schema, the description covers what is needed: purpose, payload scope, and the sibling alternative. Nothing an agent requires in order to choose and call this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% โ market, response_format, and additional_types are each fully documented in the schema, including defaults and enum meanings. The description adds no parameter guidance, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (poll what is playing right now) and scopes it precisely with 'lightweight' and 'the item and progress only', which distinguishes it from the richer get_now_playing sibling named in the same sentence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the alternative tool (get_now_playing) and states the condition that selects it ('For full session state ... use get_now_playing instead'). This is textbook when-to-use/when-not-to-use routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_devicesARead-onlyIdempotent
List available Spotify Connect devices. The same rows are readable as a resource with no tool call at spotify://player/devices ('?format=json' returns the raw API object).
| Name | Required | Description | Default |
|---|---|---|---|
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the description is not required to cover safety. It adds useful behavioral context by disclosing that the same rows are available as a resource without a tool call, and that the raw API object is accessible.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero waste. Purpose is front-loaded, and the resource alternative is appended as useful supplementary context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and read-only, with a fully documented schema and annotations. The description adds the resource alternative, which is valuable; the lack of output schema means return shape need not be explained in detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema fully documents both parameters (max_results and response_format), including defaults and enum values. The description adds no additional parameter-level detail, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('Spotify Connect devices') with no ambiguity. No sibling tool covers device listing, so an agent can distinguish it immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete alternative access path via the spotify://player/devices resource and notes that '?format=json' returns the raw API object. It does not explicitly state when to call the tool versus reading the resource, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_followed_artistsARead-onlyIdempotent
Get the artists the user follows. fetch_all=true walks every page; limit/after page manually.
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | Artist ID cursor for pagination (from previous response) | |
| limit | No | 1โ50. Default: 20 | |
| fetch_all | No | Walk every page instead of one page (ignores limit) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, covering the safety profile. The description adds pagination behavior, but this largely restates the fetch_all schema description ('Walk every page') rather than offering new behavioral context like rate limits or result-size caps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler; the primary purpose is front-loaded and the pagination note is a single compact clause. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with strong parameter documentation, the description covers the main pagination modes. However, it does not explain how fetch_all interacts with max_results, nor describe the return shape โ and there is no output schema to compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter already has documented meaning. The description mentions fetch_all, limit, and after, but adds no new semantic detail beyond the schema's own descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states the verb and resource explicitly: 'Get the artists the user follows.' The scope is clear and matches the tool name. It does not explicitly contrast with sibling tools like export_followed_artists or check_following_artists, so it lacks explicit sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear pagination guidance ('fetch_all=true walks every page; limit/after page manually'), which tells the agent when to use the fetch_all mode vs manual paging. However, it does not address when to prefer this tool over related siblings such as export_followed_artists or check_following_artists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_now_playingARead-onlyIdempotent
Full device/session state for what is playing right now โ item, progress, plus shuffle/repeat mode, active device, and volume. For a lightweight item+progress poll use get_currently_playing instead.
| Name | Required | Description | Default |
|---|---|---|---|
| market | No | ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to SPOTIFY_MCP_MARKET | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| additional_types | No | Item types to include in the response. Default: ['track', 'episode'] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds real value beyond that by disclosing the breadth of state returned (shuffle/repeat mode, active device, volume) rather than just item+progress, though it says nothing about auth requirements or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler. The scope statement is front-loaded and the sibling routing note is compact and immediately actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description enumerates what is returned, covering the gap. With read-only annotations and fully documented optional params, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and all three parameters (market, response_format, additional_types) carry their own descriptions, defaults, and enum semantics. The description adds no parameter-level detail, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb+resource (full device/session state for what is playing now) and enumerates the returned facets: item, progress, shuffle/repeat, active device, volume. It explicitly contrasts itself with the sibling get_currently_playing, so an agent can choose without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the alternative by name and the condition that selects it: 'For a lightweight item+progress poll use get_currently_playing instead.' This is an explicit when-to-use-this-vs-that routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playlistARead-onlyIdempotent
Get a playlist's metadata (including cover image) and items. Use market to relink tracks and flag unavailable ones, and fields/additional_types to trim the payload โ both are forwarded to the metadata read and the item pages.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Alias for playlist_id, resolved the same way | |
| limit | No | Items per page, 1โ100. Default: 50 | |
| fields | No | Comma-separated list of response fields to keep, e.g. 'total,items(track(name,uri))' | |
| market | No | ISO 3166-1 alpha-2 country code, e.g. 'GB'; relinks tracks to that market and flags unavailable ones | |
| offset | No | Pagination offset for items. Default: 0 | |
| fetch_all | No | Fetch all items across pages (up to 500), continuing FROM offset. limit is the page size. Note: library tools' fetch_all ignores offset โ contracts differ between modules (#110). | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | No | Playlist ID, spotify:playlist: URI, or open.spotify.com/playlist URL | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| additional_types | No | Item types to include beyond the default 'track', e.g. ['track', 'episode'] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds real behavioral context beyond that: market relinks tracks to a country and flags unavailable ones, and fields/additional_types trim the payload across both the metadata read and the item pages.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, purpose front-loaded, then parameter behavior. Dense but every clause carries information. The second sentence crams several parameters together, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description covers identity, market and field-trimming but omits response_format (concise/detailed/json โ a major output-shape decision), pagination (limit/offset/fetch_all/max_results), and the id/playlist_id alias. It is adequate but leaves notable gaps for an agent to fill from the schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds value beyond the schema by clarifying that fields/additional_types are forwarded to both the metadata read and the item pages, and that market affects linkage/unavailability rather than simple filtering. It says nothing about response_format, limit/offset, or fetch_all semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: retrieves a playlist's metadata (including cover image) and items. This implicitly separates it from siblings like get_playlist_items and get_playlist_cover, which return only one half, though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what market, fields and additional_types do and notes they are forwarded to both the metadata read and item pages, which implies when to reach for them. It never states when to prefer this tool over get_playlist_items, get_playlist_cover, or search_within_playlist, so usage remains inferred rather than guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playlist_added_datesBRead-onlyIdempotent
List when each track was added to a playlist (added_at + added_by). Quota: GET /playlists/{id}/items paged.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Sort by added_at (default added_asc) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | Yes | Playlist ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds genuine context with the pagination and quota note ('GET /playlists/{id}/items paged'), but does not say how paging interacts with max_results or what the result shape looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with no filler, and the core purpose is front-loaded before the quota note. The 'Quota:' fragment is terse to the point of being slightly cryptic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing tool with no output schema and fully documented parameters, the description covers what is returned and how it is fetched. It does not explain result ordering defaults or paging limits, but nothing critical to a correct call is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with sort, max_results, playlist_id and response_format all documented including defaults and enums, so the schema carries the load. The description adds no parameter syntax or format detail beyond the output fields it mentions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List when each track was added to a playlist') plus the fields returned (added_at, added_by), so the agent knows this is an added-date listing rather than a plain item listing. It stops short of explicitly naming the close sibling get_playlist_items, so it is clear but not sibling-differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use, when-not-to-use, or alternative guidance, despite several near-neighbors (get_playlist_items, get_playlist, search_within_playlist). Usage is only inferable from the phrase 'when each track was added'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playlist_coverBRead-onlyIdempotent
Get a playlist's cover image URLs
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Alias for playlist_id, matching get_playlist | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | No | Playlist ID (or pass it as 'id') | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, covering the safety profile, and the description is fully consistent with them (no contradiction). The description adds only the small detail that 'URLs' is plural, hinting that multiple image sizes may be returned. It does not disclose return shape, auth requirements, or rate limits, but with annotations carrying the safety burden, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single focused sentence with zero filler, front-loaded with the verb and resource. It is efficiently sized for a simple getter, though the brevity could have been leveraged to add sibling differentiation or usage context without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only getter with 100% schema coverage and safety annotations, the description is largely adequate. Gaps remain: no description of the return format despite the response_format parameter, and no routing between cover-related siblings (upload/clone/compare). The schema's note that 'id' matches get_playlist partially compensates by linking to a sibling's id format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (id, playlist_id, max_results, response_format) are already documented in the schema. The description adds nothing about parameters, so the baseline 3 applies. Notably, the schema's max_results and response_format parameters suggest the tool may behave more richly than the one-line description implies, but the schema itself documents them adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get') and resource ('a playlist's cover image'), and specifies the output ('URLs'). This distinguishes it from siblings like upload_playlist_cover, clone_playlist_cover, and compare_playlist_covers via the action verb. However, it doesn't explicitly name those alternatives, so differentiation is implied rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The description never mentions the cover-related siblings (upload/clone/compare) or any condition that would select this tool over them. An agent must infer usage entirely from the tool name and the verb in the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playlist_itemsARead-onlyIdempotent
List a playlist's items on a single page. Use market to relink tracks and flag unavailable ones, and fields/additional_types to trim the payload.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Alias for playlist_id, matching get_playlist | |
| limit | No | Items per page, 1โ100. Default: 100 | |
| fields | No | Comma-separated list of response fields to keep, e.g. 'total,items(track(name,uri))' | |
| market | No | ISO 3166-1 alpha-2 country code, e.g. 'GB'; relinks tracks to that market and flags unavailable ones | |
| offset | No | Pagination offset. Default: 0 | |
| fetch_all | No | Fetch every item across pages (up to 500), continuing FROM offset rather than restarting at 0. limit is the page size. Note: library tools' fetch_all instead ignores offset โ contracts differ between modules (#110). | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | No | Playlist ID (or pass it as 'id') | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| additional_types | No | Item types to include beyond the default 'track', e.g. ['track', 'episode'] |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and idempotent, so the safety profile is covered. The description adds real behavioral context about single-page listing and market-based relinking/flagging, but it does not disclose pagination behavior beyond the single-page claim and says nothing about the return shape or how fetch_all interacts with the stated single-page behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences front-load the core behavior and then immediately point to the most decision-relevant parameters. Every clause earns its place, with no filler or redundant restatement of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema is exhaustive and annotations cover safety, so the description does not need to repeat everything. Still, with no output schema and a 10-parameter tool, the description leaves the fetch_all behavior and return format unmentioned, and 'single page' could mislead an agent into ignoring the built-in multi-page fetch option.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the schema already thoroughly documents market, fields, additional_types, fetch_all, and the rest. The description essentially restates what market, fields, and additional_types do without adding new meaning, so it neither hurts nor materially improves parameter understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('List') and resource ('a playlist's items'), and adds the scope 'on a single page' which helps set boundaries. It is not as strong as it could be because it never names a sibling like get_playlist to explicitly differentiate, but the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives useful parameter-level guidance ('Use market to relink tracks and flag unavailable ones, and fields/additional_types to trim the payload'), implying when options matter. However, it never states when to choose this over nearby alternatives like get_playlist, get_playlist_followers, or playlist_snapshot, and it omits mention of fetch_all despite saying 'a single page'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_playlist_snapshotARead-onlyIdempotent
Expose snapshot_id + item count for optimistic concurrency. Quota: 2 GETs.
| Name | Required | Description | Default |
|---|---|---|---|
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | Yes | Playlist ID, spotify:playlist: URI, or URL | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and idempotent behavior. The description adds useful context beyond annotations: the quota cost (2 GETs) and the concurrency reason for requesting snapshot_id, though it does not detail return shape or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences/fragments with zero filler. It front-loads the returned values and then the quota constraint, so every element earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only snapshot tool with supporting annotations and a fully described schema, the description states the core return values and quota cost. It could say more about how max_results interacts with the count or what response_format controls, but it is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so playlist_id, max_results, and response_format are already documented in the schema. The description adds no parameter-specific syntax, defaults, or selection guidance, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific data it exposes (snapshot_id and item count) and a purpose (optimistic concurrency), which distinguishes it from playlist-item tools. However, it never says 'playlist' and does not explicitly contrast itself with siblings like get_playlist or get_playlist_items.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Mentions optimistic concurrency as a use context and quota cost, implying when it is useful. It does not give explicit when-not guidance or name alternative tools for cases where full playlist data or items are needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_queueARead-onlyIdempotent
Read the playback queue. Use this for queue CONTENTS (what is playing, what is up next, how long it runs, what repeats). Use peek_next for a short lookahead. Quota: 1 read; view=enriched and include=runtime add one GET /me/player, and the context label adds one catalog read.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | 'raw' (default) = the queue as returned. 'enriched' = plus the source context (playlist/album name) and total time remaining. | raw |
| include | No | Local analyses over the same single read, no extra request except runtime: runtime = total/avg/longest/shortest, time left on the current track, and a per-item timeline of when each row starts playing; duplicates = repeated rows and the runtime they waste; profile = unique artists/albums/shows, track-vs-episode mix, longest single-artist run. | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly and idempotent, but the description adds real non-structured context: the read-cost quota breakdown (1 read, plus one GET /me/player for enriched/runtime, plus one catalog read for the context label). It omits return-shape details, but the quota disclosure is genuinely useful cost information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, front-loaded with the core action, then scope, then alternative, then cost. No filler; every clause carries actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description adequately conveys what comes back (contents, runtime, repeats) and the cost profile. Minor gap: it doesn't hint at pagination or max_results behavior for large queues, though the schema covers the cap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so 3 is the baseline, but the description goes beyond the schema by tying specific parameter values (view=enriched, include=runtime, context label) to their request-cost implications, which the schema does not express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Read the playback queue') and immediately scopes it to queue contents (now playing, up next, runtime, repeat). It explicitly routes lookahead intent to a different tool, separating it from siblings like get_now_playing and skip_next.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the use case ('queue CONTENTS') and names the alternative ('Use peek_next for a short lookahead'), giving the condition that selects each. An agent can choose correctly without opening a schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_saved_albumsARead-onlyIdempotent
Get albums saved in the user's library. Set fetch_all=true to retrieve the entire collection. Output is capped by max_results (default: SPOTIFY_MCP_MAX_ITEMS).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | 1โ50. Default: 20 | |
| market | No | ISO 3166-1 alpha-2 country code, e.g. 'US' | |
| offset | No | Pagination offset. Default: 0 | |
| fetch_all | No | Fetch all pages instead of one page (ignores limit/offset) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, covering the safety profile. The description adds behavioral detail about fetch_all ignoring limit/offset and output being capped by max_results, which is useful beyond annotations. It doesn't describe return format but that's not required here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero fluff. The core purpose is front-loaded, and the important behavioral notes about fetch_all and max_results are concise and immediately actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list retrieval with 6 well-documented parameters, the description covers the key decision points (fetch_all, max_results cap). It doesn't specify return format, but given no output schema and annotations covering safety, the description is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter already has a clear description. The tool description adds no new parameter meaning beyond what the schema provides; it merely references fetch_all and max_results without additional detail. Baseline 3 is appropriate when the schema carries the burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get albums saved in the user's library.' It clearly distinguishes from sibling tools like get_saved_tracks and get_saved_shows by focusing on albums. The name and description together make the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use pagination behavior: 'Set fetch_all=true to retrieve the entire collection.' It also explains the max_results cap. It does not explicitly contrast with alternatives, but the name and context make the appropriate use case obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_saved_countsARead-onlyIdempotent
Library size snapshot: counts for tracks/albums/shows/episodes/audiobooks/playlists via limit=1 reads โ no item paging. The total covers library saves only: playlists are owned and followed collections, so their count is reported alongside the library rows and excluded from the total. A collection that could not be read (rate limited, gated, or erroring) is reported as unreadable with its reason and left out of the total โ it is never reported as 0. One attempt per collection: a rate limit is surfaced, not retried. Quota: 6 GETs.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover read-only/idempotent safety, yet the description discloses a wealth of behavior beyond them: a fixed quota of 6 GETs, one attempt per collection with rate limits surfaced rather than retried, unreadable collections reported with a reason and excluded from totals (never reported as 0), and playlists counted separately from the library total. This is exactly the operational context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the snapshot purpose, then layers in the edge cases. It is dense with clauses, but nearly every sentence carries decision-relevant information (total scope, unreadable handling, quota), so little is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter read tool with no output schema, the description fully explains what is returned (per-collection counts plus a total), how playlists relate to the total, and how failures appear. Nothing an agent needs to call or interpret it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single response_format enum is fully described in the schema, so the baseline is 3. The description adds no meaning about response_format, and its limit/quota notes are internal mechanics rather than parameter guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Library size snapshot: counts for tracks/albums/shows/episodes/audiobooks/playlists') that clearly separates it from the many sibling list/search tools (get_saved_tracks, search_saved_albums, etc.). The agent can tell this returns counts, not items, without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'no item paging' and 'limit=1 reads' phrasing implies this is the cheap-counts alternative to the listing tools, but it never explicitly names a sibling or states when to prefer this over get_saved_tracks/get_saved_albums. Usage is strongly implied rather than routed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_saved_episodesARead-onlyIdempotent
Get podcast episodes saved in the user's library. Set fetch_all=true to retrieve the entire collection. Output is capped by max_results (default: SPOTIFY_MCP_MAX_ITEMS).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | 1โ50. Default: 20 | |
| market | No | ISO 3166-1 alpha-2 country code, e.g. 'US' | |
| offset | No | Pagination offset. Default: 0 | |
| fetch_all | No | Fetch all pages instead of one page (ignores limit/offset) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, and the description adds behavioral context by explaining the fetch_all behavior and output capping via max_results with its default from SPOTIFY_MCP_MAX_ITEMS. This adds value beyond the annotations by clarifying pagination and limits, though it doesn't cover auth or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: purpose, fetch_all hint, and output cap. No redundant phrases or filler. The most important info is front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with six params and no output schema, the description covers the non-obvious behavior (fetch_all, max_results cap) while the schema fully documents the rest. It doesn't explain response_format or market, but those are in the schema, so the description is adequate for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with each parameter fully documented. The description reiterates fetch_all and max_results semantics that already exist in the schema (e.g., schema says 'Fetch all pages instead of one page (ignores limit/offset)' and max_results default), adding no new meaning. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get podcast episodes saved in the user's library' with a specific verb and resource. It distinguishes from siblings like get_saved_tracks, get_saved_albums, and get_saved_shows by specifying 'podcast episodes' and from search_saved_episodes by indicating retrieval of the entire saved library.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers usage guidance for the fetch_all and max_results parameters, but does not say when to choose this tool over alternatives like search_saved_episodes or get_episode. There is no explicit when-to-use or when-not-to-use context relative to siblings, so it relies on implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_saved_showsARead-onlyIdempotent
Get podcast shows saved in the user's library. Set fetch_all=true to retrieve the entire collection. Output is capped by max_results (default: SPOTIFY_MCP_MAX_ITEMS).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | 1โ50. Default: 20 | |
| offset | No | Pagination offset. Default: 0 | |
| fetch_all | No | Fetch all pages instead of one page (ignores limit/offset) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds useful behavioral context by mentioning that output is capped by max_results and that fetch_all retrieves the entire collection, which goes beyond the annotations without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no extraneous information. The purpose is stated first, followed by the most relevant options (fetch_all and max_results). Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with 5 parameters fully documented in the schema and safety covered by annotations, the description is sufficient. It explains the core behavior and key options, though it does not describe return format or pagination details, which are partially covered by the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all parameters are documented. The description reiterates fetch_all and max_results behavior but adds little beyond what the schema descriptions already provide. The baseline of 3 is appropriate given the schema carries the parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves podcast shows saved in the user's library, specifying a distinct resource ('saved shows') that separates it from siblings like get_show_details or list_show_episodes. The verb 'Get' and the resource are explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for fetching saved shows but does not explicitly differentiate from list_saved_shows or other show-related tools. It offers internal guidance on fetch_all and max_results but no when-to-use vs alternatives, relying on the name to convey context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_saved_tracksARead-onlyIdempotent
Get tracks saved in the user's Liked Songs. Set fetch_all=true to retrieve the entire collection. Output is capped by max_results (default: SPOTIFY_MCP_MAX_ITEMS).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | 1โ50. Default: 20 | |
| market | No | ISO 3166-1 alpha-2 country code, e.g. 'US' | |
| offset | No | Pagination offset. Default: 0 | |
| fetch_all | No | Fetch all pages instead of one page (ignores limit/offset) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds meaningful behavioral details not in annotations: fetch_all toggles full-collection retrieval, and max_results caps output with an environment-driven default. This is exactly the kind of context that helps an agent predict cost and scope.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: the purpose comes first, followed by the two behavioral knobs that matter. No filler, no repetition of schema content. Efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only collection fetch with no output schema, the description covers the main behavioral questions: what it returns, how to get everything, and how results are capped. The remaining params (limit, offset, market, response_format) are fully documented in the schema, and response_format's enum explains the return shape. Complete enough given the tool's simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema descriptions cover 100% of the 6 parameters with types, defaults, ranges, and enums, so the description doesn't need to re-document them. The description does reinforce the two decision-relevant params (fetch_all, max_results) in plain language, adding a small amount beyond schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb, resource, and collection semantics: retrieves tracks saved in the user's Liked Songs. This distinguishes it from siblings like get_saved_albums, get_saved_episodes, and search_saved_tracks. Also surfaces the key options fetch_all and max_results, making the tool's scope immediately clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational context: how to request the full collection (fetch_all=true) and how output is bounded (max_results, defaulting to SPOTIFY_MCP_MAX_ITEMS). It does not explicitly name alternatives or exclusions, but the read-only, single-collection scope is unambiguous. No misleading guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_playlistsBRead-onlyIdempotent
List the current user's playlists
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | 1โ50. Default: 20 | |
| offset | No | Pagination offset. Default: 0 | |
| fetch_all | No | Fetch every playlist (up to 500), continuing FROM offset rather than restarting at 0. limit is the page size. Note: library tools' fetch_all instead ignores offset โ contracts differ between modules (#110). | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered by structured data; 'List' is consistent with these hints. The description adds no behavioral context beyond what annotations imply, but with annotations present the bar is lower and no contradiction exists. It contributes little extra, warranting a mid score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single clean sentence with no filler, appropriately short for a straightforward read operation whose safety is already flagged by annotations. It is front-loaded with the verb and target. Slightly more utility could be packed in, but the brevity is justified here.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich parameter descriptions in the schema and annotations covering read-only/idempotent safety, the description is largely complete for a simple list tool. The main gap is the absence of an output schema and no description-level note about return shape, but for a basic current-user playlist listing this is a minor omission.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even with no parameter info in the description. The schema itself carries detailed semantics, including fetch_all's notable contract difference versus library tools and response_format's prose-versus-JSON modes. The description adds nothing on top, but the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb ('List') and resource ('the current user's playlists'). It implicitly distinguishes itself from the sibling get_user_playlists_by_id by scoping to the current user rather than an arbitrary user ID. Brief but specific enough to identify the operation at a glance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. The natural sibling get_user_playlists_by_id exists for listing another user's playlists, but the description never mentions it or the condition that selects between them. There is also no note about the several pagination/response-format parameters that control behavior, leaving routing and configuration choices entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_playlists_by_idARead-onlyIdempotent
List another Spotify user's public playlists (paginated). Removed by Spotify's February 2026 Web API changes โ unavailable for newer app registrations. Output is capped by max_results (default: SPOTIFY_MCP_MAX_ITEMS).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | 1โ50. Default: 20 | |
| offset | No | Pagination offset. Default: 0 | |
| user_id | Yes | Spotify user ID, spotify:user: URI, or open.spotify.com/user URL | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds meaningful behavioral context beyond annotations: pagination behavior, output capping by max_results, and the deprecation/unavailability caveat. It does not describe return format, but the response_format parameter partially covers that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The primary action is front-loaded, followed by the deprecation caveat and the output cap. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with full schema coverage and a response_format parameter, the description is nearly complete. It covers pagination, output capping, and the critical deprecation limitation. It does not describe the exact return structure, but no output schema exists and the response_format enum gives the agent the key options.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters. The description adds a small amount of value by clarifying that output is capped by max_results and mentioning the SPOTIFY_MCP_MAX_ITEMS default, but this largely duplicates the schema's max_results description. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List another Spotify user's public playlists (paginated).' It clearly distinguishes this tool from get_user_playlists by emphasizing 'another user's' and 'public,' and it adds a concrete deprecation caveat that further defines what the tool is.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: this is for another user's public playlists, not your own. It also provides an explicit exclusion: unavailable for newer app registrations after Spotify's February 2026 Web API changes. It does not name an alternative tool, but the context is strong enough to guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_profileARead-onlyIdempotent
Get any Spotify user's public profile (display name, profile image). Removed by Spotify's February 2026 Web API changes โ unavailable for newer app registrations. The followers field was separately removed from user profiles, so no follower count is reported
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | Yes | Spotify user ID, spotify:user: URI, or open.spotify.com/user URL | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, but the description adds critical behavioral context: the endpoint is deprecated/removed for newer app registrations, and the followers field was separately removed so no follower count is reported. These details go well beyond the annotations and materially affect expected behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tightly written sentences. It leads with the core purpose and then immediately provides availability caveats and missing-field details. Every sentence adds distinct value with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only profile lookup with full schema parameter coverage and annotations covering safety, the description supplies the missing operational context: deprecation status, registration limitations, returned fields, and the absence of follower counts. No output schema exists, and the description sufficiently clarifies expected output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents both user_id and response_format. The description does not add any parameter-specific syntax, constraints, or format meanings beyond what the schema provides, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get any Spotify user's public profile (display name, profile image).' It is clear what the tool does and what data is returned, but it does not name or explicitly distinguish itself from sibling tools such as get_user_playlists_by_id or other profile-related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an important when-not condition: it was removed by Spotify's February 2026 Web API changes and is unavailable for newer app registrations. This helps an agent avoid calling it in unsupported contexts. However, it does not suggest alternative tools or explicitly describe when to use it versus other profile-adjacent tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
grow_playlistA
Propose tracks to grow one of your playlists using ONLY your own listening data (no recommendations): finds tracks appearing in >=2 of your OTHER playlists, boosts ones sharing an artist with the target playlist, excludes tracks already in it (and optionally your saved library), and returns top candidates with evidence. Read-only: review the proposals, then call add_to_playlist with the URIs you want.
| Name | Required | Description | Default |
|---|---|---|---|
| size | No | How many candidates to propose (default 20) | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | Yes | Target playlist ID to grow | |
| exclude_saved | No | Skip tracks already in your saved library (default true) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description aligns with annotations by declaring 'Read-only' consistent with destructiveHint: false, and adds useful behavioral context: the data-source constraint, deduplication rule (>=2 playlists), artist boost, and exclusion behavior. However, it leaves the dry_run parameter's implication unexplained โ dry_run's 'describe exactly what would change without performing it' phrasing suggests a performing mode that the read-only claim doesn't reconcile. Output format ('top candidates with evidence') is also vague.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence with the core purpose front-loaded and the follow-up workflow at the end. Every clause earns its place โ algorithm, exclusions, and routing. It is slightly long and could be split into two sentences, but no filler or repetition exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter tool with no output schema, the description covers purpose, algorithm, and the follow-up action well. However, since no output schema exists, the vague 'returns top candidates with evidence' leaves the response shape under-specified, and the dry_run parameter's behavior is not integrated into the description. An agent could invoke it correctly but would not know what 'evidence' looks like in the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (size, dry_run, max_results, playlist_id, exclude_saved, response_format) already carries a description. The tool description adds marginal context by explaining the algorithm that maps to exclude_saved ('and optionally your saved library') and the candidate-count notion, but it does not need to compensate for schema gaps. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Propose tracks'), resource ('one of your playlists'), and a precise algorithm: finds tracks in >=2 other playlists, boosts artist matches, excludes existing tracks. It also explicitly distinguishes itself from recommendation tools with 'using ONLY your own listening data (no recommendations)', which sets it apart from the many playlist and discovery siblings in the toolset.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit workflow: 'Read-only: review the proposals, then call add_to_playlist with the URIs you want.' This names the exact follow-up tool and clarifies that grow_playlist is an analysis/proposal step, not a mutation. It doesn't explicitly enumerate when-not-to-use alternatives, but the '(no recommendations)' qualifier and the read-only workflow assertion provide strong contextual routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
history_searchARead-onlyIdempotent
Search portability, backup and mutation-history stores; hits name their source. Quota: local only (no API).
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Substring to match | |
| scope | No | Scope | all |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, idempotentHint), and the description adds genuinely useful operational context beyond them: the tool is local-only with no API quota consumption, and hits carry their source label. This is meaningful behavioral disclosure an agent cannot get from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short clauses, front-loaded with the action and resources, followed by the two most decision-relevant facts (source labeling, local-only quota). No wasted text, though the telegraphic style leaves some inference to the agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description at least tells the agent that results are annotated with their source, and notes the local-only execution model. For a parameterized search with full schema coverage this is close to sufficient; only the multi-store result shape remains underspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including the scope enum and response_format semantics, so the schema carries the parameter burden. The description adds nothing about query matching behavior (e.g., case sensitivity) beyond the schema's 'Substring to match'. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Search) and enumerates the three distinct stores it covers (portability, backup, mutation-history), which separates it from library search siblings like search_saved_tracks or search_deep. It stops short of naming a specific sibling alternative, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'local only (no API)' note implies when this is preferable (cheap, offline, no quota cost), but there is no explicit when-to-use versus search_history_stats, list_backups, or undo_mutation guidance, and no exclusions. Usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_from_sidecarA
Additive restore from a library.json sidecar written by export_library_json: re-adds every missing saved item across all five collections (tracks, albums, shows, episodes, audiobooks) through the unified PUT /me/library endpoint, skipping items the library already holds. Rows whose uri is not a canonical spotify::<22-char id> URI are counted as invalid and never sent. Collections the file does not carry are named in absent_keys. The exporter's own truncated / cap_reached flags are surfaced as sidecar_truncated + truncated_collections: a capped sidecar restores only the rows it holds and says so, and a file with no flag reports completeness as UNKNOWN rather than complete. The prompt and the result both state the sidecar path, the date the file itself declares (exported_at, or the named reason it declares none โ never the mtime), the row count, the one use being made of it, and whether a human confirmed that use (see consent_note). dry_run=true by default. Quota: local read + contains-check + chunked writes when dry_run=false.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only, making no API calls at all. Writes happen only when explicitly set to false. | |
| input_path | No | Path to sidecar JSON (default: <portability>/library.json) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry destructiveHint=false, so the description carries the real burden and does so thoroughly: additive semantics, skip-existing behavior, invalid-URI rows never sent, absent_keys reporting, sidecar_truncated/truncated_collections surfacing, UNKNOWN vs complete reporting, the declared-date rule, consent_note, and the quota (local read + contains-check + chunked writes only when dry_run=false). This is far beyond what the annotation provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The opening sentence is strongly front-loaded and every subsequent sentence carries behavioral information. It is dense and clause-heavy (unsaved/absent_keys/truncation/consent bundled into few long sentences), which costs a little readability, but there is essentially no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, no-output-schema restore tool, the description covers trigger, safety, default mode, the shape of the reported result (absent_keys, sidecar_truncated, truncated_collections, exported_at, consent_note) and its cost profile. An agent has everything needed to call it correctly and interpret the outcome.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented, and the description largely repeats the dry_run default rather than adding new meaning. It does add the default sidecar path and the 'no API calls at all' nuance, but the schema does the heavy lifting, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (additive restore from a library.json sidecar) and names its counterpart, export_library_json, which wrote the file. The five collections and the underlying PUT /me/library endpoint are named, so the agent can distinguish it from restore_library_snapshot and backup_first without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly establishes the usage context: it is additive (skips items already held), it reads only sidecars written by export_library_json, and dry_run is the default preview mode. It does not explicitly contrast against siblings like restore_library_snapshot or import_profile_state, so it stops short of full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_playlistA
Parse an M3U or CSV document (the inverse of export_playlist) and append its Spotify URIs to a target playlist. Pass the document inline via content, or read it from input_path (a regular file inside the configured read roots). URIs already in the playlist are skipped, so a re-run adds nothing. Adds in batches of 100. Use dry_run=true to preview without writing. Result records the document source and the use made of it (consent_note); under 100 new URIs nothing is gated.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Document format; auto-detected when omitted | |
| content | No | The M3U or CSV document body, passed inline | |
| dry_run | No | Parse and report what would be added without touching the playlist | |
| input_path | No | Read the document from this local file instead of content | |
| playlist_id | Yes | Target playlist ID, spotify:playlist: URI, or share URL | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the lone destructiveHint=false annotation: discloses idempotent dedup (existing URIs skipped, re-run adds nothing), 100-URI batching, dry_run semantics, and consent_note gating behavior under 100 new URIs. This is exactly the write-safety context an agent needs for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core action, then packs input modes, idempotency, batching, preview, and gating into tight sentences with no filler. Every clause carries operational value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, and the description proactively notes the result records the document source and consent_note, plus the gating threshold. Complete for a mutation tool; only failure/error behavior for malformed documents is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds real meaning: input_path must be a regular file inside the configured read roots, and content is the inline alternative. It also frames dry_run as preview-only, beyond the schema's terse wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('parse... and append') plus resource (M3U/CSV document into a target playlist) and explicitly positions itself as the inverse of export_playlist, so an agent can distinguish it from sibling importers and exporters.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the two input modes (inline content vs input_path from read roots) and when to use dry_run=true to preview, plus the sibling relationship to export_playlist. No explicit 'when-not' or alternative-tool routing, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_profile_stateA
Restore local sidecar stores from a profile-state archive. merge unions each store on its own keys and de-duplicates search_history by entry id; overwrite replaces each store, keeping a 0600 .bak of what it replaced. The mutation ledger (stores.mutations_history) is export-only: it is never appended to or replaced, and an archive carrying it is reported as skipped. dry_run reports the per-store plan and writes nothing. Refuses newer schema versions.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | merge = union on each store's own keys; overwrite = replace, keeping a .bak | merge |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| input_path | Yes | Path to the profile-state archive JSON file | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint=false available, the description carries real load: merge de-duplicates search_history by entry id, overwrite keeps a 0600 .bak of replaced stores, the mutation ledger is export-only and reported as skipped, dry_run writes nothing, and newer schema versions are refused. This is exactly the mutation/recovery context an agent cannot get from annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what the tool does, then mode semantics, then edge cases (ledger, dry_run, schema version). Every clause is operational information; there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an unannotated-in-practice mutation tool with no output schema, the description covers modes, side effects, backups, exclusions, and preview behavior well. Minor gaps remain: no statement of required permissions or what happens on partial/validation failure, and no hint at the dry_run plan's shape beyond 'per-store plan'.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so 3 is the baseline; the description goes beyond the schema by spelling out the de-duplication key (entry id) that merge uses and reinforcing the dry_run/ledger rules. input_path and response_format are left to the schema, which is acceptable given how well the two enums are documented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource+scope: 'Restore local sidecar stores from a profile-state archive', which an agent can act on immediately. It does not, however, differentiate itself from the closely named sibling import_from_sidecar or from restore_library_snapshot, leaving a selection ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the merge/overwrite semantics and dry_run behavior tell the agent how to call it, but there is no explicit when-to-use guidance relative to import_from_sidecar or restore_library_snapshot, and no stated prerequisites beyond the schema-version refusal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_toolARead-onlyIdempotent
Show one tool's full description and input schema before calling it
| Name | Required | Description | Default |
|---|---|---|---|
| tool_name | Yes | Exact registered tool name | |
| response_format | No | 'concise' (default) = prose bullet list; 'detailed' = the same prose; 'json' = the result payload as parseable JSON text, identical to structuredContent | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds only the timing guideline 'before calling it' and does not disclose further behavioral traits like response format or side effects, making a 3 appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with zero waste, stating the action and the key usage context immediately. It is appropriately sized for a simple inspection tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is low-complexity, has a rich schema with full parameter documentation, annotations covering safety, and an output schema, so return values need not be explained. The description is complete for an agent to understand and call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (tool_name and response_format) are fully documented in the schema. The description adds no additional meaning beyond what the schema provides, which is the expected baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Show') and resource ('one tool's full description and input schema'), clearly defining the tool's output. It does not explicitly differentiate from siblings like find_tool, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'before calling it' gives clear context for when to use this toolโprior to invoking another tool. No exclusions or alternative tools (e.g., find_tool) are mentioned, which keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
library_genre_reportARead-onlyIdempotent
Aggregate your saved library by user-declared genre tags. Scans all saved tracks and albums, joins each item's artists against your tag sidecar (see tag_management), and reports per-genre track/album counts plus the contributing artists. Genres are unavailable from Spotify itself, so only artists you have tagged appear here.
| Name | Required | Description | Default |
|---|---|---|---|
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds real behavioral context: it scans the entire saved library (not a filtered subset), performs an artist-level join against the tag sidecar, and returns counts plus contributing artists, with an explicit coverage limitation. It stops short of describing pagination or how max_results truncation affects the aggregates.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, all front-loaded with the operation first, then mechanism, then the important data-availability caveat. Every sentence earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does the work of explaining the return shape (per-genre track/album counts plus contributing artists) and the crucial limitation that untagged artists are excluded. It is nearly complete; only the effect of result truncation on the aggregates is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so max_results and response_format are already fully documented in the schema, including the enum values and default. The description adds nothing about either parameter, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Aggregate your saved library by user-declared genre tags') and explains the mechanism: scanning saved tracks/albums and joining artists against the tag sidecar. This clearly distinguishes it from siblings like filter_by_genre, tag_management, and library_hygiene without needing to open any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives strong contextual guidance: it points to tag_management for the sidecar and warns that only tagged artists appear because Spotify exposes no genre data. That tells the agent when output will be useful, but it never explicitly states when to prefer this over alternatives such as filter_by_genre or a plain saved-tracks listing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
library_hygieneA
Read-only album hygiene over your liked tracks: flags near-complete albums worth saving and lone singles with nothing else liked from their artist (low confidence). Album totals come from the /me/tracks walk; a width-bounded per-id GET /albums/{id} fills in the rest. Never mutates. dry_run previews cost.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview cost only. | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint=false provided, the description carries real extra weight: it declares read-only, 'never mutates', discloses the confidence caveat ('low confidence'), and explains that dry_run previews cost. That is meaningful behavioral context beyond the annotation. It stops at 4 because the return shape and the exact cost/preview semantics are left implicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the tool's purpose before implementation detail, and dry_run/read-only facts are packed tightly into short sentences. The implementation sentence about /me/tracks and /albums/{id} is arguably surplus for tool selection but does earn its place as transparency. Overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only, zero-required-param tool with no output schema and fully documented params, the description covers purpose, mutation profile, confidence caveat and cost preview. Nothing critical is missing, though it never describes what a result row looks like or the ordering/limit interaction.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents dry_run, max_results and response_format with defaults and bounds. The description only reinforces that dry_run previews cost, adding little beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Read-only album hygiene over your liked tracks') and enumerates the two findings it surfaces (near-complete albums, lone singles). An agent can distinguish it from siblings like unsave_orphan_tracks or find_duplicate_saved_tracks by the album-completeness angle. It does not name a sibling explicitly, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'what' is clear, so when-to-use is implied for a library-audit workflow, but there is no explicit when/when-not or reference to an alternative tool. Nothing tells the agent how this differs operationally from related hygiene tools such as unsave_orphan_tracks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
library_snapshot_diffA
Diff two sidecar JSON files (library.json or playlists.json): added/removed counts + samples. Quota: local only (no API).
| Name | Required | Description | Default |
|---|---|---|---|
| after_path | Yes | Path to after snapshot JSON | |
| before_path | Yes | Path to before snapshot JSON | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=false. The description adds two genuine behavioral traits beyond that: the operation is purely local with no API/quota cost, and the output shape is added/removed counts plus samples. It does not discuss permissions or failure modes, but for a read-only diff utility this is meaningful extra context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences with zero waste; the core purpose leads, followed by the quota caveat and output summary. Nothing is repeated from the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by summarizing the return (added/removed counts + samples). Combined with full schema coverage and the local-only note, an agent has almost everything needed; only the differentiation from sibling diff tools is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% โ all three parameters, including the concise/detailed/json enum for response_format, are documented in the schema itself. The description adds nothing about parameter format or semantics beyond naming the file types, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (diff) and specific resources (two sidecar JSON files: library.json or playlists.json) and summarizes the payload (added/removed counts + samples). It implicitly separates itself from sibling diff_playlists by scoping to local snapshot files, though it never names that sibling to make the distinction explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Quota: local only (no API)' implies when this tool is preferable (offline snapshot comparison vs live API calls), but there is no explicit when/when-not statement or named alternative such as diff_playlists or backup_first. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsARead-onlyIdempotent
List every local account this server can act as, and which one it is acting as now. Returns each account's account_id, profile name, display name and token file PATH โ never any token material. Reads the local registry and one GET /me for the acting account; no mutation requests are issued.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only and idempotent, but the description adds concrete behavior: it reads the local registry plus one GET /me for the acting account, returns account_id/profile name/display name/token file PATH, and explicitly never returns token material. This exceeds the annotation coverage and provides useful operational context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core list action, followed by return details and safety behavior. Every sentence adds useful information without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fills the gap by naming returned fields and clarifying that no token material is included. Annotations cover safety, and the description supplies the behavioral and return context an agent needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter response_format has 100% schema description coverage with an enum and default, and the description does not discuss it at all. Baseline 3 applies because the schema fully documents the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb 'List' and resource 'local accounts this server can act as', and adds the active-account distinction. This clearly separates it from sibling tools like get_user_profile and switch_account.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for discovering available local accounts and the currently active one, but does not explicitly state when to prefer it over switch_account or get_user_profile. No when-not or alternative routing is given, leaving usage to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_backupsBRead-onlyIdempotent
List complete and partial library backups (newest first) using bounded metadata sidecar reads, with a bounded prefix fallback for legacy snapshots. Expires snapshots past SPOTIFY_MCP_BACKUP_RETENTION_DAYS (default 30, 0 disables) and reports what it removed, plus the store envelope (dir_bytes, oldest_created, oldest_retention_until).
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states 'Expires snapshots past SPOTIFY_MCP_BACKUP_RETENTION_DAYS' and 'reports what it removed', which is a mutating action. The annotations declare readOnlyHint=true, which claims the tool does not modify state. This is a direct contradiction. Per the rubric, score is 1 because the description contradicts annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient, with the core listing behavior front-loaded. It includes necessary operational details (sidecar reads, retention policy, output fields) without being verbose. Could be slightly tighter, but overall well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's main actions (list, expire, report removal) and specifies the output envelope fields. It does not describe the response_format effect beyond the schema, but that field is fully documented. The only weakness is the annotation contradiction, which creates ambiguity about safety, but the description itself is fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter (response_format). The description does not need to add parameter details, so the baseline of 3 applies. The schema already explains concise/detailed/json.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'List complete and partial library backups (newest first)'. It also lists secondary behavior (expiring old snapshots) which distinguishes it from similar tools like backup_library or delete_backup. It is unambiguous what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for inspecting backups and cleaning expired ones, but it does not explicitly contrast with alternatives like delete_backup (which also deletes) or backup_library (which creates backups). When to choose this over a plain delete tool is left to inference, so guidance is only moderate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_scenesBRead-onlyIdempotent
List saved playback scenes from the local sidecar
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, covering the safety profile. The description adds the data source 'local sidecar' which is useful context, but it does not describe the return format, pagination, or any side effects. Given the annotations, the bar is lower, and the added context is minimal but not contradictory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that front-loads the verb and resource. There is zero wasted wording, and it efficiently communicates the core function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one optional parameter and no output schema, the description is mostly sufficient. It tells the agent what it does and where data comes from. However, it doesn't mention that it only lists scenes from the local sidecar as opposed to elsewhere, but that is already implicit. The lack of return format details is acceptable given no output schema, and the annotations cover safety.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers the single parameter response_format with 100% description coverage, so the schema already documents it. The tool description does not mention the parameter at all, so it adds no additional meaning. Since schema coverage is high, the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: 'List saved playback scenes from the local sidecar'. It is specific about what it does and where the data comes from. However, it does not differentiate from siblings like apply_scene or delete_scene, so the agent must infer that this is purely a listing operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. For example, the description doesn't mention that apply_scene is for applying a scene, or that scene_sampler_search might be used for searching. The agent is left to infer the tool's place in the workflow without explicit when-to-use or when-not-to-use instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
merge_playlistsA
Merge multiple playlists into one. Deduplicates tracks across sources (first-seen order wins) and adds them in batches of 100. Pass target_playlist_id to append to an existing playlist (it is NOT cleared) or new_name to create a fresh playlist.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| public | No | Visibility of a NEW playlist. Default: false | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| new_name | No | Name for a newly created target playlist | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| playlists | No | Canonical ordered playlists (1โ10) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| target_playlist_id | No | Existing playlist to APPEND into (never cleared) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false; the description carries the real behavioral burden and does so well. It discloses the dedup rule (first-seen order wins), batching (100 per request), and crucially that an existing target playlist is appended to and NOT cleared โ exactly the safety-relevant fact an agent needs before a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with zero filler. The core action is front-loaded, followed by dedup/ordering behavior and then the two target modes โ a logical, scannable order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with only a minimal annotation and no output schema, the description covers the essential operation, dedup semantics, and append-vs-create safety behavior well enough to invoke it correctly. Minor gaps remain around failure modes (e.g., duplicate IDs, exceeding source caps) and what the operation returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all nine parameters, establishing a baseline of 3. The description reinforces the target_playlist_id/new_name distinction but adds no semantics beyond what the schema fields already state (append, never cleared).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (merge multiple playlists into one) plus its distinctive semantics: cross-source deduplication with first-seen ordering and batched adds. It does not name or contrast with near-neighbours like playlist_union or copy_playlist, so an agent can't fully disambiguate from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly explains the two operating modes (append via target_playlist_id vs create via new_name) and that the target is not cleared, which is useful conditional guidance. But it never says when to prefer this tool over alternatives such as playlist_union, batch_add_to_playlist, or copy_playlist, and gives no exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
move_items_between_playlistsA
Bulk rehome items between playlists. Mode copy keeps the source intact; mode move removes from source after copying โ by playlist position, removing exactly the transferred occurrences and leaving any other copy in the source. Supports dedupe against target and optional name/artist filter. Either side may be named by lane.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | copy = leave source intact; move = remove from source after copy | copy |
| limit | No | Source page size, 1โ100. Default: 100 | |
| dedupe | No | Skip tracks already in target. Default: true | |
| filter | No | Optional substring filter: only transfer tracks whose name or artist name contains this string (case-insensitive) | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| source_lane | No | Lane name resolving to the source playlist; provide exactly one of source_playlist_id or source_lane | |
| target_lane | No | Lane name resolving to the target playlist; provide exactly one of target_playlist_id or target_lane | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| source_playlist_id | No | Source playlist ID, spotify:playlist: URI, or URL; provide exactly one of source_playlist_id or source_lane | |
| target_playlist_id | No | Target playlist ID, spotify:playlist: URI, or URL; provide exactly one of target_playlist_id or target_lane |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
This description adds substantial behavioral detail beyond the single destructiveHint annotation: move removes by playlist position, removing exactly the transferred occurrences while leaving other copies in the source, dedupe against the target, and an optional filter. There is mild tension with destructiveHint=false given that move deletes items from the source, but since the copy lands in the target first and the removal semantics are fully disclosed (not hidden), the agent is not misled. It does not cover pagination/scan behavior or error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences, front-loaded with the core operation and its mode distinction, then the removal nuance, then supporting options. No filler or repeated name/title text; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter mutating tool with no output schema and only a destructiveHint annotation, the description covers the critical semantics: what copy vs move does, how removal is scoped, dedupe and filtering. What is missing is minor for correct invocation: the response_format/dry_run usage implications, paging via limit/scan_cap, and any failure conditions, though the schema documents those parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 12 parameters are already documented in the schema (mode enum, dedupe default, filter substring semantics, lane-vs-id exclusivity). The description restates the mode and dedupe/filter ideas and adds the only novel note, that 'either side may be named by a lane,' but contributes little beyond the schema. Baseline 3 for full coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line states a specific verb and resource ('Bulk rehome items between playlists') and immediately disambiguates the two modes (copy keeps source intact, move removes after copying). It does not name or contrast itself with near-siblings like merge_playlists, copy_playlist, or playlist_union, so an agent must infer the boundary. Clear purpose, but not sibling-differentiating.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives real decision-relevant context: copy vs move semantics, dedupe-against-target, name/artist filtering, and lane-based naming of either side. However it never states when to prefer this tool over copy_playlist, merge_playlists, or batch_add_to_playlist, nor any exclusions or prerequisites. Usage is implied by capability rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
overlap_playlistsB
Find tracks shared across playlists: reports how many playlists each track appears in and lists tracks present in at least min_overlap playlists (default: all of them), most-shared first.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| playlists | No | Canonical ordered playlists (2โ10) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| min_overlap | No | Minimum number of playlists a track must appear in. Default: all playlists | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is destructiveHint=false, so the description must carry the rest. It usefully discloses the default threshold semantics and result ordering, which annotations do not cover, but says nothing about the read-only nature, the scan_cap/SPOTIFY_MCP_FETCH_ALL_CAP bounding behavior, truncation, or how dry_run interacts โ despite dry_run being a declared parameter.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence that front-loads the core operation (shared tracks), then the report contents, the threshold default, and the sort order โ no filler and nothing buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter read tool with no output schema, the description adequately conveys the operation and the shape of the result (counts plus qualifying tracks, ordered). It falls short only on dry-run semantics and the scan-cap/truncation limits that an agent would want before invoking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all seven parameters (limit, scan_cap, playlists, max_results, min_overlap, response_format, dry_run). The description adds only the min_overlap default and the ordering, which is baseline value when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource โ finding tracks shared across playlists โ and even describes the output (per-track playlist counts, tracks meeting the min_overlap threshold, sorted most-shared first). It is clear without opening the schema, though it does not name or contrast with near-neighbors like find_duplicate_tracks_across_playlists, playlist_union, or diff_playlists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what happens by default (min_overlap defaults to all playlists) but never says when to choose this over intersecting/unioning siblings or what prerequisites apply. No when-not guidance or alternative routing is present, leaving selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pauseB
Pause playback on the active device
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only declare destructiveHint=false. The description adds useful scope by specifying that playback is paused on the active device, which goes slightly beyond the annotation. It does not mention authorization needs, effect on other devices, dry_run behavior, or anything about playback state changes beyond the pause itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. It is appropriately sized for a simple playback control.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple pause tool with full schema coverage and no output schema, the description covers the core action. However, it omits how device_id overrides the 'active device' framing and does not mention dry_run or response_format behavior, leaving some ambiguity despite the schema documenting those parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents dry_run, device_id, and response_format. The description does not add any parameter meaning beyond what the schema provides. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: 'Pause playback.' It is clear enough to distinguish from play, skip_next, and skip_previous. However, it does not explicitly name or differentiate itself from those sibling playback controls, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives such as 'play' or 'transfer_playback,' nor any preconditions or exclusions. The intended action is implied, but no explicit usage context is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pin_playlistA
DEPRECATED, use follow_playlist. This tool never pinned anything; it has always saved the playlist to your Spotify library via PUT /me/library.
| Name | Required | Description | Default |
|---|---|---|---|
| public | No | Must be true or omitted; the library endpoint has no visibility parameter. | |
| dry_run | No | Preview only (default): pass dry_run: false to execute the follow. | |
| playlist_id | Yes | Playlist ID to follow | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| dry_run | No | |
| receipt | No | |
| cancelled | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover destructiveHint=false, and the description adds real behavioral context: the tool never actually pins, the underlying endpoint is PUT /me/library, and it is deprecated. It does not discuss auth/scopes or idempotency, but for a deprecated alias the disclosure is strong.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, deprecation and the correct behavior front-loaded, zero filler. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and all four parameters are fully described in the schema. The description completes the picture by explaining the misleading name and the correct alternative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and each parameter (public, dry_run, playlist_id, response_format) is documented in the schema itself. The description adds no parameter-level detail, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb+resource ('saves the playlist to your Spotify library via PUT /me/library') and explicitly corrects the misleading name, so an agent knows exactly what it does. It also names the intended replacement (follow_playlist), distinguishing it from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-not-to-use guidance ('DEPRECATED, use follow_playlist') and names the alternative tool by name. Nothing about selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_podcast_sessionARead-onlyIdempotent
Greedy-pack your saved podcast episodes into a listening session of a given length. Episodes play their remaining time (duration minus resume position); fully played ones are skipped. Scanning stops at the first unplayed episode that doesn't fit.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Restrict the source: 'episodes' = your saved episodes only, 'shows' = recent episodes of your saved shows only. Omit to use saved episodes (plus saved shows when saved_only is false) | |
| market | No | ISO 3166-1 alpha-2 country code for the saved-show episode lookups, e.g. "US". Defaults to SPOTIFY_MCP_MARKET, then to the account country โ these lookups are market-gated, so a wrong default silently drops episode rows. Ignored for a saved-episodes-only plan. | |
| minutes | Yes | Session length in minutes (1โ480) | |
| saved_only | No | When no kind is set, include recent episodes of saved shows too. Default: true (saved episodes only) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds genuine behavioral detail beyond that: episodes use remaining time (duration minus resume position), fully played episodes are skipped, and scanning aborts at the first non-fitting unplayed episode. Return format is not described, but the algorithm disclosure is substantive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with zero waste, front-loaded with the core action and followed by the algorithm rules that determine the output. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only planning tool with full schema coverage and no output schema, the description is essentially complete. The one meaningful gap is that it does not state it performs no playback, which matters given the start_podcast_session sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all six parameters (kind, market, minutes, saved_only, max_results, response_format) are already fully documented in the schema. The description's mention of resume position is algorithm context, not parameter semantics, so it adds little. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Greedy-pack your saved podcast episodes into a listening session of a given length.' The packing algorithm is clearly described. However, it never names its adjacent sibling start_podcast_session, so an agent must infer that this plans rather than plays.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the word 'plan' and 'greedy-pack' signal a non-playing computation, but there is no explicit when-to-use statement, no exclusion, and no routing to start_podcast_session, which is the most likely confusion point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playC
Start or resume playback. Optionally target specific content.
| Name | Required | Description | Default |
|---|---|---|---|
| uris | No | Up to 100 track/episode URIs to play as an ad-hoc queue | |
| offset | No | Index within an album/playlist context to start from. Ignored for ad-hoc uris; not valid for artist contexts (use offset_uri instead). | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID; uses active device if omitted | |
| offset_uri | No | Track URI inside the context to start from โ required for artist contexts, where a numeric index is rejected | |
| context_uri | No | Spotify URI for an album, artist, or playlist | |
| position_ms | No | Seek position to start at (ms) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false. The description adds no detail about authentication needs, how existing playback or queue is affected, device state requirements, or error conditions, so it contributes little beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded and free of wasted words. The second sentence is generic but not redundant, so the structure is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter playback control tool surrounded by many siblings, the description is extremely thin. It omits when to use it, device handling, playback behavior, and interaction with other controls; the schema covers parameters but the description does not supply necessary context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all eight parameters are fully documented in the schema. The description only vaguely refers to 'specific content' and adds no syntax or format details beyond what the schema already provides, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('start or resume') and resource ('playback'), so the basic action is clear. However, it does not differentiate from siblings like play_from_search or transfer_playback, leaving sibling selection to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only guidance is 'Optionally target specific content,' which is vague. There is no indication of when to use this tool versus play_from_search, pause, skip_next, or other playback controls, and no conditions or exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
play_from_searchA
Search Spotify by name and immediately play the best match. Works for songs and podcast episodes โ no URI needed.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search text, e.g. a song title or podcast episode name | |
| market | No | ISO 3166-1 alpha-2 country code โ affects availability/relinking of results; defaults to SPOTIFY_MCP_MARKET | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID; uses active device if omitted | |
| search_type | No | What to search for: 'track' (song) or 'episode' (podcast episode) | track |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false. The description usefully discloses that playback happens immediately and that both tracks and episodes are supported, but it ignores the dry_run preview path, device targeting, and market relinking behavior that the schema exposes. With annotations covering only one weak hint, a 3 is fair โ helpful but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with zero filler; the core action leads and the differentiating constraint ('no URI needed') is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter tool with real playback side effects and no output schema, the description omits the dry-run preview option and device/market scoping, leaving the agent to discover mutation-safety behavior only from the schema. Adequate but with clear gaps given the complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so every parameter including market, dry_run, device_id, search_type, and response_format is already documented in the schema. The description adds only the 'songs and podcast episodes' framing, which loosely maps to search_type. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific compound action (search by name, then immediately play the best match) and scopes it to songs and podcast episodes. The 'no URI needed' clause implicitly separates it from the sibling `play` tool, but it never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for use: when you have a name rather than a URI, this both resolves and plays. It does not state when NOT to use it (e.g., when a URI is already known, use `play`), so it stops short of the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_collab_toggleB
Toggle collaborative/public flags (guards public=true && collaborative=true 400). Quota: GET + PUT.
| Name | Required | Description | Default |
|---|---|---|---|
| public | No | Target visibility: true makes the playlist public | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID, spotify:playlist: URI, or URL | |
| collaborative | No | Target collaborative state for the playlist |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false. The description adds valuable behavior: the public=true && collaborative=true 400 guard and the GET + PUT quota cost. It omits auth/permission requirements, but this is well beyond annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two terse fragments, front-loaded with the main action; no filler. The parenthetical guard and quota line are slightly cryptic but efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a flag-toggle mutation with full schema coverage and minimal annotations, the description supplies the key validation guard and quota. It lacks any routing guidance versus update_playlist, leaving a gap for tool selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema documents all four parameters including dry_run. The description mentions the flags but adds no syntax or format beyond the schema. Baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Toggle') and resource ('collaborative/public flags'), making the action clear. It does not explicitly name or distinguish sibling tools like update_playlist, so a 4 rather than 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no alternatives, and no exclusions are provided. The guard describes a validation rule, not usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_reverseA
Reverse a playlist in one atomic replace. Quota: GET all + PUT/POST.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID, spotify:playlist: URI, or URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description adds real value by disclosing that the reversal happens via a single atomic replace and that the cost is GET all + PUT/POST. It is consistent with the non-destructive annotation (reordering, not deleting) and adds quota/atomicity context the annotation does not carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two very short sentences, front-loaded with the core action followed by the cost/quota note. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple mutation with a 100%-covered two-param schema and no output schema, the description covers action, atomicity, and cost. It omits permission requirements and return behavior, but these are marginal for a tool this simple.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% โ both playlist_id and dry_run are fully documented in the schema, including the preview semantics of dry_run. The description adds no parameter detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ("Reverse a playlist") plus the mechanism ("in one atomic replace"). It clearly distinguishes a reversal from siblings like playlist_sort or playlist_shuffle, though it never names them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use, when-not, or alternative is stated. The description only implies usage from the verb itself and gives a quota cost note, which is not usage guidance. An agent must infer that playlist_sort or playlist_shuffle are not substitutes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_shuffleB
Fisher-Yates shuffle a playlist (seeded optional). Quota: GET all + PUT/POST.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | Deterministic shuffle seed; omit for a random order | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID, spotify:playlist: URI, or URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The 'Quota: GET all + PUT/POST' note adds real operational context beyond the single destructiveHint=false annotation, implying the tool performs writes and costs a read-plus-write quota. However, it says nothing about reversibility, ownership/auth requirements, or what happens to existing ordering, which matters for a mutating operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, algorithm stated first, quota constraint second; nothing is padded or redundant. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with only a destructiveHint annotation and no output schema, the description covers the algorithm and quota cost but omits whether the change is reversible, what the tool returns, and any auth/ownership prerequisites. Adequate but with visible gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so playlist_id, seed, and dry_run are already documented in the schema; the description only echoes the optional seed behavior and never mentions dry_run. Baseline 3 is appropriate when the schema carries the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a concrete verb ('shuffle') plus resource ('playlist') and even specifies the algorithm (Fisher-Yates), which separates it from generic siblings like playlist_sort and playlist_reverse. It stops short of explicitly contrasting itself with those siblings, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no indication of when to choose this over playlist_sort, playlist_reverse, or reorder_playlist_items, nor when to prefer the dry_run preview. The parenthetical '(seeded optional)' hints at a determinism use case but never states it as guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_sortA
Sort a playlist in place by added_at/name/artist/duration. Quota: GET all + PUT/POST. popularity is not a sort key: the API no longer returns it on playlist items.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| sort_by | No | Sort key applied to the playlist | name_asc |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | Yes | Playlist ID, spotify:playlist: URI, or URL | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description usefully adds that sorting happens in place (persistent mutation of the playlist), that it costs GET all + PUT/POST requests, and that 'popularity' is not a valid key because the API no longer returns it โ a real guard against a plausible wrong invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the operation and keys come first, followed by cost and the popularity caveat. Every clause carries information an agent can act on, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the critical behavioral facts for a mutating playlist tool (in-place edit, quota cost, invalid key) are present. Minor gaps remain: it never mentions the dry_run preview path or that sorting can invalidate existing snapshots.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters (including dry_run and response_format) are already documented. The description only reinforces the sort key families and rules out popularity, which adds marginal value over the enum and defaults in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('sort') and resource ('playlist') plus the in-place scope and the available key families (added_at/name/artist/duration). It does not differentiate itself from close siblings such as playlist_reverse, playlist_shuffle or reorder_playlist_items, so it lands at a clear-but-not-discriminating 4.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the key list; there is no statement of when to prefer this over playlist_reverse/playlist_shuffle/reorder_playlist_items, nor whether it requires an unfollowed/owned playlist or snapshot handling. The quota note hints at cost but is not a when-to-use rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_subtractB
Remove tracks of B..N from A by REWRITING A: one PUT replaces every row with the ones that survive, so any row of A absent from the union is DELETED, and the rows that remain are re-written in order. Subtracting every track empties A via one PUT with an empty uris array (Spotify's documented clear); a reply with no snapshot_id reports unconfirmed, not ok. Quota: N GETs + PUT.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| playlists | No | Canonical ordered playlists (1โ10) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| base_playlist_id | Yes | Base playlist ID, URI, or URL. Required; list only the subtraction sources in playlists. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states in caps that rows of A absent from the union are DELETED and that subtracting everything empties A via a documented clear, which is destructive mutation behavior. The annotation declares destructiveHint=false, i.e. additive-only, which directly contradicts the described deletion semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core operation is front-loaded in the first clause and each sentence carries real information (rewrite semantics, empty-clear edge case, snapshot_id meaning, quota). It is dense and somewhat run-on, especially the second sentence, but there is little filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutation tool with no output schema, the description supplies the missing behavioral context: destructive rewrite semantics, empty-subtraction edge case, snapshot_id/confirmation semantics, and a quota estimate. Coverage is strong, though the contradiction with the annotation undercuts trust in the safety picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (limit, scan_cap, dry_run, playlists, max_results, response_format, base_playlist_id) is already documented in the schema. The description adds only the semantics of the empty-uris clear case and does not enrich any individual parameter beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a precise verb+resource+scope: remove tracks belonging to playlists B..N from playlist A, and it spells out the rewrite mechanism that distinguishes this set-subtraction from a plain row-by-row removal. It stops short of naming sibling alternatives (e.g., playlist_union, remove_from_playlist), so it is clear rather than sibling-routing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the operation described (a set-difference edit) and the quota note hints at cost trade-offs, but there is no explicit when-to-use / when-not-to-use guidance and no alternative tool is named. The schema's dry_run field carries most of the 'preview before committing' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_symmetric_differenceB
Tracks in exactly one of two playlists (XOR). Quota: 2 GETs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| scan_cap | No | Maximum rows to read from each playlist; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| playlist_a | No | Canonical A playlist; provide with playlist_b | |
| playlist_b | No | Canonical B playlist; provide with playlist_a | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation destructiveHint=false already signals a non-destructive read operation. The description adds a useful behavioral detail beyond the annotation: 'Quota: 2 GETs', which tells the agent about cost before invocation. It does not cover auth requirements, pagination behavior, or output structure, so it is adequate but still thin for a playlist-comparison operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise and front-loaded: the operation is stated first, then the quota cost. Both sentences carry information that an agent can use, and there is no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description states the core operation and a quota cost, which is enough to invoke the tool against a fully documented schema. However, with no output schema and no return-format guidance, it leaves gaps around what the returned result looks like, ordering, pagination behavior, and how the two playlist inputs are expected to pair. It is minimally complete rather than fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with all six parameters documented in the input schema, including defaults, bounds, and response_format enum values. The description adds no parameter-level syntax or semantics beyond what the schema already provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific operation as 'Tracks in exactly one of two playlists (XOR)', which is a clear symmetric-difference result set over playlist track resources. The XOR qualifier distinguishes it from intersection-style siblings like overlap_playlists and union-style siblings like playlist_union. It stops short of naming an explicit action verb or routing alternatives, but the purpose is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use guidance, no exclusions, and no explicit alternatives. An agent must infer that this tool is appropriate only for symmetric-difference comparisons from the operation itself. There is no mention of related siblings such as playlist_subtract, playlist_union, or overlap_playlists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_template_applyB
Create an instant mood/vibe playlist from a template (focus, wind-down, gym, commute) composed from your existing listening data. Creates a new playlist and fills it.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Playlist name (default: "<Template> Mix") | |
| limit | No | How many tracks (1-100, default 30) | |
| public | No | Whether the playlist is public | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| template | Yes | Template name | |
| description | No | Playlist description override | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations are minimal (only destructiveHint: false), so the description carries much of the behavioral burden. It does state the primary side effect explicitly ('Creates a new playlist and fills it') and adds that it uses 'your existing listening data', which is useful context. However, it does not disclose behavior around name conflicts, permission requirements, or whether the dry_run parameter actually prevents side effects, leaving the agent to infer these from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero filler. It front-loads the core purpose and template types, then clarifies the side effect. Every word contributes to understanding what the tool does, achieving high information density without unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, no output schema, many sibling playlist tools), the description is too thin. It does not explain how this differs from similar playlist generators, what a successful response looks like, or how the dry_run mode behaves. The agent would need to inspect schemas and infer relationships to use it correctly, which is a significant gap for a mutation-oriented tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all 7 parameters. The description adds only marginal value by listing template options (which are already in the enum) and mentioning the data source. It provides no extra semantics for name, limit, public, dry_run, response_format, or description beyond their schema definitions, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('create'), resource ('playlist'), and the template mechanism with concrete template names (focus, wind-down, gym, commute). It distinguishes itself from generic playlist creation by noting it composes from existing listening data. However, it does not explicitly differentiate from similar taste_* playlist-generating tools like taste_to_playlist or taste_era_playlist, so it's not a perfect sibling discriminator.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a use case ('instant mood/vibe playlist') but provides no explicit when-to-use or when-not-to-use guidance. It does not name alternatives or conditions that would make this tool preferable over others (e.g., using create_playlist for manual control or taste_* for more personalized mixes). The dry_run parameter is also not mentioned in the description, missing an opportunity for safer usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_to_libraryA
Save all tracks of a playlist to your Liked Songs (library). Quota: GET playlist items + PUT /me/tracks (chunked 50).
| Name | Required | Description | Default |
|---|---|---|---|
| dedupe | No | Skip tracks already saved (default true) | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Source playlist ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds operational context beyond the annotations: it discloses the underlying endpoints (GET playlist items and PUT /me/tracks) and chunking behavior (chunked 50). This helps the agent understand the write pattern and call volume, though it still omits auth scopes, error handling, and interaction with existing liked songs beyond what the schema's dedupe parameter implies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences with zero waste: the purpose is front-loaded and the quota detail follows. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a bulk library mutation surrounded by many similar siblings, the description covers what it does and the API cost, and the schema fully documents parameters. However, it omits usage guidance and sibling differentiation, which are meaningful gaps for correct tool selection in this toolset.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (playlist_id, dedupe, dry_run, response_format) are already documented in the schema. The description adds no parameter-level meaning beyond 'all tracks,' so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Save') and resource ('all tracks of a playlist to your Liked Songs'), making the action immediately clear. It does not explicitly distinguish itself from close siblings like save_to_library, add_to_playlist, or import_playlist, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives or what prerequisites are needed. It only describes the operation itself, leaving the agent to infer routing from the name and siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_trimB
Trim playlist to N items (keep first/last/random) by OVERWRITING the playlist: every row outside the kept set is DELETED, and the kept rows are re-written in the new order. An overwrite that deletes rows asks for confirmation first. Quota: 2 walks of the playlist items + 2 metadata GETs + PUT/POST.
| Name | Required | Description | Default |
|---|---|---|---|
| keep | Yes | How many items to keep | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| keep_which | No | Which end of the playlist to keep items from. Default first | first |
| playlist_id | Yes | Playlist ID, spotify:playlist: URI, or URL |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly says rows outside the kept set are 'DELETED' and the playlist is overwritten, but the annotation declares destructiveHint=false, which in MCP means additive-only updates. A row-deleting overwrite is not additive, so the description directly contradicts the annotation. The added confirmation and quota context would otherwise be valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action before the confirmation and quota details; each sentence carries distinct information. The all-caps emphasis is stylistically heavy but not padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation with no output schema, the description covers the mutation mechanism, the confirmation gate, and the API quota cost, which is enough for an agent to call it correctly. Its only real deficiency is the conflict with the provided annotation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so keep, keep_which, dry_run, and playlist_id are already documented in the schema. The description restates the keep modes (first/last/random) but adds no syntax or format detail beyond what the schema provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('trim playlist to N items') and names the three retention modes (first/last/random), letting an agent separate it from siblings like playlist_sort, split_playlist, and remove_from_playlist. The mechanism (overwrite + delete outside set) is spelled out up front.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The behavior implies when this tool is relevant (cutting a playlist down to a fixed size), and dry_run's purpose is clarified, but there is no explicit 'use this instead of X' routing against the many neighboring playlist-mutation tools. Usage is inferred rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
playlist_unionB
Union of 2โ10 playlists into target (deduped, first-seen order). An empty union empties the target the same way subtract does. Quota: N GETs + PUT/POST; replacing an existing target also reads its current items and its playlist metadata to measure the destructive impact.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Source page size, 1โ100. Default: 100 | |
| dedupe | No | Drop duplicate URIs across the merged sources. Default true | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| scan_cap | No | Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP | |
| playlists | No | Canonical ordered playlists (2โ10) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| target_name | No | Name for a newly created target playlist; provide exactly one of target_playlist_id or target_name | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| target_playlist_id | No | Existing target playlist (ID, URI, or URL); provide exactly one of target_playlist_id or target_name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states that an empty union 'empties the target' and that replacing an existing target reads its items 'to measure the destructive impact' โ the tool's own words acknowledge data destruction, while the annotation declares destructiveHint=false. This is a direct conflict between the description and the structured safety signal, which is worse than silence for an agent deciding whether to call it unattended.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the core operation, then the empty-union edge case, then cost. Nothing is repetitive, though 'N GETs + PUT/POST' and the trailing clause about reading playlist metadata are terse to the point of being cryptic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter mutation with full schema coverage and no output schema, the description covers the essential operational facts: merge semantics, ordering, the empty-input trap, and request cost. It omits auth/prerequisite and failure behavior, but nothing needed to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (limit, dedupe, dry_run, scan_cap, max_results, response_format, target_*) is already explained in the schema. The description adds ordering/dedupe semantics and a rough quota model but no per-parameter meaning beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause gives a specific verb+resource and precise semantics ('Union of 2โ10 playlists into target (deduped, first-seen order)'), which cleanly separates it from shuffle/trim-ish siblings. It never names the nearest alternatives (merge_playlists, playlist_symmetric_difference, playlist_subtract) outright, so an agent must infer the routing itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the analogy 'the same way subtract does' and the quota note hint at when this set-operation is appropriate, and dry_run is available in the schema. There is no explicit when-to-use statement, no when-not-to-use, and no named alternative such as merge_playlists, so the agent gets context but no routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_duplicate_playlist_itemsADestructive
Remove duplicate items from a playlist: keeps the first occurrence of each track and removes later repeats, under the match_by rule the other duplicate tools use โ uri (default, exact repeats), name_artist (same name and credited artists, catching remasters and relinks under a new URI) or name (same title only). The rule applied is echoed as match_by. Supports dry_run; removals of 10+ items ask for confirmation via elicitation. See the duplicate-matching vocabulary in SPEC section 4.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| match_by | No | Which rule decides that two items are the same: `uri` (exact URI, the default), `name_artist` (case-insensitive name + credited artists, catches relinks/remasters), or `name` (case-insensitive name only). The rule applied is echoed in the result as `match_by`. | |
| playlist_id | Yes | Playlist ID | |
| include_relinked | No | Deprecated alias for `match_by`, kept for one release: true is `name_artist` and false is `uri`. It cannot express the `name` rule, which is why `match_by` replaced it. Sending both, where they mean different rules, is an error rather than a silent choice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint=true in annotations, the description carries most of the burden and does well: it discloses what is kept vs removed, that a match rule determines equality, that dry_run previews, and that removals of 10+ items trigger elicitation confirmation. It stops short of stating irreversibility or undo behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and the match_by rules, which is efficient. The sentences are long and partially duplicate the schema's match_by and include_relinked text, costing a little density.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description notes that the applied rule is echoed as match_by, covering the key return expectation. Combined with the dry_run and confirmation disclosures, it is complete enough for a moderately complex mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents every parameter, including the full match_by enum and the include_relinked deprecation error case. The description restates the match_by rules rather than adding new syntax or constraints, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Remove duplicate items from a playlist') and immediately specifies the semantics: first occurrence kept, later repeats removed. The matching-rule mechanics distinguish it from siblings like find_duplicates_in_playlist and clean_all_playlists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context โ deduplicate a single playlist under a chosen match rule โ and mentions dry_run and the 10+ confirmation gate. It references 'the other duplicate tools use' but never explicitly says when to pick this over find_duplicates_in_playlist or clean_all_playlists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_from_libraryADestructive
Preferred. Accepts the widest URI mix (track, album, episode, show, audiobook, user, playlist) in one request. Remove one or more items from the user's library via Spotify's unified library endpoint. Max 40. PREVIEWS BY DEFAULT โ pass dry_run=false to commit. Removals of 10+ items additionally require elicitation confirmation (or SPOTIFY_MCP_CONFIRM=never for automation).
| Name | Required | Description | Default |
|---|---|---|---|
| uris | Yes | Spotify URIs to remove | |
| dry_run | No | Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry destructiveHint=true; the description adds the critical behavior that this is a preview-first operation ('PREVIEWS BY DEFAULT โ pass dry_run=false to commit') and that large removals trigger elicitation confirmation with an env-var escape hatch. That is exactly the kind of operational context an agent needs to avoid an unintended destructive call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense, front-loaded sentences that each carry a distinct fact (scope, endpoint, limit, dry-run default, confirmation rule). The leading 'Preferred.' is slightly cryptic out of context, but overall there is little waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive batch tool with no output schema, the description covers scope, limits, default preview behavior, commit path, and the confirmation requirement โ everything needed to invoke it safely and correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents uris, dry_run and response_format, so the baseline is 3. The description still adds meaning: the max-40 batch limit, the accepted URI entity types, and the preview/commit semantics of dry_run that go beyond the schema's terse wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: removes one or more items from the user's library via Spotify's unified library endpoint. It also carves out its scope against siblings ('accepts the widest URI mix (track, album, episode, show, audiobook, user, playlist) in one request'), which separates it from remove_from_playlist and remove_from_library_by_playlist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States it is 'Preferred' and explains why (widest URI mix in one request, max 40), which implies when to choose it over narrower removal tools. It stops short of explicitly naming the alternative tools or the conditions where they would win, so it's clear context rather than full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_from_library_by_playlistADestructive
Remove from Liked Songs any tracks that also appear in a given playlist. Quota: 2 GETs + DELETE (chunked). PREVIEWS BY DEFAULT โ pass dry_run=false to commit. Removing 10+ saved tracks additionally requires elicitation confirmation (or SPOTIFY_MCP_CONFIRM=never for automation).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit. | |
| playlist_id | Yes | Playlist ID whose tracks will be removed from library | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Excellent beyond annotations: quota (2 GETs + DELETE, chunked), safe-preview default, the explicit commit switch, and the elicitation/SPOTIFY_MCP_CONFIRM=never override. Annotations only note destructiveHint=true; the description carries everything else an agent needs to know before mutating.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences covering purpose, quota, safety default, and confirmation gate โ front-loaded and free of padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a destructive mutation with no output schema, the description supplies the operational facts (cost, default, confirmation) that would otherwise be missing; nothing material is left unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so dry_run, playlist_id and response_format are already fully documented in the schema. The description reinforces the dry_run default/commit behavior but adds no syntax or format detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (remove), resource (Liked Songs), and scope (tracks that also appear in a given playlist), which cleanly distinguishes it from siblings like remove_from_library and remove_from_playlist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The preview-by-default and the conditions that trigger elicitation (10+ tracks) are explicit, and the dry_run commit path is named. It does not, however, route the agent to a sibling alternative for related operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_from_playlistBDestructive
Remove tracks or episodes from a playlist. Max 100 entries per call.
| Name | Required | Description | Default |
|---|---|---|---|
| uris | Yes | URIs to remove; use { uri, positions } to target specific occurrences of a repeated URI | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID | |
| snapshot_id | No | Apply the removal against this playlist version instead of the latest |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The destructiveHint annotation already carries the safety profile, lowering the bar. The description adds the tracks/episodes scope and the per-call volume cap, but the cap duplicates the schema's maxItems: 100 and it discloses nothing about dry_run, snapshot preconditions, or undo availability.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, action first, no filler. The second sentence repeats a schema constraint, which is mild redundancy rather than bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate minimum: a destructive mutation whose parameters are fully documented by the schema and whose safety profile is covered by annotations, with no output schema needed. It stops short of useful operational context such as snapshot conflict behavior or recovery paths.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters (including the uri/positions targeting form and dry_run) are already explained. The description only restates the 100-entry ceiling, adding no semantics beyond the schema; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (remove) plus resource (tracks or episodes from a playlist), and it correctly notes both content types. It does not distinguish itself from adjacent siblings such as remove_duplicate_playlist_items or playlist_subtract, so it is clear but undifferentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use, when-not-to-use, or alternative routing is given. The description never tells the agent why it would pick this over remove_duplicate_playlist_items, playlist_subtract, or batch_add_to_playlist, leaving selection entirely to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reorder_playlist_itemsA
Move a range of items within a playlist. Spotify semantics: when insert_before > range_start, the effective destination shifts down by range_length because the moved range is lifted out first (e.g. moving [2] to insert_before=4 lands it AT index 3).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID | |
| range_start | Yes | Index of the first item to move. 0-based index into the playlist's current item order (0 = the first item). | |
| range_length | No | Number of items to move. Default: 1 | |
| insert_before | Yes | Index to insert the range before. 0-based index into the playlist's current item order (0 = the first item). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=false, so the description carries the rest, and it earns its keep by disclosing the non-obvious Spotify index-shift semantics ('when insert_before > range_start, the effective destination shifts down by range_length'), with a concrete example. That is real behavioral context beyond the annotations, though it omits side effects like snapshot changes or auth requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, action front-loaded, followed by the one piece of tricky semantics and a compact illustrative example. No filler, no repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-output-schema mutation tool with full schema coverage and a destructiveHint=false annotation, the description supplies the key gotcha an agent needs to call it correctly (index shifting), plus the existence of a dry_run parameter is visible in the schema. Missing only peripheral details like confirmation/snapshot behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds meaning the schema does not: it explains the conditional interaction between insert_before and range_start, clarifying what each index value actually does to the resulting order. This is parameter-level semantics beyond the field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource scoped to a single playlist ('Move a range of items within a playlist'), which implicitly separates it from cross-playlist siblings like move_items_between_playlists. It does not, however, name any sibling explicitly (e.g. playlist_sort, playlist_reverse), so an agent must infer the boundary itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the phrase 'within a playlist' hints at the in-playlist scope, but there is no explicit when-to-use, when-not-to-use, or named alternative such as playlist_sort or move_items_between_playlists. An agent gets the context but no routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
replace_playlist_itemsADestructive
Replace ALL items in a playlist with the supplied URIs, overwriting the current contents. Lists longer than 100 URIs are sent in chunks internally (replace + appends).
| Name | Required | Description | Default |
|---|---|---|---|
| uris | Yes | Complete ordered list of track or episode URIs the playlist should contain | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations include destructiveHint=true, which already signals the destructive nature. The description adds valuable behavioral context beyond that: it explicitly states that current contents are overwritten, and it discloses the internal chunking behavior for lists longer than 100 URIs. This is exactly the kind of behavioral detail that helps an agent understand side effects and limits. It doesn't mention reversibility or permissions, but the destructive annotation plus the overwrite statement cover the critical risk.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler. The first sentence states the core operation and its destructive effect. The second sentence adds the important chunking behavior. Every word earns its place, and the most critical information (replace + overwrite) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive mutation tool with no output schema, the description covers the essential operational facts: what it does, what it overwrites, and how it handles large inputs. The dry_run parameter is documented in the schema. The only minor gap is that it doesn't state what the response/return value is, but with no output schema and a clear operation, this is a small omission. The description is complete enough for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all three parameters. The description adds the crucial semantic that the uris array is the complete replacement set, not an incremental addition, and that the order is preserved. This adds meaning beyond the schema's 'Complete ordered list' phrasing, but the schema already carries most of the parameter documentation burden. The dry_run parameter is self-explanatory in the schema and the description doesn't add to it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Replace'), a specific resource ('ALL items in a playlist'), and the exact effect ('overwriting the current contents'). It also distinguishes itself from related playlist mutation tools by emphasizing the full-replacement semantics, which is the key differentiator among siblings like add_to_playlist, remove_from_playlist, reorder_playlist_items, and batch_add_to_playlist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use this tool: when the caller wants the playlist to contain exactly the supplied URIs and nothing else. It doesn't explicitly name alternatives or state when not to use it, but the 'Replace ALL items' phrasing makes the usage context unambiguous. It also explains the internal chunking behavior for long lists, which helps the agent understand that large inputs are handled automatically.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restore_library_snapshotA
STRICTLY ADDITIVE restore of a library snapshot written by backup_library (see list_backups). Adds only what is missing: saves absent tracks/albums/shows/episodes/audiobooks, follows unfollowed artists, and creates NEW playlists named 'Restored ยท ()' โ existing playlists are never touched and nothing is deleted, renamed, or overwritten. Truncated snapshots are previewable but refused before confirmation or writes; quota-hit, contentless or wrong-schema_version snapshots are refused outright. Prompt and result state where the stored data came from, the date the FILE declares (naming the reason when absent โ never the mtime), the item count, and the single use made of it; dry_run defaults to TRUE (read-only preview); setting dry_run=false requires explicit confirmation before any write, fails closed when elicitation is unavailable or errors, and allows writes when SPOTIFY_MCP_CONFIRM=never.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | DEFAULT true: read-only preview of exactly what would be added. Set false to perform the (additive) writes after explicit confirmation. | |
| categories | No | Which snapshot categories to restore. Default: all | |
| backup_path | Yes | Snapshot JSON path from backup_library (see list_backups) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description carries the real behavioral burden and does so richly: additive-only semantics, that existing playlists are never touched and nothing is deleted/renamed/overwritten, the 'Restored ยท <name>' naming rule, the refusal conditions, and the full dry_run/confirmation flow including the SPOTIFY_MCP_CONFIRM=never escape hatch and fail-closed elicitation. This far exceeds what the annotation conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The critical constraint ('STRICTLY ADDITIVE') is front-loaded and nearly every clause earns its place given the tool's complexity. It is, however, a single dense block with long run-on sentences, which slightly hurts scannability for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema and a guarded confirmation flow, the description covers everything needed to invoke it correctly: provenance, refusal preconditions, default-preview behavior, confirmation requirements, and env-var overrides. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; dry_run, categories, max_results and response_format are already documented in the schema. The description adds meaning beyond it by explaining that dry_run=false triggers explicit confirmation and fails closed, tying the parameter to an operational contract rather than restating its default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a precise verb+resource ('STRICTLY ADDITIVE restore of a library snapshot') and immediately ties its provenance to backup_library (see list_backups), which no sibling can be confused with. The additive scope is stated unambiguously, setting it apart from copy_playlist, import_profile_state and other write siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly establishes when to use it (restoring what a backup_library snapshot is missing) and states the alternatives for locating snapshots (list_backups). It also sets out when restore is refused (truncated, quota-hit, contentless, wrong schema_version). It stops short of explicitly contrasting with adjacent import tools like import_profile_state or library_snapshot_diff.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_discover_weeklyA
Archive your Discover Weekly into a regular playlist (creates or overwrites the archive). Resolves Discover Weekly via /me/playlists exact match first, falling back to search (unverified); dry_run previews; idempotent if archive already matches. Result echoes source identity (owner, url, verified).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| archive_name | No | Archive playlist name (created if missing, overwritten if present) | Discover Weekly Archive |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description transparently details resolution order, fallback to unverified search, dry_run behavior, idempotence, and result shape. However, it directly contradicts the annotation destructiveHint=false by saying it 'creates or overwrites the archive' and by describing overwriting as expected behavior, which is a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, each carrying distinct information: purpose, resolution/idempotence, and result. The most important action is front-loaded, and there is no filler or repetition of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the key invocation concerns: what it does, how it resolves the source playlist, fallback behavior, dry-run option, idempotence, and output identity. It does not state failure behavior if resolution/search finds nothing or mention permission requirements, but those are minor gaps for a tool with no required parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the description does not need to re-document the parameters; baseline 3 applies. It adds some useful cross-context behavior such as idempotence and dry_run, but no additional per-parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'Archive your Discover Weekly into a regular playlist (creates or overwrites the archive).' This clearly distinguishes it from the large sibling set because no other tool targets the Discover Weekly archival use case. The behavior is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for when to invoke the tool: to create or update the Discover Weekly archive, with dry_run for previewing and idempotence when the archive already matches. It does not explicitly name alternative tools or list situations where another sibling should be used, so it misses the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_release_radarA
Archive your Release Radar into a regular playlist (creates or overwrites the archive). Resolves Release Radar via /me/playlists exact match first, falling back to search (unverified); dry_run previews; idempotent if archive already matches. Result echoes source identity (owner, url, verified).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| archive_name | No | Archive playlist name (created if missing, overwritten if present) | Release Radar Archive |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (only destructiveHint=false), the description richly discloses behavior: resolution via exact match then fallback to unverified search, dry_run preview behavior, idempotency when the archive already matches, and output echoing source identity. These are meaningful operational details an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient: the primary purpose is front-loaded, and each subsequent sentence contributes a distinct behavioral fact. No filler or redundant restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the moderate complexity, full schema coverage, and lack of an output schema, the description covers the critical aspects: what happens, safety behavior via dry_run, idempotency, resolution logic, and the result format. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents dry_run, archive_name, and response_format. The description adds no new parameter-specific meaning beyond what the schema already provides, landing at the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Archive your Release Radar into a regular playlist (creates or overwrites the archive).' It clearly differentiates this tool from similar siblings by naming the exact source playlist and the archive action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage context: use this to archive Release Radar into a playlist. However, it does not explicitly say when to prefer this over related alternatives like save_discover_weekly, nor does it mention any when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_sceneA
Save a named playback scene (device + volume + shuffle/repeat + optional context) to the local sidecar (~/.spotify-mcp/scenes.json)
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Scene name (key in the sidecar) | |
| repeat | No | Repeat mode: 'off' | 'track' | 'context' | |
| volume | No | Master volume percent (0โ100) | |
| shuffle | No | Shuffle state | |
| context_uri | No | Context URI to start on apply (e.g. spotify:playlist:โฆ) | |
| device_hint | No | Device name substring (case-insensitive) or exact device id | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation only declares destructiveHint=false. The description adds useful behavioral context by naming the exact persistence location (~/.spotify-mcp/scenes.json) and the captured playback fields. However, it does not disclose whether saving a scene with an existing name overwrites it, which is important for a persistent sidecar write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence that packs the verb, resource, captured fields, and sidecar path with no filler. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is adequate for a moderately simple configuration-capture tool: it names the storage location and the scope of what is saved. However, it does not mention overwrite behavior, whether the scene is applied immediately, or any relationship to apply_scene, and there is no output schema to clarify return values. These gaps are notable but not crippling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all seven parameters. The description adds a high-level framing of what a scene bundles (device, volume, shuffle/repeat, optional context) but provides no parameter-level detail beyond what the schema already states. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Save') and a concrete resource ('named playback scene') while enumerating exactly what the scene consists of (device + volume + shuffle/repeat + optional context) and where it is persisted (local sidecar path). This clearly distinguishes it from sibling tools like apply_scene, list_scenes, and delete_scene.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states what the tool does but provides no explicit guidance on when to use it versus related siblings such as apply_scene, delete_scene, or list_scenes. The usage context is implied by the name and siblings, but there is no 'when to use' or 'when not to use' statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_to_libraryA
Preferred. Accepts the widest URI mix (track, album, episode, show, audiobook, user, playlist) in one request. Save one or more items to the user's library via Spotify's unified library endpoint. Max 40. PREVIEWS BY DEFAULT โ pass dry_run=false to commit.
| Name | Required | Description | Default |
|---|---|---|---|
| uris | Yes | Spotify URIs to save (e.g. ["spotify:track:abc", "spotify:user:xyz"]) | |
| dry_run | No | Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=false, so the description carries the real behavioral load. It discloses the critical dry-run/preview default ('PREVIEWS BY DEFAULT โ pass dry_run=false to commit'), which an agent would otherwise get wrong, plus the hard 40-item cap โ genuine value beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short clauses, front-loaded with the differentiator ('Preferred') and the commit behavior. Every sentence contributes and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description does note that a preview returns a PLAN and that response_format controls output shape, which covers the main return-value concern. It stops short of describing error behavior or partial-failure handling, a minor gap for a batch mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters are already documented in the schema, including the dry_run preview semantics and the maxItems cap. The description restates the 40 limit and preview behavior but adds no syntax, format, or edge-case detail beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Save one or more items to the user's library'), names the underlying endpoint, and explicitly enumerates the accepted URI types. The 'Preferred' framing plus the URI-mix claim clearly distinguishes it from siblings such as remove_from_library and add_to_playlist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Signals this is the preferred path for library saves and that it consolidates mixed URI types in one request, which routes the agent here over narrower alternatives. However, it never names the alternatives it is preferred over (e.g. add_to_playlist) or states when-not to use it, so the guidance is strong but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
schedule_wind_downA
Preview or start a volume wind-down: absolute-minute volume steps, then pause. Set dry_run to preview without replacing or cancelling an active timer.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| minutes | Yes | Total ramp duration in minutes (1โ180) | |
| device_id | No | Target device id; defaults to the active device | |
| floor_volume | No | Volume floor the ramp never goes below (default 10) | |
| step_minutes | No | Minutes between volume steps (default 5) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply only destructiveHint=false, so the description carries most of the burden and does so: it discloses that a non-preview run 'replac[es] or cancell[s] an active timer' and that the ramp terminates by pausing playback. These are consequential side effects an agent couldn't infer from the schema. It doesn't say whether the wind-down persists across sessions or what happens if minutes exceeds the remaining playback time.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the primary action and the ramp mechanism front-loaded, then the dry_run caveat. Nothing is redundant with the schema text. Slightly denser than needed but every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter mutation tool with no output schema and near-empty annotations, the description covers the essentials: what it changes, how to preview safely, and the effect on an active timer. Missing only edge-case behavior (persistence, interaction with cancel_wind_down), which keeps it from 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (every parameter is documented, including defaults and ranges), so the baseline is 3. The phrase 'absolute-minute volume steps' adds a small interpretive cue about how minutes/step_minutes are measured, but no syntax or constraint detail beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Preview or start a volume wind-down') plus the mechanism ('absolute-minute volume steps, then pause'), so an agent knows exactly what the tool does. It stops short of naming its siblings (wind_down_status, cancel_wind_down), so differentiation is implied rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence gives real conditional guidance: pass dry_run=true to preview, and warns that a real run replaces or cancels an active timer. That condition โ interaction with an already-active timer โ is the main selection risk, and it's stated. It doesn't explicitly route to cancel_wind_down or wind_down_status, so it's not a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-onlyIdempotent
Search Spotify's catalog for tracks, artists, albums, playlists, shows, episodes, or audiobooks. Pass types as an array (e.g. ["artist"]) to search a single kind โ no track/album fallback noise. Decision guide: search (general, โค10/type), search_deep (paginated fetch_all up to 50/type), search_fresh (tag:new last 2 weeks), search_by_isrc (exact ISRC), whats_new (personal radar from follows).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Results per type, 1โ10. Default: 5 | |
| query | Yes | Search query | |
| types | No | Content types to search, as an array. Default: ["track","artist","album"]. Pass e.g. ["artist"] for an artist-only search. "audiobook" is only available in the US, UK, CA, IE, NZ and AU markets. | |
| market | No | ISO 3166-1 alpha-2 country code, e.g. 'US' โ uppercased automatically | |
| offset | No | Index of the first result to return, 0โ1000. Use with limit to page through results | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| include_external | No | Pass "audio" to include externally-hosted audio items marked as playable |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so the safety profile is covered. The description adds non-obvious behavior beyond those annotations: passing types suppresses track/album fallback noise, and results are capped at 10 per type. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the primary purpose, then immediately useful guidance on types and sibling-tool selection. No filler, no repetition of schema fields, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the read-only annotations, fully documented 8-parameter schema, and the response_format parameter, the description covers the key contextual needs: what it searches, how to narrow results, and which sibling tools to use for deeper or newer searches. It is not exhaustive about output layout, but the schema and response_format enum already carry that burden.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description does not need to restate parameter definitions. It adds value by clarifying that the types array produces a single-kind search with no fallback noise and by tying the limit to the โค10/type behavior. Other parameters are already well documented in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Search Spotify's catalog') and enumerates the seven content types searched. It also distinguishes the tool from sibling search tools by naming them in the decision guide, so an agent can separate it from search_deep, search_fresh, and search_by_isrc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The decision guide explicitly lists when to use this tool (general, โค10/type) versus search_deep, search_fresh, search_by_isrc, and whats_new. It also explains the types-array behavior for single-kind searches. This is clear, actionable routing guidance rather than vague context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_deepARead-onlyIdempotent
Paged catalog search that walks past the API limit of 10 results per type. Fetches up to 5 pages of 10 results per requested type server-side from a caller-supplied offset, dedupes by id, and returns compact rows. Type walks overlap (width: SPOTIFY_MCP_MAX_CONCURRENCY, else SPOTIFY_MCP_FANOUT_CONCURRENCY, else 4); same request count. Decision guide: use search_deep when you need >10 results/type or a later window; otherwise use search (single page), search_fresh (new releases), search_by_isrc (ISRC-exact), whats_new (personal follows).
| Name | Required | Description | Default |
|---|---|---|---|
| pages | No | Pages of 10 results to walk per type, 1โ5. Default: 1 | |
| query | Yes | Search query | |
| types | No | Content types to search. Default: ["track"] | |
| market | No | ISO 3166-1 alpha-2 country code, e.g. 'US' | |
| offset | No | Index of the first result to walk per type, 0โ1000. The next_offset a call reports is the offset to pass here to continue. Default: 0 | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already mark it as read-only and idempotent, but the description goes further by disclosing server-side paging, deduplication by id, compact rows, overlap behavior, and continuation via offset. It adds substantial behavioral context beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loads the purpose and then moves into mechanics and the decision guide. It is longer than average, but nearly every clause conveys useful operational or routing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex paged search tool with full parameter schema coverage and no output schema, it covers the critical missing pieces: pagination continuation, result-window behavior, and sibling routing. It does not detail return shape beyond compact rows, but the schema carries the parameter burden well.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents each parameter, including offset continuation and page limits. The description reinforces paging and offset semantics but does not add much parameter-level meaning beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: paged catalog search that walks past the API limit of 10 results per type. It also explicitly distinguishes itself from close siblings such as search, search_fresh, search_by_isrc, and whats_new in the decision guide.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit when-to-use rule: use search_deep when you need more than 10 results per type or a later window. It then names each alternative and its purpose, leaving no inference needed about tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_history_statsBRead-onlyIdempotent
Analytics over the local search-history sidecar: top queries, type breakdown, recency. Quota: local only (no API).
| Name | Required | Description | Default |
|---|---|---|---|
| top_n | No | Top N queries to show (default 10) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the operation's safety profile is covered. The description adds one genuinely new behavioral fact (local-only, no API quota consumption), which is valuable, but says nothing about result format or size bounds beyond the categories listed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight clauses with zero filler, and the core purpose is front-loaded ahead of the quota note. Slightly clipped to the point of leaving the 'sidecar' concept unexplained.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only stats tool with full schema coverage and no output schema, the description is adequate but thin: it never explains what the 'sidecar' is or how recency is defined, so an agent lacks full grounding on the returned data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (top_n, response_format) are fully documented with defaults and enum semantics in the schema. The description adds no parameter-level detail, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('analytics over') and resource ('the local search-history sidecar'), then enumerates the three outputs it produces: top queries, type breakdown, recency. This clearly separates it from the search siblings like history_search, though it never names that alternative directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not-to-use guidance is given. The 'Quota: local only (no API)' note is useful context but does not tell the agent when to pick this over history_search or following_analytics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_saved_albumsARead-onlyIdempotent
Search saved albums (client-side filter over bounded walk). Quota: GET /me/albums paged.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Substring match against album name/artist | |
| artist | No | Substring match against album artist | |
| scan_cap | No | Max albums to scan (default fetchAllCap) | |
| added_after | No | ISO date โ only albums added after this | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered; the description adds the non-obvious behavior that filtering happens client-side over a paged walk and notes the quota (GET /me/albums paged), which explains why scan_cap exists. It does not describe pagination limits or return shape, but the added context is genuinely useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact clauses with no waste and the core mechanism front-loaded. It is arguably a fragment rather than prose, but nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter read-only search with full schema coverage and annotations, the description supplies the key missing behavioral fact (client-side filtering over a bounded walk) and the endpoint quota. Only explicit sibling routing guidance is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema documents all six parameters including defaults for scan_cap and max_results. The description only obliquely supports scan_cap via 'bounded walk' and adds no syntax or format detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (search saved albums) and clarifies the mechanism (client-side filter over a bounded walk), which meaningfully separates it from get_saved_albums and search_saved_tracks/shows. It stops short of naming those siblings directly, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical 'client-side filter over bounded walk' implies this is for filtered lookup rather than full enumeration, but there is no explicit when-to-use or when-not-to-use statement versus the many sibling search_* and get_saved_* tools. Usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_saved_audiobooksARead-onlyIdempotent
Search saved audiobooks (bounded walk + client-side filter). Quota: GET /me/audiobooks paged.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Substring against audiobook name/author | |
| scan_cap | No | Maximum saved items to scan; defaults to SPOTIFY_MCP_FETCH_ALL_CAP | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/idempotentHint already covering the safety profile, the description usefully adds that scanning is bounded and filtering is client-side, plus the underlying quota constraint ('GET /me/audiobooks paged'). This tells the agent that scan_cap governs coverage and that the operation is quota-sensitive โ real context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two terse sentences, fully front-loaded, with zero filler. The core purpose leads and the operational note follows.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-param, fully-documented search tool with no output schema, the description is nearly sufficient: it explains the scan-and-filter model and the quota constraint. It doesn't state the return shape, but response_format in the schema covers that, leaving only a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents query, scan_cap, max_results, and response_format. The description's 'bounded walk' loosely reinforces scan_cap semantics but adds no format, syntax, or default details beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Search saved audiobooks') and the parenthetical clarifies the mechanism (bounded walk + client-side filter). It is clearly distinguishable from siblings like search_saved_tracks or search_saved_albums, though the differentiation rests on the media noun rather than explicit contrast in the text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the name and resource type โ an agent can infer it searches the user's saved audiobook library. However, there is no explicit when-to-use vs when-not guidance, no mention of alternatives for other media types, and no stated prerequisites (e.g. scope requirements).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_saved_episodesBRead-onlyIdempotent
Search saved episodes (bounded walk + client-side filter). Quota: GET /me/episodes paged.
| Name | Required | Description | Default |
|---|---|---|---|
| show | No | Substring against show name | |
| query | No | Substring against episode/show name | |
| scan_cap | No | Maximum saved items to scan; defaults to SPOTIFY_MCP_FETCH_ALL_CAP | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, so safety is covered. The description adds genuine behavior context (bounded walk, quota against GET /me/episodes, client-side filter), but omits what happens when scan_cap is hit, whether results are truncated silently, and pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences with no filler; the mechanism detail leads and the quota note follows. The fragment 'Quota: GET /me/episodes paged.' is a bit clipped and would read better as a full clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Five optional params are fully schema-documented and there is no output schema to explain, so the basics are covered. However, for a search tool in a dense sibling cluster, the description leaves unresolved how it differs from get_saved_episodes and what a truncated or capped scan means for the caller.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters are already documented, including the response_format enum and the env-var defaults. The description adds no syntax or format detail beyond the schema, and the mention of client-side filtering only loosely maps to scan_cap/max_results.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (search) plus resource (saved episodes), and it adds real mechanism detail: a bounded walk with client-side filtering. It never names or contrasts the obvious siblings (get_saved_episodes, search_saved_shows), so the agent must infer the split between retrieving all vs. searching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this over get_saved_episodes or search_saved_shows, and no exclusions or preconditions. The only implied guidance comes from the word 'Search' itself, which is not enough to route between the many *_saved_*/search_* siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_saved_showsARead-onlyIdempotent
Search saved podcast shows (bounded walk + client-side filter). Quota: GET /me/shows paged.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Substring match against show name and publisher. Spotify removed `publisher` from show payloads in February 2026, so the publisher half can only match on an app registration created before November 2024; on a current registration this is a name search that reports 0 publisher matches rather than pretending to have searched publishers. | |
| scan_cap | No | Maximum saved items to scan; defaults to SPOTIFY_MCP_FETCH_ALL_CAP | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover readOnly and idempotent, and the description adds behavior beyond them: the search is a bounded walk with client-side filtering (implies pagination/scan cost) and it is subject to a paged GET /me/shows quota. It does not state the scan default or what happens when scan_cap is exceeded, but the mechanism disclosure is genuinely useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences with zero filler; the what and the how are front-loaded, and the quota caveat follows. Nothing is redundant with the schema or annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only search tool with no output schema, the definition supplies purpose, mechanism, and quota context. It leaves the scan/return-volume semantics and any ordering of results implicit, but the essentials for correct invocation are present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema's query parameter description is notably rich (substring match target, publisher-removal caveat). The description adds no parameter-level detail of its own, so the baseline 3 applies since the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search saved podcast shows') with a scoping distinction that separates it from get_saved_shows (unfiltered listing) and from search_saved_episodes/albums/audiobooks (different media type). The parenthetical '(bounded walk + client-side filter)' further pins down what kind of search this is.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'client-side filter' implies the tool walks saved items locally rather than querying server-side, and the quota note ('GET /me/shows paged') hints at call cost, which indirectly signals when to prefer cheaper alternatives. However, no explicit when-to-use or when-not-to-use guidance or named alternative is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_saved_tracksARead-onlyIdempotent
Search your Liked Songs (saved tracks) by text query and optional facets โ client-side filter over a bounded walk of /me/tracks. For catalog-wide search use search. Reports walk truncation.
| Name | Required | Description | Default |
|---|---|---|---|
| album | No | Filter to tracks where album name contains this substring | |
| limit | No | Max results to return | |
| query | No | Substring to match against track name, artist name, or album name (case-insensitive). Omit to list by facets/sort only. | |
| artist | No | Filter to tracks where any artist name contains this substring | |
| sort_by | No | Sort order | added_desc |
| max_items | No | How many saved tracks to walk (default SPOTIFY_MCP_FETCH_ALL_CAP) | |
| added_after | No | ISO date โ only tracks added after this date | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| added_before | No | ISO date โ only tracks added before this date | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, covering the safety profile. The description adds genuinely useful behavioral context beyond those: it discloses that filtering happens client-side over a bounded walk of /me/tracks and that walk truncation is reported. This tells the agent results may be incomplete for large libraries and that this condition is signaled โ a meaningful operational caveat the annotations do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero waste. The core purpose is front-loaded, the client-side/bounded-walk mechanism is stated in the same breath, and the sibling disambiguation and truncation disclosure round it out. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description covers the essentials: scope, mechanism, boundary condition (bounded walk), the truncation signal, and the main alternative. The response_format enum in the schema partially compensates for the missing output schema. Minor gaps: the relationship between limit and max_results is not explained in the description, and there is no guidance on how truncation affects trustworthiness of results beyond being reported.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all 10 parameters โ baseline 3 is appropriate. The description adds a small amount of conceptual glue by framing the operation as 'text query and optional facets' and explaining the bounded-walk model, which clarifies why both max_items (walk cap) and max_results/limit (result caps) exist. But it does not go beyond the schema on parameter-level detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search your Liked Songs (saved tracks)'), names the mechanism ('client-side filter over a bounded walk of /me/tracks'), and distinguishes itself from the catalog-wide sibling ('For catalog-wide search use search'). An agent can immediately tell this from search, search_tracks, get_saved_tracks, and the other saved-search tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the key alternative and the condition that selects it: 'For catalog-wide search use search.' This resolves the highest-risk confusion. It does not enumerate exclusions for adjacent siblings like get_saved_tracks (plain list vs. filtered search) or search_saved_albums, but the scope is clear enough from the first sentence that an agent will infer when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_within_playlistARead-onlyIdempotent
Text search inside a single playlist: a client-side filter over the rows the walk read, cheaper than paging get_playlist_items yourself for a narrow query โ but it can only see that window, so scanned_items/scan_cap/scan_truncated say how much of the playlist was actually read. Matches item name, artist, album and show name; kind narrows a mixed playlist to tracks only or episodes only. Quota: GET /playlists/{id}/items paged.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Alias for playlist_id, matching get_playlist_items | |
| kind | No | Item kinds to match: 'track', 'episode', or 'any' (default โ both). Mixed playlists hold both row shapes | any |
| query | Yes | Substring to match against track/episode name, artist, album, show name | |
| market | No | Market for track relinking, e.g. 'US' | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| playlist_id | No | Playlist ID (or pass it as 'id') | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say readOnly/idempotent; the description goes well beyond by disclosing that the search is client-side over a partial walk, that results depend on that window, which fields report coverage (scanned_items/scan_cap/scan_truncated), and the underlying quota cost.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the alternative-tool comparison are front-loaded in the first clause, and every clause carries information; the single dense sentence with multiple em-dash asides is slightly heavy but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully names the scan-status fields an agent should inspect, and covers matching scope, kind filtering and quota; it is nearly complete, though it leaves market/response_format semantics entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description restates the match fields and kind semantics that the schema already documents, adding little parameter syntax or formatting detail beyond what is given there.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Text search inside a single playlist') plus the mechanism ('client-side filter over the rows the walk read'), which is enough to distinguish it from get_playlist_items and from the library-wide search siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames the use case against a named alternative ('cheaper than paging get_playlist_items yourself for a narrow query') and warns of the scan-window limitation, but it never states when NOT to use it (e.g. when a full or cross-playlist search is needed, point to search_deep/search).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
seekB
Seek to a position in the current track
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID | |
| position_ms | Yes | Position in milliseconds | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, leaving the description to carry behavioral disclosure. It does not say whether seeking requires an active track, whether it affects the current device, how it behaves without playback, or what the dry_run preview returns โ none of which the terse sentence covers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; the action and target are stated immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter playback tool with no output schema, the definition is minimally viable but omits session prerequisites and device targeting behavior. The schema covers the parameters, but nothing explains runtime behavior an agent would want before invoking it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so position_ms, device_id, dry_run, and response_format are already documented in the schema. The description adds no extra meaning such as units, clamping behavior, or bounds beyond what the schema provides, making the baseline 3 correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (seek) and resource (position in the current track), which is unambiguous and distinct from siblings like play, pause, or skip_next. It stops short of naming an alternative or clarifying scope such as active device or track requirement, but the core action is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No indication of when to use this versus play, play_from_search, or skip tools, nor any prerequisite such as an active playback session. Usage is only implied by the verb itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_repeatB
Set repeat mode: off, context (repeat playlist/album), or track (repeat single track)
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | Repeat mode | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The only annotation is destructiveHint=false, so the description carries most of the behavioral burden. It does not disclose whether the change is immediate, whether it requires an active playback context, what happens on invalid devices, or what dry_run does. It lists the mode values but adds little behavioral context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence that states the operation and immediately enumerates its values. Every word earns its place, and there is no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple state-setting tool with a fully described schema and no output schema. The description adequately conveys the operation and the meaning of the required enum values. It does not cover when to use it or the purpose of optional parameters like dry_run, but those gaps are minor for such a low-complexity tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful semantics for the state enum by explaining that 'context' repeats a playlist/album and 'track' repeats a single track, which goes beyond the schema's terse 'Repeat mode' label. The other parameters are left to the schema, which is acceptable given full coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Set repeat mode.' It also lists the three possible modes, making the operation unambiguous. However, it does not explicitly distinguish this tool from the sibling set_shuffle, which controls a related but different playback setting.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers no guidance about when to use this tool versus alternatives. It does not mention set_shuffle or any other sibling, nor does it state prerequisites such as an active playback session or device targeting. The agent must infer usage entirely from the tool name and schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_shuffleC
Enable or disable shuffle mode
| Name | Required | Description | Default |
|---|---|---|---|
| state | Yes | true = shuffle on, false = shuffle off | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply only destructiveHint=false, so the description carries the full burden of behavioral disclosure and does not meet it. It never says whether the change is session-only or persisted, whether it requires an active playback context, or how device targeting interacts with the setting.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short clause with the action front-loaded and zero filler. It is efficient, though the terseness contributes to the informational gaps noted elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter mutation tool with no output schema, the schema and annotations cover parameters and the non-destructive hint, leaving the definition minimally adequate. Missing scope/persistence behavior and sibling differentiation keep it from being complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and each parameter (state, dry_run, device_id, response_format) is well documented in the schema itself. The description adds no parameter meaning beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair ('Enable or disable') and resource ('shuffle mode'), so the agent knows exactly what it does. It does not distinguish itself from the sibling 'playlist_shuffle', which is a plausible confusion point given both deal with shuffling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus set_repeat, playlist_shuffle, or a playback-state tool, and no prerequisites stated. The agent must infer context entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_volumeA
Set playback volume on one device, on a selection of devices, or across every live device. volume_percent sets an absolute level; delta_step nudges the current level by a signed step. op picks the variant: "mute" drops to 0 and remembers the level, "unmute" restores what mute remembered, "preset" applies the per-device presets stored by set_device_volume_preset, and "level" with no volume_percent copies the active device's level to the others. Quota: 1 write for a single device; 1 read + N writes when fanning out.
| Name | Required | Description | Default |
|---|---|---|---|
| op | No | Variant: "level" (default) set or copy a level, "mute", "unmute", "preset" | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Device ID for a single-device write (default: the active device) | |
| delta_step | No | Signed nudge, e.g. +10 or -10, clamped to 0โ100. Mutually exclusive with volume_percent. | |
| device_ids | No | For op "level" with volume_percent: fan out to these device ids or names. Mutually exclusive with all_devices. | |
| all_devices | No | For op "level" with volume_percent: set every volume-capable device, not a named selection. | |
| volume_percent | No | Absolute level 0โ100. Mutually exclusive with delta_step. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| exclude_device_id | No | For op "level" with no volume_percent: leave this device untouched while levelling the rest |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint=false in annotations, the description carries the behavioral load well: it discloses that mute remembers the prior level and unmute restores it, that level with no volume_percent copies the active device's level to others, and it states the quota cost (1 write single; 1 read + N writes fanning out). That is substantive context the annotations do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the target scope is front-loaded, then the two level-setting modes, then op variants, then quota. No repetition of what the schema already states verbatim, and it is compact despite covering nine parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a nine-parameter, no-output-schema mutation tool with thin annotations, the description covers target scope, the mode selection (absolute vs delta), each op's semantics, dry_run preview, and quota cost. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema by explaining op interactions (what 'preset' and 'level' actually do) and how volume_percent, delta_step, device_ids, all_devices and exclude_device_id combine. This is more than the schema conveys on its own.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (set) and resource (playback volume) and immediately scopes the target space: one device, a selection, or every live device. It also names the related sibling set_device_volume_preset, so an agent can distinguish preset-applying from preset-storing without opening another schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance per op variant (mute/unmute/preset/level) and clarifies the volume_percent vs delta_step choice. It references set_device_volume_preset as the tool that stores presets, implying the alternative, but stops short of an explicit 'use X instead when Y' rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show_new_episodesARead-onlyIdempotent
Find new episodes across your saved podcast shows: reports episodes released within the lookback window (default 7 days), marking which are already saved in your episode library. Fetches /me/shows then each show's latest episodes, overlapping episode lookups (width: SPOTIFY_MCP_MAX_CONCURRENCY, else SPOTIFY_MCP_FANOUT_CONCURRENCY, else 4) so a 25-show scan is not 25 serial round trips. WARNING: M saved shows โ M+1 requests (1 show page + M episode lookups). Use max_shows to budget and cost_preview to see the cost without making any calls. This tool is read-only: nothing is ever changed.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Lookback window in days. Default 7. | |
| market | No | ISO 3166-1 alpha-2 country code for the per-show episode lookups, e.g. "US". Defaults to SPOTIFY_MCP_MARKET, then to the account country โ these lookups are market-gated, so a wrong default silently drops episode rows. | |
| max_shows | No | Per-call budget for show episode lookups. Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET / SPOTIFY_MCP_SHOWRADAR_BUDGET). Scan caps at min(budget, SPOTIFY_MCP_FETCH_ALL_CAP) and reports truncation. WARNING: each lookup is an API request. | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| cost_preview | No | Cost preview only: make no API calls and return the request budget instead of the episode list. Use it to size a real call; it does not report any episodes. Default false. | |
| per_show_limit | No | How many latest episodes to check per show for recency. Default 3. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only mark readOnly/idempotent, but the description discloses substantial behavior beyond them: concurrency resolution via SPOTIFY_MCP_MAX_CONCURRENCY/FANOUT_CONCURRENCY, the M saved shows โ M+1 requests cost model, truncation reporting, and the warning that a wrong market default silently drops episode rows. This is exactly the operational context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose in the first clause, then layers cost model and warnings. Dense but every sentence carries information; the concurrency env-var detail is the only part bordering on excessive for a tool-selection description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter read-only tool with no output schema, the description covers purpose, cost, concurrency, market gating, and the saved-vs-new marking. It does not describe the returned structure (e.g., what the concise/detailed/json formats contain), a minor gap given response_format is exposed as a parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents each parameter and the baseline is 3. The description adds cross-parameter meaning the schema cannot: the max_shows โ request-count relationship, cost_preview's 'no API calls, budget only' semantics, and the concurrency env fallback chain.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: finds new episodes across saved shows within a lookback window, marking which are already saved. Distinguishes itself from siblings like get_saved_shows and search_saved_episodes by describing a recency-scan rather than a library listing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear use conditions (find episodes released within the lookback window) and routes the agent to cost_preview and max_shows for budgeting before spending requests. It does not explicitly name a sibling alternative (e.g., whats_new) or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skip_nextB
Skip to the next track in the queue or context.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Only annotation is destructiveHint=false, which is nearly uninformative for a playback control. The description adds that skipping occurs relative to queue or context, useful behavioral context, but omits what happens at the end of the queue, whether playback state must be active, and whether an active device is required.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with no waste. Efficient, though it may be under-specified rather than truly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a playback-control mutation adjacent to many stateful siblings (play, pause, seek, set_shuffle, get_queue), the description is thin. It lacks prerequisites (active playback, valid device) and edge-case behavior (end of queue), so an agent could misuse it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters (dry_run, device_id, response_format) are fully documented in the schema. The description adds no parameter detail, which is acceptable at full coverage but leaves no extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Skip to') and resource ('the next track in the queue or context'). An agent can distinguish it immediately from siblings like pause, seek, and play.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this vs. alternatives like play, seek, or skip_previous. The phrase 'queue or context' gestures faintly at playback-state behavior but doesn't explain prerequisites or the difference between skipping within a queue vs. a context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skip_previousA
Skip to the previous track. If more than 3 seconds in, restarts the current track first.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | Target device ID | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations only declare destructiveHint=false, while the description adds a key behavioral trait: playback restarts the current track when more than 3 seconds have elapsed. This is meaningful context beyond the annotation and helps the agent predict outcomes. It still does not cover authentication, rate limits, or device-state requirements, so it falls short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, front-loaded with the primary action and followed by one important conditional behavior. Every sentence earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple playback-control tool with a fully documented schema and a non-destructive annotation, the description covers the essential purpose and the one non-obvious behavioral nuance. No output schema exists, and none is needed for this action. The definition is complete for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and all three parameters are documented in the input schema. The description adds no parameter-specific detail beyond what the schema already provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Skip to the previous track.' This clearly distinguishes the tool from sibling skip_next and from playback controls like play, pause, and seek. The added conditional restart behavior further specifies what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when the tool is useful by explaining that it restarts the current track if more than 3 seconds in. However, it does not explicitly compare this tool to alternatives like skip_next or seek, nor does it state when not to use it. Usage guidance is therefore implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
split_playlistB
Split a playlist into N chunks (new playlists). Quota: GET all + N POST /me/playlists + N POST items.
| Name | Required | Description | Default |
|---|---|---|---|
| parts | Yes | Number of parts (2โ10) | |
| public | No | Public flag for new playlists | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| name_prefix | No | Prefix for new playlist names (default: source name) | |
| playlist_id | Yes | Source playlist ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description carries most of the behavioral burden. It usefully discloses the quota footprint (1 GET + N POST /me/playlists + N POST items) and that new playlists are created, but says nothing about whether the source playlist is left intact, what happens on partial failure, or how dry_run interacts with the quota.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two front-loaded sentences with no filler; the core operation comes first and the quota cost second. The '(new playlists)' parenthetical is slightly redundant but harmless, and the terse quota shorthand is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With five parameters, no output schema, and minimal annotations, the description covers the operation and its cost but omits important context: whether the source playlist survives, ordering of items across chunks, and what a dry_run report actually returns. Adequate but with clear gaps for a mutation-style tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters including name_prefix defaults and the dry_run preview semantics. The description adds no syntax or behavioral nuance beyond what is in the schema, which is the expected baseline when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Split a playlist into N chunks') and immediately clarifies the output form ('new playlists'), which distinguishes it from siblings like merge_playlists, playlist_union, or playlist_trim. An agent can identify the operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use guidance, prerequisites, or named alternatives among the many playlist-manipulation siblings (merge_playlists, playlist_trim, copy_playlist). The quota note hints at cost but does not say when splitting is the right choice over manual item manipulation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
spotify_doctorARead-onlyIdempotent
Run read-only diagnostics: token presence/expiry, auth-time scopes vs write tools enabled by active toolsets, Premium gating, rate-limit cooldown, config state, visible account details when reachable, and the live registered-tool surface with toolset/scope/READONLY trim causes. The only live request is GET /me; no mutation requests are issued.
| Name | Required | Description | Default |
|---|---|---|---|
| verbose | No | Include per-check technical detail lines when response_format is concise | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds real value beyond that by naming the specific checks performed and stating the network footprint ('The only live request is GET /me; no mutation requests are issued'), which tells the agent this cannot alter state. It stops short of describing cost, latency, or failure modes of the checks.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the verb and mode ('Run read-only diagnostics:') followed by a compact enumeration, then a closing sentence that bounds the network behavior. The enumerated list is long but each item is a distinct diagnostic, so it earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is not required, and the description covers scope, safety, and the one outbound call. The main gap is the absence of guidance on when to run it versus the other diagnostic/toolset siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (verbose, response_format) are fully documented in the schema, including the enum semantics for response_format. The description adds nothing about how verbose or response_format interact, so the baseline 3 applies โ the schema carries the full burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ('Run read-only diagnostics') followed by a concrete enumeration of what is checked: token expiry, scopes, Premium gating, cooldown, config, account, and registered-tool surface. An agent immediately knows this is an environment/health check rather than a data or playback tool. It does not explicitly distinguish itself from nearby diagnostic siblings like toolset_report, inspect_tool, or find_tool, which mention overlapping toolset/scope concerns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied ('diagnostics' suggests troubleshooting when auth, scopes, Premium, or rate limits are suspect), but there is no explicit when-to-use statement or 'use X instead' routing against toolset_report or inspect_tool. An agent must infer the trigger condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_podcast_sessionA
Plan a podcast session (see plan_podcast_session) and start it on a device. Limitation: Spotify cannot apply resume offsets when queueing โ only the first episode can start at its resume point (via PUT /me/player/play on its show context); later episodes are appended to the queue and play from the beginning. With dry_run, nothing is played or queued.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Restrict the source: 'episodes' = your saved episodes only, 'shows' = recent episodes of your saved shows only. Omit to use saved episodes (plus saved shows when saved_only is false) | |
| market | No | ISO 3166-1 alpha-2 country code for the saved-show episode lookups, e.g. "US". Defaults to SPOTIFY_MCP_MARKET, then to the account country โ these lookups are market-gated, so a wrong default silently drops episode rows. Ignored for a saved-episodes-only plan. | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| minutes | Yes | Session length in minutes (1โ480) | |
| device_id | No | Target device ID; omit for the active device | |
| saved_only | No | When no kind is set, include recent episodes of saved shows too. Default: true (saved episodes only) | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations supply only destructiveHint=false, so the description carries most of the behavioral burden and does so well: it discloses a real, non-obvious constraint about Spotify resume offsets when queueing and clarifies that dry_run plays/queues nothing. It doesn't state whether starting a session interrupts current playback or whether a device must be active, which are relevant mutation side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the purpose, then the limitation, then the dry_run caveat. The limitation sentence is dense but each clause carries information an agent needs; nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter playback tool with full schema coverage and no output schema, the description covers purpose, sibling routing, a key platform limitation, and dry_run behavior. It omits what a session result looks like and any playback-interruption or device-state side effects, which are the remaining gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description's note that 'with dry_run, nothing is played or queued' restates the schema's dry_run description rather than adding new semantics, and no other parameter is elaborated.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb+resource ('Plan a podcast session ... and start it on a device') and explicitly distinguishes itself from the sibling plan_podcast_session by the fact that it starts playback. An agent can tell the two apart without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It routes the agent to plan_podcast_session for planning-only and explains the dry_run mode as the no-playback path, giving clear context for when each behavior applies. It stops short of naming exclusions versus general playback tools like play or add_to_queue.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
switch_accountADestructive
Change which registered account this session acts as. Takes effect for every subsequent call in this session: the client re-points its token file, drops the previous account's cached reads and validators, and refuses to switch while a request is in flight. Asks for confirmation first, because every later write then lands in the new account's library. Changes local session state and the account registry only โ it issues no Spotify writes.
| Name | Required | Description | Default |
|---|---|---|---|
| profile | Yes | Profile name to act as โ the same value "--profile <name>" takes, or "default" for the account this server started as. The name must already have been authenticated with "spotify-mcp auth --profile <name>"; this tool does not run the auth flow. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavioral context beyond the annotations: it re-points the token file, drops the previous account's cached reads and validators, requests confirmation first, and refuses during in-flight requests. Critically, it resolves the ambiguity of destructiveHint=true by clarifying no Spotify writes are issued โ a genuinely valuable distinction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, then layers effect, mechanics, and safety in dense, non-redundant sentences. It is on the longer side, but nearly every clause carries operational information an agent needs before switching accounts.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a session-state-mutating tool with no output schema, the description covers scope of effect, prerequisite auth state, cache invalidation, concurrency behavior, and confirmation handling. Nothing an agent needs to call it safely is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the profile parameter and its auth prerequisite, plus the response_format enum, are fully documented in the schema. The description adds no parameter-level syntax or constraints beyond that, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource โ 'Change which registered account this session acts as' โ and scopes it to the session, which cleanly separates it from list_accounts and other account-adjacent siblings. An agent can act on it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for when the tool applies (every subsequent call in the session, requires prior 'spotify-mcp auth --profile <name>') and a guard condition (refuses while a request is in flight). It stops short of naming an alternative sibling or an explicit 'don't use this when...' rule, so it lands at 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tag_managementA
Declare or retract genre tags for an artist in your local sidecar (~/.spotify-mcp/genre-tags.json), which library_genre_report and filter_by_genre consume. add requires at least one tag; remove drops the listed tags, or the artist entirely when none are listed. Supports dry_run preview.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Tags to add/remove; omit on remove to drop the artist entirely | |
| action | Yes | add tags to an artist, or remove tags/artist | |
| artist | Yes | Artist name exactly as it appears in your library | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the minimal destructiveHint annotation, the description discloses the exact sidecar file path, the persistence model, the consuming tools, the add/remove semantics, and the dry_run preview capability. It does not discuss irreversibility or edge cases like missing files, but it adds meaningful behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words. The primary purpose and file location are front-loaded, followed by compact action semantics and dry-run mention. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of an output schema and minimal annotations, the description covers the essential context: what the tool does, where state lives, what consumes it, and how add/remove/dry_run behave. It omits details like whether the sidecar file is auto-created or whether tags are case-sensitive, but these are not critical for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds at least one meaningful constraint not visible in the schema: 'add requires at least one tag.' It also reinforces the distinction between removing listed tags and removing the artist entirely, adding context beyond bare parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: declare or retract genre tags for an artist in a local sidecar file. It also names the consuming tools (library_genre_report and filter_by_genre), which distinguishes it from the many sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context by explaining that the tags feed library_genre_report and filter_by_genre, implying when an agent should use this tool. It also provides operational guidance (add requires at least one tag; remove can drop an artist entirely), though it does not explicitly contrast with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
toolset_reportA
Report the active toolsets and registration modules, plus the live registered tool count โ answers "how much surface is exposed right now". Discovery set; always available. Also see find_tool / inspect_tool.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | 'concise' (default) = prose bullet list; 'detailed' = the same prose; 'json' = the result payload as parseable JSON text, identical to structuredContent | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry destructiveHint=false, so the description supplements it with the meaningful behavioral trait that this is an always-available discovery tool. A return schema exists, so return format need not be described. It stops short of explicitly confirming read-only, keeping it at 4.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the purpose, followed by availability context and the sibling pointer. There is no filler, and the framing question aids quick scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, zero-required introspection tool with a full output schema and near-minimal annotations, the description covers purpose, availability, and alternatives adequately. An explicit read-only statement would complete it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single response_format parameter is fully documented in the schema, so the baseline of 3 applies. The description adds no format guidance beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Report the active toolsets and registration modules, plus the live registered tool count') and even frames it with a plain-language question it answers. It is clearly distinguishable from find_tool and inspect_tool, which it names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives useful context ('Discovery set; always available') and points to the alternative tools find_tool / inspect_tool, but does not state explicitly when to reach for this report versus those siblings. Clear context with no exclusions, so a 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transfer_playbackA
Move playback to a different Spotify Connect device, named by exact id, by the label you gave it, or by a case-insensitive name substring. A plain transfer restarts the track at 0:00 on the target; preserve_position: true carries the current track and play position across instead, and restore_shuffle_repeat: true re-applies the current shuffle and repeat modes on the target. Quota: 1 read to resolve the device, then 1โ4 writes depending on the flags.
| Name | Required | Description | Default |
|---|---|---|---|
| play | No | Force play (true) or arrive paused (false); omit to preserve the current play state. With preserve_position, true also resumes a session that is currently paused. | |
| device | Yes | Target device: exact id, sidecar label, or case-insensitive name substring | |
| volume | No | Volume to set on the target after transfer, 0โ100 | |
| dry_run | No | Preview only: describe what would change without performing it. Default false โ pass true to preview. | |
| device_id | No | DEPRECATED: use `device` | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
| preserve_position | No | Resume the current track at its current position on the target instead of restarting it (default: false) | |
| restore_shuffle_repeat | No | Re-apply the current shuffle and repeat modes on the target (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=false, so the description carries real weight and delivers: it discloses that a plain transfer restarts the track at 0:00, that preserve_position carries position across, that shuffle/repeat can be re-applied, and gives an explicit write-quota cost (1 read + 1โ4 writes). This is exactly the behavior an agent needs before invoking a state-changing playback operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with the core action and then the flag semantics and cost. Every clause carries information an agent would otherwise have to guess; no filler or restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter mutation tool with no output schema, the description covers the risky aspects: track position, shuffle/repeat restoration, and operation cost. It omits any mention of dry_run previewing or the deprecated device_id alias, both of which an agent might want surfaced at the description level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds genuine value by describing the interplay between flags (e.g. preserve_position combined with play resumes a paused session) and by spelling out the three device-resolution modes. It does not, however, cover volume, dry_run, or the deprecated device_id, leaving those to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Move playback to a different Spotify Connect device') and immediately scopes how the target is identified. It is clearly distinguishable from siblings like play, pause, seek, and set_volume, which operate on the current session rather than relocating it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the behavioral variants (plain transfer vs preserve_position vs restore_shuffle_repeat), which implies when each flag is appropriate, but it never explicitly names an alternative tool or a when-not condition. An agent must infer the choice of flags rather than being routed to them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undo_last_mutationADestructive
Undo the most recent reversible mutation (receipt FIFO). Same inversion semantics as undo_mutation: add/save โ remove, removal โ re-add. Executing needs confirmation and is refused when the client cannot prompt (SPOTIFY_MCP_CONFIRM=never bypasses).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only, and the default: pass dry_run: false to execute the rollback. | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint=true, yet the description adds substantial behavioral context: confirmation is required to execute, execution is refused when the client can't prompt, SPOTIFY_MCP_CONFIRM=never bypasses that gate, and the exact inversion mapping (add/save โ remove, removal โ re-add). This is exactly the beyond-annotation disclosure a destructive tool needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three front-loaded sentences, no filler: purpose and ordering first, semantic equivalence second, execution gating third. Every clause carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and only destructiveHint in annotations, the description carries the full burden and meets it: it covers ordering, inversion semantics, and the confirmation/refusal behavior that determines whether the call can even succeed. Nothing material is left for the agent to guess.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (both dry_run and response_format are fully documented, including the default of dry_run=true). The description adds no parameter-level syntax or format information, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Undo the most recent reversible mutation') and pins the scope with 'receipt FIFO'. It explicitly names the sibling undo_mutation as the related-but-different operation, so an agent can route between them without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The FIFO scope makes the selection condition clear: use this for the latest mutation, and it alludes to undo_mutation for targeted rollback via 'Same inversion semantics as undo_mutation'. It stops short of an explicit 'use undo_mutation instead when you know the receipt id' sentence, so no exclusion list, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
undo_mutationADestructive
Undo a specific mutation by receipt ID. Inverts the recorded direction: an add/save is undone by removing, a removal by re-adding (playlist items or library). A playlist add undo removes only the rows it created, refusing when no row positions are recorded. The result reflects the refetched post-state. Non-reversible kinds return not reversible. Executing needs confirmation and is refused when the client cannot prompt (SPOTIFY_MCP_CONFIRM=never bypasses).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only, and the default: pass dry_run: false to execute the rollback. | |
| receipt_id | Yes | Receipt ID to undo | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations carry only destructiveHint=true, and the description goes well beyond it: it discloses the inversion semantics (add undone by remove, removal by re-add), the partial-rollback guarantee for playlist adds, the refusals, the confirmation requirement, and the SPOTIFY_MCP_CONFIRM escape hatch. That is exactly the mutation-risk context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five dense sentences, front-loaded with the core action and receipt key before the refusal and confirmation caveats. Efficient, though the clause-heavy style ('an add/save is undone by removing, a removal by re-adding') costs some readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must cover behavior, and it does: reversibility semantics, refusal cases, confirmation gating, and the fact that results reflect the refetched post-state. Combined with a fully covered schema, an agent has what it needs to call this correctly and safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so receipt_id, dry_run, and response_format are already documented in the schema, and the description only echoes dry_run implicitly via 'Executing needs confirmation'. With the schema doing the heavy lifting, baseline 3 is appropriate; response_format is not touched by the description at all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource ('Undo a specific mutation') plus the scoping key ('by receipt ID'), which implicitly separates it from the sibling undo_last_mutation. It does not name that sibling outright, so the differentiation is inferable rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete operating conditions: non-reversible kinds return 'not reversible', playlist-add undos refuse when no row positions are recorded, and execution requires confirmation. It stops short of telling the agent when to prefer this over undo_last_mutation or verify_receipt, so alternatives are left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unfollow_playlistADestructive
Unfollow a playlist โ remove it from your Spotify library โ via DELETE /me/library. Always asks before writing unless SPOTIFY_MCP_CONFIRM=never.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID to unfollow | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| dry_run | No | |
| receipt | No | |
| cancelled | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only destructiveHint=true in the annotations, the description adds real behavioral context: it discloses a confirmation prompt ('Always asks before writing') and the environment variable that suppresses it (SPOTIFY_MCP_CONFIRM=never). This is meaningful beyond the annotation, though it says nothing about reversibility or whether the removal is recoverable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the core action and scope first, followed by one short clause on the confirmation behavior. No filler, nothing an agent must wade through.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained. For a destructive mutation the description covers the important safety behavior (confirmation gate) and the endpoint, though it omits reversibility, which would fully round out a destructive operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so playlist_id, dry_run, and response_format are already fully documented in the schema. The description adds no parameter meaning beyond that, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource ('Unfollow a playlist') and immediately clarifies the effect ('remove it from your Spotify library'), which distinguishes it from the sibling remove_from_playlist that removes tracks. Naming the underlying endpoint (DELETE /me/library) removes any residual ambiguity about scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It conveys the operation but gives no explicit when-to-use vs. alternatives guidance, e.g. it never points to follow_playlist or check_playlist_following for the reverse or verification cases. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unpin_playlistADestructive
DEPRECATED, use unfollow_playlist. This tool never unpinned anything; it has always removed the playlist from your Spotify library via DELETE /me/library.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| playlist_id | Yes | Playlist ID to unfollow | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| dry_run | No | |
| receipt | No | |
| cancelled | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true, and the description corroborates this by disclosing the actual destructive effect (library removal via DELETE /me/library). It adds genuinely useful context the annotations cannot convey: deprecation status and the mismatch between the name and real behavior. It does not cover auth or reversibility, so not a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, deprecation warning and replacement named first, then the actual behavior. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and full schema coverage, the description only needs to convey purpose, deprecation, and real effect, all of which it does. Nothing required to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with playlist_id, dry_run, and response_format all documented in the schema, so the baseline is 3. The description adds no parameter-level syntax or format detail beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States exactly what the tool does ('removed the playlist from your Spotify library via DELETE /me/library') and explicitly corrects the misleading name by noting it 'never unpinned anything.' An agent can distinguish it from unfollow_playlist and pin_playlist without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Front-loads 'DEPRECATED, use unfollow_playlist,' which is an explicit when-not-to-use directive naming the replacement sibling. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unsave_orphan_tracksADestructive
Find saved tracks that appear in no playlist (orphans) and optionally unsave them. Quota: walks library + all playlists (capped). PREVIEWS BY DEFAULT โ pass dry_run=false to commit. Removing 10+ orphans additionally requires elicitation confirmation (or SPOTIFY_MCP_CONFIRM=never for automation).
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit. | |
| scan_cap | No | Max saved tracks to scan (default fetchAllCap) | |
| max_remove | No | Max orphans to remove (default 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the destructiveHint annotation by disclosing the cost profile (walks library plus all playlists, capped), the safe-by-default preview behavior, the confirmation threshold of 10+ removals, and the SPOTIFY_MCP_CONFIRM=never escape hatch for automation. These are exactly the operational details an agent needs before triggering a destructive call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the purpose, then the preview-default rule, then the edge-case confirmation. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description explains that dry_run returns a PLAN, covering the main return expectation. The detailed shape of the plan and per-track results is left unspecified, which is a minor gap for a destructive multi-item tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds value by reinforcing dry_run's default semantics, framing the plan-only return, and implying that max_remove interacts with the 10+ elicitation threshold. Quota/scoping context for scan_cap is meaningful beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with a precise scope: 'Find saved tracks that appear in no playlist (orphans) and optionally unsave them.' This is distinguishable from siblings like find_duplicate_saved_tracks and library_hygiene, which target different conditions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly explains the operating mode: preview by default, pass dry_run=false to commit, and that removing 10+ orphans requires elicitation. It does not name a sibling alternative (e.g., remove_from_library or library_hygiene) for a simple single-track removal, so the routing guidance is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_playlistC
Update a playlist's name, description, or visibility
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Alias for playlist_id | |
| name | No | New name | |
| public | No | New public state | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| description | No | New description | |
| playlist_id | No | Playlist ID | |
| collaborative | No | New collaborative state |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say destructiveHint=false, and the description adds no behavioral context beyond that: it does not state that changes are partial, that dry_run previews without performing, or how the API treats omitted fields. The description mostly restates the tool's name and schema fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with no filler, which is efficient. It loses a point because 'visibility' is ambiguous relative to the actual boolean fields and collaborative is omitted without any structural payoff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with seven optional parameters, no output schema, and only a destructiveHint annotation, this is under-specified. It fails to mention the dry_run preview option, leaves collaborative out, and gives no selection rule among numerous playlist mutators, so an agent gets little help beyond the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 and the schema already documents each parameter. The description adds no new parameter meaning and even calls the public field 'visibility' while omitting collaborative; however, the schema's per-parameter descriptions carry the needed semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Begins with a specific verb ('Update') and names the resource ('a playlist') plus the affected fields (name, description, visibility), so the basic purpose is clear. It does not differentiate against sibling playlist tools such as create_playlist, playlist_sort, or add_to_playlist, and 'visibility' maps only loosely to the schema's public/collaborative booleans.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No sentence explains when to use this tool instead of the many playlist-editing siblings, and there are no exclusions or alternatives. The only guidance is implied by the verb 'Update,' which does not help choose between update_playlist, playlist_reverse, playlist_trim, or remove_from_playlist.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_playlist_coverA
Replace a playlist's cover image with a base64-encoded JPEG. Requires the ugc-image-upload scope on the Spotify developer dashboard app (plus playlist-modify-public/private); without it Spotify rejects the upload with 403.
| Name | Required | Description | Default |
|---|---|---|---|
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| jpeg_base64 | Yes | Base64-encoded JPEG file contents (max 256 KB decoded) | |
| playlist_id | Yes | Playlist ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse annotations (destructiveHint=false), the description discloses the mutation semantics ('Replace' = overwriting the existing cover), the external authorization dependency (ugc-image-upload scope), and the concrete failure behavior (Spotify rejects with 403). No contradiction with annotations. It could add what a successful response looks like, but the replace semantics and failure mode are the important behavioral facts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, roughly 40 words, with the core action front-loaded and the scope prerequisite plus its consequence in the second sentence. Every clause earns its place; no repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter mutation with full schema coverage and no output schema, the description covers the action, input format, prerequisites, and error behavior โ enough for an agent to invoke it correctly and anticipate the main failure. Minor gap: it doesn't state what a successful call returns or whether the previous cover is permanently lost, but 'Replace' plus the dry_run parameter keeps this marginal.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the schema already documents playlist_id, jpeg_base64 (with max 256 KB decoded), and dry_run. The description reinforces that the image must be base64-encoded JPEG but adds nothing about the parameters that the schema doesn't already say.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource โ 'Replace a playlist's cover image' โ and adds the required input format (base64-encoded JPEG). This sharply distinguishes it from sibling cover tools like get_playlist_cover, clone_playlist_cover, and compare_playlist_covers, which read, copy, or compare covers rather than write them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear, actionable context: it names the required ugc-image-upload scope (plus playlist-modify-public/private) and predicts the exact failure mode (403) if the scope is missing, so an agent can verify prerequisites before calling. It does not explicitly name alternative tools or exclusion conditions, leaving when-versus-alternatives routing mostly implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_receiptARead-onlyIdempotent
Verify that a previous mutation actually landed on Spotify by looking up its receipt. Receipts are session-scoped: the 100 most recent mutations, in this process only, and lost on restart unless SPOTIFY_MCP_RECEIPTS is set. An unknown or expired id returns isError with found:false โ a fact about the lookup, not about the mutation.
| Name | Required | Description | Default |
|---|---|---|---|
| receipt_id | Yes | Receipt ID copied verbatim from a receipt-bearing mutation result (rcpt_<bootId>-<n>) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the readOnly/idempotent annotations: session-scoped retention (100 most recent, this process only, lost on restart unless SPOTIFY_MCP_RECEIPTS is set) and precise error semantics (isError with found:false is a fact about the lookup, not the mutation). This is exactly the operational detail annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the core action, then retention semantics, then error meaning. Every sentence carries non-redundant information; nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return contract (isError with found:false) and the retention window, which are the facts an agent needs to interpret results correctly. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the pattern and the 'rcpt_<bootId>-<n>' format are already documented in the schema. The description reinforces the id's origin ('copied verbatim from a receipt-bearing mutation result') but adds no format or syntax beyond that.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: verifying that a prior mutation landed, by looking up its receipt. The operation is unambiguous and distinct from mutating siblings. It stops short of naming the nearest alternatives (undo_mutation, undo_last_mutation), so an agent must infer the boundary itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly frames the use case: confirm that a previous mutation actually landed on Spotify. It also explains the provenance of the input ('receipt-bearing mutation result'), which tells the agent when this tool is applicable. No explicit when-not-to-use or named alternative is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whats_newA
Personal new-releases radar: derive what's new from followed artists (new albums/singles) and saved shows (new podcast episodes), replacing the removed browse/new-releases surface. WARNING: the follow list is paged 50 artists per request, so on a COLD read cache the album leg costs ceil(max_artists/50) follow pages PLUS up to max_artists album lookups (#679); a repeat scan inside the cache window re-probes the same canonical request and spends no request (#900). A large library can still exhaust small dev-account quotas in one call. Use max_artists to budget and dry_run to preview the cost before running; dry_run labels its figure a budget bound (it is arithmetic over the budget, not a measurement) and a real call reports the request count it actually issued in cost. Decision guide: whats_new for personal follows radar; search_fresh for query-scoped tag:new, search/search_deep for general catalog, search_by_isrc for ISRC-exact.
| Name | Required | Description | Default |
|---|---|---|---|
| kinds | No | Which sources to scan. Default: ['albums','podcasts'] | |
| since | No | Only include releases on/after this date (YYYY-MM-DD), or 'last-check' to resume from the stored per-kind watermark file (default path ~/.spotify-mcp/freshness.json). Tracked per kind, so a call scoped to one kind never moves the other kind's mark. An explicit date never writes this file; 'last-check' and a days_back window do. | |
| dry_run | No | Preview only: validate inputs and describe exactly what would change without performing it | |
| days_back | No | Look this many days back when `since` is omitted. Default: 30 | |
| max_artists | No | Per-call budget for artist album lookups (and show episode lookups). Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET). Walk caps at this budget and reports truncation. Independent of SPOTIFY_MCP_FETCH_ALL_CAP. WARNING: each lookup costs a request unless the read cache already holds that artist's canonical release probe (#900). | |
| max_results | No | Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50) | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only carry destructiveHint=false, so the description carries the real burden and does so richly: paging cost (ceil(max_artists/50) pages plus album lookups), cache-window behavior, quota exhaustion risk on small dev accounts, dry_run semantics (budget bound vs measured cost), and the cost field returned by a real call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then warnings, then a decision guide. Dense and long but each block earns its place for a quota-sensitive tool; minor redundancy around the cost/cache message and issue-number parentheticals.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, zero-required-param tool with no output schema, the description covers budgeting, dry_run vs real-run cost reporting, watermark persistence, and sibling routing - everything an agent needs to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds genuine interpretive context beyond the schema: how max_artists interacts with fetch caps and cache, that dry_run's figure is arithmetic not measurement, and how since/'last-check' watermarks are tracked per kind.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'derive what's new from followed artists (new albums/singles) and saved shows (new podcast episodes)'. It also names the surface it replaces and explicitly differentiates itself from four named siblings in the decision guide.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit decision guide routing between whats_new, search_fresh, search/search_deep, and search_by_isrc by scenario. Adds concrete advice on when to use max_artists to budget and dry_run to preview cost.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wind_down_statusA
Read the current or most recent wind-down progress, including per-step failures
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Only return status for this device id | |
| response_format | No | 'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object | concise |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only indicate destructiveHint=false, but the description adds the useful detail about per-step failures and that it returns current or most recent progress. It does not describe other behavioral aspects like whether it blocks or requires active scheduling, but with limited annotations the description provides moderate value beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that front-loads the main purpose and includes the critical per-step failures detail. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with only two optional parameters, no required params, and the schema covers them well. The description covers the core read operation and the availability of per-step failure info. An agent has enough to invoke it correctly without more detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameters are well documented in the schema itself. The description adds no extra semantics beyond what the schema provides, so a baseline of 3 is appropriate. It doesn't clarify how response_format affects output beyond the schema's enum descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads wind-down progress and includes per-step failures. It is specific about the resource (wind-down status) and the action (read). While it does not name a sibling, the purpose is clear and distinct from scheduling/canceling wind-down tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies it is for reading status, but does not explicitly state when to use it over siblings like schedule_wind_down or cancel_wind_down. It does not mention that it only reads and does not modify, though the annotation hints at non-destructive behavior.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
527 tool updates
v3.0.1- Changed
add_to_playlist1 field changed- changed
Input schema / properties / position / descriptionPrevious value: -"Insert at index; appends if omitted"New value: +"Insert at this index; appends if omitted. 0-based index into the playlist's current item order (0 = the first item)."
- Changed
add_to_queue2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
added_on_this_day - Removed
album_anniversary_check - Removed
album_duration_report - Removed
album_edition_lint - Removed
album_focus_report - Removed
album_openers_report - Removed
album_representative_plan - Removed
album_track_explorer - Removed
album_track_stats - Removed
albums_runtime_batch - Removed
apply_device_presets - Changed
apply_scene2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
apply_snapshot_changes - Removed
apply_volume_plan - Removed
archive_played_episodes - Removed
artist_affinity - Removed
artist_album_completeness - Removed
artist_album_timeline - Removed
artist_catalog_stats - Removed
artist_collab_network - Removed
artist_collaboration_network - Removed
artist_collection_gaps - Removed
artist_complete_check - Removed
artist_completeness_score - Removed
artist_debut_release_finder - Removed
artist_decade_span - Removed
artist_deep_cuts - Removed
artist_deep_dive - Removed
artist_discography_explorer - Removed
artist_discography_gaps - Removed
artist_discography_search - Removed
artist_discography_stats - Removed
artist_discography_timeline - Removed
artist_era_map - Removed
artist_era_sampler - Removed
artist_first_release - Removed
artist_genres_compact - Removed
artist_latest_release_report - Removed
artist_latest_releases - Removed
artist_listening_clock - Removed
artist_live_albums_finder - Removed
artist_name_disambiguator - Removed
artist_reissue_detector - Removed
artist_release_digest - Removed
artist_release_type_breakdown - Removed
artist_representation_census - Removed
artist_scout_from_playlists - Removed
artist_singles_timeline - Removed
artist_top_vs_saved - Removed
artist_velocity_report - Removed
artistwatch_new_additions - Removed
audiobook_chapter_map - Removed
audiobook_library_progress - Removed
audiobooks_by_author - Removed
b_sides_detector - Removed
b_sides_finder - Changed
backup_library2 fields changed- removed
Input schema / properties / max_resultsRemoved value: -{ - "description": "Per-category walk cap for THIS call (default: SPOTIFY_MCP_FETCH_ALL_CAP)", - "exclusiveMinimum": 0, - "maximum": 2000, - "type": "integer" -} - added
Input schema / properties / walk_capAdded value: +{ + "description": "Cap on items per category walked for THIS call (default: SPOTIFY_MCP_FETCH_ALL_CAP). Bounds what is READ, not rows rendered โ use max_results to shrink the response.", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +}
- Removed
balance_playlist_pairs - Changed
batch_add_to_playlist3 fields changed- added
Input schema / properties / target_laneAdded value: +{ + "description": "Lane name from the lane registry; provide exactly one of target_playlist_id or target_lane", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Target playlist ID, spotify:playlist: URI, or URL"New value: +"Target playlist ID, spotify:playlist: URI, or URL; provide exactly one of target_playlist_id or target_lane" - changed
Input schema / requiredPrevious value: -[ - "target_playlist_id", - "source_uris" -]New value: +[ + "source_uris" +]
- Removed
batch_add_to_queue - Removed
binge_detector_report - Removed
browse_category_deepdive - Removed
canonicalize_spotify_uri - Removed
capture_playback_position - Removed
catalog_batch_lookup - Removed
category_resolver - Removed
chapter_bookmarks - Removed
check_artist_releases - Removed
check_episode_saved - Changed
check_playlist_following2 fields changed- removed
Input schema / properties / playlist_idsRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists.", - "items": { - "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", - "minLength": 1, - "type": "string" - }, - "maxItems": 50, - "minItems": 1, - "type": "array" -} - changed
Input schema / properties / playlists / descriptionPrevious value: -"Canonical ordered playlists (1โ50), or provide the complete documented legacy alias accepted by this tool"New value: +"Canonical ordered playlists (1โ50)"
- Removed
check_saved_items - Removed
checkpoint_playback - Changed
clean_all_playlists3 fields changed- removed
Input schema / properties / include_relinked / defaultRemoved value: -false - changed
Input schema / properties / include_relinked / descriptionPrevious value: -"Also count/collapse same-song entries under different URIs (relinks/remasters)."New value: +"Deprecated alias for `match_by`, kept for one release: true is `name_artist` and false is `uri`. It cannot express the `name` rule, which is why `match_by` replaced it. Sending both, where they mean different rules, is an error rather than a silent choice." - added
Input schema / properties / match_byAdded value: +{ + "description": "Which rule decides that two items are the same: `uri` (exact URI, the default), `name_artist` (case-insensitive name + credited artists, catches relinks/remasters), or `name` (case-insensitive name only). The rule applied is echoed in the result as `match_by`.", + "enum": [ + "uri", + "name_artist", + "name" + ], + "type": "string" +}
- Added
clean_backup_artifacts - Changed
clone_playlist_cover1 field changed- changed
Input schema / properties / image_index / descriptionPrevious value: -"Which cover image to copy (0-based). Default 0"New value: +"Which cover image to copy. Default 0. 0-based index into the playlist's current item order (0 = the first item)."
- Removed
collab_density_report - Removed
collab_mix_from_followed - Removed
compare_devices - Changed
compare_playlist_covers4 fields changed- changed
Input schema / properties / playlist_a / descriptionPrevious value: -"Canonical A playlist; provide with playlist_b or one complete documented legacy pair"New value: +"Canonical A playlist; provide with playlist_b" - changed
Input schema / properties / playlist_b / descriptionPrevious value: -"Canonical B playlist; provide with playlist_a or one complete documented legacy pair"New value: +"Canonical B playlist; provide with playlist_a" - removed
Input schema / properties / playlist_id_aRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b.", - "minLength": 1, - "type": "string" -} - removed
Input schema / properties / playlist_id_bRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b.", - "minLength": 1, - "type": "string" -}
- Removed
continue_last - Removed
daily_pick - Removed
dead_library_finder - Removed
decade_sampler_plan - Removed
dedupe_playlist_apply - Removed
dedupe_playlist_plan - Removed
dedupe_spotify_uris - Removed
deep_cuts_finder - Removed
deep_dive_report - Removed
delete_playback_bookmark - Removed
delete_playlist_snapshot - Removed
describe_listening_session - Removed
describe_queue - Removed
device_health - Removed
device_sync_state - Removed
device_type_census - Removed
diff_playlist_snapshots - Changed
diff_playlists4 fields changed- removed
Input schema / properties / aRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b.", - "minLength": 1, - "type": "string" -} - removed
Input schema / properties / bRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b.", - "minLength": 1, - "type": "string" -} - changed
Input schema / properties / playlist_a / descriptionPrevious value: -"Canonical A playlist; provide with playlist_b or one complete documented legacy pair"New value: +"Canonical A playlist; provide with playlist_b" - changed
Input schema / properties / playlist_b / descriptionPrevious value: -"Canonical B playlist; provide with playlist_a or one complete documented legacy pair"New value: +"Canonical B playlist; provide with playlist_a"
- Removed
diff_since_snapshot - Removed
discover_weekly_diff - Removed
discovery_digest - Removed
discovery_ratio - Removed
duplicate_saved_versions - Removed
episode_bookmark - Removed
episode_context_bundle - Removed
episode_guest_census - Removed
episode_resume - Removed
episode_runtime_report - Removed
era_distribution_report - Removed
era_preference_report - Added
expand_mood_to_queries - Removed
explicit_content_ratio - Removed
export_playlist_json - Removed
export_playlist_markdown - Removed
export_shows_opml - Removed
export_snapshot_bundle - Removed
exposure_check - Removed
extract_playlist_range - Removed
featuring_density_report - Removed
filter_playlist_by_artist - Removed
filter_playlist_by_duration - Removed
filter_playlist_by_era - Removed
find_canonical_track - Removed
find_collaborations - Removed
find_duplicate_playlists - Changed
find_duplicate_tracks_across_playlists2 fields changed- removed
Input schema / properties / playlist_idsRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists.", - "items": { - "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", - "minLength": 1, - "type": "string" - }, - "maxItems": 20, - "minItems": 2, - "type": "array" -} - changed
Input schema / properties / playlists / descriptionPrevious value: -"Canonical ordered playlists (2โ20), or provide the complete documented legacy alias accepted by this tool"New value: +"Canonical ordered playlists (2โ20)"
- Changed
find_duplicates_in_playlist1 field changed- added
Input schema / properties / match_byAdded value: +{ + "description": "Which rule decides that two items are the same: `uri` (exact URI, the default), `name_artist` (case-insensitive name + credited artists, catches relinks/remasters), or `name` (case-insensitive name only). The rule applied is echoed in the result as `match_by`.", + "enum": [ + "uri", + "name_artist", + "name" + ], + "type": "string" +}
- Removed
find_lost_since_snapshot - Removed
find_new_since_snapshot - Removed
find_show_by_publisher - Changed
find_tool2 fields changed- changed
Input schema / properties / response_format / descriptionPrevious value: -"'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object"New value: +"'concise' (default) = prose bullet list; 'detailed' = the same prose; 'json' = the result payload as parseable JSON text, identical to structuredContent" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": {}, + "properties": {}, + "type": "object" +}
- Removed
follow_artists - Added
follow_playlist - Changed
following_analytics1 field changed- changed
Input schema / properties / group_by / descriptionPrevious value: -"Rollup dimension for the report"New value: +"Rollup dimension; popularity/followers report 'unavailable'"
- Removed
forgotten_favorites - Removed
format_spotify_uri - Removed
front_to_back_plan - Removed
genre_dive_search - Removed
genre_trends_over_time - Removed
get_album - Removed
get_album_tracks - Removed
get_artist - Removed
get_artist_albums - Removed
get_artist_appearances - Removed
get_artist_discography - Removed
get_artist_genres - Removed
get_artist_singles - Removed
get_artist_top_tracks - Removed
get_audiobook - Removed
get_audiobook_chapters - Removed
get_available_markets - Removed
get_categories - Removed
get_category - Removed
get_category_playlists - Removed
get_chapter - Removed
get_context_inspect - Removed
get_device_volume_report - Removed
get_episode - Removed
get_episode_details - Removed
get_me - Removed
get_newly_released_episodes - Removed
get_playback_context - Removed
get_playback_snapshot - Changed
get_playlist7 fields changed- added
Input schema / properties / additional_typesAdded value: +{ + "description": "Item types to include beyond the default 'track', e.g. ['track', 'episode']", + "items": { + "enum": [ + "track", + "episode" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / fieldsAdded value: +{ + "description": "Comma-separated list of response fields to keep, e.g. 'total,items(track(name,uri))'", + "type": "string" +} - changed
Input schema / properties / id / descriptionPrevious value: -"Alias for playlist_id"New value: +"Alias for playlist_id, resolved the same way" - added
Input schema / properties / id / minLengthAdded value: +1 - added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code, e.g. 'GB'; relinks tracks to that market and flags unavailable ones", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - changed
Input schema / properties / playlist_id / descriptionPrevious value: -"Playlist ID"New value: +"Playlist ID, spotify:playlist: URI, or open.spotify.com/playlist URL" - added
Input schema / properties / playlist_id / minLengthAdded value: +1
- Removed
get_playlist_followers - Changed
get_queue2 fields changed- added
Input schema / properties / includeAdded value: +{ + "default": [], + "description": "Local analyses over the same single read, no extra request except runtime: runtime = total/avg/longest/shortest, time left on the current track, and a per-item timeline of when each row starts playing; duplicates = repeated rows and the runtime they waste; profile = unique artists/albums/shows, track-vs-episode mix, longest single-artist run.", + "items": { + "enum": [ + "runtime", + "duplicates", + "profile" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / viewAdded value: +{ + "default": "raw", + "description": "'raw' (default) = the queue as returned. 'enriched' = plus the source context (playlist/album name) and total time remaining.", + "enum": [ + "raw", + "enriched" + ], + "type": "string" +}
- Removed
get_queue_snapshot - Removed
get_recently_played - Removed
get_saved_audiobooks - Removed
get_several_albums - Removed
get_several_artists - Removed
get_several_audiobooks - Removed
get_several_chapters - Removed
get_several_episodes - Removed
get_several_shows - Removed
get_several_tracks - Removed
get_show - Removed
get_show_details - Removed
get_show_latest_episode - Removed
get_top_artists - Removed
get_top_tracks - Removed
get_track - Removed
handoff - Changed
inspect_tool2 fields changed- changed
Input schema / properties / response_format / descriptionPrevious value: -"'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object"New value: +"'concise' (default) = prose bullet list; 'detailed' = the same prose; 'json' = the result payload as parseable JSON text, identical to structuredContent" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": {}, + "properties": {}, + "type": "object" +}
- Removed
interleave_playlists_plan - Removed
is_local_census - Removed
jump_to_chapter - Removed
label_discography_explorer - Removed
label_explorer - Removed
last_heard - Removed
library_coverage_report - Removed
library_growth_report - Removed
library_growth_timeline - Removed
library_to_playlist - Removed
library_value_summary - Added
list_accounts - Removed
list_all_chapters - Removed
list_device_presets - Removed
list_playback_bookmarks - Removed
list_playback_states - Removed
list_playlist_snapshots - Removed
list_saved_shows - Removed
list_saved_snapshots - Removed
list_sessions - Removed
list_show_episodes - Removed
listening_clock - Removed
listening_clock_heatmap - Removed
listening_consistency_score - Removed
listening_eras - Removed
listening_gaps_report - Removed
listening_heatmap - Removed
listening_history_export - Removed
listening_journal_append - Removed
listening_recap_brief - Removed
listening_report - Removed
listening_session_close - Removed
listening_session_report - Removed
listening_session_start - Removed
listening_sessions - Removed
listening_streak_report - Removed
listening_streaks - Removed
listening_week_in_time - Removed
longest_saved_tracks - Removed
lyric_snippet_search - Removed
mark_episode_played_plan - Removed
market_availability - Removed
market_validate - Changed
merge_playlists2 fields changed- changed
Input schema / properties / playlists / descriptionPrevious value: -"Canonical ordered playlists (1โ10), or provide the complete documented legacy alias accepted by this tool"New value: +"Canonical ordered playlists (1โ10)" - removed
Input schema / properties / sourcesRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists.", - "items": { - "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", - "minLength": 1, - "type": "string" - }, - "maxItems": 10, - "minItems": 1, - "type": "array" -}
- Removed
merge_playlists_plan - Removed
merge_snapshot_changes_plan - Removed
monthly_listening_report - Removed
mood_bucket_report - Removed
morning_briefing - Removed
most_replayed - Changed
move_items_between_playlists5 fields changed- added
Input schema / properties / source_laneAdded value: +{ + "description": "Lane name resolving to the source playlist; provide exactly one of source_playlist_id or source_lane", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / source_playlist_id / descriptionPrevious value: -"Source playlist ID, spotify:playlist: URI, or URL"New value: +"Source playlist ID, spotify:playlist: URI, or URL; provide exactly one of source_playlist_id or source_lane" - added
Input schema / properties / target_laneAdded value: +{ + "description": "Lane name resolving to the target playlist; provide exactly one of target_playlist_id or target_lane", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Target playlist ID, spotify:playlist: URI, or URL"New value: +"Target playlist ID, spotify:playlist: URI, or URL; provide exactly one of target_playlist_id or target_lane" - removed
Input schema / requiredRemoved value: -[ - "source_playlist_id", - "target_playlist_id" -]
- Removed
move_tracks_between_playlists - Removed
mutation_log_export - Removed
mute - Removed
never_played_saved - Removed
new_music_from_saved_artists - Removed
new_music_from_top_artists - Removed
now_playing_history - Removed
orphaned_artist_check - Changed
overlap_playlists1 field changed- changed
Input schema / properties / playlists / descriptionPrevious value: -"Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool"New value: +"Canonical ordered playlists (2โ10)"
- Removed
parse_spotify_uri - Removed
parse_spotify_uris - Changed
pause2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
pause_everywhere - Removed
peek_next - Changed
pin_playlist1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": {}, + "properties": { + "cancelled": { + "type": "boolean" + }, + "dry_run": { + "type": "boolean" + }, + "ok": { + "type": "boolean" + }, + "receipt": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" +}
- Changed
plan_podcast_session1 field changed- added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code for the saved-show episode lookups, e.g. \"US\". Defaults to SPOTIFY_MCP_MARKET, then to the account country โ these lookups are market-gated, so a wrong default silently drops episode rows. Ignored for a saved-episodes-only plan.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +}
- Removed
plan_volume_level_across_devices - Changed
play2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
play_at - Changed
play_from_search2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
play_on - Removed
playback_compare_states - Removed
playback_health_check - Removed
playback_timeline - Removed
playback_timer_status - Removed
playlist_add_by_search - Removed
playlist_artist_heat - Removed
playlist_balance - Removed
playlist_changelog - Removed
playlist_chunk_preview - Removed
playlist_clone_live - Removed
playlist_clone_snapshot - Removed
playlist_collaboration_report - Removed
playlist_cover_from_track - Removed
playlist_dedupe_advanced - Removed
playlist_diff - Removed
playlist_difference_plan - Removed
playlist_edit_journal - Removed
playlist_era_profile - Removed
playlist_exclude_artists - Removed
playlist_expression_algebra - Removed
playlist_fill_from_search - Removed
playlist_filter_runtime - Removed
playlist_flip_order - Removed
playlist_from_tags - Removed
playlist_health_check - Removed
playlist_history - Removed
playlist_intersect - Removed
playlist_intersection - Removed
playlist_keep_artist - Removed
playlist_keep_only - Removed
playlist_move_block - Removed
playlist_move_to_top - Removed
playlist_names_bulk_normalize - Removed
playlist_overlap_matrix - Removed
playlist_pair_check - Removed
playlist_remove_artist - Removed
playlist_resequence - Removed
playlist_rotate - Removed
playlist_seed_shuffle - Removed
playlist_slice - Removed
playlist_snapshot_detail - Removed
playlist_staleness_report - Removed
playlist_staleness_score - Removed
playlist_strip_episodes - Changed
playlist_subtract4 fields changed- changed
Input schema / properties / base_playlist_id / descriptionPrevious value: -"Base playlist ID, URI, or URL. Optional only for the deprecated positional form, where playlists[0] is the base."New value: +"Base playlist ID, URI, or URL. Required; list only the subtraction sources in playlists." - changed
Input schema / properties / playlists / descriptionPrevious value: -"Canonical ordered playlists (1โ10), or provide the complete documented legacy alias accepted by this tool"New value: +"Canonical ordered playlists (1โ10)" - removed
Input schema / properties / subtract_playlist_idsRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists.", - "items": { - "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", - "minLength": 1, - "type": "string" - }, - "maxItems": 10, - "minItems": 1, - "type": "array" -} - added
Input schema / requiredAdded value: +[ + "base_playlist_id" +]
- Removed
playlist_swap_positions - Changed
playlist_symmetric_difference4 fields changed- changed
Input schema / properties / playlist_a / descriptionPrevious value: -"Canonical A playlist; provide with playlist_b or one complete documented legacy pair"New value: +"Canonical A playlist; provide with playlist_b" - changed
Input schema / properties / playlist_b / descriptionPrevious value: -"Canonical B playlist; provide with playlist_a or one complete documented legacy pair"New value: +"Canonical B playlist; provide with playlist_a" - removed
Input schema / properties / playlist_id_aRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b.", - "minLength": 1, - "type": "string" -} - removed
Input schema / properties / playlist_id_bRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b.", - "minLength": 1, - "type": "string" -}
- Removed
playlist_table_of_contents - Removed
playlist_trim_to_duration - Changed
playlist_union2 fields changed- changed
Input schema / properties / playlists / descriptionPrevious value: -"Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool"New value: +"Canonical ordered playlists (2โ10)" - removed
Input schema / properties / source_playlist_idsRemoved value: -{ - "description": "Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists.", - "items": { - "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", - "minLength": 1, - "type": "string" - }, - "maxItems": 10, - "minItems": 2, - "type": "array" -}
- Removed
playlist_union_preview - Removed
predict_next_tracks - Removed
prune_old_snapshots - Removed
publisher_portfolio - Removed
queue_duplicate_check - Removed
queue_next - Removed
queue_next_episode - Removed
queue_playlist - Removed
queue_profile - Removed
queue_prune_plan - Removed
queue_replace_via_playlist - Removed
queue_runtime_report - Removed
quick_save_now - Removed
quota_probe - Removed
read_playlist_snapshot - Removed
receipt_lookup - Removed
record_feedback - Removed
refresh_smart_playlist - Changed
remove_duplicate_playlist_items3 fields changed- removed
Input schema / properties / include_relinked / defaultRemoved value: -false - changed
Input schema / properties / include_relinked / descriptionPrevious value: -"Also collapse same-song duplicates under different URIs (relinks/remasters). Default false โ only exact URI repeats are removed."New value: +"Deprecated alias for `match_by`, kept for one release: true is `name_artist` and false is `uri`. It cannot express the `name` rule, which is why `match_by` replaced it. Sending both, where they mean different rules, is an error rather than a silent choice." - added
Input schema / properties / match_byAdded value: +{ + "description": "Which rule decides that two items are the same: `uri` (exact URI, the default), `name_artist` (case-insensitive name + credited artists, catches relinks/remasters), or `name` (case-insensitive name only). The rule applied is echoed in the result as `match_by`.", + "enum": [ + "uri", + "name_artist", + "name" + ], + "type": "string" +}
- Changed
remove_from_library2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +true - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: show exactly which URIs would be removed without calling the API"New value: +"Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit."
- Changed
remove_from_library_by_playlist2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +true - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit."
- Changed
remove_from_playlist1 field changed- changed
Input schema / properties / uris / items / anyOfPrevious value: -[ - { - "type": "string" - }, - { - "properties": { - "positions": { - "items": { - "maximum": 9007199254740991, - "minimum": 0, - "type": "integer" - }, - "minItems": 1, - "type": "array" - }, - "uri": { - "type": "string" - } - }, - "required": [ - "uri", - "positions" - ], - "type": "object" - } -]New value: +[ + { + "type": "string" + }, + { + "properties": { + "positions": { + "description": "0-based index into the playlist's current item order (0 = the first item).", + "items": { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "minItems": 1, + "type": "array" + }, + "uri": { + "type": "string" + } + }, + "required": [ + "uri", + "positions" + ], + "type": "object" + } +]
- Removed
remove_playlist_range - Removed
remove_saved_episode - Removed
remove_saved_items - Removed
remove_saved_shows - Removed
remove_unavailable_playlist_items - Removed
rename_device - Changed
reorder_playlist_items2 fields changed- changed
Input schema / properties / insert_before / descriptionPrevious value: -"Index to insert the range before"New value: +"Index to insert the range before. 0-based index into the playlist's current item order (0 = the first item)." - changed
Input schema / properties / range_start / descriptionPrevious value: -"Index of the first item to move"New value: +"Index of the first item to move. 0-based index into the playlist's current item order (0 = the first item)."
- Removed
repeat_listener_report - Removed
repeat_queue_toggle - Removed
replay_session - Removed
resolve_artist - Removed
restore_playback_state - Removed
restore_playlist_from_snapshot - Removed
restore_playlist_plan - Removed
resume_playback_position - Removed
reverse_playlist_plan - Removed
room_level - Removed
rotate_playlist_plan - Removed
sample_playlist_tracks - Removed
save_artist_new_releases - Removed
save_episode - Removed
save_items - Removed
save_playback_state - Removed
save_queue_as_playlist - Removed
save_show_digest - Removed
save_smart_playlist_rule - Changed
save_to_library2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +true - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit."
- Removed
saved_albums_by_decade - Removed
saved_albums_by_label - Removed
saved_albums_by_type - Removed
saved_albums_by_year - Removed
saved_library_delta - Removed
saved_runtime_by_era - Removed
saved_shows_publisher_census - Removed
saved_track_age_report - Removed
saved_tracks_by_artist - Removed
saved_tracks_roulette - Removed
saved_vs_playlist_coverage - Removed
scene_sampler_search - Changed
schedule_wind_down2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
scope_audit - Removed
search_advanced - Removed
search_albums - Removed
search_artists - Removed
search_audiobooks - Removed
search_by_isrc - Removed
search_episodes - Removed
search_fresh - Removed
search_history - Removed
search_market_diff - Removed
search_playlists - Removed
search_rerun - Changed
search_saved_shows1 field changed- changed
Input schema / properties / query / descriptionPrevious value: -"Substring match against show name/publisher"New value: +"Substring match against show name and publisher. Spotify removed `publisher` from show payloads in February 2026, so the publisher half can only match on an app registration created before November 2024; on a current registration this is a name search that reports 0 publisher matches rather than pretending to have searched publishers."
- Removed
search_shows - Removed
search_tracks - Changed
search_within_playlist6 fields changed- added
Input schema / properties / idAdded value: +{ + "description": "Alias for playlist_id, matching get_playlist_items", + "type": "string" +} - added
Input schema / properties / kindAdded value: +{ + "default": "any", + "description": "Item kinds to match: 'track', 'episode', or 'any' (default โ both). Mixed playlists hold both row shapes", + "enum": [ + "track", + "episode", + "any" + ], + "type": "string" +} - changed
Input schema / properties / playlist_id / descriptionPrevious value: -"Playlist ID"New value: +"Playlist ID (or pass it as 'id')" - removed
Input schema / properties / playlist_id / minLengthRemoved value: -1 - changed
Input schema / properties / query / descriptionPrevious value: -"Substring to match against track/episode name, artist, album"New value: +"Substring to match against track/episode name, artist, album, show name" - changed
Input schema / requiredPrevious value: -[ - "playlist_id", - "query" -]New value: +[ + "query" +]
- Changed
seek2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
seek_relative - Removed
session_length_report - Removed
session_stats - Removed
set_device_volume_preset - Changed
set_repeat2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Changed
set_shuffle2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Changed
set_volume10 fields changed- added
Input schema / properties / all_devicesAdded value: +{ + "description": "For op \"level\" with volume_percent: set every volume-capable device, not a named selection.", + "type": "boolean" +} - added
Input schema / properties / delta_stepAdded value: +{ + "description": "Signed nudge, e.g. +10 or -10, clamped to 0โ100. Mutually exclusive with volume_percent.", + "maximum": 100, + "minimum": -100, + "type": "integer" +} - changed
Input schema / properties / device_id / descriptionPrevious value: -"Target device ID"New value: +"Device ID for a single-device write (default: the active device)" - added
Input schema / properties / device_idsAdded value: +{ + "description": "For op \"level\" with volume_percent: fan out to these device ids or names. Mutually exclusive with all_devices.", + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview." - added
Input schema / properties / exclude_device_idAdded value: +{ + "description": "For op \"level\" with no volume_percent: leave this device untouched while levelling the rest", + "type": "string" +} - added
Input schema / properties / opAdded value: +{ + "description": "Variant: \"level\" (default) set or copy a level, \"mute\", \"unmute\", \"preset\"", + "enum": [ + "level", + "mute", + "unmute", + "preset" + ], + "type": "string" +} - changed
Input schema / properties / volume_percent / descriptionPrevious value: -"Volume level 0โ100"New value: +"Absolute level 0โ100. Mutually exclusive with delta_step." - removed
Input schema / requiredRemoved value: -[ - "volume_percent" -]
- Removed
shortest_saved_tracks - Removed
show_activity_feed - Removed
show_backlog_plan - Removed
show_backlog_report - Removed
show_episode_search - Removed
show_episode_timeline - Changed
show_new_episodes1 field changed- added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code for the per-show episode lookups, e.g. \"US\". Defaults to SPOTIFY_MCP_MARKET, then to the account country โ these lookups are market-gated, so a wrong default silently drops episode rows.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +}
- Removed
show_recommendation_brief - Removed
show_runtime_stats - Removed
shows_release_calendar - Removed
shows_without_new_episodes - Removed
shuffle_state_report - Removed
sidecar_export_bundle - Removed
skip_n - Changed
skip_next2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Changed
skip_previous2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview."
- Removed
sleep_timer - Removed
sleep_timer_plan - Removed
snapshot_added_at_report - Removed
snapshot_changelog - Removed
snapshot_diff_summary - Removed
snapshot_disk_usage - Removed
snapshot_integrity_check - Removed
snapshot_integrity_report - Removed
snapshot_new_tracks - Removed
snapshot_playlist - Removed
snapshot_registry_report - Removed
snapshot_removed_tracks - Removed
snapshot_retention_plan - Removed
snapshot_stats_report - Removed
sort_playlist_apply - Removed
sort_playlist_plan - Removed
split_playlist_by_count - Removed
split_playlist_by_duration - Removed
split_queue_plan - Changed
spotify_doctor1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": {}, + "properties": {}, + "type": "object" +}
- Removed
spotify_uri_stats - Removed
stale_saved_shows_plan - Changed
start_podcast_session1 field changed- added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code for the saved-show episode lookups, e.g. \"US\". Defaults to SPOTIFY_MCP_MARKET, then to the account country โ these lookups are market-gated, so a wrong default silently drops episode rows. Ignored for a saved-episodes-only plan.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +}
- Removed
statsfm_album_date_stats - Removed
statsfm_album_stats - Removed
statsfm_artist_affinity - Removed
statsfm_artist_date_stats - Removed
statsfm_artist_stats - Removed
statsfm_catalog_album - Removed
statsfm_catalog_artist - Removed
statsfm_catalog_track - Removed
statsfm_charts_albums - Removed
statsfm_charts_artists - Removed
statsfm_charts_tracks - Removed
statsfm_charts_users - Removed
statsfm_exposure_check - Removed
statsfm_forgotten_favorites - Removed
statsfm_friend_count - Removed
statsfm_friends - Removed
statsfm_genre_artists - Removed
statsfm_listening_eras - Removed
statsfm_listening_sessions - Removed
statsfm_now_playing - Removed
statsfm_recaps - Removed
statsfm_recent_streams - Removed
statsfm_record_feedback - Removed
statsfm_records_artists - Removed
statsfm_resolve_user - Removed
statsfm_search - Removed
statsfm_streams_stats - Removed
statsfm_taste_profile - Removed
statsfm_taste_recommendations - Removed
statsfm_top_albums - Removed
statsfm_top_albums_from_artist - Removed
statsfm_top_artists - Removed
statsfm_top_genres - Removed
statsfm_top_tracks - Removed
statsfm_top_tracks_from_album - Removed
statsfm_top_tracks_from_artist - Removed
statsfm_track_date_stats - Removed
statsfm_track_stats - Removed
subscribe_to_show - Removed
surprise_me - Added
switch_account - Removed
switch_device - Removed
tag_listening_session - Removed
take_playlist_snapshot - Removed
taste_checkpoint - Removed
taste_checkpoint_diff - Removed
taste_daily_brief - Removed
taste_diamond_rotation - Removed
taste_era_playlist - Removed
taste_forgotten_bangers - Removed
taste_genre_bridge - Removed
taste_listening_clock - Removed
taste_novelty_loyalty - Removed
taste_obsession_ladder - Removed
taste_profile - Removed
taste_recommendations - Removed
taste_revival_queue - Removed
taste_shift_report - Removed
taste_to_playlist - Removed
taste_weekly_recap - Removed
title_length_outliers - Changed
toolset_report2 fields changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' (default) = prose bullet list; 'detailed' = the same prose; 'json' = the result payload as parseable JSON text, identical to structuredContent", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": {}, + "properties": {}, + "type": "object" +}
- Removed
top_artist_leaderboard - Removed
top_artist_ranking_delta - Removed
top_artists_by_range - Removed
top_genre_census - Removed
top_track_leaderboard - Removed
top_track_ranking_delta - Removed
track_album_bundle - Removed
track_enrichment_batch - Removed
track_release_origin - Removed
track_rotation_report - Changed
transfer_playback9 fields changed- added
Input schema / properties / deviceAdded value: +{ + "description": "Target device: exact id, sidecar label, or case-insensitive name substring", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / device_id / descriptionPrevious value: -"Target device ID to transfer playback to"New value: +"DEPRECATED: use `device`" - added
Input schema / properties / dry_run / defaultAdded value: +false - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: describe what would change without performing it. Default false โ pass true to preview." - changed
Input schema / properties / play / descriptionPrevious value: -"Force play immediately (default: maintain current state)"New value: +"Force play (true) or arrive paused (false); omit to preserve the current play state. With preserve_position, true also resumes a session that is currently paused." - added
Input schema / properties / preserve_positionAdded value: +{ + "description": "Resume the current track at its current position on the target instead of restarting it (default: false)", + "type": "boolean" +} - added
Input schema / properties / restore_shuffle_repeatAdded value: +{ + "description": "Re-apply the current shuffle and repeat modes on the target (default: false)", + "type": "boolean" +} - added
Input schema / properties / volumeAdded value: +{ + "description": "Volume to set on the target after transfer, 0โ100", + "maximum": 100, + "minimum": 0, + "type": "integer" +} - changed
Input schema / requiredPrevious value: -[ - "device_id" -]New value: +[ + "device" +]
- Removed
transfer_playback_with_state - Removed
undo_preview - Removed
unfollow_artists - Added
unfollow_playlist - Removed
unmute - Changed
unpin_playlist1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "additionalProperties": {}, + "properties": { + "cancelled": { + "type": "boolean" + }, + "dry_run": { + "type": "boolean" + }, + "ok": { + "type": "boolean" + }, + "receipt": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" +}
- Removed
unplayable_saved_check - Changed
unsave_orphan_tracks2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +true - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only: perform the read side and return a PLAN without changing anything. Default true โ pass dry_run=false to commit."
- Removed
unsubscribe_from_show - Changed
verify_receipt3 fields changed- changed
Input schema / properties / receipt_id / descriptionPrevious value: -"Receipt ID from a receipt-bearing mutation result"New value: +"Receipt ID copied verbatim from a receipt-bearing mutation result (rcpt_<bootId>-<n>)" - removed
Input schema / properties / receipt_id / minLengthRemoved value: -1 - added
Input schema / properties / receipt_id / patternAdded value: +"^rcpt_(?:[0-9a-z]+-)?\\d+$"
- Removed
volume_ramp - Removed
volume_report - Removed
volume_step - Removed
watch_artists - Removed
week_in_review_playlist - Removed
weekday_heatmap - Removed
weekday_listening_report - Removed
weekly_rotation_report - Changed
whats_new2 fields changed- changed
Input schema / properties / max_artists / descriptionPrevious value: -"Per-call budget for artist album lookups (and show episode lookups). Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET). Walk caps at this budget and reports truncation. Independent of SPOTIFY_MCP_FETCH_ALL_CAP. WARNING: each lookup is an API request."New value: +"Per-call budget for artist album lookups (and show episode lookups). Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET). Walk caps at this budget and reports truncation. Independent of SPOTIFY_MCP_FETCH_ALL_CAP. WARNING: each lookup costs a request unless the read cache already holds that artist's canonical release probe (#900)." - changed
Input schema / properties / since / descriptionPrevious value: -"Only include releases on/after this date (YYYY-MM-DD), or 'last-check' to resume from the stored watermark file (default path ~/.spotify-mcp/freshness.json)"New value: +"Only include releases on/after this date (YYYY-MM-DD), or 'last-check' to resume from the stored per-kind watermark file (default path ~/.spotify-mcp/freshness.json). Tracked per kind, so a call scoped to one kind never moves the other kind's mark. An explicit date never writes this file; 'last-check' and a days_back window do."
- Removed
where_was_i - Removed
year_explorer - Removed
year_in_review
88 tool updates
v2.1.2- Changed
album_focus_report2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
album_representative_plan2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
album_track_stats2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
albums_runtime_batch2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
artist_collab_network3 fields changed- added
Input schema / properties / include_track_featuresAdded value: +{ + "description": "Opt in: also read track-level credits (1 extra GET /albums/{id}/tracks per album, up to 10 albums) so featured-artist collaborations are counted. Default: false. Albums whose credits could not be read are listed as unreadable with the reason, never counted as zero collaborators.", + "type": "boolean" +} - changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
artist_discography_timeline1 field changed- changed
Input schema / properties / max_results / descriptionPrevious value: -"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"New value: +"Max rows to return (default: SPOTIFY_MCP_FETCH_ALL_CAP or 500)"
- Changed
artist_name_disambiguator2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
artist_release_digest1 field changed- changed
Input schema / properties / max_artists / descriptionPrevious value: -"Per-call budget for artist lookups. Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET)."New value: +"Per-call artist lookup budget. Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET)."
- Changed
audiobook_chapter_map1 field changed- changed
Input schema / properties / max_results / descriptionPrevious value: -"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"New value: +"Max rows to return (default: SPOTIFY_MCP_FETCH_ALL_CAP or 500)"
- Changed
audiobooks_by_author2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
browse_category_deepdive1 field changed- changed
Input schema / properties / category_id / descriptionPrevious value: -"Category ID from get_categories"New value: +"Category ID"
- Changed
check_artist_releases1 field changed- changed
Input schema / properties / max_artists / descriptionPrevious value: -"Per-call budget for artist lookups. Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET). Truncates to max_artists and reports watchlist_size / artists_scanned / truncated."New value: +"Per-call artist lookup budget. Default: 25 (or SPOTIFY_MCP_FRESHNESS_BUDGET). Reports watchlist_size / artists_scanned / truncated."
- Changed
check_following_artists2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify artist IDs to check"New value: +"Artist IDs, spotify:artist: URIs, or artist URLs; CSV accepted" - added
Input schema / properties / ids / items / minLengthAdded value: +1
- Changed
deep_cuts_finder1 field changed- added
Input schema / properties / max_singlesAdded value: +{ + "description": "Singles to scan for the exclusion set, newest first. Default: the fetch-all cap, clamped to it.", + "exclusiveMinimum": 0, + "maximum": 1000, + "type": "integer" +}
- Added
delete_backup - Changed
discovery_digest2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
episode_context_bundle2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
export_all_playlists1 field changed- changed
Input schema / properties / output_dir / descriptionPrevious value: -"Local directory (default: ~/.spotify-mcp/portability)"New value: +"Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it)"
- Changed
export_followed_artists1 field changed- changed
Input schema / properties / output_dir / descriptionPrevious value: -"Local directory to write files into (default: ~/.spotify-mcp/portability)"New value: +"Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it)"
- Changed
export_library_json1 field changed- changed
Input schema / properties / output_dir / descriptionPrevious value: -"Local directory to write files into (default: ~/.spotify-mcp/portability)"New value: +"Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it)"
- Changed
export_listening_history1 field changed- changed
Input schema / properties / output_dir / descriptionPrevious value: -"Local directory to write files into (default: ~/.spotify-mcp/portability)"New value: +"Local directory to write into, confined to the output root (default ~/.spotify-mcp/portability, set SPOTIFY_MCP_PORTABILITY_DIR to move it)"
- Changed
export_playlist2 fields changed- changed
Input schema / properties / output_path / descriptionPrevious value: -"Write the full document to this local file instead of returning it inline"New value: +"Write the full document to this local file (relative paths resolve inside the output root, default ~/.spotify-mcp/exports) instead of returning it inline" - added
Input schema / properties / overwriteAdded value: +{ + "default": false, + "description": "Allow replacing an existing file at output_path (refused by default)", + "type": "boolean" +}
- Changed
export_profile_state1 field changed- changed
Input schema / properties / output_dir / descriptionPrevious value: -"Directory to write the archive into (default: ~/.spotify-mcp/exports)"New value: +"Directory to write the archive into, confined to the output root (default ~/.spotify-mcp/exports, set SPOTIFY_MCP_EXPORT_DIR to move it)"
- Changed
find_canonical_track2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
find_collaborations2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
find_show_by_publisher2 fields changed- added
Input schema / properties / limitAdded value: +{ + "description": "Catalogue rows fetched per request, 1-10 (Feb-2026 /search cap). Default 10", + "maximum": 10, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Catalogue rows to skip before the page (Spotify /search max offset 1000). Default 0", + "maximum": 1000, + "minimum": 0, + "type": "integer" +}
- Changed
follow_artists2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify artist IDs to follow"New value: +"Artist IDs, spotify:artist: URIs, or artist URLs; CSV accepted" - added
Input schema / properties / ids / items / minLengthAdded value: +1
- Changed
front_to_back_plan2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
genre_dive_search2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_album3 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify album ID"New value: +"Spotify album ID, spotify:album: URI, or open.spotify.com/album URL" - added
Input schema / properties / id / minLengthAdded value: +1 - changed
Input schema / properties / market / descriptionPrevious value: -"ISO country code; defaults to account country."New value: +"ISO country code; defaults to SPOTIFY_MCP_MARKET."
- Changed
get_album_tracks3 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify album ID"New value: +"Spotify album ID, spotify:album: URI, or open.spotify.com/album URL" - added
Input schema / properties / id / minLengthAdded value: +1 - changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code. Defaults to the account country; affects track availability."New value: +"ISO 3166-1 alpha-2 country code. Defaults to SPOTIFY_MCP_MARKET; affects track availability."
- Changed
get_artist2 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify artist ID"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / id / minLengthAdded value: +1
- Changed
get_artist_albums3 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify artist ID"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / id / minLengthAdded value: +1 - changed
Input schema / properties / market / descriptionPrevious value: -"ISO country code; defaults to account country."New value: +"ISO country code; defaults to SPOTIFY_MCP_MARKET."
- Changed
get_artist_appearances2 fields changed- changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify artist ID"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / artist_id / minLengthAdded value: +1
- Changed
get_artist_singles2 fields changed- changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify artist ID"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / artist_id / minLengthAdded value: +1
- Changed
get_artist_top_tracks3 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify artist ID"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / id / minLengthAdded value: +1 - changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, e.g. 'US' โ defaults to the account country"New value: +"ISO 3166-1 alpha-2 code, e.g. 'US' โ defaults to SPOTIFY_MCP_MARKET"
- Changed
get_audiobook_chapters1 field changed- added
Input schema / properties / fetch_allAdded value: +{ + "description": "When true, walk every chapter page up to the fetch-all cap (SPOTIFY_MCP_FETCH_ALL_CAP) instead of returning one page. Default: false", + "type": "boolean" +}
- Changed
get_categories1 field changed- changed
Input schema / properties / market / descriptionPrevious value: -"Canonical ISO 3166-1 alpha-2 market code, e.g. 'US'; forwarded to Spotify as market."New value: +"Canonical ISO 3166-1 alpha-2 market code, e.g. 'US'; sent as country."
- Changed
get_category1 field changed- changed
Input schema / properties / category_id / descriptionPrevious value: -"Category ID from get_categories"New value: +"Category ID"
- Changed
get_category_playlists2 fields changed- changed
Input schema / properties / category_id / descriptionPrevious value: -"Category ID (from get_categories)"New value: +"Category ID" - changed
Input schema / properties / market / descriptionPrevious value: -"Canonical ISO 3166-1 alpha-2 market code, e.g. 'US'; forwarded to Spotify as market."New value: +"Canonical ISO 3166-1 alpha-2 market code, e.g. 'US'; sent as country."
- Changed
get_currently_playing1 field changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to the account market"New value: +"ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to SPOTIFY_MCP_MARKET"
- Changed
get_episode2 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify episode ID"New value: +"Spotify episode ID, spotify:episode: URI, or open.spotify.com/episode URL" - added
Input schema / properties / id / minLengthAdded value: +1
- Changed
get_followed_artists1 field changed- added
Input schema / properties / fetch_allAdded value: +{ + "description": "Walk every page instead of one page (ignores limit)", + "type": "boolean" +}
- Changed
get_now_playing1 field changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to the account market"New value: +"ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to SPOTIFY_MCP_MARKET"
- Changed
get_several_albums2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify albums IDs (1โ20 per request; longer lists are fetched in chunks of 20 and merged)"New value: +"Spotify album IDs, spotify:album: URIs, or open.spotify.com/album URLs (1โ20 per request; longer lists are fetched in chunks of 20 and merged)" - added
Input schema / properties / ids / items / descriptionAdded value: +"Spotify album ID, spotify:album: URI, or open.spotify.com/album URL"
- Changed
get_several_artists2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify artists IDs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)"New value: +"Spotify artist IDs, spotify:artist: URIs, or open.spotify.com/artist URLs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)" - added
Input schema / properties / ids / items / descriptionAdded value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
get_several_audiobooks2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify audiobooks IDs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)"New value: +"Spotify audiobook IDs, spotify:audiobook: URIs, or open.spotify.com/audiobook URLs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)" - added
Input schema / properties / ids / items / descriptionAdded value: +"Spotify audiobook ID, spotify:audiobook: URI, or open.spotify.com/audiobook URL"
- Changed
get_several_episodes2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify episodes IDs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)"New value: +"Spotify episode IDs, spotify:episode: URIs, or open.spotify.com/episode URLs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)" - added
Input schema / properties / ids / items / descriptionAdded value: +"Spotify episode ID, spotify:episode: URI, or open.spotify.com/episode URL"
- Changed
get_several_shows2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify shows IDs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)"New value: +"Spotify show IDs, spotify:show: URIs, or open.spotify.com/show URLs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)" - added
Input schema / properties / ids / items / descriptionAdded value: +"Spotify show ID, spotify:show: URI, or open.spotify.com/show URL"
- Changed
get_several_tracks2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify tracks IDs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)"New value: +"Spotify track IDs, spotify:track: URIs, or open.spotify.com/track URLs (1โ50 per request; longer lists are fetched in chunks of 50 and merged)" - added
Input schema / properties / ids / items / descriptionAdded value: +"Spotify track ID, spotify:track: URI, or open.spotify.com/track URL"
- Changed
get_show2 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify show ID"New value: +"Spotify show ID, spotify:show: URI, or open.spotify.com/show URL" - added
Input schema / properties / id / minLengthAdded value: +1
- Changed
get_track2 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Spotify track ID"New value: +"Spotify track ID, spotify:track: URI, or open.spotify.com/track URL" - added
Input schema / properties / id / minLengthAdded value: +1
- Changed
get_user_playlists_by_id1 field changed- changed
Input schema / properties / user_id / descriptionPrevious value: -"Spotify user ID"New value: +"Spotify user ID, spotify:user: URI, or open.spotify.com/user URL"
- Changed
get_user_profile1 field changed- changed
Input schema / properties / user_id / descriptionPrevious value: -"Spotify user ID"New value: +"Spotify user ID, spotify:user: URI, or open.spotify.com/user URL"
- Changed
handoff1 field changed- added
Input schema / properties / playAdded value: +{ + "description": "Resume playback on the target even if the session is currently paused (default: preserve the current play state)", + "type": "boolean" +}
- Changed
history_search2 fields changed- changed
Input schema / properties / query / descriptionPrevious value: -"Substring to match (default: all)"New value: +"Substring to match" - added
Input schema / properties / scopeAdded value: +{ + "default": "all", + "description": "Scope", + "enum": [ + "portability", + "backups", + "history", + "all" + ], + "type": "string" +}
- Changed
import_from_sidecar1 field changed- changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only when true"New value: +"Preview only, making no API calls at all. Writes happen only when explicitly set to false."
- Changed
import_profile_state2 fields changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - changed
Input schema / properties / mode / descriptionPrevious value: -"merge = add to existing stores; overwrite = replace them"New value: +"merge = union on each store's own keys; overwrite = replace, keeping a .bak"
- Changed
library_hygiene1 field changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview cost only.", + "type": "boolean" +}
- Changed
listening_heatmap1 field changed- added
Input schema / properties / timezoneAdded value: +{ + "description": "IANA time zone for the day/hour slots, e.g. Asia/Tokyo (default SPOTIFY_MCP_TIMEZONE, else UTC). Never the host time zone.", + "type": "string" +}
- Changed
lyric_snippet_search2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
pin_playlist2 fields changed- added
Input schema / properties / dry_runAdded value: +{ + "default": true, + "description": "Preview only (default): pass dry_run: false to execute the follow.", + "type": "boolean" +} - changed
Input schema / properties / public / descriptionPrevious value: -"Whether the follow should be public (Spotify default: true)"New value: +"Must be true or omitted; the library endpoint has no visibility parameter."
- Changed
play_from_search1 field changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code โ affects availability/relinking of results; defaults to the account market"New value: +"ISO 3166-1 alpha-2 country code โ affects availability/relinking of results; defaults to SPOTIFY_MCP_MARKET"
- Changed
playlist_era_profile1 field changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market, e.g. 'US' โ when given, items are REFETCHED with this market so album release dates resolve (disclosed second GET)"New value: +"ISO 3166-1 alpha-2 market, e.g. 'US' โ when given, items are REFETCHED with this market and the profile is computed from THOSE rows, so album release dates resolve (disclosed second GET)"
- Changed
playlist_sort1 field changed- changed
Input schema / properties / sort_by / enumPrevious value: -[ - "added_asc", - "added_desc", - "name_asc", - "name_desc", - "artist_asc", - "duration_asc", - "duration_desc", - "popularity_desc" -]New value: +[ + "added_asc", + "added_desc", + "name_asc", + "name_desc", + "artist_asc", + "duration_asc", + "duration_desc" +]
- Changed
receipt_lookup2 fields changed- changed
Input schema / properties / id / descriptionPrevious value: -"Exact receipt id (rcpt_N)"New value: +"Exact receipt id (rcpt_โฆ-N)" - changed
Input schema / properties / since / descriptionPrevious value: -"Only receipts issued... they carry no wall-clock; use id/uri filters mostly"New value: +"Only receipts issued at/after this date; receipts with no recorded issue time are always included"
- Changed
refresh_smart_playlist1 field changed- changed
Input schema / properties / playlist_id / descriptionPrevious value: -"Existing playlist id to refresh (else creates new)"New value: +"Playlist id to rebuild in place. Defaults to the id recorded by the previous refresh; otherwise the playlist is created."
- Changed
restore_library_snapshot1 field changed- changed
Input schema / properties / backup_path / descriptionPrevious value: -"Path to the snapshot JSON file from backup_library_snapshot"New value: +"Snapshot JSON path from backup_library (see list_backups)"
- Changed
save_smart_playlist_rule1 field changed- changed
Input schema / properties / rule / descriptionPrevious value: -"Rule object (source, filters, limit, etc.)"New value: +"Rule object: { source: top_tracks|recently_played|saved_tracks, time_range: short_term|medium_term|long_term, limit (1-500), artist_filter: string[], unique_artists: bool, scan_cap, description, public } โ defaults as create_smart_playlist, unknown keys ignored. A refresh records playlist_id/last_refreshed here."
- Changed
scene_sampler_search2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_advanced2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_by_isrc2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_deep1 field changed- added
Input schema / properties / offsetAdded value: +{ + "description": "Index of the first result to walk per type, 0โ1000. The next_offset a call reports is the offset to pass here to continue. Default: 0", + "maximum": 1000, + "minimum": 0, + "type": "integer" +}
- Changed
search_fresh2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_market_diff2 fields changed- changed
Input schema / properties / types / descriptionPrevious value: -"Types to search (up to 2). Default: ['track']"New value: +"Type to search. Default: ['track']" - changed
Input schema / properties / types / maxItemsPrevious value: -2New value: +1
- Changed
show_episode_search2 fields changed- changed
Input schema / properties / fetch_all / descriptionPrevious value: -"When true, walk all pages (up to cap) to find matches"New value: +"When true, walk from offset to the end (500-episode cap)" - changed
Input schema / properties / show_id / descriptionPrevious value: -"Spotify show ID"New value: +"Spotify show ID, spotify:show: URI, or open.spotify.com/show URL"
- Changed
show_episode_timeline3 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$" - changed
Input schema / properties / max_results / descriptionPrevious value: -"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"New value: +"Max rows to return (default: SPOTIFY_MCP_FETCH_ALL_CAP or 500)"
- Changed
show_new_episodes2 fields changed- added
Input schema / properties / cost_previewAdded value: +{ + "description": "Cost preview only: make no API calls and return the request budget instead of the episode list. Use it to size a real call; it does not report any episodes. Default false.", + "type": "boolean" +} - removed
Input schema / properties / dry_runRemoved value: -{ - "description": "Preview only: validate inputs and describe exactly what would change without performing it", - "type": "boolean" -}
- Changed
show_recommendation_brief1 field changed- changed
Input schema / properties / max_shows / descriptionPrevious value: -"Max per-show episode lookups (request budget). Default 50"New value: +"Max per-show episode lookups (request budget). Default 50; this also bounds the /me/episodes/contains calls (1 per 50 episodes found)"
- Changed
show_runtime_stats2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
taste_to_playlist3 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +true - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only (default true). False still only returns the list โ writes happen via Spotify tools."New value: +"Preview only: return the plan and write nothing. Pass false to actually create the playlist in your library and add the tracks that resolve to a Spotify id. Default true" - added
Input schema / properties / playlist_nameAdded value: +{ + "description": "Name for the playlist created when dry_run=false. Default: \"Taste: <user> (<seed>)\"", + "maxLength": 100, + "minLength": 1, + "type": "string" +}
- Changed
track_album_bundle2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
undo_last_mutation2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +true - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only, and the default: pass dry_run: false to execute the rollback."
- Changed
undo_mutation2 fields changed- added
Input schema / properties / dry_run / defaultAdded value: +true - changed
Input schema / properties / dry_run / descriptionPrevious value: -"Preview only: validate inputs and describe exactly what would change without performing it"New value: +"Preview only, and the default: pass dry_run: false to execute the rollback."
- Changed
undo_preview1 field changed- changed
Input schema / properties / mutation_id / descriptionPrevious value: -"Receipt id (rcpt_N) to preview reverting"New value: +"Receipt id (rcpt_โฆ-N) to preview reverting"
- Changed
unfollow_artists2 fields changed- changed
Input schema / properties / ids / descriptionPrevious value: -"Spotify artist IDs to unfollow"New value: +"Artist IDs, spotify:artist: URIs, or artist URLs; CSV accepted" - added
Input schema / properties / ids / items / minLengthAdded value: +1
- Changed
whats_new1 field changed- changed
Input schema / properties / since / anyOfPrevious value: -[ - { - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "type": "string" - }, - { - "const": "last-check", - "type": "string" - } -]New value: +[ + { + "const": "last-check", + "type": "string" + }, + { + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "type": "string" + } +]
- Changed
year_explorer2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market code (e.g. 'US'); omit for 'from_token' behaviour"New value: +"ISO 3166-1 alpha-2 market code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
612 tool updates
v1.31.0- Changed
add_to_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
add_to_queue2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
added_on_this_day2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
album_anniversary_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
album_duration_report3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
album_edition_lint2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
album_focus_report3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / album_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify album ID, spotify:album: URI, or open.spotify.com/album URL"
- Changed
album_openers_report3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max album openers to return (default 100).", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +}
- Changed
album_representative_plan3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / album_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify album ID, spotify:album: URI, or open.spotify.com/album URL"
- Changed
album_track_explorer3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
album_track_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
albums_runtime_batch2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
apply_device_presets2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
apply_scene2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
apply_snapshot_changes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
apply_volume_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
archive_played_episodes3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / confirm / descriptionPrevious value: -"Confirm bulk removal when >50 fully-played episodes found"New value: +"Deprecated and ignored: it no longer authorises the write. Over 50 episodes requires elicitation confirmation, or SPOTIFY_MCP_CONFIRM=never."
- Changed
artist_affinity2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_album_completeness3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
artist_album_timeline3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_catalog_stats3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
artist_collab_network3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_collaboration_network4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_collection_gaps3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_complete_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_completeness_score2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_debut_release_finder2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_decade_span2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_deep_cuts4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_deep_dive3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
artist_discography_explorer3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max releases to return (default 40)."
- Changed
artist_discography_gaps4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_discography_search3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_discography_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_discography_timeline3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_era_map2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_era_sampler3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
artist_first_release3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
artist_genres_compact2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_latest_release_report3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
artist_latest_releases2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_listening_clock2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_live_albums_finder3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_name_disambiguator2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_reissue_detector3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max reissue groups to return (default 100)."
- Changed
artist_release_digest2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_release_type_breakdown2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_representation_census2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_scout_from_playlists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_singles_timeline3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
artist_top_vs_saved2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artist_velocity_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
artistwatch_new_additions2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
audiobook_chapter_map3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
audiobook_library_progress4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_audiobooks / descriptionAdded value: +"How many audiobooks to scan (default 25, max 100)" - added
Input schema / properties / sort / descriptionAdded value: +"Report sort order"
- Changed
audiobook_progress2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
audiobooks_by_author2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
b_sides_detector3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
b_sides_finder4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL" - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
backup_first2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
backup_library2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
balance_playlist_pairs7 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_ids / descriptionPrevious value: -"Playlists to balance (2โ10)"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Removed
base62_to_uri - Changed
batch_add_to_playlist6 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Target playlist ID or spotify:playlist: URI"New value: +"Target playlist ID, spotify:playlist: URI, or URL" - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1
- Changed
batch_add_to_queue2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
batch_parse_spotify_uris - Changed
binge_detector_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
browse_category_deepdive2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
cancel_wind_down2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
canonicalize_spotify_uri4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / expected_kindAdded value: +{ + "description": "Kind used to canonicalise bare IDs", + "enum": [ + "track", + "album", + "artist", + "playlist", + "show", + "episode", + "audiobook", + "user" + ], + "type": "string" +} - changed
Input schema / properties / uris / descriptionPrevious value: -"References to canonicalise"New value: +"Spotify references to canonicalise"
- Changed
capture_playback_position2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
catalog_batch_lookup2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
category_resolver2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
chapter_bookmarks3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / op / descriptionAdded value: +"Action to take: list bookmarks, save a chapter, or delete one. Default list"
- Changed
check_artist_releases4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / limit / descriptionPrevious value: -"Albums per artist to fetch, 1โ50. Default: 10"New value: +"Albums per artist to fetch, 1โ10. Default: 10" - changed
Input schema / properties / limit / maximumPrevious value: -50New value: +10
- Changed
check_episode_saved3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / episode_ids / items / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify episode ID, spotify:episode: URI, or open.spotify.com/episode URL"
- Changed
check_following_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
check_in_library2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
check_playlist_following7 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlist_ids / descriptionAdded value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (1โ50), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Changed
check_saved_items2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
checkpoint_playback2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
classify_spotify_uris - Changed
clean_all_playlists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
clone_playlist_cover7 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / image_index / descriptionAdded value: +"Which cover image to copy (0-based). Default 0" - added
Input schema / properties / source_playlist_id / descriptionAdded value: +"Source playlist ID, URI, or URL" - added
Input schema / properties / source_playlist_id / minLengthAdded value: +1 - added
Input schema / properties / target_playlist_id / descriptionAdded value: +"Target playlist ID, URI, or URL" - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1
- Changed
collab_density_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
collab_mix_from_followed2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
compare_devices2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
compare_playlist_covers11 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / playlist_aAdded value: +{ + "description": "Canonical A playlist; provide with playlist_b or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / playlist_bAdded value: +{ + "description": "Canonical B playlist; provide with playlist_a or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / playlist_id_a / descriptionAdded value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_id_a / minLengthAdded value: +1 - added
Input schema / properties / playlist_id_b / descriptionAdded value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_id_b / minLengthAdded value: +1 - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum rows to read from each playlist; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_id_a", - "playlist_id_b" -]
- Changed
continue_last2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
copy_playlist6 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / source_playlist_id / descriptionPrevious value: -"Source playlist ID or spotify:playlist: URI"New value: +"Source playlist ID, spotify:playlist: URI, or URL" - added
Input schema / properties / source_playlist_id / minLengthAdded value: +1
- Removed
count_uris_by_type - Changed
create_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
create_smart_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
daily_pick2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
dead_library_finder2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
decade_sampler_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
dedupe_playlist_apply2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
dedupe_playlist_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
dedupe_spotify_uris4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / expected_kindAdded value: +{ + "description": "Kind used to interpret bare IDs; typed references retain their own kind", + "enum": [ + "track", + "album", + "artist", + "playlist", + "show", + "episode", + "audiobook", + "user" + ], + "type": "string" +} - changed
Input schema / properties / uris / descriptionPrevious value: -"References to dedupe"New value: +"Spotify references to deduplicate"
- Changed
deep_cuts_finder3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
deep_dive_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
delete_playback_bookmark2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
delete_playlist_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
delete_scene2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
describe_listening_session2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
describe_queue2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
device_health2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
device_sync_state2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
device_type_census2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
diff_playlist_snapshots2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
diff_playlists11 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / a / descriptionPrevious value: -"First playlist, as ID or spotify:playlist: URI"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / a / minLengthAdded value: +1 - changed
Input schema / properties / b / descriptionPrevious value: -"Second playlist, as ID or spotify:playlist: URI"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / b / minLengthAdded value: +1 - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / playlist_aAdded value: +{ + "description": "Canonical A playlist; provide with playlist_b or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / playlist_bAdded value: +{ + "description": "Canonical B playlist; provide with playlist_a or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - removed
Input schema / requiredRemoved value: -[ - "a", - "b" -]
- Changed
diff_since_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
discover_weekly_diff2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
discovery_digest2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
discovery_ratio2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
duplicate_saved_versions2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
episode_bookmark2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
episode_context_bundle2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
episode_guest_census2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
episode_resume2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
episode_runtime_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
era_distribution_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
era_preference_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
explicit_content_ratio2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_all_playlists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_followed_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_library_json2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_listening_history2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_playlist_json2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_playlist_markdown2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_profile_state2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_shows_opml2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
export_snapshot_bundle2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
exposure_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
extract_playlist_range2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
extract_spotify_id - Changed
featuring_density_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
filter_by_genre2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
filter_playlist_by_artist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
filter_playlist_by_duration2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
filter_playlist_by_era2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
find_canonical_track2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
find_collaborations3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / artist_a / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify artist ID, spotify:artist: URI, or open.spotify.com/artist URL"
- Changed
find_duplicate_playlists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
find_duplicate_saved_tracks4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / include_near_duplicates / descriptionPrevious value: -"Also report same-song groups whose durations differ by more than ยฑ2s (remasters/re-recordings). Default false."New value: +"Also report same-title/artist groups with a different ISRC, release, or duration. Near duplicates are review-only and never recommend removal. Default false." - changed
Input schema / properties / playlist_id / descriptionPrevious value: -"Optional playlist ID to cross-reference: members of each duplicate group that also appear in this playlist are flagged, so removal decisions can account for where the track is already curated."New value: +"Optional playlist ID to cross-reference: members of each duplicate group that also appear in this playlist are flagged, so cleanup or review decisions can account for where the track is already curated."
- Removed
find_duplicate_spotify_uris - Changed
find_duplicate_tracks_across_playlists6 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_ids / descriptionPrevious value: -"Playlist IDs to compare (2โ20)"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ20), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 20, + "minItems": 2, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Changed
find_duplicates_in_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
find_lost_since_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
find_new_since_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
find_show_by_publisher2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
find_tool2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
follow_artists3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: show exactly which artists would be followed without calling the API", + "type": "boolean" +}
- Changed
followed_playlists_audit2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
following_analytics3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / group_by / descriptionAdded value: +"Rollup dimension for the report"
- Changed
forgotten_favorites2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
format_spotify_uri6 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / id / descriptionPrevious value: -"Spotify entity ID"New value: +"Spotify ID (exactly 22 Base62 characters for catalog kinds; user IDs may be non-fixed)" - changed
Input schema / properties / kind / descriptionPrevious value: -"Entity kind, e.g. track, album, artist, playlist, show, episode, audiobook, user"New value: +"Spotify entity kind" - added
Input schema / properties / kind / enumAdded value: +[ + "track", + "album", + "artist", + "playlist", + "show", + "episode", + "audiobook", + "user" +] - removed
Input schema / properties / kind / minLengthRemoved value: -1
- Changed
front_to_back_plan3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / album_id / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify album ID, spotify:album: URI, or open.spotify.com/album URL"
- Changed
genre_dive_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
genre_trends_over_time2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_album3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code. Defaults to the account country; affects track playability."New value: +"ISO country code; defaults to account country."
- Changed
get_album_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_artist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_artist_albums5 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / fetch_all / descriptionPrevious value: -"When true, walk all pages via getAllPages up to cap (fetch_all_cap) โ use for \"all\" queries. Default: false"New value: +"Fetch all pages up to cap. Default: false" - changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code. Defaults to the account country; affects album availability."New value: +"ISO country code; defaults to account country." - changed
Input schema / properties / offset / descriptionPrevious value: -"Index of the first album to return. Default: 0"New value: +"Album offset. Default: 0"
- Changed
get_artist_appearances2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_artist_discography4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / limit / descriptionPrevious value: -"Results per page, 1โ50. Default: 20"New value: +"Results per page, 1โ10. Default: 10" - changed
Input schema / properties / limit / maximumPrevious value: -50New value: +10
- Changed
get_artist_genres2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_artist_singles2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_artist_top_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_audiobook2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_audiobook_chapters2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_available_markets2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_categories4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, e.g. 'US' (alias: market)"New value: +"Deprecated compatibility spelling for market. Prefer market; conflicting spellings are rejected." - added
Input schema / properties / marketAdded value: +{ + "description": "Canonical ISO 3166-1 alpha-2 market code, e.g. 'US'; forwarded to Spotify as market.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +}
- Changed
get_category2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_category_playlists4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code, e.g. 'US' (alias: market)"New value: +"Deprecated compatibility spelling for market. Prefer market; conflicting spellings are rejected." - added
Input schema / properties / marketAdded value: +{ + "description": "Canonical ISO 3166-1 alpha-2 market code, e.g. 'US'; forwarded to Spotify as market.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +}
- Changed
get_chapter2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_context_inspect2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_currently_playing2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_device_volume_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_devices2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_episode2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_episode_details2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_followed_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_me2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_newly_released_episodes3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / since / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$"
- Changed
get_now_playing2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playback_context2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playback_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playlist_added_dates2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playlist_cover2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playlist_followers2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playlist_items2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_playlist_snapshot3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlist_id / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or URL"
- Changed
get_queue2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_queue_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_recently_played2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_saved_albums2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_saved_audiobooks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_saved_counts2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_saved_episodes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_saved_shows2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_saved_tracks4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / fetch_all / defaultAdded value: +false - added
Input schema / properties / offset / defaultAdded value: +0
- Changed
get_several_albums2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_several_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_several_audiobooks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_several_chapters2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_several_episodes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_several_shows2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_several_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_show2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_show_details2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
get_show_episodes - Changed
get_show_latest_episode2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_top_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_top_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_track2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_user_playlists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_user_playlists_by_id2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
get_user_profile2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
grow_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
handoff2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
history_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
import_from_sidecar2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
import_playlist3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_id / descriptionPrevious value: -"Target playlist ID or spotify:playlist: URI"New value: +"Target playlist ID, spotify:playlist: URI, or share URL"
- Changed
import_profile_state2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
inspect_tool2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
interleave_playlists_plan9 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_ids / descriptionPrevious value: -"Playlists to interleave (2โ10), in round order"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Existing playlist (ID or URI) to atomically overwrite with the interleave. Omit = read-only plan"New value: +"Existing playlist (ID, URI, or URL) to atomically overwrite with the interleave. Omit = read-only plan" - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1 - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Changed
is_local_census2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
is_valid_spotify_uri - Removed
join_uri_list - Changed
jump_to_chapter2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
label_discography_explorer3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
label_explorer3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
last_heard2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
library_coverage_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
library_genre_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
library_growth_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
library_growth_timeline2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
library_hygiene2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
library_snapshot_diff2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
library_to_playlist3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / limit / descriptionPrevious value: -"Max items to export. Default 500"New value: +"Max playable track URIs to export. Default: configured fetch-all cap"
- Changed
library_value_summary2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_all_chapters2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_backups2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_device_presets2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_playback_bookmarks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_playback_states2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_playlist_snapshots2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_saved_shows2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_saved_snapshots2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_scenes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_sessions2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_show_episodes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_clock2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_clock_heatmap2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_consistency_score2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_eras2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_gaps_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_heatmap2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_history_export2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_journal_append2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_recap_brief2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_session_close2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_session_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_session_start2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_sessions2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_streak_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
listening_streaks3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / max_items / descriptionPrevious value: -"Max history items to walk (default 150)"New value: +"Max history items to read (default 150); lower values stop the cursor walk early"
- Changed
listening_week_in_time2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
longest_saved_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
lyric_snippet_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
make_spotify_uri - Changed
mark_episode_played_plan3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / episode_ids / items / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify episode ID, spotify:episode: URI, or open.spotify.com/episode URL"
- Changed
market_availability2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
market_validate2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
merge_playlists12 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (1โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / sources / descriptionPrevious value: -"Source playlists as IDs or spotify:playlist: URIs"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / sources / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / sources / items / minLengthAdded value: +1 - added
Input schema / properties / sources / maxItemsAdded value: +10 - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Existing playlist to APPEND into (never cleared), as ID or spotify:playlist: URI"New value: +"Existing playlist to APPEND into (never cleared)" - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1 - removed
Input schema / requiredRemoved value: -[ - "sources" -]
- Changed
merge_playlists_plan7 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_ids / descriptionPrevious value: -"Playlists to merge (2โ10), in order"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Changed
merge_snapshot_changes_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
monthly_listening_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
mood_bucket_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
morning_briefing2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
most_replayed2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
move_items_between_playlists8 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / source_playlist_id / descriptionPrevious value: -"Source playlist ID or spotify:playlist: URI"New value: +"Source playlist ID, spotify:playlist: URI, or URL" - added
Input schema / properties / source_playlist_id / minLengthAdded value: +1 - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Target playlist ID or spotify:playlist: URI"New value: +"Target playlist ID, spotify:playlist: URI, or URL" - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1
- Changed
move_tracks_between_playlists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
mutation_log_export3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / format / descriptionAdded value: +"Export format. Default markdown"
- Changed
mute2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
never_played_saved2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
new_music_from_saved_artists3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
new_music_from_top_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
normalize_spotify_uri - Changed
now_playing_history2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
open_url_to_spotify_uri - Changed
orphaned_artist_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
overlap_playlists9 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / playlists / descriptionPrevious value: -"Two or more playlists, as IDs or spotify:playlist: URIs"New value: +"Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool" - added
Input schema / properties / playlists / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlists / items / minLengthAdded value: +1 - added
Input schema / properties / playlists / maxItemsAdded value: +10 - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - removed
Input schema / requiredRemoved value: -[ - "playlists" -]
- Changed
parse_spotify_uri4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / expected_kindAdded value: +{ + "description": "Require this entity kind", + "enum": [ + "track", + "album", + "artist", + "playlist", + "show", + "episode", + "audiobook", + "user" + ], + "type": "string" +} - changed
Input schema / properties / uri / descriptionPrevious value: -"Spotify URI, open.spotify.com URL, or bare ID to parse"New value: +"Spotify reference to parse"
- Added
parse_spotify_uris - Changed
pause2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
pause_everywhere2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
peek_next2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
pin_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
plan_podcast_session2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
plan_volume_level_across_devices2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
play2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
play_at5 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / context_uri / descriptionPrevious value: -"Context URI (playlist/album URI) โ XOR uris"New value: +"Context URI (playlist/album/artist) โ XOR uris" - changed
Input schema / properties / uris / descriptionPrevious value: -"Track/episode URIs"New value: +"Up to 100 track/episode URIs โ XOR context_uri" - added
Input schema / properties / uris / maxItemsAdded value: +100
- Changed
play_from_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
play_on2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playback_compare_states2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playback_health_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playback_timeline2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Added
playback_timer_status - Changed
playlist_add_by_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_artist_heat2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_balance2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_changelog2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_chunk_preview2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_clone_live2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_clone_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_collab_toggle5 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / collaborative / descriptionAdded value: +"Target collaborative state for the playlist" - added
Input schema / properties / playlist_id / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or URL" - added
Input schema / properties / public / descriptionAdded value: +"Target visibility: true makes the playlist public"
- Changed
playlist_collaboration_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_cover_from_track2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_dedupe_advanced3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_diff9 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlist_aAdded value: +{ + "description": "Canonical A playlist; provide with playlist_b or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / playlist_a_id / descriptionPrevious value: -"First playlist, as ID or spotify:playlist: URI"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_a_id / minLengthAdded value: +1 - added
Input schema / properties / playlist_bAdded value: +{ + "description": "Canonical B playlist; provide with playlist_a or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / playlist_b_id / descriptionPrevious value: -"Second playlist, as ID or spotify:playlist: URI"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_b_id / minLengthAdded value: +1 - removed
Input schema / requiredRemoved value: -[ - "playlist_a_id", - "playlist_b_id" -]
- Changed
playlist_difference_plan11 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / base_playlist_id / descriptionPrevious value: -"Base playlist (ID or URI) whose survivors are kept"New value: +"Base playlist (ID, URI, or URL) whose survivors are kept" - added
Input schema / properties / base_playlist_id / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (1โ5), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 5, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / subtract_playlist_ids / descriptionPrevious value: -"Playlists whose tracks are removed from the base (1โ5)"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / subtract_playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / subtract_playlist_ids / items / minLengthAdded value: +1 - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Existing playlist (ID or URI) to atomically overwrite with the difference. Omit = read-only plan"New value: +"Existing playlist (ID, URI, or URL) to atomically overwrite with the difference. Omit = read-only plan" - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1 - changed
Input schema / requiredPrevious value: -[ - "base_playlist_id", - "subtract_playlist_ids" -]New value: +[ + "base_playlist_id" +]
- Changed
playlist_edit_journal2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_era_profile2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_exclude_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_expression_algebra2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_fill_from_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_filter_runtime3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_flip_order3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_from_tags3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / mode / descriptionAdded value: +"create builds a new playlist; refresh rewrites the existing one. Default create"
- Changed
playlist_health_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_history2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_intersect9 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - changed
Input schema / properties / source_playlist_ids / descriptionPrevious value: -"Playlists to intersect, as IDs or spotify:playlist: URIs (2โ10)"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / source_playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / source_playlist_ids / items / minLengthAdded value: +1 - changed
Input schema / properties / target_playlist_id / descriptionPrevious value: -"Existing playlist (ID or spotify:playlist: URI) to ATOMICALLY OVERWRITE with the result. Omit to compute read-only."New value: +"Existing playlist (ID, URI, or URL) to ATOMICALLY OVERWRITE with the result. Omit to compute read-only." - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1 - removed
Input schema / requiredRemoved value: -[ - "source_playlist_ids" -]
- Changed
playlist_intersection7 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_ids / descriptionPrevious value: -"Playlists to intersect (2โ10)"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Changed
playlist_keep_artist3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_keep_only2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_move_block3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_move_to_top2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_names_bulk_normalize2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_overlap_matrix7 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_ids / descriptionPrevious value: -"Playlists to compare (2โ10)"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Changed
playlist_pair_check9 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlist_aAdded value: +{ + "description": "Canonical A playlist; provide with playlist_b or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / playlist_a_id / descriptionPrevious value: -"First playlist, as ID or spotify:playlist: URI"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_a_id / minLengthAdded value: +1 - added
Input schema / properties / playlist_bAdded value: +{ + "description": "Canonical B playlist; provide with playlist_a or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / playlist_b_id / descriptionPrevious value: -"Second playlist, as ID or spotify:playlist: URI"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_b_id / minLengthAdded value: +1 - removed
Input schema / requiredRemoved value: -[ - "playlist_a_id", - "playlist_b_id" -]
- Changed
playlist_remove_artist3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_resequence3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_reverse3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlist_id / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or URL"
- Changed
playlist_rotate3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_seed_shuffle3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_shuffle4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlist_id / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or URL" - added
Input schema / properties / seed / descriptionAdded value: +"Deterministic shuffle seed; omit for a random order"
- Changed
playlist_slice2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_snapshot_detail2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_sort4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / playlist_id / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or URL" - added
Input schema / properties / sort_by / descriptionAdded value: +"Sort key applied to the playlist"
- Changed
playlist_staleness_report3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / sort / descriptionAdded value: +"Report sort order"
- Changed
playlist_staleness_score2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_strip_episodes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_subtract14 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / base_playlist_id / descriptionAdded value: +"Base playlist ID, URI, or URL. Optional only for the deprecated positional form, where playlists[0] is the base." - added
Input schema / properties / base_playlist_id / minLengthAdded value: +1 - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (1โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / subtract_playlist_ids / descriptionAdded value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / subtract_playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / subtract_playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / subtract_playlist_ids / maxItemsAdded value: +10 - removed
Input schema / requiredRemoved value: -[ - "base_playlist_id", - "subtract_playlist_ids" -]
- Changed
playlist_swap_positions3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / include_full_orderAdded value: +{ + "description": "Opt in to the full planned order; otherwise structuredContent is capped", + "type": "boolean" +}
- Changed
playlist_symmetric_difference11 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / playlist_aAdded value: +{ + "description": "Canonical A playlist; provide with playlist_b or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / playlist_bAdded value: +{ + "description": "Canonical B playlist; provide with playlist_a or one complete documented legacy pair", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / playlist_id_a / descriptionAdded value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_id_a / minLengthAdded value: +1 - added
Input schema / properties / playlist_id_b / descriptionAdded value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide a complete pair or canonical playlist_a/playlist_b." - added
Input schema / properties / playlist_id_b / minLengthAdded value: +1 - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum rows to read from each playlist; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_id_a", - "playlist_id_b" -]
- Changed
playlist_table_of_contents2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_template_apply2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_to_library2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_trim5 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / keep / descriptionAdded value: +"How many items to keep" - added
Input schema / properties / keep_which / descriptionAdded value: +"Which end of the playlist to keep items from. Default first" - added
Input schema / properties / playlist_id / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or URL"
- Changed
playlist_trim_to_duration2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
playlist_union15 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / dedupe / descriptionAdded value: +"Drop duplicate URIs across the merged sources. Default true" - added
Input schema / properties / limitAdded value: +{ + "description": "Source page size, 1โ100. Default: 100", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - added
Input schema / properties / scan_capAdded value: +{ + "description": "Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP", + "maximum": 10000, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / source_playlist_ids / descriptionAdded value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / source_playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / source_playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / target_name / descriptionAdded value: +"Name for a newly created target playlist; provide exactly one of target_playlist_id or target_name" - added
Input schema / properties / target_playlist_id / descriptionAdded value: +"Existing target playlist (ID, URI, or URL); provide exactly one of target_playlist_id or target_name" - added
Input schema / properties / target_playlist_id / minLengthAdded value: +1 - removed
Input schema / requiredRemoved value: -[ - "source_playlist_ids" -]
- Changed
playlist_union_preview7 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / playlist_ids / descriptionPrevious value: -"Playlists to union (2โ10)"New value: +"Deprecated one-release alias supported through v2.0; removed in v2.1. Provide this complete alias or canonical playlists." - added
Input schema / properties / playlist_ids / items / descriptionAdded value: +"Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field" - added
Input schema / properties / playlist_ids / items / minLengthAdded value: +1 - added
Input schema / properties / playlistsAdded value: +{ + "description": "Canonical ordered playlists (2โ10), or provide the complete documented legacy alias accepted by this tool", + "items": { + "description": "Playlist ID, spotify:playlist: URI, or Spotify playlist URL; use this reference in the canonical or documented legacy field", + "minLength": 1, + "type": "string" + }, + "maxItems": 10, + "minItems": 2, + "type": "array" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_ids" -]
- Changed
predict_next_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
prune_old_snapshots2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
publisher_portfolio3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_showsAdded value: +{ + "description": "Max per-show episode lookups (request budget). Default 20", + "maximum": 200, + "minimum": 1, + "type": "integer" +}
- Changed
queue_duplicate_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
queue_next2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
queue_next_episode2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
queue_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
queue_profile2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
queue_prune_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
queue_replace_via_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
queue_runtime_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
quick_save_now2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
quota_probe2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
read_playlist_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
receipt_lookup2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
record_feedback2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
refresh_smart_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
remove_duplicate_playlist_items2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
remove_from_library2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
remove_from_library_by_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
remove_from_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
remove_playlist_range2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
remove_saved_episode3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / episode_ids / items / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify episode ID, spotify:episode: URI, or open.spotify.com/episode URL"
- Changed
remove_saved_items2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
remove_saved_shows3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / show_ids / items / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify show ID, spotify:show: URI, or open.spotify.com/show URL"
- Changed
remove_unavailable_playlist_items4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_removalsAdded value: +{ + "description": "Destructive cap: maximum unavailable playlist rows to remove; defaults to all detected unavailable rows", + "maximum": 9007199254740991, + "minimum": 1, + "type": "integer" +} - removed
Input schema / properties / max_resultsRemoved value: -{ - "description": "Max unavailable items to remove (default 100)", - "maximum": 100, - "minimum": 1, - "type": "integer" -}
- Changed
rename_device2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
reorder_playlist_items2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
repeat_listener_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
repeat_queue_toggle2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
replace_playlist_items2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
replay_session2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
resolve_artist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
restore_library_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
restore_playback_state2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
restore_playlist_from_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
restore_playlist_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
resume_playback_position2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
reverse_playlist_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
room_level2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
rotate_playlist_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
sample_playlist_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_artist_new_releases4 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / limit / descriptionPrevious value: -"Albums to fetch, 1โ50. Default: 20"New value: +"Albums to fetch, 1โ10. Default: 10" - changed
Input schema / properties / limit / maximumPrevious value: -50New value: +10
- Changed
save_discover_weekly2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_episode3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / episode_ids / items / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify episode ID, spotify:episode: URI, or open.spotify.com/episode URL"
- Changed
save_items2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_playback_state2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_queue_as_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_release_radar2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_scene2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_show_digest2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_smart_playlist_rule2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
save_to_library2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_albums_by_decade2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_albums_by_label2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_albums_by_type2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_albums_by_year2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_library_delta2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_runtime_by_era2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_shows_publisher_census2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_track_age_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_tracks_by_artist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_tracks_roulette2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
saved_vs_playlist_coverage2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
scene_sampler_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
schedule_wind_down3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Changed
scope_audit2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / offset / defaultAdded value: +0
- Changed
search_advanced3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
search_albums2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_audiobooks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_by_isrc2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_deep2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_episodes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_fresh3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
search_history2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_history_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_market_diff2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_playlists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_rerun2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_saved_albums2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_saved_audiobooks3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / scan_cap / descriptionAdded value: +"Maximum saved items to scan; defaults to SPOTIFY_MCP_FETCH_ALL_CAP"
- Changed
search_saved_episodes3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / scan_cap / descriptionAdded value: +"Maximum saved items to scan; defaults to SPOTIFY_MCP_FETCH_ALL_CAP"
- Changed
search_saved_shows3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / scan_cap / descriptionAdded value: +"Maximum saved items to scan; defaults to SPOTIFY_MCP_FETCH_ALL_CAP"
- Changed
search_saved_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_shows2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
search_within_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
seek2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
seek_relative2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
session_length_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
session_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
set_device_volume_preset2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
set_repeat2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
set_shuffle2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
set_volume2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
shortest_saved_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
show_activity_feed2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
show_backlog_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
show_backlog_report3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / sort / descriptionAdded value: +"Report sort order"
- Changed
show_episode_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
show_episode_timeline3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
show_new_episodes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
show_recommendation_brief3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / since / patternAdded value: +"^\\d{4}-\\d{2}-\\d{2}$"
- Changed
show_runtime_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
shows_release_calendar2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
shows_without_new_episodes2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
shuffle_state_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
sidecar_export_bundle2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
skip_n2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
skip_next2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
skip_previous2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
sleep_timer2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
sleep_timer_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_added_at_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_changelog2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_diff_summary2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_disk_usage2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_integrity_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_integrity_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_new_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_registry_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_removed_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_retention_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
snapshot_stats_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
sort_playlist_apply2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
sort_playlist_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
sort_uris_by_kind - Changed
split_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
split_playlist_by_count2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
split_playlist_by_duration2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
split_queue_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
split_uri_list - Changed
spotify_doctor5 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / response_format / defaultAdded value: +"concise" - changed
Input schema / properties / response_format / descriptionPrevious value: -"Response format: concise (default) returns human-readable text, detailed adds metadata, json returns structured data"New value: +"'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object" - changed
Input schema / properties / verbose / descriptionPrevious value: -"Include per-check technical detail lines in the prose output"New value: +"Include per-check technical detail lines when response_format is concise"
- Removed
spotify_uri_kind - Added
spotify_uri_stats - Removed
spotify_uri_to_open_url - Changed
stale_saved_shows_plan2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
start_podcast_session2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_album_date_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_album_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_artist_affinity2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_artist_date_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_artist_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_catalog_album2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_catalog_artist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_catalog_track2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_charts_albums2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_charts_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_charts_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_charts_users2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_exposure_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_forgotten_favorites2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_friend_count2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_friends2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_genre_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_listening_eras2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_listening_sessions2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_now_playing2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_recaps2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_recent_streams2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_record_feedback2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_records_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_resolve_user2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_search2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_streams_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_taste_profile2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_taste_recommendations2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_top_albums2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_top_albums_from_artist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_top_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_top_genres2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_top_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_top_tracks_from_album2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_top_tracks_from_artist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_track_date_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
statsfm_track_stats2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
subscribe_to_show3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - changed
Input schema / properties / show_ids / items / descriptionPrevious value: -"Spotify ID, URI (spotify:...), or open.spotify.com URL โ all resolve to the same entity"New value: +"Spotify show ID, spotify:show: URI, or open.spotify.com/show URL"
- Changed
surprise_me2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
switch_device2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
tag_listening_session2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
tag_management2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
take_playlist_snapshot2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_checkpoint2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_checkpoint_diff2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_daily_brief2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_diamond_rotation2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_era_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_forgotten_bangers2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_genre_bridge2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_listening_clock2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_novelty_loyalty2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_obsession_ladder2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_profile2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_recommendations2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_revival_queue2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_shift_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_to_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
taste_weekly_recap2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
title_length_outliers2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
toolset_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
top_artist_leaderboard2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
top_artist_ranking_delta2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
top_artists_by_range2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
top_genre_census2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
top_track_leaderboard2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
top_track_ranking_delta2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
track_album_bundle2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
track_enrichment_batch3 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / max_results / descriptionAdded value: +"Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)"
- Changed
track_release_origin2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
track_rotation_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
transfer_playback2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
transfer_playback_with_state2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
undo_last_mutation2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
undo_mutation2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
undo_preview2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
unfollow_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
unmute2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
unpin_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
unplayable_saved_check2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
unsave_orphan_tracks2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
unsubscribe_from_show2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
update_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
upload_playlist_cover2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Removed
uri_kind_stats - Removed
uri_namespace_census - Removed
uri_shorthand_expand - Removed
uri_to_base62 - Removed
validate_spotify_uri - Changed
verify_receipt2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
volume_ramp2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
volume_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
volume_step2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
watch_artists2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
week_in_review_playlist2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
weekday_heatmap2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
weekday_listening_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
weekly_rotation_report2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
whats_new2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
where_was_i2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Added
wind_down_status - Changed
year_explorer2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
- Changed
year_in_review2 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - added
Input schema / additionalPropertiesAdded value: +false
19 tool updates
v1.30.0- Added
statsfm_artist_affinity - Added
statsfm_exposure_check - Added
statsfm_forgotten_favorites - Added
statsfm_listening_eras - Added
statsfm_listening_sessions - Added
statsfm_record_feedback - Added
statsfm_taste_profile - Added
statsfm_taste_recommendations - Added
taste_daily_brief - Added
taste_diamond_rotation - Added
taste_era_playlist - Added
taste_forgotten_bangers - Added
taste_genre_bridge - Added
taste_listening_clock - Added
taste_novelty_loyalty - Added
taste_obsession_ladder - Added
taste_revival_queue - Added
taste_to_playlist - Added
taste_weekly_recap
38 tool updates
v1.29.0- Added
artist_affinity - Added
exposure_check - Added
forgotten_favorites - Added
listening_eras - Added
listening_sessions - Added
record_feedback - Added
statsfm_album_date_stats - Added
statsfm_album_stats - Added
statsfm_artist_date_stats - Added
statsfm_artist_stats - Added
statsfm_catalog_album - Added
statsfm_catalog_artist - Added
statsfm_catalog_track - Added
statsfm_charts_albums - Added
statsfm_charts_artists - Added
statsfm_charts_tracks - Added
statsfm_charts_users - Added
statsfm_friend_count - Added
statsfm_friends - Added
statsfm_genre_artists - Added
statsfm_now_playing - Added
statsfm_recaps - Added
statsfm_recent_streams - Added
statsfm_records_artists - Added
statsfm_resolve_user - Added
statsfm_search - Added
statsfm_streams_stats - Added
statsfm_top_albums - Added
statsfm_top_albums_from_artist - Added
statsfm_top_artists - Added
statsfm_top_genres - Added
statsfm_top_tracks - Added
statsfm_top_tracks_from_album - Added
statsfm_top_tracks_from_artist - Added
statsfm_track_date_stats - Added
statsfm_track_stats - Added
taste_profile - Added
taste_recommendations
64 tool updates
v1.28.0- Changed
audiobook_progress2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"Market"New value: +"Market, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
backup_first1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
batch_add_to_queue - Changed
browse_category_deepdive2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / country / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
category_resolver2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / country / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
clean_all_playlists2 fields changed- changed
Input schema / properties / apply / descriptionPrevious value: -"false (default): report only โ nothing is changed. true: execute the cleanup across all playlists with duplicates."New value: +"Deprecated alias for dry_run โ prefer dry_run. false (default): report only. true: execute the cleanup across all playlists with duplicates. If both are given, dry_run wins." - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only โ when true, nothing is changed; when false via dry_run=false or apply=true, executes the cleanup", + "type": "boolean" +}
- Changed
create_smart_playlist1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
diff_since_snapshot1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
find_duplicate_playlists1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
find_show_by_publisher2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for the search"New value: +"ISO 3166-1 alpha-2 market for the search, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
find_tool1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_album_tracks1 field changed- added
Input schema / properties / fetch_allAdded value: +{ + "description": "When true, walk all pages via getAllPages up to cap (fetch_all_cap) โ use for \"all\" queries. Default: false", + "type": "boolean" +}
- Changed
get_artist_albums1 field changed- added
Input schema / properties / fetch_allAdded value: +{ + "description": "When true, walk all pages via getAllPages up to cap (fetch_all_cap) โ use for \"all\" queries. Default: false", + "type": "boolean" +}
- Changed
get_artist_discography2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_artist_top_tracks2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code. Defaults to the account country."New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US' โ defaults to the account country" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_categories2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US' (alias: market)" - added
Input schema / properties / country / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_category2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / country / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_category_playlists2 fields changed- changed
Input schema / properties / country / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US' (alias: market)" - added
Input schema / properties / country / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_episode2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_episode_details2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for availability"New value: +"ISO 3166-1 alpha-2 market for availability, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_playlist_followers1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_playlist_items1 field changed- added
Input schema / properties / fetch_allAdded value: +{ + "description": "Fetch every item across pages (up to 500), continuing FROM offset rather than restarting at 0. limit is the page size. Note: library tools' fetch_all instead ignores offset โ contracts differ between modules (#110).", + "type": "boolean" +}
- Changed
get_saved_albums2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_saved_episodes2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_saved_tracks2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_show_details2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for availability"New value: +"ISO 3166-1 alpha-2 market for availability, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
get_show_episodes1 field changed- added
Input schema / properties / fetch_allAdded value: +{ + "description": "When true, walk all pages via getAllPages up to cap (fetch_all_cap) โ use for \"all\" queries. Default: false", + "type": "boolean" +}
- Changed
get_show_latest_episode2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for availability"New value: +"ISO 3166-1 alpha-2 market for availability, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
import_playlist1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
inspect_tool1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
list_playlist_snapshots1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
list_show_episodes2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for availability"New value: +"ISO 3166-1 alpha-2 market for availability, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
market_availability3 fields changed- removed
Input schema / properties / markets / items / maxLengthRemoved value: -5 - removed
Input schema / properties / markets / items / minLengthRemoved value: -2 - added
Input schema / properties / markets / items / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
market_validate3 fields changed- removed
Input schema / properties / markets / items / maxLengthRemoved value: -2 - removed
Input schema / properties / markets / items / minLengthRemoved value: -2 - added
Input schema / properties / markets / items / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
pause1 field changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Changed
playlist_collaboration_report1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
playlist_era_profile2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market. When given, items are REFETCHED with this market so album release dates resolve (disclosed second GET)."New value: +"ISO 3166-1 alpha-2 market, e.g. 'US' โ when given, items are REFETCHED with this market so album release dates resolve (disclosed second GET)" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
playlist_fill_from_search4 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for search"New value: +"ISO 3166-1 alpha-2 market for search, e.g. 'US'" - removed
Input schema / properties / market / maxLengthRemoved value: -2 - removed
Input schema / properties / market / minLengthRemoved value: -2 - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
playlist_health_check1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
playlist_staleness_score2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for availability"New value: +"ISO 3166-1 alpha-2 market for availability, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
quick_save_now2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO-3166 market code passed on the player read"New value: +"ISO-3166 market code passed on the player read, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
remove_unavailable_playlist_items1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
save_artist_new_releases2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
saved_tracks_by_artist2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 market for the artist search"New value: +"ISO 3166-1 alpha-2 market for the artist search, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US' โ uppercased automatically" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_albums2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_artists2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_audiobooks2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_deep2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_episodes2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_market_diff6 fields changed- removed
Input schema / properties / market_a / maxLengthRemoved value: -2 - removed
Input schema / properties / market_a / minLengthRemoved value: -2 - added
Input schema / properties / market_a / patternAdded value: +"^[A-Za-z]{2}$" - removed
Input schema / properties / market_b / maxLengthRemoved value: -2 - removed
Input schema / properties / market_b / minLengthRemoved value: -2 - added
Input schema / properties / market_b / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_playlists2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_shows2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_tracks2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
search_within_playlist2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"Market for track relinking"New value: +"Market for track relinking, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
seek1 field changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Changed
set_repeat1 field changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Changed
set_shuffle1 field changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Changed
set_volume1 field changed- added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Changed
show_episode_search2 fields changed- changed
Input schema / properties / market / descriptionPrevious value: -"ISO 3166-1 alpha-2 country code"New value: +"ISO 3166-1 alpha-2 country code, e.g. 'US'" - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$"
- Changed
snapshot_playlist1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
spotify_doctor1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "description": "Response format: concise (default) returns human-readable text, detailed adds metadata, json returns structured data", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
undo_last_mutation1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
undo_mutation1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
550 tool updates
v1.26.1- Changed
add_to_playlist4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / check_duplicatesAdded value: +{ + "description": "Skip URIs that are already in the playlist instead of appending them (default: false)", + "type": "boolean" +} - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / position / maximumAdded value: +9007199254740991
- Changed
add_to_queue3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
added_on_this_day - Added
album_anniversary_check - Added
album_duration_report - Added
album_edition_lint - Added
album_focus_report - Added
album_openers_report - Added
album_representative_plan - Added
album_track_explorer - Added
album_track_stats - Added
albums_runtime_batch - Added
apply_device_presets - Added
apply_scene - Added
apply_snapshot_changes - Added
apply_volume_plan - Added
archive_played_episodes - Added
artist_album_completeness - Added
artist_album_timeline - Added
artist_catalog_stats - Added
artist_collab_network - Added
artist_collaboration_network - Added
artist_collection_gaps - Added
artist_complete_check - Added
artist_completeness_score - Added
artist_debut_release_finder - Added
artist_decade_span - Added
artist_deep_cuts - Added
artist_deep_dive - Added
artist_discography_explorer - Added
artist_discography_gaps - Added
artist_discography_search - Added
artist_discography_stats - Added
artist_discography_timeline - Added
artist_era_map - Added
artist_era_sampler - Added
artist_first_release - Added
artist_genres_compact - Added
artist_latest_release_report - Added
artist_latest_releases - Added
artist_listening_clock - Added
artist_live_albums_finder - Added
artist_name_disambiguator - Added
artist_reissue_detector - Added
artist_release_digest - Added
artist_release_type_breakdown - Added
artist_representation_census - Added
artist_scout_from_playlists - Added
artist_singles_timeline - Added
artist_top_vs_saved - Added
artist_velocity_report - Added
artistwatch_new_additions - Added
audiobook_chapter_map - Added
audiobook_library_progress - Added
audiobook_progress - Added
audiobooks_by_author - Added
b_sides_detector - Added
b_sides_finder - Added
backup_first - Added
backup_library - Added
balance_playlist_pairs - Added
base62_to_uri - Added
batch_add_to_playlist - Added
batch_parse_spotify_uris - Added
binge_detector_report - Added
browse_category_deepdive - Added
cancel_wind_down - Added
canonicalize_spotify_uri - Added
capture_playback_position - Added
catalog_batch_lookup - Added
category_resolver - Added
chapter_bookmarks - Added
check_artist_releases - Added
check_episode_saved - Changed
check_following_artists3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
check_in_library - Added
check_playlist_following - Changed
check_saved_items5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - changed
Input schema / properties / uris / descriptionPrevious value: -"Spotify URIs to check (accepts tracks, albums, shows, episodes, artists, playlists)"New value: +"Spotify URIs to check (accepts tracks, albums, shows, episodes, audiobooks)" - changed
Input schema / properties / uris / maxItemsPrevious value: -40New value: +50
- Added
checkpoint_playback - Added
classify_spotify_uris - Added
clean_all_playlists - Added
clone_playlist_cover - Added
collab_density_report - Added
collab_mix_from_followed - Added
compare_devices - Added
compare_playlist_covers - Added
continue_last - Added
copy_playlist - Added
count_uris_by_type - Changed
create_playlist2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Added
create_smart_playlist - Added
daily_pick - Added
dead_library_finder - Added
decade_sampler_plan - Added
dedupe_playlist_apply - Added
dedupe_playlist_plan - Added
dedupe_spotify_uris - Added
deep_cuts_finder - Added
deep_dive_report - Added
delete_playback_bookmark - Added
delete_playlist_snapshot - Added
delete_scene - Added
describe_listening_session - Added
describe_queue - Added
device_health - Added
device_sync_state - Added
device_type_census - Added
diff_playlist_snapshots - Added
diff_playlists - Added
diff_since_snapshot - Added
discover_weekly_diff - Added
discovery_digest - Added
discovery_ratio - Added
duplicate_saved_versions - Added
episode_bookmark - Added
episode_context_bundle - Added
episode_guest_census - Added
episode_resume - Added
episode_runtime_report - Added
era_distribution_report - Added
era_preference_report - Added
explicit_content_ratio - Added
export_all_playlists - Added
export_followed_artists - Added
export_library_json - Added
export_listening_history - Added
export_playlist - Added
export_playlist_json - Added
export_playlist_markdown - Added
export_profile_state - Added
export_shows_opml - Added
export_snapshot_bundle - Added
extract_playlist_range - Added
extract_spotify_id - Added
featuring_density_report - Added
filter_by_genre - Added
filter_playlist_by_artist - Added
filter_playlist_by_duration - Added
filter_playlist_by_era - Added
find_canonical_track - Added
find_collaborations - Added
find_duplicate_playlists - Added
find_duplicate_saved_tracks - Added
find_duplicate_spotify_uris - Added
find_duplicate_tracks_across_playlists - Added
find_duplicates_in_playlist - Added
find_lost_since_snapshot - Added
find_new_since_snapshot - Added
find_show_by_publisher - Added
find_tool - Added
follow_artists - Added
followed_playlists_audit - Added
following_analytics - Added
format_spotify_uri - Added
front_to_back_plan - Added
genre_dive_search - Added
genre_trends_over_time - Changed
get_album4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code. Defaults to the account country; affects track playability.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_album_tracks5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code. Defaults to the account country; affects track availability.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_artist2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_artist_albums7 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / limit / descriptionPrevious value: -"Results per page, 1โ50. Default: 20"New value: +"Results per page, 1โ10. Default: 10" - changed
Input schema / properties / limit / maximumPrevious value: -50New value: +10 - added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code. Defaults to the account country; affects album availability.", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Index of the first album to return. Default: 0", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_artist_appearances - Added
get_artist_discography - Added
get_artist_genres - Added
get_artist_singles - Added
get_artist_top_tracks - Changed
get_audiobook3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$" - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_audiobook_chapters5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$" - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_available_markets - Added
get_categories - Added
get_category - Added
get_category_playlists - Changed
get_chapter3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$" - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_context_inspect - Changed
get_currently_playing3 fields changed- added
Input schema / properties / additional_typesAdded value: +{ + "default": [ + "track", + "episode" + ], + "description": "Item types to include in the response. Default: ['track', 'episode']", + "items": { + "enum": [ + "track", + "episode" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to the account market", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_device_volume_report - Changed
get_devices2 fields changed- added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_episode2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_episode_details - Changed
get_followed_artists3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_me1 field changed- added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_newly_released_episodes - Changed
get_now_playing3 fields changed- added
Input schema / properties / additional_typesAdded value: +{ + "default": [ + "track", + "episode" + ], + "description": "Item types to include in the response. Default: ['track', 'episode']", + "items": { + "enum": [ + "track", + "episode" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code โ localises item names; lowercase input is uppercased; defaults to the account market", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_playback_context - Added
get_playback_snapshot - Changed
get_playlist8 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / fetch_all / descriptionPrevious value: -"Fetch all items across pages (up to 500) instead of a single page"New value: +"Fetch all items across pages (up to 500), continuing FROM offset. limit is the page size. Note: library tools' fetch_all ignores offset โ contracts differ between modules (#110)." - changed
Input schema / properties / id / descriptionPrevious value: -"Playlist ID"New value: +"Alias for playlist_id" - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / playlist_idAdded value: +{ + "description": "Playlist ID", + "type": "string" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "id" -]
- Added
get_playlist_added_dates - Changed
get_playlist_cover6 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / idAdded value: +{ + "description": "Alias for playlist_id, matching get_playlist", + "type": "string" +} - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - changed
Input schema / properties / playlist_id / descriptionPrevious value: -"Playlist ID"New value: +"Playlist ID (or pass it as 'id')" - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "playlist_id" -]
- Added
get_playlist_followers - Added
get_playlist_items - Added
get_playlist_snapshot - Changed
get_queue2 fields changed- added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_queue_snapshot - Changed
get_recently_played7 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / after / maximumAdded value: +9007199254740991 - added
Input schema / properties / after / minimumAdded value: +-9007199254740991 - added
Input schema / properties / before / maximumAdded value: +9007199254740991 - added
Input schema / properties / before / minimumAdded value: +-9007199254740991 - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_saved_albums5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / fetch_all / descriptionPrevious value: -"Fetch all pages instead of one page (ignores limit/offset; capped at 500 items)"New value: +"Fetch all pages instead of one page (ignores limit/offset)" - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_saved_audiobooks4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_saved_counts - Changed
get_saved_episodes5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / fetch_all / descriptionPrevious value: -"Fetch all pages instead of one page (ignores limit/offset; capped at 500 items)"New value: +"Fetch all pages instead of one page (ignores limit/offset)" - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_saved_shows5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / fetch_all / descriptionPrevious value: -"Fetch all pages instead of one page (ignores limit/offset; capped at 500 items)"New value: +"Fetch all pages instead of one page (ignores limit/offset)" - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_saved_tracks5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / fetch_all / descriptionPrevious value: -"Fetch all pages instead of one page (ignores limit/offset; capped at 500 items)"New value: +"Fetch all pages instead of one page (ignores limit/offset)" - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_several_albums - Added
get_several_artists - Added
get_several_audiobooks - Added
get_several_chapters - Added
get_several_episodes - Added
get_several_shows - Added
get_several_tracks - Changed
get_show3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$" - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_show_details - Changed
get_show_episodes5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / market / patternAdded value: +"^[A-Za-z]{2}$" - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_show_latest_episode - Changed
get_top_artists4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Start position (0-based). Default: 0", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_top_tracks4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Start position (0-based). Default: 0", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_track2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
get_user_playlists5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / fetch_all / descriptionPrevious value: -"Fetch every page (up to 500 playlists) instead of a single page"New value: +"Fetch every playlist (up to 500), continuing FROM offset rather than restarting at 0. limit is the page size. Note: library tools' fetch_all instead ignores offset โ contracts differ between modules (#110)." - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
get_user_playlists_by_id - Added
get_user_profile - Added
grow_playlist - Added
handoff - Added
history_search - Added
import_from_sidecar - Added
import_playlist - Added
import_profile_state - Added
inspect_tool - Added
interleave_playlists_plan - Added
is_local_census - Added
is_valid_spotify_uri - Added
join_uri_list - Added
jump_to_chapter - Added
label_discography_explorer - Added
label_explorer - Added
last_heard - Added
library_coverage_report - Added
library_genre_report - Added
library_growth_report - Added
library_growth_timeline - Added
library_hygiene - Added
library_snapshot_diff - Added
library_to_playlist - Added
library_value_summary - Added
list_all_chapters - Added
list_backups - Added
list_device_presets - Added
list_playback_bookmarks - Added
list_playback_states - Added
list_playlist_snapshots - Added
list_saved_shows - Added
list_saved_snapshots - Added
list_scenes - Added
list_sessions - Added
list_show_episodes - Added
listening_clock - Added
listening_clock_heatmap - Added
listening_consistency_score - Added
listening_gaps_report - Added
listening_heatmap - Added
listening_history_export - Added
listening_journal_append - Added
listening_recap_brief - Added
listening_report - Added
listening_session_close - Added
listening_session_report - Added
listening_session_start - Added
listening_streak_report - Added
listening_streaks - Added
listening_week_in_time - Added
longest_saved_tracks - Added
lyric_snippet_search - Added
make_spotify_uri - Added
mark_episode_played_plan - Added
market_availability - Added
market_validate - Added
merge_playlists - Added
merge_playlists_plan - Added
merge_snapshot_changes_plan - Added
monthly_listening_report - Added
mood_bucket_report - Added
morning_briefing - Added
most_replayed - Added
move_items_between_playlists - Added
move_tracks_between_playlists - Added
mutation_log_export - Added
mute - Added
never_played_saved - Added
new_music_from_saved_artists - Added
new_music_from_top_artists - Added
normalize_spotify_uri - Added
now_playing_history - Added
open_url_to_spotify_uri - Added
orphaned_artist_check - Added
overlap_playlists - Added
parse_spotify_uri - Changed
pause2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
pause_everywhere - Added
peek_next - Added
pin_playlist - Added
plan_podcast_session - Added
plan_volume_level_across_devices - Changed
play8 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - changed
Input schema / properties / offset / descriptionPrevious value: -"Index within context to start from"New value: +"Index within an album/playlist context to start from. Ignored for ad-hoc uris; not valid for artist contexts (use offset_uri instead)." - added
Input schema / properties / offset / maximumAdded value: +9007199254740991 - added
Input schema / properties / offset_uriAdded value: +{ + "description": "Track URI inside the context to start from โ required for artist contexts, where a numeric index is rejected", + "type": "string" +} - added
Input schema / properties / position_ms / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - added
Input schema / properties / uris / maxItemsAdded value: +100
- Added
play_at - Changed
play_from_search4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / marketAdded value: +{ + "description": "ISO 3166-1 alpha-2 country code โ affects availability/relinking of results; defaults to the account market", + "pattern": "^[A-Za-z]{2}$", + "type": "string" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
play_on - Added
playback_compare_states - Added
playback_health_check - Added
playback_timeline - Added
playlist_add_by_search - Added
playlist_artist_heat - Added
playlist_balance - Added
playlist_changelog - Added
playlist_chunk_preview - Added
playlist_clone_live - Added
playlist_clone_snapshot - Added
playlist_collab_toggle - Added
playlist_collaboration_report - Added
playlist_cover_from_track - Added
playlist_dedupe_advanced - Added
playlist_diff - Added
playlist_difference_plan - Added
playlist_edit_journal - Added
playlist_era_profile - Added
playlist_exclude_artists - Added
playlist_expression_algebra - Added
playlist_fill_from_search - Added
playlist_filter_runtime - Added
playlist_flip_order - Added
playlist_from_tags - Added
playlist_health_check - Added
playlist_history - Added
playlist_intersect - Added
playlist_intersection - Added
playlist_keep_artist - Added
playlist_keep_only - Added
playlist_move_block - Added
playlist_move_to_top - Added
playlist_names_bulk_normalize - Added
playlist_overlap_matrix - Added
playlist_pair_check - Added
playlist_remove_artist - Added
playlist_resequence - Added
playlist_reverse - Added
playlist_rotate - Added
playlist_seed_shuffle - Added
playlist_shuffle - Added
playlist_slice - Added
playlist_snapshot_detail - Added
playlist_sort - Added
playlist_staleness_report - Added
playlist_staleness_score - Added
playlist_strip_episodes - Added
playlist_subtract - Added
playlist_swap_positions - Added
playlist_symmetric_difference - Added
playlist_table_of_contents - Added
playlist_template_apply - Added
playlist_to_library - Added
playlist_trim - Added
playlist_trim_to_duration - Added
playlist_union - Added
playlist_union_preview - Added
predict_next_tracks - Added
prune_old_snapshots - Added
publisher_portfolio - Added
queue_duplicate_check - Added
queue_next - Added
queue_next_episode - Added
queue_playlist - Added
queue_profile - Added
queue_prune_plan - Added
queue_replace_via_playlist - Added
queue_runtime_report - Added
quick_save_now - Added
quota_probe - Added
read_playlist_snapshot - Added
receipt_lookup - Added
refresh_smart_playlist - Added
remove_duplicate_playlist_items - Added
remove_from_library - Added
remove_from_library_by_playlist - Changed
remove_from_playlist7 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / snapshot_idAdded value: +{ + "description": "Apply the removal against this playlist version instead of the latest", + "type": "string" +} - changed
Input schema / properties / uris / descriptionPrevious value: -"URIs to remove"New value: +"URIs to remove; use { uri, positions } to target specific occurrences of a repeated URI" - added
Input schema / properties / uris / items / anyOfAdded value: +[ + { + "type": "string" + }, + { + "properties": { + "positions": { + "items": { + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" + }, + "minItems": 1, + "type": "array" + }, + "uri": { + "type": "string" + } + }, + "required": [ + "uri", + "positions" + ], + "type": "object" + } +] - removed
Input schema / properties / uris / items / typeRemoved value: -"string" - added
Input schema / properties / uris / maxItemsAdded value: +100
- Added
remove_playlist_range - Added
remove_saved_episode - Changed
remove_saved_items3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: show exactly which URIs would be removed without calling the API", + "type": "boolean" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
remove_saved_shows - Added
remove_unavailable_playlist_items - Added
rename_device - Changed
reorder_playlist_items5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / insert_before / maximumAdded value: +9007199254740991 - added
Input schema / properties / range_length / maximumAdded value: +9007199254740991 - added
Input schema / properties / range_start / maximumAdded value: +9007199254740991
- Added
repeat_listener_report - Added
repeat_queue_toggle - Added
replace_playlist_items - Added
replay_session - Added
resolve_artist - Added
restore_library_snapshot - Added
restore_playback_state - Added
restore_playlist_from_snapshot - Added
restore_playlist_plan - Added
resume_playback_position - Added
reverse_playlist_plan - Added
room_level - Added
rotate_playlist_plan - Added
sample_playlist_tracks - Added
save_artist_new_releases - Added
save_discover_weekly - Added
save_episode - Changed
save_items3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
save_playback_state - Added
save_queue_as_playlist - Added
save_release_radar - Added
save_scene - Added
save_show_digest - Added
save_smart_playlist_rule - Added
save_to_library - Added
saved_albums_by_decade - Added
saved_albums_by_label - Added
saved_albums_by_type - Added
saved_albums_by_year - Added
saved_library_delta - Added
saved_runtime_by_era - Added
saved_shows_publisher_census - Added
saved_track_age_report - Added
saved_tracks_by_artist - Added
saved_tracks_roulette - Added
saved_vs_playlist_coverage - Added
scene_sampler_search - Added
schedule_wind_down - Added
scope_audit - Changed
search7 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / include_externalAdded value: +{ + "description": "Pass \"audio\" to include externally-hosted audio items marked as playable", + "enum": [ + "audio" + ], + "type": "string" +} - added
Input schema / properties / max_resultsAdded value: +{ + "description": "Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)", + "exclusiveMinimum": 0, + "maximum": 2000, + "type": "integer" +} - added
Input schema / properties / offsetAdded value: +{ + "description": "Index of the first result to return, 0โ1000. Use with limit to page through results", + "maximum": 1000, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +} - changed
Input schema / properties / types / descriptionPrevious value: -"Content types to search, as an array. Default: [\"track\",\"artist\",\"album\"]. Pass e.g. [\"artist\"] for an artist-only search."New value: +"Content types to search, as an array. Default: [\"track\",\"artist\",\"album\"]. Pass e.g. [\"artist\"] for an artist-only search. \"audiobook\" is only available in the US, UK, CA, IE, NZ and AU markets." - changed
Input schema / properties / types / items / enumPrevious value: -[ - "track", - "artist", - "album", - "playlist", - "show", - "episode" -]New value: +[ + "track", + "artist", + "album", + "playlist", + "show", + "episode", + "audiobook" +]
- Added
search_advanced - Added
search_albums - Added
search_artists - Added
search_audiobooks - Added
search_by_isrc - Added
search_deep - Added
search_episodes - Added
search_fresh - Added
search_history - Added
search_history_stats - Added
search_market_diff - Added
search_playlists - Added
search_rerun - Added
search_saved_albums - Added
search_saved_audiobooks - Added
search_saved_episodes - Added
search_saved_shows - Added
search_saved_tracks - Added
search_shows - Added
search_tracks - Added
search_within_playlist - Changed
seek3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / position_ms / maximumAdded value: +9007199254740991 - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
seek_relative - Added
session_length_report - Added
session_stats - Added
set_device_volume_preset - Changed
set_repeat2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
set_shuffle2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
set_volume2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
shortest_saved_tracks - Added
show_activity_feed - Added
show_backlog_plan - Added
show_backlog_report - Added
show_episode_search - Added
show_episode_timeline - Added
show_new_episodes - Added
show_recommendation_brief - Added
show_runtime_stats - Added
shows_release_calendar - Added
shows_without_new_episodes - Added
shuffle_state_report - Added
sidecar_export_bundle - Added
skip_n - Changed
skip_next3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Changed
skip_previous3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
sleep_timer - Added
sleep_timer_plan - Added
snapshot_added_at_report - Added
snapshot_changelog - Added
snapshot_diff_summary - Added
snapshot_disk_usage - Added
snapshot_integrity_check - Added
snapshot_integrity_report - Added
snapshot_new_tracks - Added
snapshot_playlist - Added
snapshot_registry_report - Added
snapshot_removed_tracks - Added
snapshot_retention_plan - Added
snapshot_stats_report - Added
sort_playlist_apply - Added
sort_playlist_plan - Added
sort_uris_by_kind - Added
split_playlist - Added
split_playlist_by_count - Added
split_playlist_by_duration - Added
split_queue_plan - Added
split_uri_list - Added
spotify_doctor - Added
spotify_uri_kind - Added
spotify_uri_to_open_url - Added
stale_saved_shows_plan - Added
start_podcast_session - Added
subscribe_to_show - Added
surprise_me - Added
switch_device - Added
tag_listening_session - Added
tag_management - Added
take_playlist_snapshot - Added
taste_checkpoint - Added
taste_checkpoint_diff - Added
taste_shift_report - Added
title_length_outliers - Added
toolset_report - Added
top_artist_leaderboard - Added
top_artist_ranking_delta - Added
top_artists_by_range - Added
top_genre_census - Added
top_track_leaderboard - Added
top_track_ranking_delta - Added
track_album_bundle - Added
track_enrichment_batch - Added
track_release_origin - Added
track_rotation_report - Changed
transfer_playback3 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - added
Input schema / properties / response_formatAdded value: +{ + "default": "concise", + "description": "'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object", + "enum": [ + "concise", + "detailed", + "json" + ], + "type": "string" +}
- Added
transfer_playback_with_state - Added
undo_last_mutation - Added
undo_mutation - Added
undo_preview - Added
unfollow_artists - Added
unmute - Added
unpin_playlist - Added
unplayable_saved_check - Added
unsave_orphan_tracks - Added
unsubscribe_from_show - Changed
update_playlist5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +} - changed
Input schema / properties / id / descriptionPrevious value: -"Playlist ID"New value: +"Alias for playlist_id" - added
Input schema / properties / playlist_idAdded value: +{ + "description": "Playlist ID", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "id" -]
- Changed
upload_playlist_cover2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / dry_runAdded value: +{ + "description": "Preview only: validate inputs and describe exactly what would change without performing it", + "type": "boolean" +}
- Added
uri_kind_stats - Added
uri_namespace_census - Added
uri_shorthand_expand - Added
uri_to_base62 - Added
validate_spotify_uri - Added
verify_receipt - Added
volume_ramp - Added
volume_report - Added
volume_step - Added
watch_artists - Added
week_in_review_playlist - Added
weekday_heatmap - Added
weekday_listening_report - Added
weekly_rotation_report - Added
whats_new - Added
where_was_i - Added
year_explorer - Added
year_in_review
50 tool updates
v1.0.1- First observed
add_to_playlist - First observed
add_to_queue - First observed
check_following_artists - First observed
check_saved_items - First observed
create_playlist - First observed
get_album - First observed
get_album_tracks - First observed
get_artist - First observed
get_artist_albums - First observed
get_audiobook - First observed
get_audiobook_chapters - First observed
get_chapter - First observed
get_currently_playing - First observed
get_devices - First observed
get_episode - First observed
get_followed_artists - First observed
get_me - First observed
get_now_playing - First observed
get_playlist - First observed
get_playlist_cover - First observed
get_queue - First observed
get_recently_played - First observed
get_saved_albums - First observed
get_saved_audiobooks - First observed
get_saved_episodes - First observed
get_saved_shows - First observed
get_saved_tracks - First observed
get_show - First observed
get_show_episodes - First observed
get_top_artists - First observed
get_top_tracks - First observed
get_track - First observed
get_user_playlists - First observed
pause - First observed
play - First observed
play_from_search - First observed
remove_from_playlist - First observed
remove_saved_items - First observed
reorder_playlist_items - First observed
save_items - First observed
search - First observed
seek - First observed
set_repeat - First observed
set_shuffle - First observed
set_volume - First observed
skip_next - First observed
skip_previous - First observed
transfer_playback - First observed
update_playlist - First observed
upload_playlist_cover
TDQS
Scored across 129 tools
129 tools with massive overlap: at least four search variants (search, search_deep, search_fresh, search_by_isrc) plus wow search helpers; five duplicate detectors (find_duplicates_in_playlist, find_duplicate_saved_tracks, find_duplicate_tracks_across_playlists, clean_all_playlists, remove_duplicate_playlist_items); multiple playlist export/import/backup tools (export_playlist, export_all_playlists, import_playlist, backup_library, backup_first, import_from_sidecar / backup_library / restore_library_snapshot, backup_library / export_library_json, backup_library / export_profile_state); get_now_playing vs get_currently_playing; follow_playlist vs pin_playlist (deprecated); follow/unfollow vs check_following_artists vs check_in_library. The descriptions do contain decision guides and cross-references, which helps, but the volume of overlapping purpose makes misselection highly probable.
Names are overwhelmingly snake_case verb_noun (get_devices, create_playlist, remove_from_library, add_to_queue), with occasional noun_verb constructions (playlist_shuffle, library_genre_report) but consistently readable. No camelCase mixing except the deprecated processV2-style naming is absent. One or two oddballs (whats_new, wind_down_status, spotify_doctor) but not enough to break the pattern.
129 tools for a music/podcast control server vastly exceeds a manageable surface. Even accounting for discovery helpers (find_tool, inspect_tool, toolset_report), the set is huge and many tools have narrow, heavily qualified purposes, making it effectively unusable without a meta-discovery layer. This is an extreme count mismatch.
The surface covers core playback, library CRUD, playlist manipulation, podcast/audiobook, search, export/import/backup, and account management extremely thoroughly. Notable gaps are around artist follow/unfollow (explicitly unavailable in API) and playlist reordering by drag-and-drop, but those are external limitations or edge cases. For the apparent domain, the coverage is nearly exhaustive.
Maintenance
Related MCP Connectors
Spotify: Spotify Data API for Millions of songs & podcasts, artists, albums, playlists and more.
Full Spotify Web API coverage - albums, artists, playlists, player controls, and more.
The media memory layer for AI agents and their humans. Your AI client gets 29 tools to search your collection, add items, update ratings, preview music, and find patterns across everything you've read, watched, and listened to.
AI music and podcast platform for autonomous agents. SoundCloud for AI bots.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI assistants to control Spotify playback, search for music, manage playlists, and interact with your Spotify library through natural language commands.19-
- FlicenseAqualityDmaintenanceEnables AI assistants to control Spotify playback, search for music, manage playlists, and access library information through the Spotify API. Requires Spotify Premium for playback control features.4-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to control Spotify playback, search music, manage playlists and library, and access user listening insights via the Spotify Web API.-
- FlicenseBqualityBmaintenanceEnables AI assistants to control Spotify playback, search the catalog, and manage playlists and liked songs through natural language. Supports reading currently playing tracks, queues and devices, plus play, pause, skip, queueing, volume control, and playlist creation and editing.30-