Skip to main content
Glama
davehenke

rekordbox-mcp

get_track_details

Retrieve detailed track metadata, cue points, and play history from rekordbox DJ databases using a unique track identifier.

Instructions

Get detailed information about a specific track.

Args: track_id: The unique track identifier

Returns: Detailed track information including metadata, cue points, and play history

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
track_idYes

Implementation Reference

  • The handler function for the 'get_track_details' tool, registered via @mcp.tool() decorator. It handles input validation via type hints, fetches the track from the RekordboxDatabase instance, and returns the track details as a dictionary using model_dump().
    @mcp.tool()
    async def get_track_details(track_id: str) -> Dict[str, Any]:
        """
        Get detailed information about a specific track.
        
        Args:
            track_id: The unique track identifier
            
        Returns:
            Detailed track information including metadata, cue points, and play history
        """
        if not db:
            raise RuntimeError("Database not initialized.")
        
        track = await db.get_track_by_id(track_id)
        if not track:
            raise ValueError(f"Track with ID {track_id} not found")
        
        return track.model_dump()
  • Pydantic BaseModel defining the output schema for track details, used in the tool's return value via model_dump().
    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}"
  • Supporting method in RekordboxDatabase class that retrieves a track by ID from the pyrekordbox database instance, filtering soft-deleted tracks and converting to Track model.
    async def get_track_by_id(self, track_id: str) -> Optional[Track]:
        """
        Get a specific track by its ID.
        
        Args:
            track_id: The track's unique identifier
            
        Returns:
            Track object if found, None otherwise
        """
        if not self.db:
            raise RuntimeError("Database not connected")
        
        try:
            # Get all content and find by ID, filtering out soft-deleted tracks
            all_content = list(self.db.get_content())
            active_content = [c for c in all_content if getattr(c, 'rb_local_deleted', 0) == 0]
            content_id = int(track_id)
            
            # Find content by ID
            for content in active_content:
                if content.ID == content_id:
                    return self._content_to_track(content)
            
            return None
        except (ValueError, Exception):
            return None
  • Private helper method that maps raw pyrekordbox Content objects to the structured Track Pydantic model, handling data type conversions and object extractions.
    def _content_to_track(self, content) -> Track:
        """
        Convert pyrekordbox content object to our Track model.
        
        Args:
            content: pyrekordbox content object
            
        Returns:
            Track model instance
        """
        # Handle BPM - it's stored as integer * 100 in the database
        bpm_value = getattr(content, 'BPM', 0) or 0
        bpm_float = float(bpm_value) / 100.0 if bpm_value else 0.0
        
        # Handle artist - it might be an object or string
        artist_name = ""
        if hasattr(content, 'ArtistName'):
            artist_name = content.ArtistName or ""
        elif hasattr(content, 'Artist'):
            artist_obj = content.Artist
            if hasattr(artist_obj, 'Name'):
                artist_name = artist_obj.Name or ""
            else:
                artist_name = str(artist_obj) if artist_obj else ""
        
        # Handle key - it might be an object
        key_name = ""
        if hasattr(content, 'KeyName'):
            key_name = content.KeyName or ""
        elif hasattr(content, 'Key'):
            key_obj = content.Key
            if hasattr(key_obj, 'Name'):
                key_name = key_obj.Name or ""
            else:
                key_name = str(key_obj) if key_obj else ""
        
        # Handle album - it might be an object
        album_name = ""
        if hasattr(content, 'AlbumName'):
            album_name = content.AlbumName or ""
        elif hasattr(content, 'Album'):
            album_obj = content.Album
            if hasattr(album_obj, 'Name'):
                album_name = album_obj.Name or ""
            else:
                album_name = str(album_obj) if album_obj else ""
        
        # Handle genre - it might be an object
        genre_name = ""
        if hasattr(content, 'GenreName'):
            genre_name = content.GenreName or ""
        elif hasattr(content, 'Genre'):
            genre_obj = content.Genre
            if hasattr(genre_obj, 'Name'):
                genre_name = genre_obj.Name or ""
            else:
                genre_name = str(genre_obj) if genre_obj else ""
        
        return Track(
            id=str(content.ID),
            title=content.Title or "",
            artist=artist_name,
            album=album_name,
            genre=genre_name,
            bpm=bpm_float,
            key=key_name,
            rating=int(getattr(content, 'Rating', 0) or 0),
            play_count=int(getattr(content, 'DJPlayCount', 0) or 0),
            length=int(getattr(content, 'Length', 0) or 0),
            file_path=getattr(content, 'FolderPath', '') or "",
            date_added=getattr(content, 'DateCreated', '') or "",
            date_modified=getattr(content, 'StockDate', '') or "",
            bitrate=int(getattr(content, 'BitRate', 0) or 0),
            sample_rate=int(getattr(content, 'SampleRate', 0) or 0),
            comments=getattr(content, 'Commnt', '') or ""
        )
  • The @mcp.tool() decorator on the handler function registers 'get_track_details' as an MCP tool with FastMCP, using the function signature for input schema.
    @mcp.tool()

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