MCP server for controlling Spotify playback, searching tracks, managing playlists, and accessing Spotify API features
Server has 5 tools with explicit Pydantic model definitions and schema registration. All tools have descriptions and input schemas with typed parameters. However, descriptions vary in quality and completeness. Tool naming uses 'Spotify' prefix convention but lacks action verbs. Several parameters lack detailed constraints and validation guidance. Output schemas are not documented. Error handling is present but minimal, no recovery guidance or error classification. No tool annotations (readOnlyHint/destructiveHint/idempotentHint). The codebase shows deliberate schema construction via Pydantic BaseModel, which is a strength, but the overall design treats some tools as multi-action wrappers (Playback, Queue, Playlist) rather than single-purpose tools, increasing cognitive load on the LLM.
Get detailed information about a Spotify item (track, album, artist, or playlist).
Manages the current playback with the following actions: - get: Get information about user's current track. - start: Starts playing new item or resumes current playback if called with no uri. - pause: Pauses current playback. - skip: Skips current track.
Manage Spotify playlists. - get: Get a list of user's playlists. - get_tracks: Get tracks in a specific playlist. - add_tracks: Add tracks to a specific playlist. - remove_tracks: Remove tracks from a specific playlist. - change_details: Change details of a specific playlist. - create: Create a new playlist.
Manage the playback queue - get the queue or add tracks.
Search for tracks, albums, artists, or playlists on Spotify.
Multi-action tools (Playback, Queue, Playlist) violate single-responsibility pattern. Playlist alone handles 6 distinct operations via an action enum string, forcing LLM to reason about which action to invoke instead of selecting a dedicated tool. This increases error rate and token consumption.
'action' parameters are free-form strings without enum constraints in the JSON schema. Descriptions list valid values, but LLMs cannot parse unstructured text reliably. Should declare 'action' as enum: ["get", "start", "pause", "skip"] in the schema to prevent invalid actions.
No output schemas documented. LLMs cannot plan multi-step operations or extract downstream parameters (e.g., track_id, playlist_id for chaining calls) without knowing the response structure. Tool descriptions do not specify return field names or types.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 44 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 39 | - | v1 |
Parameter relationships undocumented. Playlist.playlist_id is optional but required for actions 'get_tracks', 'add_tracks', 'remove_tracks', 'change_details'. Queue.track_id is optional but required for 'add'. LLMs have no way to know and will pass both or neither, causing runtime errors.
No tool annotations present. Tools like delete (implicit in remove_tracks) and modify (change_details, start_playback) lack destructiveHint or readOnlyHint. Clients and LLMs cannot distinguish safe reads from state-modifying operations without extra documentation.
No error handling guidance. Code catches SpotifyException but returns raw JSON or generic text like 'Playback starting.' without recovery suggestions. If a start_playback fails (device offline, auth expired), LLM receives no hint to retry, authenticate, or select a device.
Tool names lack action verbs. 'Playback', 'Search', 'Queue', 'GetInfo', 'Playlist' are noun-heavy or generic. Should be: 'control_playback', 'search_spotify', 'manage_queue', 'get_spotify_item', 'manage_playlists' or break into single-action tools.
Numeric and string parameters lack constraints. 'limit' has no schema max; LLM could request 10000 results. 'num_skips' has no min/max. 'spotify_uri' has no pattern/format validation.
Playlist.public defaults to true. If LLM creates a playlist without specifying 'public', it becomes public by default. This can cause privacy issues if the user intended a private playlist but LLM omitted the param.