Skip to main content
Glama
Stipe15

spotify-mcp

by Stipe15

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
SPOTIFY_CLIENT_IDYesYour Spotify app Client ID, used for PKCE authorization. Required to run the server.
SPOTIFY_MCP_DRY_RUNNoWhen 'true' (default), write operations are previewed but never sent to Spotify. Set to 'false' to actually execute writes.true
SPOTIFY_MCP_TIMEZONENoIANA timezone name (e.g. Europe/Zagreb) used for local listening-history analytics. Without it, hour-of-day/day-of-week results are bucketed in UTC.
SPOTIFY_REDIRECT_PORTNoPort for the local redirect URI. Must match the redirect URI registered in your Spotify app.8888
SPOTIFY_MCP_ALLOW_REMOVALSNoSet to 'true' to enable the remove_playlist_items tool. Default is 'false'.false

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_meA

Return the current user's Spotify profile: id, display name, uri, images, follower count. Note: email, country, and product tier were removed from this endpoint by Spotify in February 2026 and are never present.

server_statusA

Report this server's own state: dry-run mode, Spotify authorization, granted OAuth scopes, whether destructive playlist removals are enabled, the local listening-history database's size and date range if built, and HTTP cache stats.

get_playback_stateA

Current Spotify playback state: what's playing, on which device, progress, shuffle/repeat. Returns active=false (nothing else populated) when no device is active — that is normal, not an error.

get_top_artistsA

The user's most-played artists over a time window (short_term=~4 weeks, medium_term=~6 months, long_term=~1 year). This is Spotify's own affinity ranking, computed from listening history — not a live popularity/trending signal (Spotify removed those in 2026).

get_top_tracksA

The user's most-played tracks over a time window (short_term=~4 weeks, medium_term=~6 months, long_term=~1 year). Spotify's own affinity ranking from listening history — not a live popularity/trending signal.

get_recently_playedA

The user's last-played tracks, most recent first. Spotify caps this at the last 50 plays — it is NOT a full listening history (use the local analytics tools for that, once built). after_ms/before_ms are Unix ms timestamps and mutually exclusive.

get_saved_tracksA

Tracks saved to the user's library ('Liked Songs'), most recent first.

get_saved_albumsB

Albums saved to the user's library, most recently added first.

get_followed_artistsA

Artists the user follows. Cursor-paginated: pass the last returned artist id as after.

get_my_playlistsC

Playlists the user owns or follows.

get_playlistA

Metadata for one playlist (name, description, owner, item count) — not its contents. Use get_playlist_items for the tracks. Works for any playlist id, but the item count is only meaningful for playlists you own or collaborate on.

get_playlist_itemsA

Tracks (and episodes) in a playlist, paginated. IMPORTANT: only works for playlists the user owns or collaborates on — Spotify returns 403 for any other playlist, including every Spotify-editorial playlist. There is no way around this restriction. Each item's item field holds the track/episode object.

search_catalogA

Search the Spotify catalog. limit is capped at 10 (Spotify reduced this from 50 in Feb 2026) and offset at 1000 — for more than 10 matches, page with offset rather than expecting a bigger single batch. Prefer field-filtered terms (track/artist/album/year/isrc) over free_text: bare title text reliably matches sped-up edits, live versions, karaoke covers, and tribute recordings instead of the real thing. There is no popularity or relevance score in the response — nothing here indicates what is currently popular or trending.

get_trackA

Full metadata for one track by its Spotify id.

get_artistA

Full metadata for one artist by its Spotify id.

get_artist_albumsB

An artist's albums. include_groups filters by relationship — a comma-separated subset of album,single,appears_on,compilation; omit for all.

get_album_tracksC

An album's tracklist.

create_playlistA

Create a new, empty Spotify playlist. Requires confirmation (call once for a preview, again with confirm_token to execute — see the tool's response for exactly how). collaborative and public cannot both be true.

add_playlist_itemsA

Add tracks/episodes to a playlist by URI. Spotify accepts at most 100 URIs per request; this tool chunks automatically, so 250 tracks = 3 API calls under the hood (all covered by one confirmation). Append-only and does NOT deduplicate — check get_playlist_items first if duplicates matter. position (0-based) only guarantees exact placement for the first 100 URIs; any beyond that append at the end regardless of position. The preview shows the URIs verbatim: resolve them to human-readable names yourself first (e.g. via search_catalog) so you can show the user something readable.

replace_playlist_itemsA

Replace a playlist's entire contents with a new list of URIs — the existing items are discarded. The preview shows what will be lost alongside what replaces it. Pass an empty list to clear the playlist entirely. For more than 100 URIs, the first 100 replace in one call and the rest are appended after.

reorder_playlist_itemsA

Move a contiguous slice of a playlist's items to a new position. range_start is the 0-based index of the first item to move, range_length how many items (default 1), insert_before the 0-based index to insert them at. Pins to the playlist's current snapshot if you don't supply one — if the playlist changed since you last looked, get_playlist_items first.

update_playlist_detailsA

Update a playlist's name, description, and/or public/private visibility. Only the fields you pass are changed. The preview shows an old-to-new diff of just those fields.

set_playlist_coverA

Set a playlist's cover image from a local JPEG file. Spotify caps the encoded payload at 256 KB — this checks that before offering confirmation, so an oversized image fails fast with a clear message instead of a wasted round trip.

remove_playlist_itemsA

DESTRUCTIVE. Remove specific items from a playlist by URI. Disabled by default — set SPOTIFY_MCP_ALLOW_REMOVALS=true to enable. Requires a snapshot_id you fetched yourself (e.g. via get_playlist) immediately beforehand, so a removal only ever applies to the playlist state you actually looked at. Never call this from a broad instruction like 'clean up my library' — only on an explicit, specific removal request the user approved for these exact items.

describe_listening_dataA

Describe the local listening-history schema: tables, views, columns, and example queries. Read this before writing SQL for query_listening_history — it also documents what is_skip actually means and its limitations.

listening_summaryA

Overall listening totals, optionally within a date range (start/end as YYYY-MM-DD). Includes an overall skip rate — see describe_listening_data for what is_skip means and why it's a heuristic, not ground truth.

listening_by_hourA

Play counts and hours by local hour of day, day of week, or both. by is 'hour', 'dow' (1=Monday..7=Sunday), or 'hour_dow'. Uses whatever timezone was configured at ingest (SPOTIFY_MCP_TIMEZONE) — check server_status or describe_listening_data if results look shifted from your actual clock.

skip_statsA

Skip-rate leaderboard grouped by artist, track, or month. Reports both the derived skip rate (reason_end='fwdbtn' AND played under the skip threshold) and the export's own raw 'skipped' field's rate side by side — they can disagree; see describe_listening_data. min_plays filters out low-sample noise.

top_localA

Ranked artists, tracks, or albums by play count or total listening time, optionally within a date range. This is YOUR local listening history, not a live popularity signal — Spotify removed those endpoints in 2026.

taste_driftA

Compare artist listening between two date periods (each [start, end] as YYYY-MM-DD) by share of total plays. Returns three lists: gained (no plays in period A, present in B), lost (present in A, none in B), held (present in both, ranked by the biggest change in share). This is how your taste drifted, by your own play counts — not an external trend signal.

dropped_artistsA

Artists you used to play a lot but have gone quiet on: at least min_plays total plays, with none in the last silent_since_months. Ranked by historical play count.

rediscover_tracksA

Tracks you played a lot during a past window (played_start/played_end, YYYY-MM-DD) but haven't touched in not_since_months — e.g. '40 tracks I played a lot in 2023 but haven't touched since'. Returns track URIs ready to hand to build_playlist_from_candidates or add_playlist_items once you've reviewed them.

query_listening_historyA

Run a read-only SQL query (SELECT/WITH only) against the local listening database — the escape hatch for questions the named analytics tools don't cover. Call describe_listening_data first for the schema. Exactly one statement; no INSERT/UPDATE/DELETE/CREATE/ATTACH/PRAGMA/file-reading functions — all rejected before execution. Capped at a few thousand rows (truncated: true if hit) and a several-second timeout.

resolve_tracksA

Resolve {artist, title} candidates to verified Spotify track URIs. Every input ends up in exactly one of resolved/unresolved — never silently substituted or dropped. Matching requires the artist to genuinely match (not just the title), which is what catches sped-up edits, karaoke covers, tribute recordings, and live versions that a title-only search would happily return instead of the real track. strict=true (default) only accepts exact/strong title matches; set false to also accept fuzzy 'weak' matches (still flagged as such) at the cost of precision. This tool has no opinion on what is currently popular — chart freshness is only as good as whatever produced the candidate list.

build_playlist_from_candidatesA

Resolve {artist, title} candidates and build a new playlist from whatever resolves, in one two-phase call (resolve -> create playlist -> add tracks). Chart freshness comes entirely from wherever the candidate list came from — this tool cannot tell you what's currently popular on Spotify's own authority; say so to the user rather than implying otherwise. The preview always shows both the resolved tracks and the unresolved list before anything is created, and is marked low_confidence if fewer than ~70% of candidates resolved. skip_unresolved=false refuses to create anything unless every single candidate resolves.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Stipe15/spotify-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server