Spotify MCP Server
This Spotify MCP server enables AI assistants to search, control playback, manage playlists and library, browse content, and access profile, podcasts, and audiobooks via the Spotify Web API.
Search for tracks, albums, artists, playlists, shows, episodes, and audiobooks
Control playback: play/pause, skip, seek, volume, shuffle, repeat, queue, transfer, devices
Manage playlists: create, update, add/remove/reorder tracks (auto-chunks large batches)
Manage library: save/remove/check saved items and follow/unfollow artists, users, playlists
Browse details: albums, artists, tracks, shows, episodes, audiobooks, chapters
View user profile, top artists/tracks, recently played, and diagnostic whoami
List followed artists and user's playlists
Access resources (profile, playback, queue, top items) and prebuilt prompts for workflows
Provides tools for searching music, controlling playback, managing playlists, and accessing user library via the Spotify Web API.
Spotify MCP Server
A Model Context Protocol (MCP) server that provides tools for interacting with the Spotify Web API. Enables AI assistants like Claude to search music, control playback, manage playlists, and more.
Features
Search - Find tracks, albums, artists, playlists, shows, episodes, and audiobooks
Playback Control - Play, pause, skip, seek, volume, shuffle, repeat, queue management
Playlists - Create, update, add/remove/reorder tracks (auto-chunks large batches)
Library - View and manage saved tracks, albums, shows, episodes, and audiobooks
Browse - Get details on tracks, albums, artists, episodes, and chapters
Podcasts & Audiobooks - Browse shows, episodes, audiobooks, and chapters
Follow - List followed artists; follow/unfollow artists, users, and playlists through the library tools by URI
User Profile - View profile, top artists/tracks, diagnostic
whoamiResources - Subscribable snapshots of profile, playback, queue, top items
Prompts - Pre-baked workflows for playlist building, listening summaries, library cleanup
Transports -
stdio(default),sse, andstreamable-httpUses only non-deprecated Spotify Web API endpoints
Related MCP server: Spotify MCP Server
Example interactions
"What am I listening to right now?"
"Play some Radiohead on my living room speaker."
"Skip this track and turn the volume down to 30."
"Build me a playlist of 25 chill tracks based on what I've been listening to this week."
"Add the last three songs I played to my 'Focus' playlist."
"Show me my top artists from the last six months."
"Search for live albums by Nils Frahm and save the best one to my library."
"Unfollow every playlist I haven't opened that wasn't made by me."
"Queue up the next episode of the show I was listening to yesterday."
Prerequisites
uv — install with
curl -LsSf https://astral.sh/uv/install.sh | shA Spotify Developer account
A Spotify app with Client ID and Client Secret
Getting Your Spotify Credentials
Go to the Spotify Developer Dashboard
Click Create App
Fill in the app details:
App name: Choose any name (e.g., "My MCP Server")
App description: Optional
Redirect URI:
http://127.0.0.1:8888/callbackWhich API/SDKs are you planning to use?: Select Web API
Click Save
On your app's page, find your Client ID
Click Show client secret to reveal your Client Secret
Important: The redirect URI must exactly match
http://127.0.0.1:8888/callback(or whatever you set inSPOTIFY_REDIRECT_URI). Do not uselocalhost— use127.0.0.1.
Installation
Pick your client below. All examples use uvx to fetch the server on demand — no clone, no manual install.
Claude Code
claude mcp add spotify \
-e SPOTIFY_CLIENT_ID=your_client_id \
-e SPOTIFY_CLIENT_SECRET=your_client_secret \
-- uvx mcp-server-spotifyOther MCP clients
Most MCP clients configure servers via a JSON file. Add this entry to your client's MCP config:
{
"mcpServers": {
"spotify": {
"command": "uvx",
"args": ["mcp-server-spotify"],
"env": {
"SPOTIFY_CLIENT_ID": "your_client_id",
"SPOTIFY_CLIENT_SECRET": "your_client_secret"
}
}
}
}Running from a local checkout
For development, or if you want to run a modified copy:
git clone https://github.com/llyfn/spotify-mcp.git
cd spotify-mcp && uv syncThen point your client at the local checkout instead of uvx:
"command": "uv",
"args": ["--directory", "/absolute/path/to/spotify-mcp", "run", "mcp-server-spotify"]Configuration
Variable | Required | Default | Description |
| Yes | — | Your Spotify app's Client ID |
| Yes | — | Your Spotify app's Client Secret |
| No |
| OAuth redirect URI |
| No |
| MCP transport: |
| For | — | Bearer token clients must send on every request (min. 32 ASCII chars) |
| No |
| HTTP bind address. Non-loopback values require |
| No |
| HTTP port |
| No | — | Comma-separated |
Spotify API notes
Development-mode Spotify apps have these restrictions (see the February 2026 migration guide):
The app owner needs an active Spotify Premium subscription.
API quota is shared by all Client IDs on the developer account. When it runs out, tools report
Quota exceeded.Search returns at most 10 results per type.
Full playlist contents are only returned for playlists you own or collaborate on.
Authentication
The server uses Spotify's Authorization Code flow:
On first use, the server opens your browser to Spotify's login page
Spotify will ask you to approve access — the server requests all scopes needed for the full tool set (playback, library, playlists, and user data)
After you authorize, Spotify redirects to the local callback server
The server exchanges the authorization code for access/refresh tokens
Tokens are stored securely in
~/.spotify-mcp/credentials.jsonTokens are automatically refreshed when they expire
In stdio mode, if running in a headless environment (SSH, Docker), the auth URL will be printed to stderr — copy and paste it into a browser manually.
Remote servers
HTTP transports never start the browser login themselves. Authorize once on the server host:
ssh -L 8888:127.0.0.1:8888 you@server # forwards Spotify's callback to the server
mcp-server-spotify auth # run on the server, in that SSH session, with your SPOTIFY_* env varsuvx users run uvx mcp-server-spotify auth. Open the printed URL in your local browser; the 8888 must match the port in SPOTIFY_REDIRECT_URI. Run auth as the user the server runs as, since credentials are written to that user's ~/.spotify-mcp. Alternatively, run mcp-server-spotify auth on any machine and copy ~/.spotify-mcp/credentials.json to the server (for containers, into a volume mounted at the user's ~/.spotify-mcp); this works only with the same SPOTIFY_CLIENT_ID and SPOTIFY_CLIENT_SECRET on both.
Re-authenticating
To re-authenticate (e.g., after revoking access), delete the stored credentials:
rm ~/.spotify-mcp/credentials.jsonAvailable Tools
Search
Tool | Description |
| Search for tracks, albums, artists, playlists, shows, episodes, or audiobooks |
Albums
Tool | Description |
| Get album details by ID |
| Get tracks in an album |
Artists
Tool | Description |
| Get artist details by ID |
| Get albums by an artist |
Tracks
Tool | Description |
| Get track details by ID |
Playlists
Tool | Description |
| Get playlist details |
| Update playlist name, description, or visibility |
| Get items in a playlist |
| Add tracks/episodes to a playlist |
| Remove items from a playlist |
| Reorder items in a playlist |
| Get the current user's playlists |
| Create a new playlist |
Library
Tool | Description |
| Get saved tracks |
| Get saved albums |
| Get saved shows |
| Get saved episodes |
| Get saved audiobooks |
| Save items to library, or follow artists/users/playlists by URI (max 40/request, auto-chunked) |
| Remove items from library, or unfollow artists/users/playlists by URI (max 40/request, auto-chunked) |
| Check if items are saved, or artists/users/playlists are followed, by URI (max 40/request, auto-chunked) |
Player
Tool | Description |
| Get current playback state |
| Get the currently playing track |
| Start or resume playback |
| Pause playback |
| Skip to next track |
| Skip to previous track |
| Seek to position in track |
| Set repeat mode (track/context/off) |
| Set playback volume |
| Toggle shuffle mode |
| Transfer playback to another device |
| Get available devices |
| Add item to playback queue |
| Get the playback queue |
| Get recently played tracks |
Shows & Podcasts
Tool | Description |
| Get show details |
| Get episodes of a show |
| Get a single episode by ID |
Audiobooks
Tool | Description |
| Get audiobook details |
| Get chapters of an audiobook |
| Get chapter details |
Follow
Tool | Description |
| List artists the user follows (cursor-paginated) |
Users
Tool | Description |
| Get current user's profile |
| Get top artists or tracks |
| Diagnostic — auth status, active device, configured scopes |
Resources
Snapshots of user state exposed under the spotify:// URI scheme. MCP clients can
include them as context or subscribe for updates without calling a tool.
URI | Description |
| Profile basics — display name, user ID, account ID |
| Current playback state (episode-aware) |
| Currently playing + next-up queue |
| Top tracks (last ~6 months) |
| Top artists (last ~6 months) |
Prompts
Canned workflows MCP clients can offer in their prompt picker. Each one walks the assistant through a multi-step task using the tools above.
Prompt | Description |
| Build a new playlist seeded by recent listening ( |
| Summarize the past week's listening grouped by artist/album |
| Build a playlist from a comma-separated list of artists ( |
| Scan saved tracks and propose cleanup candidates ( |
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
MIT - see LICENSE for details.
Available Tools
47 toolsadd_playlist_itemsA
Add tracks or episodes to a playlist. Auto-chunks at 100 items per request.
Args:
playlist_id: The Spotify ID of the playlist.
uris: List of Spotify URIs to add (e.g. ["spotify:track:xxx"]).
position: Position to insert items (0-based). Appends to end if not specified.
When chunking, subsequent chunks insert immediately after the previous.
Inputs: uris (required), playlist_id (required), position. Returns: result
add_to_queueA
Add a track or episode to the playback queue.
Args:
uri: Spotify URI of the item to add. E.g. "spotify:track:xxx".
device_id: ID of the device. If not provided, uses the active device.
Inputs: uri (required), device_id. Returns: result
check_saved_in_libraryB
Check whether items are saved or artists/users/playlists are followed.
Auto-chunks at 40 URIs per request.
Args:
uris: Spotify URIs: track, album, episode, show, audiobook, artist, user, or
playlist (e.g. ["spotify:track:xxx", "spotify:artist:yyy"]).
Inputs: uris (required). Returns: result
create_playlistB
Create a new playlist for the current user.
Args:
name: Name for the new playlist.
description: Description for the playlist.
public: Whether the playlist should be public (default True).
Inputs: name (required), public, description. Returns: result
get_albumA
Get details of a Spotify album by its ID.
Args:
album_id: The Spotify ID of the album.
market: ISO 3166-1 alpha-2 country code; affects availability/relinking.
Inputs: album_id (required), market. Returns: result
get_album_tracksA
Get tracks of a Spotify album.
Args:
album_id: The Spotify ID of the album.
limit: Maximum number of tracks to return (1-50, default 20).
offset: Index of the first track to return (default 0).
market: ISO 3166-1 alpha-2 country code.
Inputs: album_id (required), limit, market, offset. Returns: result
get_artistA
Get details of a Spotify artist by their ID.
Args:
artist_id: The Spotify ID of the artist.
Inputs: artist_id (required). Returns: result
get_artist_albumsB
Get albums by a Spotify artist.
Args:
artist_id: The Spotify ID of the artist.
include_groups: Comma-separated album types: album, single, appears_on, compilation.
limit: Maximum number of albums to return (1-10, default 10).
offset: Index of the first album to return (default 0).
market: ISO 3166-1 alpha-2 country code.
Inputs: artist_id (required), limit, market, offset, +1 more. Returns: result
get_audiobookB
Get details of a Spotify audiobook.
Args:
audiobook_id: The Spotify ID of the audiobook.
market: ISO 3166-1 alpha-2 country code.
Inputs: audiobook_id (required), market. Returns: result
get_audiobook_chaptersA
Get chapters of a Spotify audiobook.
Args:
audiobook_id: The Spotify ID of the audiobook.
limit: Maximum number of chapters to return (1-50, default 20).
offset: Index of the first chapter to return (default 0).
market: ISO 3166-1 alpha-2 country code.
Inputs: audiobook_id (required), limit, market, offset. Returns: result
get_chapterA
Get details of a specific audiobook chapter.
Args:
chapter_id: The Spotify ID of the chapter.
market: ISO 3166-1 alpha-2 country code.
Inputs: chapter_id (required), market. Returns: result
get_currently_playingB
Get the currently playing track or episode.
Inputs: no named parameters. Returns: result
get_devicesA
Get the user's available Spotify devices.
Inputs: no named parameters. Returns: result
get_episodeA
Get details of a podcast episode.
Args:
episode_id: The Spotify ID of the episode.
market: ISO 3166-1 alpha-2 country code.
Inputs: episode_id (required), market. Returns: result
get_followed_artistsA
Get the current user's followed artists. Cursor-paginated.
To follow or unfollow, use `save_to_library` / `remove_from_library` with Spotify URIs.
Args:
limit: Maximum number of artists to return (1-50, default 20).
after: Cursor (last artist ID from previous page) to fetch the next page.
Inputs: after, limit. Returns: result
get_my_playlistsA
Get the current user's playlists.
Args:
limit: Maximum number of playlists to return (1-50, default 20).
offset: Index of the first playlist to return (default 0).
Inputs: limit, offset. Returns: result
get_my_profileA
Get the current user's Spotify profile.
Inputs: no named parameters. Returns: result
get_my_top_itemsB
Get the current user's top artists or tracks.
Args:
item_type: Type of items: "artists" or "tracks" (default "tracks").
time_range: "short_term" (~4wk), "medium_term" (~6mo), or "long_term" (all time).
limit: Maximum number of items to return (1-50, default 20).
offset: Index of the first item to return (default 0).
Inputs: limit, offset, item_type, time_range. Returns: result
get_playback_stateA
Get the current playback state including track, device, and progress.
Inputs: no named parameters. Returns: result
get_playlistA
Get details of a Spotify playlist.
Shows playlist metadata plus the first 20 tracks. For more tracks or
pagination, use `get_playlist_items`.
Args:
playlist_id: The Spotify ID of the playlist.
market: ISO 3166-1 alpha-2 country code; affects track availability.
Inputs: playlist_id (required), market. Returns: result
get_playlist_itemsB
Get items (tracks/episodes) in a playlist.
Args:
playlist_id: The Spotify ID of the playlist.
limit: Maximum number of items to return (1-50, default 20).
offset: Index of the first item to return (default 0).
market: ISO 3166-1 alpha-2 country code.
Inputs: playlist_id (required), limit, market, offset. Returns: result
get_queueB
Get the current playback queue.
Inputs: no named parameters. Returns: result
get_recently_playedB
Get the user's recently played tracks.
Args:
limit: Maximum number of items to return (1-50, default 20).
after: Unix-ms cursor; return items played AFTER this timestamp.
before: Unix-ms cursor; return items played BEFORE this timestamp.
Only one of `after` / `before` may be set.
Inputs: after, limit, before. Returns: result
get_saved_albumsA
Get the current user's saved albums.
Args:
limit: Maximum number of albums to return (1-50, default 20).
offset: Index of the first album to return (default 0).
Inputs: limit, offset. Returns: result
get_saved_audiobooksA
Get the current user's saved audiobooks.
Args:
limit: Maximum number of audiobooks to return (1-50, default 20).
offset: Index of the first audiobook to return (default 0).
Inputs: limit, offset. Returns: result
get_saved_episodesA
Get the current user's saved episodes.
Args:
limit: Maximum number of episodes to return (1-50, default 20).
offset: Index of the first episode to return (default 0).
Inputs: limit, offset. Returns: result
get_saved_showsA
Get the current user's saved shows (podcasts).
Args:
limit: Maximum number of shows to return (1-50, default 20).
offset: Index of the first show to return (default 0).
Inputs: limit, offset. Returns: result
get_saved_tracksA
Get the current user's saved tracks.
Args:
limit: Maximum number of tracks to return (1-50, default 20).
offset: Index of the first track to return (default 0).
Inputs: limit, offset. Returns: result
get_showA
Get details of a Spotify show (podcast).
Args:
show_id: The Spotify ID of the show.
market: ISO 3166-1 alpha-2 country code; affects availability.
Inputs: show_id (required), market. Returns: result
get_show_episodesA
Get episodes of a Spotify show.
Args:
show_id: The Spotify ID of the show.
limit: Maximum number of episodes to return (1-50, default 20).
offset: Index of the first episode to return (default 0).
market: ISO 3166-1 alpha-2 country code.
Inputs: show_id (required), limit, market, offset. Returns: result
get_trackA
Get details of a Spotify track by its ID.
Args:
track_id: The Spotify ID of the track.
market: ISO 3166-1 alpha-2 country code; affects availability/relinking.
Inputs: track_id (required), market. Returns: result
next_trackA
Skip to the next track.
Args:
device_id: ID of the device. If not provided, uses the active device.
Inputs: device_id. Returns: result
pauseB
Pause playback on the active device.
Args:
device_id: ID of the device to pause. If not provided, pauses the active device.
Inputs: device_id. Returns: result
playA
Start or resume playback.
Args:
device_id: ID of the device to play on. Uses active device if omitted.
context_uri: Spotify URI of context (album, artist, playlist).
uris: List of Spotify track URIs to play. E.g. ["spotify:track:xxx"].
offset_position: Position in the context to start playback (0-based index).
position_ms: Position in milliseconds to seek to.
Inputs: uris, device_id, context_uri, position_ms, +1 more. Returns: result
previous_trackA
Skip to the previous track.
Args:
device_id: ID of the device. If not provided, uses the active device.
Inputs: device_id. Returns: result
remove_from_libraryA
Remove items from the user's library, or unfollow artists, users, and playlists.
Auto-chunks at 40 URIs per request.
Args:
uris: Spotify URIs: track, album, episode, show, audiobook, artist, user, or
playlist (e.g. ["spotify:track:xxx", "spotify:playlist:yyy"]).
Inputs: uris (required). Returns: result
remove_playlist_itemsA
Remove tracks or episodes from a playlist. Auto-chunks at 100 items per request.
Args:
playlist_id: The Spotify ID of the playlist.
uris: List of Spotify URIs to remove (e.g. ["spotify:track:xxx"]).
Inputs: uris (required), playlist_id (required). Returns: result
reorder_playlist_itemsB
Reorder items in a playlist.
Args:
playlist_id: The Spotify ID of the playlist.
range_start: Position of the first item to be reordered.
insert_before: Position where the items should be inserted.
range_length: Number of items to reorder (default 1).
Inputs: playlist_id (required), range_start (required), insert_before (required), range_length. Returns: result
save_to_libraryA
Save items to the user's library, or follow artists, users, and playlists.
Auto-chunks at 40 URIs per request.
Args:
uris: Spotify URIs: track, album, episode, show, audiobook, artist, user, or
playlist (e.g. ["spotify:track:xxx", "spotify:artist:yyy"]).
Inputs: uris (required). Returns: result
searchA
Search for tracks, albums, artists, playlists, shows, episodes, or audiobooks on Spotify.
Args:
query: Search query. Supports filters: artist:, album:, track:, year:, genre:,
isrc: (track ISRC), upc: (album UPC). Use NOT/OR with quotes for refinement.
types: Comma-separated types: track, album, artist, playlist, show, episode, audiobook.
limit: Maximum results per type (1-10, default 10).
offset: Index of first result to return (default 0).
market: ISO 3166-1 alpha-2 country code to filter results.
Inputs: query (required), limit, types, market, +1 more. Returns: result
seekA
Seek to a position in the currently playing track.
Args:
position_ms: Position in milliseconds to seek to.
device_id: ID of the device. If not provided, uses the active device.
Inputs: position_ms (required), device_id. Returns: result
set_repeatA
Set the repeat mode for playback.
Args:
state: Repeat mode: "track", "context", or "off".
device_id: ID of the device. If not provided, uses the active device.
Inputs: state (required), device_id. Returns: result
set_volumeA
Set the playback volume.
Args:
volume_percent: Volume level (0-100).
device_id: ID of the device. If not provided, uses the active device.
Inputs: volume_percent (required), device_id. Returns: result
toggle_shuffleA
Set or toggle shuffle mode for playback.
Args:
state: True to enable, False to disable. If omitted, flips the current state.
device_id: ID of the device. If not provided, uses the active device.
Inputs: state, device_id. Returns: result
transfer_playbackA
Transfer playback to a different device.
Args:
device_id: ID of the device to transfer to.
play: Whether to start playing on the new device (default True).
Inputs: device_id (required), play. Returns: result
update_playlistB
Update a playlist's name, description, or visibility.
Args:
playlist_id: The Spotify ID of the playlist.
name: New name for the playlist.
description: New description for the playlist.
public: Whether the playlist should be public.
Inputs: playlist_id (required), name, public, description. Returns: result
whoamiA
Diagnostic: show auth status, profile basics, active device, and configured scopes.
Inputs: no named parameters. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 47 tools
Tools target distinct resources and actions, but there are minor overlaps: get_playlist vs get_playlist_items and get_playback_state vs get_currently_playing could be confused, though descriptions clarify the differences.
Mostly consistent snake_case with verb_noun (get_track, add_playlist_items), but some tools are single imperatives (play, pause, search) or use an adjective_noun form (next_track), slightly breaking the pattern.
With 47 tools, the server far exceeds the recommended 3-15 range and crosses the 25+ threshold for 'too many', making it heavy and potentially overwhelming despite the broad Spotify domain.
Core CRUD for playlists, library, and playback is covered, but notable gaps remain such as no delete_playlist and no access to recommendations, audio features, or artist top tracks—minor omissions agents can work around.
Maintenance
Related MCP Connectors
Generate AI music via the Lacuna Music API from MCP clients like Claude Desktop & Code.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
MCP server for Producer/Riffusion AI music generation
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables AI assistants like Claude to interact with Spotify, allowing them to search for tracks, control playback, and manage playlists.1ISC
- AlicenseAqualityDmaintenanceA Model Context Protocol server that enables AI assistants like Claude Desktop to interact with Spotify's music streaming service, supporting playback control, playlist management, music search, and user profile access.412MIT
- FlicenseNot gradedqualityDmaintenanceA FastMCP server that exposes Spotify's catalog and user context as tools for Claude, enabling track search, audio features, artist discography, recommendations, currently playing, and playlist creation.-
- FlicenseAqualityDmaintenanceA lightweight MCP server that enables AI assistants like Cursor and Claude to control Spotify playback, playlists, and manage tokens via OAuth.152-