Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Spotify MCP

NPM · @NOVALUX12/SPOTIFY-MCP

Spotify Web API MCP: playback, library, playlists, search, podcasts. Not affiliated with Spotify.

+11 this week 96 Trust /100

Last scanned (9 hours ago)

Scores higher than 99% of npm servers

Category Entertainment and Games

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security98
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • 32 of 104 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency100
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Cryptographically verified build provenance (signed, bound to NovaLux12/spotify-mcp-server). View diagnostics → Pass
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 17 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability81
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 24249 tokens (~163/item across 148 items; 131 tools + 17 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
  • No destabilizing schema changes in the last 30 days.Pass
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (8% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 10 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 133 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
What we tested

Checks we ran (16)

  • Malware scan
  • Known CVEs
  • Install scripts
  • Dependency health
  • Source repository
  • Provenance
  • License
  • Maintenance
  • Security disclosure
  • Schema quality
  • Stability
  • Tool coverage
  • Injection markers
  • Destructive annotations
  • Judged manipulation
  • MCP protocol

Does not apply to this package (2)

  • Endpoint SecurityScored on hosted endpoints only. A package has no live endpoint of its own for us to probe.
  • Transport & ReachabilityScored on hosted endpoints only. A package has no live endpoint of its own for us to probe.

The score does not measure everything. What the score does not measure →

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 1 Nov 26 +11
    • Stability: fail → pass ▲ security
  • 25 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 17 to 20.

  • 23 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 10 to 14.

  • 20 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 0 to 4.

  • 19 Oct 26 0
    • Stability: fail → unverified ▼ security
    • Tool safety: pass → unverified ▼ security
    • Capabilities: pass → unverified ▼ functional
    • Tool coverage: 100 → unverified ▼ functional
    • Schema quality: 100 → unverified ▼ functional
    • Package version: 3.1.0 → 3.1.1 functional
  • 14 Oct 26 +33
    • Stability: unverified → fail ▼ security
    • Injection markers: unverified → pass ▲ security
    • Tool coverage: unverified → 100 ▲ functional
    • Schema quality: unverified → 100 ▲ functional
    • MCP protocol: unverified → pass ▲ functional
  • 13 Oct 26 0
    • Package version: 3.0.1 → 3.1.0 functional
  • 11 Oct 26 −33
    • Stability: fail → unverified ▼ security
    • Tool safety: pass → unverified ▼ security
    • Capabilities: pass → unverified ▼ functional
    • Tool coverage: 100 → unverified ▼ functional
    • Schema quality: 100 → unverified ▼ functional
    • Package version: 3.0.1 → 3.1.0 functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 5 Nov 2026 · Analysed npm/@novalux12/spotify-mcp@3.1.1

Provenance Verified

A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.

Result Verified
Ecosystem npm
Reason Verified
Discovered via Registry attestation endpoint
Source repo NovaLux12/spotify-mcp-server
Certificate issuer https://token.actions.githubusercontent.com
Certificate SAN https://github.com/NovaLux12/spotify-mcp-server/.github/workflows/publish.yml@refs/tags/v3.1.1
Rekor log index 3316895548
Predicate type SLSA build provenance https://slsa.dev/provenance/v1
Subject digest sha512:2540a1fa4aacf0673c6ff516b98214d6eb33fdc66f31143b60e77a8126ca0dd3b342ca039af3a3f85a91545074c36de9e080ed2ea8d3986235e9e47da

Background: How many MCP packages publish verified provenance →

Dependencies 104 packages
Packages resolved 104
Stale 32
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 131 exposed · ~23,162 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
get_saved_episodes ~180

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).

NameTypeReqDescription
fetch_allboolean–Fetch all pages instead of one page (ignores limit/offset)
limitinteger–1–50. Default: 20
marketstring–ISO 3166-1 alpha-2 country code, e.g. 'US'
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
offsetinteger–Pagination offset. Default: 0
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

get_saved_shows ~156

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).

NameTypeReqDescription
fetch_allboolean–Fetch all pages instead of one page (ignores limit/offset)
limitinteger–1–50. Default: 20
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
offsetinteger–Pagination offset. Default: 0
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

get_saved_tracks ~180

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).

NameTypeReqDescription
fetch_allboolean–Fetch all pages instead of one page (ignores limit/offset)
limitinteger–1–50. Default: 20
marketstring–ISO 3166-1 alpha-2 country code, e.g. 'US'
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
offsetinteger–Pagination offset. Default: 0
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

get_user_playlists ~155

List the current user's playlists

NameTypeReqDescription
fetch_allboolean–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…
limitinteger–1–50. Default: 20
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
offsetinteger–Pagination offset. Default: 0
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

get_user_playlists_by_id ~169

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).

NameTypeReqDescription
limitinteger–1–50. Default: 20
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
offsetinteger–Pagination offset. Default: 0
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
user_idstringyesSpotify user ID, spotify:user: URI, or open.spotify.com/user URL

No output schema declared.

No examples provided.

get_user_profile ~115

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

NameTypeReqDescription
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
user_idstringyesSpotify user ID, spotify:user: URI, or open.spotify.com/user URL

No output schema declared.

No examples provided.

grow_playlist ~214

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.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
exclude_savedboolean–Skip tracks already in your saved library (default true)
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
playlist_idstringyesTarget playlist ID to grow
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
sizeinteger–How many candidates to propose (default 20)

No output schema declared.

No examples provided.

history_search ~83

Search portability, backup and mutation-history stores; hits name their source. Quota: local only (no API).

NameTypeReqDescription
querystring–Substring to match
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
scopestring–Scope

No output schema declared.

No examples provided.

import_from_sidecar ~315

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:<kind>:<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.

NameTypeReqDescription
dry_runboolean–Preview only, making no API calls at all. Writes happen only when explicitly set to false.
input_pathstring–Path to sidecar JSON (default: <portability>/library.json)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

import_playlist ~239

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.

NameTypeReqDescription
contentstring–The M3U or CSV document body, passed inline
dry_runboolean–Parse and report what would be added without touching the playlist
formatstring–Document format; auto-detected when omitted
input_pathstring–Read the document from this local file instead of content
playlist_idstringyesTarget playlist ID, spotify:playlist: URI, or share URL
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

import_profile_state ~201

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 <file>.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.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
input_pathstringyesPath to the profile-state archive JSON file
modestring–merge = union on each store's own keys; overwrite = replace, keeping a .bak
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

inspect_tool ~79

Show one tool's full description and input schema before calling it

NameTypeReqDescription
response_formatstring–'concise' (default) = prose bullet list; 'detailed' = the same prose; 'json' = the result payload as parseable JSON text, identical to structuredContent
tool_namestringyesExact registered tool name

Structured output declared, but exposes no named fields.

No examples provided.

library_genre_report ~132

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.

NameTypeReqDescription
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

library_hygiene ~147

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.

NameTypeReqDescription
dry_runboolean–Preview cost only.
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

library_snapshot_diff ~97

Diff two sidecar JSON files (library.json or playlists.json): added/removed counts + samples. Quota: local only (no API).

NameTypeReqDescription
after_pathstringyesPath to after snapshot JSON
before_pathstringyesPath to before snapshot JSON
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

list_accounts ~102

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.

NameTypeReqDescription
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

list_backups ~115

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).

NameTypeReqDescription
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

list_scenes ~52

List saved playback scenes from the local sidecar

NameTypeReqDescription
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

merge_playlists ~251

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.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
limitinteger–Source page size, 1–100. Default: 100
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
new_namestring–Name for a newly created target playlist
playlistsarray–Canonical ordered playlists (1–10)
publicboolean–Visibility of a NEW playlist. Default: false
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
scan_capinteger–Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP
target_playlist_idstring–Existing playlist to APPEND into (never cleared)

No output schema declared.

No examples provided.

move_items_between_playlists ~375

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.

NameTypeReqDescription
dedupeboolean–Skip tracks already in target. Default: true
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
filterstring–Optional substring filter: only transfer tracks whose name or artist name contains this string (case-insensitive)
limitinteger–Source page size, 1–100. Default: 100
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
modestring–copy = leave source intact; move = remove from source after copy
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
scan_capinteger–Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP
source_lanestring–Lane name resolving to the source playlist; provide exactly one of source_playlist_id or source_lane
source_playlist_idstring–Source playlist ID, spotify:playlist: URI, or URL; provide exactly one of source_playlist_id or source_lane
target_lanestring–Lane name resolving to the target playlist; provide exactly one of target_playlist_id or target_lane
target_playlist_idstring–Target playlist ID, spotify:playlist: URI, or URL; provide exactly one of target_playlist_id or target_lane

No output schema declared.

No examples provided.

overlap_playlists ~207

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.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
limitinteger–Source page size, 1–100. Default: 100
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
min_overlapinteger–Minimum number of playlists a track must appear in. Default: all playlists
playlistsarray–Canonical ordered playlists (2–10)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
scan_capinteger–Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP

No output schema declared.

No examples provided.

pause ~84

Pause playback on the active device

NameTypeReqDescription
device_idstring–Target device ID
dry_runboolean–Preview only: describe what would change without performing it. Default false — pass true to preview.
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

pin_playlist ~124

DEPRECATED, use follow_playlist. This tool never pinned anything; it has always saved the playlist to your Spotify library via PUT /me/library.

NameTypeReqDescription
dry_runboolean–Preview only (default): pass dry_run: false to execute the follow.
playlist_idstringyesPlaylist ID to follow
publicboolean–Must be true or omitted; the library endpoint has no visibility parameter.
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
NameTypeReqDescription
cancelledboolean––
dry_runboolean––
okboolean––
receiptstring|null––

No examples provided.

plan_podcast_session ~281

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.

NameTypeReqDescription
kindstring–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)
marketstring–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 silentl…
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
minutesintegeryesSession length in minutes (1–480)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
saved_onlyboolean–When no kind is set, include recent episodes of saved shows too. Default: true (saved episodes only)

No output schema declared.

No examples provided.

play ~217

Start or resume playback. Optionally target specific content.

NameTypeReqDescription
context_uristring–Spotify URI for an album, artist, or playlist
device_idstring–Target device ID; uses active device if omitted
dry_runboolean–Preview only: describe what would change without performing it. Default false — pass true to preview.
offsetinteger–Index within an album/playlist context to start from. Ignored for ad-hoc uris; not valid for artist contexts (use offset_uri instead).
offset_uristring–Track URI inside the context to start from — required for artist contexts, where a numeric index is rejected
position_msinteger–Seek position to start at (ms)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
urisarray–Up to 100 track/episode URIs to play as an ad-hoc queue

No output schema declared.

No examples provided.

play_from_search ~190

Search Spotify by name and immediately play the best match. Works for songs and podcast episodes — no URI needed.

NameTypeReqDescription
device_idstring–Target device ID; uses active device if omitted
dry_runboolean–Preview only: describe what would change without performing it. Default false — pass true to preview.
marketstring–ISO 3166-1 alpha-2 country code — affects availability/relinking of results; defaults to SPOTIFY_MCP_MARKET
querystringyesSearch text, e.g. a song title or podcast episode name
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
search_typestring–What to search for: 'track' (song) or 'episode' (podcast episode)

No output schema declared.

No examples provided.

playlist_collab_toggle ~100

Toggle collaborative/public flags (guards public=true && collaborative=true 400). Quota: GET + PUT.

NameTypeReqDescription
collaborativeboolean–Target collaborative state for the playlist
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
playlist_idstringyesPlaylist ID, spotify:playlist: URI, or URL
publicboolean–Target visibility: true makes the playlist public

No output schema declared.

No examples provided.

playlist_reverse ~67

Reverse a playlist in one atomic replace. Quota: GET all + PUT/POST.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
playlist_idstringyesPlaylist ID, spotify:playlist: URI, or URL

No output schema declared.

No examples provided.

playlist_shuffle ~88

Fisher-Yates shuffle a playlist (seeded optional). Quota: GET all + PUT/POST.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
playlist_idstringyesPlaylist ID, spotify:playlist: URI, or URL
seedstring–Deterministic shuffle seed; omit for a random order

No output schema declared.

No examples provided.

playlist_sort ~163

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.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
playlist_idstringyesPlaylist ID, spotify:playlist: URI, or URL
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
sort_bystring–Sort key applied to the playlist

No output schema declared.

No examples provided.

playlist_subtract ~270

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.

NameTypeReqDescription
base_playlist_idstringyesBase playlist ID, URI, or URL. Required; list only the subtraction sources in playlists.
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
limitinteger–Source page size, 1–100. Default: 100
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
playlistsarray–Canonical ordered playlists (1–10)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
scan_capinteger–Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP

No output schema declared.

No examples provided.

playlist_symmetric_difference ~168

Tracks in exactly one of two playlists (XOR). Quota: 2 GETs.

NameTypeReqDescription
limitinteger–Source page size, 1–100. Default: 100
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
playlist_astring–Canonical A playlist; provide with playlist_b
playlist_bstring–Canonical B playlist; provide with playlist_a
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
scan_capinteger–Maximum rows to read from each playlist; bounded by SPOTIFY_MCP_FETCH_ALL_CAP

No output schema declared.

No examples provided.

playlist_template_apply ~164

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.

NameTypeReqDescription
descriptionstring–Playlist description override
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
limitinteger–How many tracks (1-100, default 30)
namestring–Playlist name (default: "<Template> Mix")
publicboolean–Whether the playlist is public
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
templatestringyesTemplate name

No output schema declared.

No examples provided.

playlist_to_library ~122

Save all tracks of a playlist to your Liked Songs (library). Quota: GET playlist items + PUT /me/tracks (chunked 50).

NameTypeReqDescription
dedupeboolean–Skip tracks already saved (default true)
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
playlist_idstringyesSource playlist ID
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

playlist_trim ~154

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.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
keepintegeryesHow many items to keep
keep_whichstring–Which end of the playlist to keep items from. Default first
playlist_idstringyesPlaylist ID, spotify:playlist: URI, or URL

No output schema declared.

No examples provided.

playlist_union ~285

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.

NameTypeReqDescription
dedupeboolean–Drop duplicate URIs across the merged sources. Default true
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
limitinteger–Source page size, 1–100. Default: 100
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
playlistsarray–Canonical ordered playlists (2–10)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
scan_capinteger–Maximum source rows to scan; bounded by SPOTIFY_MCP_FETCH_ALL_CAP
target_namestring–Name for a newly created target playlist; provide exactly one of target_playlist_id or target_name
target_playlist_idstring–Existing target playlist (ID, URI, or URL); provide exactly one of target_playlist_id or target_name

No output schema declared.

No examples provided.

remove_duplicate_playlist_items ~293

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.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
include_relinkedboolean–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…
match_bystring–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 o…
playlist_idstringyesPlaylist ID

No output schema declared.

No examples provided.

remove_from_library ~173

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).

NameTypeReqDescription
dry_runboolean–Preview only: perform the read side and return a PLAN without changing anything. Default true — pass dry_run=false to commit.
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
urisarrayyesSpotify URIs to remove

No output schema declared.

No examples provided.

remove_from_library_by_playlist ~158

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).

NameTypeReqDescription
dry_runboolean–Preview only: perform the read side and return a PLAN without changing anything. Default true — pass dry_run=false to commit.
playlist_idstringyesPlaylist ID whose tracks will be removed from library
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

remove_from_playlist ~102

Remove tracks or episodes from a playlist. Max 100 entries per call.

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
playlist_idstringyesPlaylist ID
snapshot_idstring–Apply the removal against this playlist version instead of the latest
urisarrayyesURIs to remove; use { uri, positions } to target specific occurrences of a repeated URI

No output schema declared.

No examples provided.

reorder_playlist_items ~179

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).

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
insert_beforeintegeryesIndex to insert the range before. 0-based index into the playlist's current item order (0 = the first item).
playlist_idstringyesPlaylist ID
range_lengthinteger–Number of items to move. Default: 1
range_startintegeryesIndex of the first item to move. 0-based index into the playlist's current item order (0 = the first item).

No output schema declared.

No examples provided.

replace_playlist_items ~98

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).

NameTypeReqDescription
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
playlist_idstringyesPlaylist ID
urisarrayyesComplete ordered list of track or episode URIs the playlist should contain

No output schema declared.

No examples provided.

restore_library_snapshot ~326

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 · <name> (<snapshot date>)' — 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.

NameTypeReqDescription
backup_pathstringyesSnapshot JSON path from backup_library (see list_backups)
categoriesarray–Which snapshot categories to restore. Default: all
dry_runboolean–DEFAULT true: read-only preview of exactly what would be added. Set false to perform the (additive) writes after explicit confirmation.
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

save_discover_weekly ~145

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).

NameTypeReqDescription
archive_namestring–Archive playlist name (created if missing, overwritten if present)
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

save_release_radar ~144

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).

NameTypeReqDescription
archive_namestring–Archive playlist name (created if missing, overwritten if present)
dry_runboolean–Preview only: validate inputs and describe exactly what would change without performing it
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object

No output schema declared.

No examples provided.

save_scene ~173

Save a named playback scene (device + volume + shuffle/repeat + optional context) to the local sidecar (~/.spotify-mcp/scenes.json)

NameTypeReqDescription
context_uristring–Context URI to start on apply (e.g. spotify:playlist:…)
device_hintstring–Device name substring (case-insensitive) or exact device id
namestringyesScene name (key in the sidecar)
repeatstring–Repeat mode: 'off' | 'track' | 'context'
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
shuffleboolean–Shuffle state
volumeinteger–Master volume percent (0–100)

No output schema declared.

No examples provided.

save_to_library ~163

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.

NameTypeReqDescription
dry_runboolean–Preview only: perform the read side and return a PLAN without changing anything. Default true — pass dry_run=false to commit.
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
urisarrayyesSpotify URIs to save (e.g. ["spotify:track:abc", "spotify:user:xyz"])

No output schema declared.

No examples provided.

schedule_wind_down ~166

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.

NameTypeReqDescription
device_idstring–Target device id; defaults to the active device
dry_runboolean–Preview only: describe what would change without performing it. Default false — pass true to preview.
floor_volumeinteger–Volume floor the ramp never goes below (default 10)
minutesintegeryesTotal ramp duration in minutes (1–180)
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
step_minutesinteger–Minutes between volume steps (default 5)

No output schema declared.

No examples provided.

search ~338

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).

NameTypeReqDescription
include_externalstring–Pass "audio" to include externally-hosted audio items marked as playable
limitinteger–Results per type, 1–10. Default: 5
marketstring–ISO 3166-1 alpha-2 country code, e.g. 'US' — uppercased automatically
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
offsetinteger–Index of the first result to return, 0–1000. Use with limit to page through results
querystringyesSearch query
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
typesarray–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.

No output schema declared.

No examples provided.

search_deep ~324

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).

NameTypeReqDescription
marketstring–ISO 3166-1 alpha-2 country code, e.g. 'US'
max_resultsinteger–Max items to return (default: SPOTIFY_MCP_MAX_ITEMS env or 50)
offsetinteger–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
pagesinteger–Pages of 10 results to walk per type, 1–5. Default: 1
querystringyesSearch query
response_formatstring–'concise' = human prose, 'detailed' = more fields in prose, 'json' = raw API object
typesarray–Content types to search. Default: ["track"]

No output schema declared.

No examples provided.

Install

How do I install the Spotify MCP server?

Spotify MCP runs locally as an npm package, launched with npx -y @novalux12/spotify-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

npm · @novalux12/spotify-mcp

# add to Claude Code
claude mcp add novalux12-spotify-mcp-server -- npx -y @novalux12/spotify-mcp
Common questions

What is the Spotify MCP server?

Spotify MCP is listed in the public MCP registry as io.github.NovaLux12/spotify-mcp-server. Spotify Web API MCP: playback, library, playlists, search, podcasts. Not affiliated with Spotify. This page covers its npm package (@novalux12/spotify-mcp).

Is the Spotify MCP server safe to use?

Spotify MCP scores 96 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Spotify MCP server expose?

Spotify MCP exposes 131 tools: search, get_saved_tracks, get_saved_albums, get_saved_shows, get_saved_episodes, and 126 more. Their descriptions and schemas cost roughly 23,162 tokens of context every time the server is loaded.

Is the Spotify MCP server still maintained?

Spotify MCP is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the Spotify MCP server under?

Spotify MCP declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

What did VerifyMCP test on the Spotify MCP server?

VerifyMCP ran 16 checks on Spotify MCP, covering Malware scan, Known CVEs, Install scripts, Dependency health and 12 more. Endpoint Security and Transport & Reachability do not apply to an npm package, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.