Skip to main content
Glama
freddy24-7

spotify-mcp-server

by freddy24-7

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 /app for playback control, playlist management, and AI playlist generation


Tools

Tool

Description

get_current_track

Metadata for the currently playing track

play_pause

Play, pause, or toggle playback

skip_track

Skip to next or previous track

add_to_queue

Add a track to the playback queue

get_recommendations

Fetch track recommendations from seed tracks

get_user_playlists

List the user's playlists

create_playlist

Create a new empty playlist

add_to_playlist

Add tracks to an existing playlist

search_and_add

Search for a track and add it to a playlist

play_context

Start playback of a playlist, album, or artist

get_devices

List available Spotify playback devices

transfer_playback

Transfer playback to a specific device

switch_user

Switch between pre-authenticated user profiles

generate_playlist

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

Create one here

Gemini API key

Optional — only needed for generate_playlist


Quick Start

1. Clone the repo

git clone <repo-url> spotify-mcp-server
cd spotify-mcp-server

2. Install dependencies

uv sync

uv downloads Python 3.12, creates a virtual environment, and installs all locked dependencies automatically.

3. Create a Spotify Developer App

  1. Go to developer.spotify.com/dashboard

  2. Click Create App

  3. Add a Redirect URI — use http://127.0.0.1:8888/callback for local use, or https://your-domain/callback for Railway

  4. Note your Client ID and Client Secret

4. Configure credentials

cp .env.example .env

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

.env is gitignored. Never commit it.

5. Authenticate with Spotify (one-time)

uv run python scripts/authenticate.py

This 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.json

  • Windows: %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

  1. Fork this repo to your GitHub account

  2. Create a new Railway project and connect your fork

  3. Railway will detect the Dockerfile and deploy automatically

2. Set environment variables in Railway

Variable

Value

SPOTIFY_CLIENT_ID

From Spotify Developer Dashboard

SPOTIFY_CLIENT_SECRET

From Spotify Developer Dashboard

SPOTIFY_REDIRECT_URI

https://your-railway-domain/callback

MCP_TRANSPORT

sse

GEMINI_API_KEY

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=theirname

and 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 conventions

License

MIT

Available Tools

14 tools
add_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
track_urisYes
playlist_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
uriYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes
descriptionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
promptYes
playlist_nameNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
seed_tracksYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
context_uriYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionNotoggle

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
playlist_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
directionNonext

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
device_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

  1. 14 tool updatesv0.1.0
    • First observedadd_to_playlist
    • First observedadd_to_queue
    • First observedcreate_playlist
    • First observedgenerate_playlist
    • First observedget_current_track
    • First observedget_devices
    • First observedget_recommendations
    • First observedget_user_playlists
    • First observedplay_context
    • First observedplay_pause
    • First observedsearch_and_add
    • First observedskip_track
    • First observedswitch_user
    • First observedtransfer_playback

TDQS

A4.3/5.0

Scored across 14 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness3/5

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

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers