Skip to main content
Glama
davehenke

rekordbox-mcp

get_playlist_tracks

Retrieve all tracks from a specific rekordbox playlist using its unique identifier. This tool queries the DJ database to list tracks within a playlist for analysis or integration purposes.

Instructions

Get all tracks in a specific playlist.

Args: playlist_id: The unique playlist identifier

Returns: List of tracks in the playlist

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
playlist_idYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • MCP tool handler for 'get_playlist_tracks'. Ensures database is initialized, fetches tracks from the database layer using the provided playlist_id, converts Track models to dictionaries via model_dump(), and returns the list. This is the entry point for the MCP tool.
    @mcp.tool()
    async def get_playlist_tracks(playlist_id: str) -> List[Dict[str, Any]]:
        """
        Get all tracks in a specific playlist.
        
        Args:
            playlist_id: The unique playlist identifier
            
        Returns:
            List of tracks in the playlist
        """
        if not db:
            raise RuntimeError("Database not initialized.")
        
        tracks = await db.get_playlist_tracks(playlist_id)
        return [track.model_dump() for track in tracks]
  • Pydantic BaseModel defining the Track schema used in the tool's output. The handler returns a list of track.model_dump() which serializes to dicts matching this structure, providing input/output validation and type definitions for track metadata.
    class Track(BaseModel):
        """
        Rekordbox track model with comprehensive metadata.
        """
        
        id: str = Field(..., description="Unique track identifier")
        title: str = Field(..., description="Track title")
        artist: str = Field(..., description="Track artist")
        album: Optional[str] = Field(None, description="Album name")
        genre: Optional[str] = Field(None, description="Musical genre")
        bpm: float = Field(0.0, description="Beats per minute")
        key: Optional[str] = Field(None, description="Musical key (e.g., '5A', '12B')")
        rating: int = Field(0, ge=0, le=5, description="Track rating (0-5)")
        play_count: int = Field(0, ge=0, description="Number of times played")
        length: int = Field(0, ge=0, description="Track length in seconds")
        file_path: Optional[str] = Field(None, description="Path to audio file")
        date_added: Optional[str] = Field(None, description="Date track was added to library")
        date_modified: Optional[str] = Field(None, description="Date track was last modified")
        
        # Additional metadata
        bitrate: Optional[int] = Field(None, description="Audio bitrate in kbps")
        sample_rate: Optional[int] = Field(None, description="Audio sample rate in Hz")
        color: Optional[str] = Field(None, description="Track color tag")
        comments: Optional[str] = Field(None, description="Track comments")
        
        @field_validator('key')
        @classmethod
        def validate_key(cls, v):
            """Validate musical key format."""
            if v and v not in []:  # Add valid key formats
                # Basic validation - could be more sophisticated
                pass
            return v
        
        def duration_formatted(self) -> str:
            """Get track duration in MM:SS format."""
            if self.length <= 0:
                return "0:00"
            
            minutes = self.length // 60
            seconds = self.length % 60
            return f"{minutes}:{seconds:02d}"
  • Core helper function in the database layer that implements the logic: queries pyrekordbox for playlist_songs by PlaylistID, filters active ones, matches ContentID to tracks via lookup, sorts by TrackNo to preserve order, converts to Track models using _content_to_track, returns list of Track objects.
    async def get_playlist_tracks(self, playlist_id: str) -> List[Track]:
        """
        Get all tracks in a specific playlist.
        
        Args:
            playlist_id: The playlist's unique identifier
            
        Returns:
            List of tracks in the playlist
        """
        if not self.db:
            raise RuntimeError("Database not connected")
        
        try:
            # Get song-playlist relationships for this playlist
            playlist_songs = list(self.db.get_playlist_songs(PlaylistID=int(playlist_id)))
            # Filter out soft-deleted relationships
            active_songs = [s for s in playlist_songs if getattr(s, 'rb_local_deleted', 0) == 0]
            
            # Get all content to match against
            all_content = list(self.db.get_content())
            active_content = [c for c in all_content if getattr(c, 'rb_local_deleted', 0) == 0]
            
            # Create a lookup for faster access
            content_lookup = {str(c.ID): c for c in active_content}
            
            # Build tracks list maintaining playlist order
            tracks = []
            # Sort by TrackNo to maintain playlist order
            sorted_songs = sorted(active_songs, key=lambda x: getattr(x, 'TrackNo', 0))
            
            for song_playlist in sorted_songs:
                content_id = str(song_playlist.ContentID)
                if content_id in content_lookup:
                    track = self._content_to_track(content_lookup[content_id])
                    tracks.append(track)
            
            return tracks
            
        except Exception as e:
            logger.error(f"Failed to get playlist tracks for playlist {playlist_id}: {e}")
            return []
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It states it 'Get[s] all tracks' but doesn't disclose behavioral traits like whether this is a read-only operation, if it requires authentication, rate limits, pagination behavior, or error handling. The description is minimal and lacks critical operational context for a tool that likely interacts with a playlist system.

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 appropriately sized with three sentences: purpose, args, and returns. It's front-loaded with the core function. However, the 'Args' and 'Returns' sections could be integrated more smoothly, and some redundancy exists (e.g., 'playlist' repeated). Overall efficient but with minor structural improvements possible.

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?

Given low complexity (1 parameter), no annotations, and an output schema exists (so return values are documented elsewhere), the description is somewhat complete but has gaps. It covers the basic purpose and parameter semantics but lacks usage guidelines and behavioral transparency, making it inadequate for optimal agent operation without external context.

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 0%, so the description must compensate. It adds meaning by explaining 'playlist_id' as 'The unique playlist identifier', which clarifies beyond the schema's generic 'Playlist Id' title. However, it doesn't cover format (e.g., string pattern), validation, or examples, leaving gaps. With one parameter, the baseline is 4, but incomplete compensation reduces it to 3.

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 verb 'Get' and resource 'tracks in a specific playlist', making the purpose explicit. It distinguishes from siblings like 'get_playlists' (which lists playlists) and 'get_track_details' (which gets metadata for individual tracks). However, it doesn't specify if this returns all tracks at once or uses pagination, which slightly limits differentiation from other track-fetching tools.

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 alternatives. It doesn't mention siblings like 'get_playlists' (to first find playlist IDs) or 'search_tracks' (for broader searches), nor does it specify prerequisites (e.g., needing a valid playlist_id from elsewhere). The context is implied but not explicit.

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/davehenke/rekordbox-mcp'

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