Skip to main content
Glama

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