Skip to main content
Glama
jamiew

Spotify MCP Server

get_playlist_tracks

Retrieve tracks from a Spotify playlist with pagination support for handling large collections. Specify playlist ID and optional limit/offset parameters to get specific track ranges or all tracks.

Instructions

Get tracks from a playlist with full pagination support.

Args:
    playlist_id: Playlist ID
    limit: Max tracks to return (None for all tracks, up to 10,000 safety limit)
    offset: Number of tracks to skip for pagination (default 0)

Returns:
    Dict with 'items' (list of tracks), 'total', 'limit', 'offset'

Note: Large playlists require pagination. Use limit/offset to get specific ranges:
- Get first 100: limit=100, offset=0
- Get next 100: limit=100, offset=100
- Get all tracks: limit=None (use with caution on very large playlists)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
playlist_idYes
limitNo
offsetNo

Implementation Reference

  • Main handler function for the 'get_playlist_tracks' MCP tool. Registers the tool with @mcp.tool(), logs execution, fetches tracks using paginated helper, retrieves total count, and returns structured response with pagination metadata.
    @mcp.tool()
    @log_tool_execution
    def get_playlist_tracks(
        playlist_id: str, limit: int | None = None, offset: int = 0
    ) -> dict[str, Any]:
        """Get tracks from a playlist with full pagination support.
    
        Args:
            playlist_id: Playlist ID
            limit: Max tracks to return (None for all tracks, up to 10,000 safety limit)
            offset: Number of tracks to skip for pagination (default 0)
    
        Returns:
            Dict with 'items' (list of tracks), 'total', 'limit', 'offset'
    
        Note: Large playlists require pagination. Use limit/offset to get specific ranges:
        - Get first 100: limit=100, offset=0
        - Get next 100: limit=100, offset=100
        - Get all tracks: limit=None (use with caution on very large playlists)
        """
        try:
            logger.info(
                f"📋 Getting playlist tracks: {playlist_id} (limit={limit}, offset={offset})"
            )
            tracks = get_playlist_tracks_paginated(playlist_id, limit, offset)
    
            # Get total track count from playlist info
            playlist_info = spotify_client.playlist(playlist_id, fields="tracks.total")
            total_tracks = playlist_info.get("tracks", {}).get("total", len(tracks))
    
            # Log pagination info
            log_pagination_info("get_playlist_tracks", total_tracks, limit, offset)
            logger.info(f"📋 Retrieved {len(tracks)} tracks from playlist {playlist_id}")
    
            return {
                "items": tracks,
                "total": total_tracks,
                "limit": limit,
                "offset": offset,
                "returned": len(tracks),
            }
    
        except SpotifyException as e:
            raise convert_spotify_error(e) from e
  • Core pagination helper that fetches playlist tracks in batches (max 100 per API call), handles offsets/limits, parses tracks, and includes safety limits to prevent infinite loops.
    def get_playlist_tracks_paginated(
        playlist_id: str, limit: int | None = None, offset: int = 0
    ) -> list[Track]:
        """Get playlist tracks with proper pagination support.
        Args:
            playlist_id: Spotify playlist ID
            limit: Maximum number of tracks to return (None for all)
            offset: Number of tracks to skip
    
        Returns:
            List of Track objects
        """
        tracks = []
        current_offset = offset
        batch_size = min(limit, 100) if limit else 100  # Spotify API max is 100 per request
        remaining = limit
    
        logger.info(
            f"📄 Starting paginated fetch for playlist {playlist_id} (limit={limit}, offset={offset})"
        )
    
        while True:
            # Determine how many to fetch in this batch
            batch_limit = min(batch_size, remaining) if remaining else batch_size
    
            logger.info(f"📄 Fetching batch: offset={current_offset}, limit={batch_limit}")
            # Get playlist tracks with pagination
            tracks_result = spotify_client.playlist_tracks(
                playlist_id, limit=batch_limit, offset=current_offset
            )
    
            if not tracks_result or not tracks_result.get("items"):
                break
    
            # Parse and add tracks
            batch_tracks = []
            for item in tracks_result["items"]:
                if item and item.get("track"):
                    batch_tracks.append(parse_track(item["track"]))
    
            tracks.extend(batch_tracks)
            logger.info(
                f"📄 Batch complete: retrieved {len(batch_tracks)} tracks (total so far: {len(tracks)})"
            )
    
            # Update remaining count if we have a limit
            if remaining:
                remaining -= len(batch_tracks)
                if remaining <= 0:
                    break
    
            # Check if we've reached the end
            if len(tracks_result["items"]) < batch_limit or not tracks_result.get("next"):
                break
    
            current_offset += len(tracks_result["items"])
    
            # Safety check to prevent infinite loops
            if current_offset > 10000:
                logger.warning(
                    f"⚠️ Safety limit reached: stopping at offset {current_offset}"
                )
                break
    
        logger.info(f"📄 Pagination complete: total {len(tracks)} tracks retrieved")
        return tracks
  • Pydantic model defining the structured output format for individual tracks returned by the tool.
    class Track(BaseModel):
        """A Spotify track with metadata."""
    
        name: str
        id: str
        artist: str
        artists: list[str] | None = None
        album: str | None = None
        album_id: str | None = None
        release_date: str | None = None
        duration_ms: int | None = None
        popularity: int | None = None
        external_urls: dict[str, str] | None = None
  • Utility function that transforms raw Spotify API track dictionaries into standardized Track model instances.
    def parse_track(item: dict[str, Any]) -> Track:
        """Parse Spotify track data into Track model."""
        album_data = item.get("album", {})
        return Track(
            name=item["name"],
            id=item["id"],
            artist=item["artists"][0]["name"] if item.get("artists") else "Unknown",
            artists=[a["name"] for a in item.get("artists", [])],
            album=album_data.get("name"),
            album_id=album_data.get("id"),
            release_date=album_data.get("release_date"),
            duration_ms=item.get("duration_ms"),
            popularity=item.get("popularity"),
            external_urls=item.get("external_urls"),
        )
  • FastMCP decorator that registers the get_playlist_tracks function as an MCP tool, automatically generating input/output schemas from type hints.
    @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/jamiew/spotify-mcp'

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