Skip to main content
Glama
keenanbb

TIDAL MCP Server

by keenanbb

remove_tracks_from_playlist

Delete specific songs from a TIDAL playlist using track IDs or position numbers to customize your music collection.

Instructions

Remove tracks from a playlist by track ID or position index.

Args: playlist_id: ID of the playlist track_ids: List of track IDs to remove (optional) indices: List of position indices to remove, 0-based (optional) Note: Provide either track_ids OR indices, not both

Returns: Success status and number of tracks removed

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
playlist_idYes
track_idsNo
indicesNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
statusYesOperation status (success/error)
messageYesStatus message
playlist_idYesID of the playlist
playlist_nameYesName of the playlist
tracks_removedYesNumber of tracks successfully removed

Implementation Reference

  • The primary handler function decorated with @mcp.tool(), implementing the logic to remove tracks from a TIDAL playlist by either track IDs or indices using the tidalapi session.
    @mcp.tool()
    async def remove_tracks_from_playlist(
        playlist_id: str, track_ids: Optional[List[str]] = None, indices: Optional[List[int]] = None
    ) -> RemoveTracksResult:
        """
        Remove tracks from a playlist by track ID or position index.
    
        Args:
            playlist_id: ID of the playlist
            track_ids: List of track IDs to remove (optional)
            indices: List of position indices to remove, 0-based (optional)
            Note: Provide either track_ids OR indices, not both
    
        Returns:
            Success status and number of tracks removed
        """
        if not await ensure_authenticated():
            raise ToolError("Not authenticated. Please run the 'login' tool first.")
    
        if not track_ids and not indices:
            raise ToolError("Must provide either track_ids or indices to remove")
    
        if track_ids and indices:
            raise ToolError("Provide either track_ids or indices, not both")
    
        try:
            playlist = await anyio.to_thread.run_sync(session.playlist, playlist_id)
            if not playlist:
                raise ToolError(f"Playlist with ID '{playlist_id}' not found")
    
            if indices:
                # Remove by index position
                await anyio.to_thread.run_sync(playlist.remove_by_indices, indices)
                removed_count = len(indices)
            else:
                # Remove by track ID
                track_ids_int = [int(tid) for tid in track_ids]
                await anyio.to_thread.run_sync(playlist.remove_by_id, track_ids_int)
                removed_count = len(track_ids)
    
            return RemoveTracksResult(
                status="success",
                playlist_id=playlist_id,
                playlist_name=playlist.name,
                tracks_removed=removed_count,
                message=f"Removed {removed_count} tracks from playlist '{playlist.name}'",
            )
        except ValueError as e:
            raise ToolError(f"Invalid ID format: {str(e)}")
        except ToolError:
            raise
        except Exception as e:
            raise ToolError(f"Failed to remove tracks: {str(e)}")
  • Pydantic model defining the structured output schema for the remove_tracks_from_playlist tool response.
    class RemoveTracksResult(BaseModel):
        """Result of removing tracks from a playlist."""
    
        status: str = Field(description="Operation status (success/error)")
        playlist_id: str = Field(description="ID of the playlist")
        playlist_name: str = Field(description="Name of the playlist")
        tracks_removed: int = Field(description="Number of tracks successfully removed")
        message: str = Field(description="Status message")
  • The @mcp.tool() decorator from FastMCP that registers the remove_tracks_from_playlist function as an available MCP tool.
    @mcp.tool()
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. It clearly indicates this is a destructive mutation operation (removing tracks), describes the return format (success status and count), and mentions the exclusive parameter requirement. However, it doesn't address permission requirements, rate limits, or what happens with invalid IDs/indices.

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 clear purpose statement followed by Args and Returns sections. Every sentence adds value, though the 'Note' about exclusive parameters could be integrated more smoothly. The two-sentence structure is appropriately front-loaded.

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?

For a mutation tool with no annotations, the description provides good coverage: clear purpose, parameter semantics, usage constraint, and return format. With an output schema present, it doesn't need to detail return values further. The main gap is lack of behavioral context like permissions or error handling.

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?

With 0% schema description coverage, the description compensates well by explaining all 3 parameters: playlist_id (ID of the playlist), track_ids (list of track IDs to remove), and indices (list of position indices, 0-based). It also clarifies the critical constraint that only one of track_ids or indices should be provided. The only gap is not explaining what happens if both are omitted.

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 specific action (remove tracks), target resource (playlist), and mechanism (by track ID or position index). It distinguishes itself from sibling tools like 'delete_playlist' (which removes entire playlists) and 'remove_track_from_favorites' (which operates on favorites rather than playlists).

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 provides clear context about when to use this tool (to remove tracks from playlists) and includes an important usage constraint ('Provide either track_ids OR indices, not both'). However, it doesn't explicitly mention when NOT to use it (e.g., vs 'delete_playlist' for removing entire playlists) or name specific alternatives.

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

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/keenanbb/tidal-mcp'

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