Skip to main content
Glama
Spotify MCP Server

Spotify MCP Server

by jamiew

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
SPOTIFY_CLIENT_IDYesYour Spotify Client ID from developer.spotify.com
SPOTIFY_REDIRECT_URINoThe redirect URI configured in your Spotify apphttp://localhost:8888
SPOTIFY_CLIENT_SECRETYesYour Spotify Client Secret from developer.spotify.com

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

Get the signed-in user's Spotify profile.

Returns:
    UserProfile. email/country/product are unavailable on newer Spotify apps
    and come back empty rather than erroring.
get_playback_stateA

Get the current playback state: track, device, progress, shuffle and repeat.

Returns:
    PlaybackState (is_playing is False when nothing is playing)
control_playbackA

Control Spotify playback. Requires Premium and an active device.

Args:
    action: 'play', 'pause', 'next', 'previous', 'seek', 'volume', 'shuffle' or 'repeat'
    track_ids: Tracks or episodes to play (action='play'; ignored when
        context_uri is set). Bare IDs are tracks; pass spotify:episode: URIs
        or episode share URLs for podcast episodes.
    context_uri: Album, playlist, artist or show URI to play (action='play')
    position_ms: Position in milliseconds (required for action='seek')
    volume_percent: Volume 0-100 (required for action='volume')
    state: 'on'/'off' for shuffle; 'track'/'context'/'off' for repeat
    device_id: Target device (default: the currently active one)

Returns:
    Last observed PlaybackState, possibly unconfirmed.

Confirmation is best effort: at most five post-action reads with brief waits.
Stale state or a later read failure returns the last observation. Checks do not
verify every requested track, context or device transition.
list_devicesA

List the user's available Spotify devices.

Returns:
    DeviceList; use transfer_playback with a device id to make one active
transfer_playbackA

Move playback to a different device (see list_devices).

Args:
    device_id: Target device ID
    play: Start playing after the transfer (default True)
search_musicA

Search Spotify for tracks, albums, artists, or playlists.

Args:
    query: Search query
    qtype: Type ('track', 'album', 'artist', 'playlist')
    limit: Max results per page (1-50, default 10). Spotify caps search at 10
        per page for restricted apps and rejects anything larger; a larger
        limit is retried at the cap rather than failing. Check the returned
        `limit` for what was actually served, and use `offset` to go deeper.
    offset: Number of results to skip for pagination (default 0)
    year: Filter by year (e.g., '2024')
    year_range: Filter by year range (e.g., '2020-2024')
    genre: Filter by genre (e.g., 'electronic', 'hip-hop')
    artist: Filter by artist name
    album: Filter by album name

Returns:
    SearchResults with 'items' (list of tracks) and pagination info ('total', 'limit', 'offset')

Note: Filters use Spotify's search syntax. For large result sets, use offset to paginate.
Example: query='love', year='2024', genre='pop' searches for 'love year:2024 genre:pop'
add_to_queueB

Add a track or podcast episode to the playback queue.

Args:
    track_id: Track ID, or a spotify:track:/spotify:episode: URI or
        open.spotify.com URL. A bare ID is taken as a track.
Returns:
    Status and message
get_queueB

Get the current playback queue. Returns: Currently playing track and queue of upcoming tracks

get_tracksA

Get detailed information about one or more Spotify tracks.

Args:
    track_ids: Single track ID or list of track IDs (up to 50)

Returns:
    TrackList with 'tracks' containing track metadata including release_date.
    For single ID, returns {'tracks': [track]}.

Note: Batch lookup is much more efficient where it is available - 50 tracks
in 1 API call instead of 50. Spotify withholds the batch endpoint from some
apps, in which case this transparently falls back to one request per track,
so the result is the same either way.
get_artistA

Get details for one or more Spotify artists, batched into a single request.

Args:
    artist_ids: One artist ID/URI, or a list of up to 50. A list costs one
        Spotify request rather than one per artist.
Returns:
    ArtistInfo whose `artists` follows the order requested. `top_tracks` is
    filled only when a single artist was requested, and is empty rather than
    an error when Spotify withholds that endpoint.
get_playlistA

Get basic information about a Spotify playlist.

Args:
    playlist_id: Spotify playlist ID

Returns:
    Playlist metadata (no tracks - use get_playlist_tracks for tracks)

Note: This returns playlist info only. For tracks, use get_playlist_tracks
which supports full pagination for large playlists.
create_playlistB

Create a new Spotify playlist.

Args:
    name: Playlist name
    description: Playlist description (default: empty)
    public: Whether playlist is public (default: False)

Returns:
    The created Playlist
add_tracks_to_playlistB

Add tracks or podcast episodes to a playlist.

Args:
    playlist_id: Playlist ID
    track_uris: Track or episode URIs/URLs (up to 100). Bare IDs are tracks;
        pass spotify:episode: URIs or episode URLs for episodes.
list_playlistsA

Get current user's playlists with pagination support.

Args:
    limit: Max playlists to return per page (1-50, default 20)
    offset: Number of playlists to skip for pagination (default 0)

Returns:
    PlaylistList with 'items' (list of playlists) and pagination info ('total', 'limit', 'offset')

Note: For users with many playlists, use offset to paginate through results.
Example: offset=0 gets playlists 1-20, offset=20 gets playlists 21-40, etc.
get_playlist_tracksA

Get tracks from a playlist with full pagination support.

Args:
    playlist_id: Playlist ID
    limit: Max tracks to return (None for all tracks, up to 10,000 safety limit)
    offset: Number of tracks to skip for pagination (default 0)

Returns:
    PlaylistTracks with 'items' (list of tracks), 'total', 'limit', 'offset'

Note: Large playlists require pagination. Use limit/offset to get specific ranges:
- Get first 100: limit=100, offset=0
- Get next 100: limit=100, offset=100
- Get all tracks: limit=None (use with caution on very large playlists)
remove_tracks_from_playlistB

Remove tracks or podcast episodes from a playlist.

Args:
    playlist_id: Playlist ID
    track_uris: Track or episode URIs/URLs to remove. Bare IDs are tracks.
update_playlist_detailsC

Modify playlist details.

Args:
    playlist_id: Playlist ID
    name: New playlist name (optional)
    description: New playlist description (optional)
    public: Whether playlist should be public (optional)
reorder_playlistA

Move a contiguous block of tracks to a new position within a playlist.

Args:
    playlist_id: Playlist ID
    range_start: Zero-based position of the first track to move
    insert_before: Zero-based position to insert the moved block before.
        Pass the playlist's total track count to move the block to the end.
    range_length: Number of consecutive tracks to move (default 1)
    snapshot_id: Optional playlist snapshot ID to guard against concurrent edits

Returns:
    ActionResult with the new snapshot_id

Note: Positions are zero-based. Example: move the first 3 tracks to just
before position 10 with range_start=0, range_length=3, insert_before=10.
get_albumA

Get details for one or more Spotify albums, batched into a single request.

Args:
    album_ids: One album ID/URI, or a list of up to 20 — Spotify's own cap
        for album batches, which is lower than the 50 for tracks and artists.

Returns:
    AlbumInfo whose `albums` follows the order requested. `tracks` holds the
    album's track list only when a single album was requested.
get_saved_tracksA

Get user's saved/liked tracks (Liked Songs library).

Args:
    limit: Max tracks to return per page (1-50, default 20)
    offset: Number of tracks to skip for pagination (default 0)

Returns:
    SavedTracks with 'items' (tracks with added_at timestamp) and pagination info
save_tracksA

Save (like) tracks to the user's library.

Args:
    track_ids: Track IDs or URIs (up to 50)
remove_saved_tracksA

Remove tracks from the user's saved (liked) tracks.

Args:
    track_ids: Track IDs or URIs (up to 50)
check_saved_tracksA

Check which tracks are already liked, without paging the whole library.

Up to 50 tracks per tool call, split into upstream chunks of at most 40.
Use this before save_tracks rather than paging through get_saved_tracks.

Args:
    track_ids: Track IDs or URIs (up to 50)
Returns:
    MembershipStatus.results maps each Spotify track id to true if liked
check_saved_albumsA

Check which albums are already saved to the library.

Up to 20 albums per tool call, preserving this tool's existing album cap.

Args:
    album_ids: Album IDs or URIs (up to 20)
Returns:
    MembershipStatus.results maps each Spotify album id to true if saved
check_following_artistsA

Check up to 50 artist follows in upstream chunks of at most 40.

Uses artist URIs on the consolidated library route, with a legacy fallback.
Requires user-follow-read; reauthorize if your existing grant lacks it.

Args:
    artist_ids: Artist IDs or URIs (up to 50)
Returns:
    MembershipStatus.results maps each Spotify artist id to true if followed
get_saved_albumsB

Get albums saved in the user's library.

Args:
    limit: Max albums to return per page (1-50, default 20)
    offset: Number of albums to skip for pagination (default 0)

Returns:
    SavedAlbums with 'items' (albums with added_at) and pagination info
save_albumsB

Save albums to the user's library.

Args:
    album_ids: Album IDs or URIs (up to 20)
remove_saved_albumsB

Remove albums from the user's library.

Args:
    album_ids: Album IDs or URIs (up to 20)
get_followed_artistsA

Get the artists the user follows. Paged by cursor, not offset.

Args:
    limit: Max artists to return per page (1-50, default 20)
    after: The `after` cursor from the previous page (omit for the first page)

Returns:
    FollowedArtists; pass its `after` back for the next page (None on the last)
follow_artistsA

Follow artists. Requires user-follow-modify; reauthorize if it is missing.

Args:
    artist_ids: Artist IDs or URIs (up to 50)
unfollow_artistsA

Unfollow artists. Requires user-follow-modify; reauthorize if it is missing.

Args:
    artist_ids: Artist IDs or URIs (up to 50)
follow_playlistA

Follow (save) a playlist so it appears in the user's library.

Args:
    playlist_id: Playlist ID, URI or open.spotify.com URL
unfollow_playlistA

Unfollow a playlist, removing it from the user's library.

For playlists the user owns this is how Spotify deletes them — there is no
separate delete endpoint.

Args:
    playlist_id: Playlist ID or URI
get_saved_showsA

Get the podcast shows saved in the user's library.

Args:
    limit: Max shows to return per page (1-50, default 20)
    offset: Number of shows to skip for pagination (default 0)

Returns:
    SavedShows with 'items' (shows with added_at) and pagination info
save_showsB

Save (follow) podcast shows to the user's library.

Args:
    show_ids: Show IDs or URIs (up to 50)
remove_saved_showsB

Remove podcast shows from the user's library.

Args:
    show_ids: Show IDs or URIs (up to 50)
check_saved_showsA

Check which podcast shows are already saved, in upstream chunks of 40.

Args:
    show_ids: Show IDs or URIs (up to 50)
Returns:
    MembershipStatus.results maps each Spotify show id to true if saved
check_saved_episodesA

Check which podcast episodes are already saved, in upstream chunks of 40.

Args:
    episode_ids: Episode IDs or URIs (up to 50)
Returns:
    MembershipStatus.results maps each Spotify episode id to true if saved
get_show_episodesA

Get a podcast show's episodes, with the user's resume point for each.

Args:
    show_id: Show ID, URI or open.spotify.com URL
    limit: Max episodes to return per page (1-50, default 20)
    offset: Number of episodes to skip for pagination (default 0)

Returns:
    EpisodeList with 'items' and pagination info
get_saved_episodesA

Get the podcast episodes saved in the user's library.

Args:
    limit: Max episodes to return per page (1-50, default 20)
    offset: Number of episodes to skip for pagination (default 0)

Returns:
    EpisodeList with 'items' (episodes with show and added_at) and pagination info
save_episodesA

Save podcast episodes to the user's library.

Args:
    episode_ids: Episode IDs or URIs (up to 50)
remove_saved_episodesB

Remove podcast episodes from the user's library.

Args:
    episode_ids: Episode IDs or URIs (up to 50)
get_saved_audiobooksB

Get the audiobooks saved in the user's library.

Args:
    limit: Max audiobooks to return per page (1-50, default 20)
    offset: Number of audiobooks to skip for pagination (default 0)

Returns:
    SavedAudiobooks with 'items' and pagination info
check_saved_audiobooksA

Check which audiobooks are already saved, in upstream chunks of 40.

Args:
    audiobook_ids: Audiobook IDs or URIs (up to 50)
Returns:
    MembershipStatus.results maps each Spotify audiobook id to true if saved
save_audiobooksB

Save audiobooks to the user's library.

Args:
    audiobook_ids: Audiobook IDs or URIs (up to 50)
remove_saved_audiobooksB

Remove audiobooks from the user's library.

Args:
    audiobook_ids: Audiobook IDs or URIs (up to 50)
get_recently_playedB

Get recently played tracks, most recent first.

Args:
    limit: Max tracks to return (1-50, default 20)

Returns:
    RecentlyPlayed with each track's played_at timestamp
get_top_itemsA

Get the user's top artists or tracks over a time range.

This remains useful when recommendations or related artists are unavailable
to the app. Spotify's policy also restricts analysis and AI ingestion.

Args:
    item_type: 'tracks' or 'artists' (default 'tracks')
    time_range: 'short_term' (~4 weeks), 'medium_term' (~6 months) or 'long_term'
    limit: Max items to return (1-50, default 20)

Returns:
    TopItems with either 'tracks' or 'artists' populated

Prompts

Interactive templates invoked by user choice

NameDescription
discover_similarFind artists similar to one you name, without a recommendations endpoint.
taste_profileSummarize listening habits from top items and recent plays.
create_mood_playlistCreate a playlist based on mood and preferences.
analyze_large_playlistAnalyze a large playlist efficiently using pagination.
discover_music_systematicallySystematically discover music using search pagination.

Resources

Contextual data attached and managed by the client

NameDescription
current_userCurrent user's profile.
current_playback_resourceCurrent playback state.

TDQS

B3.4/5.0

Scored across 48 tools

Disambiguation4/5

Most tools target a clear resource+action pair (save_tracks vs check_saved_tracks vs get_saved_tracks, follow_artists vs check_following_artists), and descriptions explicitly cross-reference each other. The main soft spots are control_playback being a multi-action mega-tool that partly overlaps transfer_playback and add_to_queue, and the large family of save/remove/check/get library tools for six resource types that a hurried agent could mix up.

Naming Consistency4/5

Nearly everything follows a verb_noun pattern (get_tracks, save_albums, remove_saved_shows, list_playlists, check_saved_episodes), with predictable get_/save_/remove_/check_ prefixes per resource. Minor deviations like get_me and control_playback (verb-only, multiplexed) are the only breaks in the pattern.

Tool Count2/5

48 tools is heavy for a single MCP surface; the library-management matrix (get/save/remove/check for tracks, albums, shows, episodes, audiobooks, artists, playlists) alone accounts for ~20 tools. It mirrors the Spotify API faithfully, but many of these will rarely be selected and inflate the decision space for an agent.

Completeness4/5

Coverage is broad: playback control, queue, playlists with reorder, library CRUD across all media types, podcasts, audiobooks, and personalization. Gaps are mostly read-side detail endpoints — no get_show, get_episode, or get_audiobook metadata tools, and playlist deletion is only reachable via unfollow_playlist — but agents can work around these.

Maintenance

ActivityMaintained
ResponsivenessLimited data