Skip to main content
Glama
kylestratis

Spotify Playlist MCP Server

by kylestratis

spotify_get_audio_features

Retrieve detailed audio analysis features for Spotify tracks, including energy, tempo, danceability, and other sonic characteristics to power similarity matching and playlist creation.

Instructions

Get detailed audio analysis features for one or more Spotify tracks.

Retrieves sonic characteristics (energy, tempo, danceability, valence, acousticness, etc.) that power the similarity engine. Supports batch processing of up to 100 tracks. Args: - track_ids: List of Spotify track IDs, 1-100 tracks - response_format: 'markdown' or 'json' (default: JSON) Returns: Markdown: Per-track audio features (acousticness, danceability, energy, instrumentalness, liveness, loudness, speechiness, valence, tempo, key, mode, time_signature) JSON: {"track_count": N, "features": [{id, acousticness, danceability, energy, instrumentalness, liveness, loudness, speechiness, valence, tempo, key, mode, time_signature, duration_ms, analysis_url, track_href, type, uri}]} Examples: - "Analyze the audio features of this track" -> Get sonic characteristics - "What's the tempo and energy of these songs?" -> Extract specific features Errors: Returns "No audio features available" if not found, or error for auth failure (401), rate limits (429). Note: Audio features endpoint deprecated for NEW apps (Nov 2024), but existing apps with extended mode access can still use it.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paramsYes

Implementation Reference

  • server.py:579-588 (registration)
    Registers the spotify_get_audio_features tool using the @mcp.tool decorator with appropriate annotations.
    @mcp.tool( name="spotify_get_audio_features", annotations={ "title": "Get Spotify Audio Features", "readOnlyHint": True, "destructiveHint": False, "idempotentHint": True, "openWorldHint": True, }, )
  • The main handler function that fetches audio features using the helper function and formats the output in markdown or JSON based on the input parameters.
    async def spotify_get_audio_features(params: GetAudioFeaturesInput) -> str: """Get detailed audio analysis features for one or more Spotify tracks. Retrieves sonic characteristics (energy, tempo, danceability, valence, acousticness, etc.) that power the similarity engine. Supports batch processing of up to 100 tracks. Args: - track_ids: List of Spotify track IDs, 1-100 tracks - response_format: 'markdown' or 'json' (default: JSON) Returns: Markdown: Per-track audio features (acousticness, danceability, energy, instrumentalness, liveness, loudness, speechiness, valence, tempo, key, mode, time_signature) JSON: {"track_count": N, "features": [{id, acousticness, danceability, energy, instrumentalness, liveness, loudness, speechiness, valence, tempo, key, mode, time_signature, duration_ms, analysis_url, track_href, type, uri}]} Examples: - "Analyze the audio features of this track" -> Get sonic characteristics - "What's the tempo and energy of these songs?" -> Extract specific features Errors: Returns "No audio features available" if not found, or error for auth failure (401), rate limits (429). Note: Audio features endpoint deprecated for NEW apps (Nov 2024), but existing apps with extended mode access can still use it. """ try: features_map = await get_audio_features_for_tracks(params.track_ids) if not features_map: return "No audio features available for the provided track IDs." if params.response_format == ResponseFormat.MARKDOWN: lines = ["# Audio Features\n"] for track_id, features in features_map.items(): lines.append(f"## Track: {track_id}") lines.append( f"- **Acousticness**: {features.get('acousticness', 0):.3f}" ) lines.append( f"- **Danceability**: {features.get('danceability', 0):.3f}" ) lines.append(f"- **Energy**: {features.get('energy', 0):.3f}") lines.append( f"- **Instrumentalness**: {features.get('instrumentalness', 0):.3f}" ) lines.append(f"- **Liveness**: {features.get('liveness', 0):.3f}") lines.append(f"- **Loudness**: {features.get('loudness', 0):.1f} dB") lines.append(f"- **Speechiness**: {features.get('speechiness', 0):.3f}") lines.append(f"- **Valence**: {features.get('valence', 0):.3f}") lines.append(f"- **Tempo**: {features.get('tempo', 0):.1f} BPM") lines.append(f"- **Key**: {features.get('key', -1)}") lines.append( f"- **Mode**: {'Major' if features.get('mode') == 1 else 'Minor'}" ) lines.append( f"- **Time Signature**: {features.get('time_signature', 4)}/4\n" ) return "\n".join(lines) else: # JSON format return json.dumps( { "track_count": len(features_map), "features": list(features_map.values()), }, indent=2, ) except Exception as e: return handle_spotify_error(e)
  • Pydantic BaseModel defining the input schema for the tool, validating track_ids (1-100) and response_format.
    class GetAudioFeaturesInput(BaseModel): """Input model for getting audio features.""" model_config = ConfigDict(str_strip_whitespace=True, validate_assignment=True) track_ids: list[str] = Field( ..., description="List of Spotify track IDs (1-100)", min_length=1, max_length=100, ) response_format: ResponseFormat = Field( default=ResponseFormat.JSON, description="Output format: 'markdown' or 'json'", )
  • Helper function that retrieves audio features from the Spotify API for a list of track IDs, handling batch requests up to 100 tracks and fallback to individual requests if needed.
    async def get_audio_features_for_tracks( track_ids: list[str], ) -> dict[str, dict[str, Any]]: """Get audio features for multiple tracks. Args: track_ids: List of Spotify track IDs Returns: Dictionary mapping track IDs to their audio features """ features_map = {} # Spotify API supports up to 100 tracks at once for i in range(0, len(track_ids), 100): batch = track_ids[i : i + 100] ids_param = ",".join(batch) try: data = await make_spotify_request(f"audio-features?ids={ids_param}") audio_features_list = data.get("audio_features", []) for features in audio_features_list: if features: # Skip None values for unavailable tracks features_map[features["id"]] = features except Exception: # If batch fails, try individual requests for track_id in batch: try: features = await make_spotify_request(f"audio-features/{track_id}") features_map[track_id] = features except Exception: pass # Skip tracks that fail return features_map

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/kylestratis/spotify-mcp'

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