Skip to main content
Glama
g2dgaming

Spotify MCP Server

by g2dgaming

SpotifyPlaylist

Manage Spotify playlists by retrieving, adding, or removing tracks, updating details, or listing user playlists through the Spotify MCP Server.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform: 'get', 'get_tracks', 'add_tracks', 'remove_tracks', 'change_details'.
descriptionNoNew description for the playlist.
nameNoNew name for the playlist.
playlist_idNoID of the playlist to manage.
track_idsNoList of track IDs to add/remove.

Implementation Reference

  • Main handler for SpotifyPlaylist tool calls, handling actions: get, get_tracks, add_tracks, remove_tracks, change_details by delegating to spotify_client.
    case "Playlist":
        logger.info(f"Playlist operation with arguments: {arguments}")
        action = arguments.get("action")
        match action:
            case "get":
                logger.info(f"Getting current user's playlists with arguments: {arguments}")
                playlists = spotify_client.get_current_user_playlists()
                return [types.TextContent(
                    type="text",
                    text=json.dumps(playlists, indent=2)
                )]
            case "get_tracks":
                logger.info(f"Getting tracks in playlist with arguments: {arguments}")
                if not arguments.get("playlist_id"):
                    logger.error("playlist_id is required for get_tracks action.")
                    return create_error_response("playlist_id is required for get_tracks action.")
                tracks = spotify_client.get_playlist_tracks(arguments.get("playlist_id"))
                return [types.TextContent(
                    type="text",
                    text=json.dumps(tracks, indent=2)
                )]
            case "add_tracks":
                logger.info(f"Adding tracks to playlist with arguments: {arguments}")
                track_ids = arguments.get("track_ids")
                if isinstance(track_ids, str):
                    try:
                        track_ids = json.loads(track_ids)  # Convert JSON string to Python list
                    except json.JSONDecodeError:
                        logger.error("track_ids must be a list or a valid JSON array.")
                        return create_error_response("track_ids must be a list or a valid JSON array.")
    
                spotify_client.add_tracks_to_playlist(
                    playlist_id=arguments.get("playlist_id"),
                    track_ids=track_ids
                )
                return [types.TextContent(
                    type="text",
                    text="Tracks added to playlist."
                )]
            case "remove_tracks":
                logger.info(f"Removing tracks from playlist with arguments: {arguments}")
                track_ids = arguments.get("track_ids")
                if isinstance(track_ids, str):
                    try:
                        track_ids = json.loads(track_ids)  # Convert JSON string to Python list
                    except json.JSONDecodeError:
                        logger.error("track_ids must be a list or a valid JSON array.")
                        return create_error_response("track_ids must be a list or a valid JSON array.")
    
                spotify_client.remove_tracks_from_playlist(
                    playlist_id=arguments.get("playlist_id"),
                    track_ids=track_ids
                )
                return [types.TextContent(
                    type="text",
                    text="Tracks removed from playlist."
                )]
    
            case "change_details":
                logger.info(f"Changing playlist details with arguments: {arguments}")
                if not arguments.get("playlist_id"):
                    logger.error("playlist_id is required for change_details action.")
                    return create_error_response("playlist_id is required for change_details action.")
                if not arguments.get("name") and not arguments.get("description"):
                    logger.error("At least one of name, description or public is required.")
                    return create_error_response(
                        "At least one of name, description, public, or collaborative is required.")
    
                spotify_client.change_playlist_details(
                    playlist_id=arguments.get("playlist_id"),
                    name=arguments.get("name"),
                    description=arguments.get("description")
                )
                return [types.TextContent(
                    type="text",
                    text="Playlist details changed."
                )]
    
            case _:
                return create_error_response(
                    f"Unknown playlist action: {action}. Supported actions are: get, get_tracks, add_tracks, remove_tracks, change_details.")
    case _:
  • Pydantic schema defining inputs for the SpotifyPlaylist tool.
    class Playlist(ToolModel):
        """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.
        """
        action: str = Field(
            description="Action to perform: 'get', 'get_tracks', 'add_tracks', 'remove_tracks', 'change_details'.")
        playlist_id: Optional[str] = Field(default=None, description="ID of the playlist to manage.")
        track_ids: Optional[List[str]] = Field(default=None, description="List of track IDs to add/remove.")
        name: Optional[str] = Field(default=None, description="New name for the playlist.")
        description: Optional[str] = Field(default=None, description="New description for the playlist.")
  • Base ToolModel class with as_tool method that names the tool 'SpotifyPlaylist' for Playlist class.
    class ToolModel(BaseModel):
        @classmethod
        def as_tool(cls):
            return types.Tool(
                name="Spotify" + cls.__name__,
                description=cls.__doc__,
                inputSchema=cls.model_json_schema()
            )
  • Registration of the SpotifyPlaylist tool (Playlist.as_tool()) in the list_tools handler.
    tools = [
        Playback.as_tool(),
        Search.as_tool(),
        Queue.as_tool(),
        GetInfo.as_tool(),
        Playlist.as_tool(),
    ]
Behavior2/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 lists actions but fails to describe critical behavioral traits: authentication requirements (e.g., user authorization), rate limits, whether changes are reversible, error conditions, or what the tool returns. For a multi-action tool with mutations (add_tracks, remove_tracks, change_details), this is a significant gap.

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 efficiently structured with a brief header followed by a bulleted list of actions. Each bullet is clear and specific. However, the first line 'Manage Spotify playlists.' is somewhat redundant with the tool name, and the description could be more front-loaded with critical behavioral information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a multi-action tool with mutations and no annotations or output schema, the description is incomplete. It lacks essential context: authentication needs, error handling, return formats, and differentiation from sibling tools. The 100% schema coverage helps with parameters, but overall guidance for an AI agent remains inadequate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 5 parameters thoroughly. The description adds minimal value beyond the schema by listing action types, but doesn't provide additional semantic context (e.g., format of playlist_id, source of track_ids, or constraints on name/description changes). Baseline 3 is appropriate when the schema does the heavy lifting.

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 clearly states the tool's purpose as 'Manage Spotify playlists' and enumerates five specific actions (get, get_tracks, add_tracks, remove_tracks, change_details), providing a comprehensive overview of functionality. However, it doesn't explicitly differentiate this playlist management tool from sibling tools like SpotifyGetInfo or SpotifySearch, which likely handle different Spotify resources.

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?

The description provides no guidance on when to use this tool versus the sibling tools (SpotifyGetInfo, SpotifyPlayback, SpotifyQueue, SpotifySearch). It lists actions but offers no context about prerequisites, appropriate scenarios, or exclusions. Users must infer usage from action names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/g2dgaming/spotify-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server