spotify-mcp-server
Provides tools to control Spotify playback, manage playlists, search tracks, and get recommendations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@spotify-mcp-serverplay something relaxing"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
spotify-mcp-server
A FastMCP 3.0 server that exposes Spotify controls as Model Context Protocol (MCP) tools. Use it in two ways:
Claude Desktop / Claude Code — let Claude control Spotify during a conversation ("play something relaxing", "create a jazz playlist for dinner")
Web app — a mobile-friendly player at
/appfor playback control, playlist management, and AI playlist generation
Tools
Tool | Description |
| Metadata for the currently playing track |
| Play, pause, or toggle playback |
| Skip to next or previous track |
| Add a track to the playback queue |
| Fetch track recommendations from seed tracks |
| List the user's playlists |
| Create a new empty playlist |
| Add tracks to an existing playlist |
| Search for a track and add it to a playlist |
| Start playback of a playlist, album, or artist |
| List available Spotify playback devices |
| Transfer playback to a specific device |
| Switch between pre-authenticated user profiles |
| Generate and populate a playlist from a natural-language prompt (requires Gemini API key) |
Related MCP server: Spotify MCP Server
Prerequisites
Requirement | Notes |
uv ≥ 0.4 | Python package manager |
Python ≥ 3.10 | Managed automatically by uv |
Spotify account | Free or Premium |
Spotify Developer App | |
Gemini API key | Optional — only needed for |
Quick Start
1. Clone the repo
git clone <repo-url> spotify-mcp-server
cd spotify-mcp-server2. Install dependencies
uv syncuv downloads Python 3.12, creates a virtual environment, and installs all locked dependencies automatically.
3. Create a Spotify Developer App
Click Create App
Add a Redirect URI — use
http://127.0.0.1:8888/callbackfor local use, orhttps://your-domain/callbackfor RailwayNote your Client ID and Client Secret
4. Configure credentials
cp .env.example .envEdit .env:
SPOTIFY_CLIENT_ID=your_client_id_here
SPOTIFY_CLIENT_SECRET=your_client_secret_here
SPOTIFY_REDIRECT_URI=http://127.0.0.1:8888/callback
# Optional — for AI playlist generation
GEMINI_API_KEY=your_gemini_api_key_here
.envis gitignored. Never commit it.
5. Authenticate with Spotify (one-time)
uv run python scripts/authenticate.pyThis opens a browser for Spotify OAuth. After approving, the token is cached
in .cache for all subsequent runs.
Option A — Claude Desktop (local, stdio)
This runs the server locally on your machine. Claude Desktop launches it automatically when you start a conversation.
Add to claude_desktop_config.json:
{
"mcpServers": {
"spotify": {
"command": "uv",
"args": ["run", "fastmcp", "run", "src/server.py"],
"cwd": "/absolute/path/to/spotify-mcp-server",
"env": {
"SPOTIFY_CLIENT_ID": "your_client_id",
"SPOTIFY_CLIENT_SECRET": "your_client_secret",
"SPOTIFY_REDIRECT_URI": "http://127.0.0.1:8888/callback"
}
}
}
}The config file is located at:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Restart Claude Desktop after saving. The Spotify tools will appear automatically in your next conversation.
Example prompts for Claude:
"What's playing on Spotify?"
"Skip this track"
"Create a playlist called Dinner Jazz and add 10 tracks"
"Generate a playlist of 10 summer hits from 2024"
Option B — Railway (cloud, web app + MCP)
Deploy to Railway to get a persistent URL accessible from any device, including mobile.
1. Fork and connect
Fork this repo to your GitHub account
Create a new Railway project and connect your fork
Railway will detect the
Dockerfileand deploy automatically
2. Set environment variables in Railway
Variable | Value |
| From Spotify Developer Dashboard |
| From Spotify Developer Dashboard |
|
|
|
|
| Optional — for AI playlist generation |
3. Add the redirect URI to Spotify
In your Spotify Developer App settings, add https://your-railway-domain/callback
as an allowed Redirect URI and click Save.
4. Authenticate
Visit https://your-railway-domain/auth/login in a browser to complete the
Spotify OAuth flow. The token is stored on the Railway volume at /data/.cache.
5. Access the web app
Open https://your-railway-domain/app on any device — desktop or mobile.
Web app features:
Now Playing card with album art and progress bar
Play / pause / skip / queue controls
Device picker — switch playback between laptop, phone, Bluetooth speakers
Search and add tracks to playlists
Create playlists and browse your library
AI playlist generation from natural-language prompts (requires Gemini API key)
Connect Claude Desktop to the Railway server
You can also point Claude Desktop at the Railway deployment instead of running the server locally:
{
"mcpServers": {
"spotify": {
"type": "http",
"url": "https://your-railway-domain/mcp"
}
}
}Multi-user / Family Accounts
The server supports multiple pre-authenticated Spotify accounts on the same deployment.
One-time setup per user:
Each family member visits:
https://your-railway-domain/auth/login?user=theirnameand logs in with their own Spotify account. Their token is stored as
.cache-theirname on the Railway volume.
Switching accounts:
Call the switch_user tool with the profile name, or ask Claude:
"Switch to mum's Spotify account"
Switch back to the default account with switch_user("default").
Note: Spotify limits development apps to 25 users. Beyond that, submit your app for extended quota mode (free, requires review).
Project Structure
.
├── src/
│ └── server.py # FastMCP server + all tool definitions
├── static/
│ └── index.html # Mobile web app (served at /app)
├── config/
│ └── settings.py # pydantic-settings config loader
├── scripts/
│ └── authenticate.py # One-time local OAuth helper
├── .env.example # Credential template
├── Dockerfile # Railway deployment
├── railway.json # Railway configuration
├── pyproject.toml # Dependencies (managed by uv)
├── uv.lock # Locked dependency graph
└── CLAUDE.md # Project conventionsLicense
MIT
Available Tools
14 toolsadd_to_playlistA
Add one or more tracks to an existing Spotify playlist.
Handles batching automatically (Spotify API limit: 100 tracks per request).
Parameters
playlist_id : str Spotify playlist ID or full URI. track_uris : list[str] Spotify track URIs or bare track IDs.
Returns
dict
Keys: playlist_id (str), tracks_added (int).
Raises
ValueError
If track_uris is empty.
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| track_uris | Yes | ||
| playlist_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It transparently discloses batching (100 tracks per request), error handling (ValueError for empty track_uris, SpotifyException propagation), and return format. However, it omits permission requirements (e.g., playlist ownership/collaboration) which are relevant for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections for Parameters, Returns, and Raises. No fluff, every section adds necessary info, and it is appropriately concise for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, parameters, returns, and exceptions, making it fairly complete for a simple tool. However, it lacks context about prerequisites like playlist access/ownership, and does not clarify overlap with search_and_add, leaving minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description provides detailed parameter documentation beyond the input schema, including accepted formats ('Spotify playlist ID or full URI', 'track URIs or bare track IDs'). Since schema description coverage is 0%, this fully compensates and enhances meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Add one or more tracks to an existing Spotify playlist', using a specific verb and resource. This distinguishes it from siblings like add_to_queue (adds to queue) and create_playlist (creates new playlist).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for adding tracks to playlists but does not explicitly specify when to use it over alternatives like add_to_queue or search_and_add. No exclusion or alternative guidance is provided, making usage context clear only by implication.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_to_queueA
Add a track to the user's active Spotify playback queue.
Parameters
uri : str
Spotify track URI (spotify:track:<id>) or bare track ID.
Returns
dict
{"status": "queued", "uri": "<full_spotify_uri>"}
Raises
spotipy.SpotifyException Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses the return format ('{"status": "queued", "uri": "<full_spotify_uri>"}') and raises spotipy.SpotifyException for non-2xx responses. It also notes the 'active' queue, hinting at a device requirement, though it stops short of detailing preconditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections for Parameters, Returns, and Raises, and is appropriately concise—each section adds necessary information without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (one parameter), the description covers the core behaviors: the action, parameter format, return payload, and error conditions. It lacks explicit preconditions (e.g., active device), but the mention of 'active queue' partially addresses this. Overall it is sufficient for basic use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description explains that 'uri' can be a full Spotify track URI (spotify:track:<id>) or a bare track ID, adding format details beyond the schema's bare string type. This is valuable since schema description coverage is 0%.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Add a track to the user's active Spotify playback queue' with a specific verb and resource, distinguishing it from sibling tools like add_to_playlist by specifying the queue rather than a playlist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by naming the queue but does not explicitly state when to use this tool instead of alternatives such as add_to_playlist or search_and_add. No exclusions or preconditions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_playlistA
Create a new empty private playlist for the current user.
Parameters
name : str Display name for the new playlist. description : str, optional Short description shown in Spotify clients (default: empty string).
Returns
dict
Keys: id, name, url.
Raises
ValueError
If name is blank.
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| description | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It details the mutation, the 'empty' and 'private' natures, required name, optional description, return keys, and possible exceptions. Some context like authentication requirements or rate limits is omitted, but the stated behaviors are clear and useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a front-loaded purpose sentence, concise parameter docs, return type, and raised errors. Every sentence adds value, and there is no redundancy or padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two simple parameters and an existing output schema, the description covers the purpose, parameters, returns, and errors comprehensively. It leaves no significant gaps for an agent to misunderstand.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no descriptions and the context indicates 0% schema coverage, so the description is essential. It provides meaningful semantics for both parameters: 'name' as display name, 'description' with default empty string and its purpose. This fully compensates for the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('create'), the resource ('playlist'), and specific attributes ('new empty private'), with scope ('for the current user'). This distinguishes it from sibling tools like add_to_playlist and generate_playlist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose statement implies when to use this tool (creating a fresh empty private playlist), but it does not explicitly contrast with alternatives or provide exclusion criteria. No when-not-to-use guidance is given, falling short of a fully explicit guideline.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_playlistA
Generate and populate a Spotify playlist from a natural-language prompt.
Uses Claude to interpret the prompt and produce a tracklist, then creates a new playlist and searches for each track on Spotify.
Parameters
prompt : str
Natural-language description, e.g. "10 summer hits from 2024".
playlist_name : str, optional
Name for the new playlist. If omitted, Claude will suggest one.
Returns
dict
Keys: playlist_id, playlist_name, playlist_url,
tracks_added (int), tracks_not_found (list[str]).
Raises
EnvironmentError
If GEMINI_API_KEY is not configured.
ValueError
If prompt is blank.
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | ||
| playlist_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the workflow (interpret prompt, create playlist, search/add tracks), return values, and error conditions, which is commendable for a tool with no annotations. However, it contains an internal contradiction: it says 'Uses Claude' but then raises EnvironmentError for 'GEMINI_API_KEY', which could mislead an agent about the actual API dependency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a one-sentence summary, a brief workflow explanation, and clearly labeled Parameters/Returns/Raises sections. It is appropriately sized, with no filler words, and front-loads the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the full workflow, output keys, and exceptions, making it mostly self-sufficient. However, the Claude/Gemini naming inconsistency is a notable error that reduces reliability, and it does not reference sibling tools or mention Spotify authentication requirements. Given the tool's moderate complexity, this leaves a few gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema only provides types and required status for the two parameters, with no descriptions. The description compensates fully by documenting each parameter in a dedicated section, including an example for 'prompt' and the default behavior for 'playlist_name'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb ('Generate and populate') and resource ('Spotify playlist') and input ('natural-language prompt'). It differentiates from sibling tools like create_playlist by describing the end-to-end workflow of interpreting the prompt, creating the playlist, and adding tracks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies its use case by emphasizing 'natural-language prompt' and the automated workflow, but it does not explicitly state when to prefer this over alternatives like add_to_playlist or search_and_add. No exclusions or sibling comparisons are provided, though the context is clear enough for most cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_current_trackA
Retrieve information about the track currently playing on Spotify.
Returns structured metadata including the track URI, which is needed by
other tools such as add_to_queue and get_recommendations.
Returns
dict
Keys: is_playing, track_name, artists, album,
duration_ms, progress_ms, track_url, track_uri.
Returns {"is_playing": False} when nothing is playing.
Raises
spotipy.SpotifyException Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It details the exact return structure, includes the empty-state behavior ('Returns {"is_playing": False} when nothing is playing'), and explicitly documents the spotipy.SpotifyException raises condition. This is comprehensive transparency beyond what a typical tool description offers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear first sentence and dedicated Returns/Raises sections. It is not overly verbose, though the detailed Returns list may be partially redundant if an output schema exists. Overall, it is organized and front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no annotations and no parameters, the description is complete: it covers the purpose, return structure, empty state, exception behavior, and relationship to other tools. The output schema may already describe return values, but the description adds essential behavioral context, making it sufficiently complete for an agent to use the tool effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema fully covers inputs. The baseline for 0-param tools is 4, and since there are no parameter semantics to explain, this score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Retrieve information about the track currently playing on Spotify.' This is a specific verb+resource combination that distinguishes it from sibling tools, and it further differentiates itself by noting the track URI is needed by other tools like add_to_queue and get_recommendations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use this tool—when you need current track information or the track URI for downstream tools. It names dependent tools and states the URI 'is needed by other tools,' providing practical context. However, it does not explicitly list exclusions or alternative tools when this tool would not be appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_devicesA
List all available Spotify playback devices for the current user.
Returns
dict
Keys: devices (list of dicts with id, name, type,
is_active, volume_percent).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure. It clearly indicates a read-only operation ('list'), scopes to the current user, and reveals the return structure (dict with 'devices' list containing keys). It does not mention auth or rate limits, but for a simple listing tool this is reasonably transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence followed by a structured 'Returns' block. Every element contributes meaningful information, and the format is well-organized and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (no parameters), the presence of an output schema in the description, and the absence of complex behaviors, the description is complete. It provides all necessary context for an agent to invoke and interpret the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so per the rubric the baseline for this dimension is 4. The description and schema fully cover the lack of parameters, making any additional explanation unnecessary.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'List all available Spotify playback devices for the current user.' It clearly distinguishes from sibling tools like transfer_playback or get_current_track by focusing on the device list resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage through its function (listing devices), but provides no explicit guidance on when to use it versus alternatives like transfer_playback, which would benefit from a device_id. It does not state exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recommendationsA
Fetch track recommendations based on a list of seed track URIs or IDs.
Note
Spotify deprecated the public recommendations endpoint in November 2024. This tool works for apps created before that date or granted continued access.
Parameters
seed_tracks : list[str] Spotify track URIs or bare IDs (max 5 seeds; excess are truncated). limit : int, optional Number of recommendations to return (1–100, default: 5).
Returns
dict
Keys: seeds (list[str]), tracks (list[dict]).
Raises
ValueError
If seed_tracks is empty or limit is out of range.
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| seed_tracks | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden, and it excels: it discloses seed truncation ('max 5 seeds; excess are truncated'), limit bounds ('1–100, default: 5'), return keys, and raised exceptions (ValueError, spotipy.SpotifyException). This goes well beyond basic behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, well-structured with sections (Note, Parameters, Returns, Raises), and front-loaded with a single-sentence purpose. Every section adds value and there is no redundant wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having an output schema, the description provides additional critical context: deprecation status, parameter constraints, error behavior, and return shape. It is fully self-contained for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It fully defines seed_tracks as 'Spotify track URIs or bare IDs' and documents limit's range and default, adding meaning beyond the bare schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Fetch track recommendations based on a list of seed track URIs or IDs,' which is a specific verb+resource. However, it does not explicitly distinguish itself from the sibling tool 'generate_playlist,' which may also operate on seed tracks, so it lacks clear sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The deprecation note provides a clear when/when-not condition ('works for apps created before that date or granted continued access'), serving as an explicit usage constraint. However, no alternative tools are named, so it does not fully meet the 'alternatives' criterion for a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_playlistsA
Fetch a paginated list of the current user's Spotify playlists.
Parameters
limit : int, optional Maximum number of playlists to return (1–50, default: 20). offset : int, optional Zero-based index of the first playlist to return (default: 0).
Returns
dict
Keys: total, limit, offset, playlists.
Raises
ValueError
If limit is outside [1, 50].
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| offset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It discloses pagination behavior, the response dictionary keys, and error conditions (ValueError, spotipy.SpotifyException). This exceeds the typical description and leaves little ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections (Parameters, Returns, Raises). Every sentence provides useful information without padding. It is appropriately sized for a two-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no annotations and a sparse input schema, the description provides a complete behavioral contract: it defines the return structure, error handling, and parameter constraints. This makes the tool usable without any external documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description fully compensates. It explains both parameters in detail: limit with allowed range and default, offset with meaning, and even note the ValueError raised when limit is invalid. This adds significant meaning beyond the schema's minimal type/default fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear, specific verb+resource phrase: "Fetch a paginated list of the current user's Spotify playlists." This immediately distinguishes it from sibling tools like create_playlist or add_to_playlist, which perform different actions on playlists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context (current user's playlists, paginated) but does not explicitly mention when to use this tool versus alternatives or any exclusions. The usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
play_contextA
Start playback of a Spotify context (playlist, album, or artist).
Parameters
context_uri : str
Spotify URI (e.g. spotify:playlist:<id>) or bare playlist ID.
Returns
dict
{"status": "playing", "context_uri": str}
Raises
spotipy.SpotifyException Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| context_uri | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It adds behavioral context by specifying the return format ({"status": "playing", "context_uri": str}) and that spotipy.SpotifyException is propagated on non-2xx responses. This provides meaningful behavioral detail beyond the schema, though it doesn't discuss side effects like current playback replacement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the purpose. It uses clear sections for parameters, returns, and raises, with no redundant filler. Every sentence contributes useful information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter nature, the description is nearly complete. It covers the parameter format, return value, and error behavior. The output schema exists, so return details are further reinforced, though no extra context about prerequisites (e.g., auth) is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description enriches the single parameter (context_uri) with a clear type, example format ('spotify:playlist:<id>'), and bare ID alternative. The schema only says 'string', so the description adds significant meaning and usage guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Start playback of a Spotify context (playlist, album, or artist)' with a specific verb and resource. It differentiates from siblings like play_pause and skip_track by focusing on context-based playback.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly implies when to use this tool (to play a specific playlist, album, or artist) and the context is unambiguous. It doesn't explicitly name alternatives or exclusions, but the purpose is clear enough to guide selection among sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
play_pauseA
Control Spotify playback – play, pause, or toggle the current state.
Parameters
action : str, optional
One of "play", "pause", or "toggle" (default).
Returns
dict
{"status": "playing" | "paused" | "no_active_device"}
Raises
ValueError
If action is not one of the accepted values.
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | toggle |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses return statuses ('playing', 'paused', 'no_active_device') and raises ValueError/SpotifyException, providing meaningful behavioral context. Minor gaps: it doesn't explicitly state that playback state changes, though that is inherently clear from the verb 'toggle'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with a one-line summary, followed by concise parameter, returns, and raises sections. Every sentence adds value without redundancy or unnecessary verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, has an output schema, and the description covers parameters, return values, and error conditions. It is complete for its complexity and leaves no significant gaps for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has only one parameter 'action' with no description or enum, giving 0% schema coverage. The description fully compensates by listing accepted values ('play', 'pause', 'toggle') and default ('toggle'), adding essential semantic meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Control Spotify playback – play, pause, or toggle the current state' uses a specific verb and resource, clearly differentiating from sibling tools like skip_track or play_context. The action options are explicitly listed, leaving no ambiguity about the tool's core function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide explicit when-to-use or when-not-to-use guidance compared to alternatives. It implies usage for basic playback control but lacks direct references to sibling tools or exclusion scenarios, so it earns a 'implied usage' score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_and_addA
Search for a track and add the top result to a playlist in one step.
Parameters
query : str
Free-text search query (e.g. "Shape of You Ed Sheeran").
playlist_id : str
Spotify playlist ID or full URI to add the track to.
Returns
dict
Keys: track_name, artists, track_uri, playlist_id.
Raises
ValueError
If query is blank or the search returns no results.
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| playlist_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description must disclose behavior. It explains the search-add flow, returns a dict with track details, and raises ValueError for blank/no-result queries and propagates SpotifyException. This covers key behavioral outcomes, though it omits potential side effects like playlist size limits or authentication requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and structured with clear sections for parameters, returns, and raises. The opening sentence states the core action, and each subsequent line adds necessary detail without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers purpose, all parameter semantics, return format, and errors. The presence of an output schema is noted, but the description's return documentation aligns with it, making the tool fully understandable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines two string fields with no descriptions, while the description elaborates both: 'query' is a free-text search with an example, and 'playlist_id' accepts a Spotify ID or full URI. This fully compensates for the 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concise verb phrase 'Search for a track and add the top result to a playlist in one step,' which clearly identifies the tool's function and distinguishes it from sibling tools like add_to_playlist that likely require an existing track URI.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool—when you have a free-text query and want to add the top match directly—but does not explicitly state alternatives or when not to use it. The one-step framing differentiates it from separate search and add operations, and the parameter examples provide contextual usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
skip_trackA
Skip to the next or previous track on the active Spotify device.
Parameters
direction : str, optional
"next" (default) to skip forward, "previous" to go back.
Returns
dict
{"status": "skipped_next" | "skipped_previous" | "no_active_device"}
Raises
ValueError
If direction is not "next" or "previous".
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| direction | No | next |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosure. It explains the return status for no_active_device, raises ValueError for invalid direction, and notes that spotipy.SpotifyException may be propagated, providing useful behavioral context beyond simple 'skips track.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a well-organized docstring with clear sections for parameters, returns, and raises. Each sentence earns its place with no fluff or repetition, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers the tool's behavior for the simple task: it specifies the parameter, possible return values, and error handling. Given the tool has only one optional parameter and a straightforward action, this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only shows direction with a default, but the description fully explains the two valid values ('next'/'previous'), their meanings, and the default behavior. It also documents the return dict and error conditions, adding complete semantic meaning that schema alone lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Skip to the next or previous track on the active Spotify device.' This is a specific verb (skip) and resource (track), and it distinguishes the tool from siblings like play_pause or get_current_track.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by explaining the direction parameter, but it does not explicitly mention when to use this tool versus alternatives such as play_pause or transfer_playback. The context is clear from the purpose, but no exclusions or alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
switch_userA
Switch the active Spotify user profile.
Updates the server's internal state so all subsequent tool calls use the
token cache for name. Each user's token lives in .cache-<name> in
the project root; pass "default" to return to the primary account.
Parameters
name : str
User profile name. Must have a corresponding cache file or be
"default".
Returns
dict
{"previous_user": str, "current_user": str}
Raises
ValueError
If name is blank or no token cache exists for that profile.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool updates server state, relies on token cache files, and raises an error for invalid names. It doesn't elaborate on permissions or side effects on other users, but covers the core behavior well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with clear sections (overview, parameters, returns, raises) and every sentence adds value. It is detailed without being bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool, the description covers purpose, parameter constraints, return format, and error cases. It is fully self-contained and leaves no significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only a string 'name', but the description thoroughly explains the meaning: user profile name, must have a cache file or be 'default'. This fully compensates for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Switch the active Spotify user profile.' It clearly distinguishes this tool from its siblings (playback, queue, playlist tools) by focusing on profile management.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context on when to use (switching profiles, returning to default) but doesn't explicitly mention alternatives or when not to use. Given the unique purpose among siblings, the lack of exclusions is acceptable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
transfer_playbackA
Transfer Spotify playback to a specific device.
Parameters
device_id : str The Spotify device ID to transfer playback to.
Returns
dict
{"status": "transferred", "device_id": str}
Raises
ValueError
If device_id is blank.
spotipy.SpotifyException
Propagated if the Spotify API returns a non-2xx response.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of explaining the tool's behavior. It does disclose the return format and potential exceptions, which gives some transparency about outcomes. However, it omits broader behavioral context like whether the operation is reversible, whether it requires an active playback session, or what happens to the previous device's state. Given the simplicity of the operation, this is adequate but not thorough, warranting a 3.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a front-loaded one-sentence purpose followed by clear sections for Parameters, Returns, and Raises. Every section is concise and contributes necessary information without redundancy. It is appropriately sized for a simple one-parameter tool and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity—one parameter, no nested objects, and an output schema—the description is complete. It covers the parameter meaning, the exact return value, and the error scenarios, leaving no ambiguity. The absence of annotations is compensated by the explanation of return behavior and exceptions, making the tool fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines device_id as a string with no description, but the description explicitly states 'The Spotify device ID to transfer playback to,' providing essential meaning beyond the schema. Since schema description coverage is 0%, this is a critical addition and is done clearly. It doesn't elaborate on how to obtain the ID, but the semantic meaning is fully conveyed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb and resource: 'Transfer Spotify playback to a specific device.' This distinguishes it from sibling tools like play_pause, skip_track, or get_devices, all of which have different purposes. The one-sentence summary is unambiguous and immediately understandable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives, nor does it mention prerequisites such as obtaining a device ID from get_devices or ensuring playback is active. The description only states what the tool does, not when it should be invoked. This is a clear gap that leaves the agent to infer usage context from the tool name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
14 tool updates
v0.1.0- First observed
add_to_playlist - First observed
add_to_queue - First observed
create_playlist - First observed
generate_playlist - First observed
get_current_track - First observed
get_devices - First observed
get_recommendations - First observed
get_user_playlists - First observed
play_context - First observed
play_pause - First observed
search_and_add - First observed
skip_track - First observed
switch_user - First observed
transfer_playback
TDQS
Scored across 14 tools
Every tool serves a distinct resource or action: playback control (play_pause, skip_track, transfer_playback), queue management (add_to_queue), context playback (play_context), and playlist operations (create, list, add, search_and_add, generate). No two tools have overlapping purposes, and the descriptions make each tool's role clear.
All tool names follow a consistent lowercase snake_case pattern with a verb-first structure (e.g., get_devices, create_playlist, add_to_queue). Compound names like play_pause and search_and_add remain readable and do not break the overall convention.
With 14 tools, the server is well-scoped for its purpose: it provides essential playback controls, playlist management, and a few convenience functions like generate_playlist and switch_user. The count feels appropriate for a Spotify MCP server without being bloated or too thin.
Core workflows are covered: playback (play/pause/skip/queue/devices) and playlist creation/listing/adding tracks. However, notable gaps exist, such as removing tracks from a playlist, deleting/updating playlists, and missing playback features like seek, volume, or shuffle. These would require external workarounds.
Maintenance
Related MCP Connectors
Generate AI music via the Lacuna Music API from MCP clients like Claude Desktop & Code.
MCP server for Producer/Riffusion AI music generation
Remote MCP for RunComfy: ComfyUI deployments, hosted models, LoRA training. 31 tools.
Automate 1,000+ services from any MCP-compatible AI agent: build Applets, run actions and queries.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables control of Spotify playback, search, and playlist management through MCP tools and Apple Shortcuts/Siri integration via HTTP bridge.12-
- AlicenseBqualityCmaintenanceMCP server for the Spotify Web API — gives Claude and other AI assistants tools to search music, control playback, manage playlists, library, and podcasts.59MIT
- AlicenseNot gradedqualityDmaintenanceEnables control of Spotify playback, track search, and user profile retrieval via MCP tools with automatic OAuth token management.383MIT
- FlicenseNot gradedqualityDmaintenanceEnables interaction with Spotify through MCP, providing tools for searching tracks, artists, albums, playlists, and accessing user data like top tracks and recently played.-