Skip to main content
Glama

SpotifySearch

Search for tracks, albums, artists, or playlists on Spotify using specific queries and customizable filters to find and retrieve music content efficiently.

Instructions

Search for tracks, albums, artists, or playlists on Spotify.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of items to return
qtypeNoType of items to search for (track, album, artist, playlist, or comma-separated combination)track
queryYesquery term

Implementation Reference

  • Main handler logic for executing the SpotifySearch tool. Extracts query, qtype, limit from arguments, calls spotify_client.search(), formats the search results into a user-friendly list with URIs and details for tracks, artists, albums, playlists, handles no results and errors.
    case "Search": try: logger.info(f"Performing search with arguments: {arguments}") query = arguments.get("query", "") qtype = arguments.get("qtype", "track") limit = arguments.get("limit", 10) search_results = spotify_client.search( query=query, qtype=qtype, limit=limit ) logger.info(f"Search results: {search_results}") formatted_results = [f"🔍 Search Results for {qtype}s:"] # Map qtype to corresponding key in the response result_items = search_results.get(f"{qtype}s", []) if not result_items: return create_error_response(f"No {qtype}s found for your query.") for idx, item in enumerate(result_items, start=1): if qtype == "track": title = item.get("name", "Unknown Title") uri = f"spotify:track:{item.get('id', 'N/A')}" formatted_results.append(f"{idx}. \"{title}\" by {get_artist_string(item)}\n URI: {uri}") elif qtype == "artist": name = item.get("name", "Unknown Artist") uri = f"spotify:artist:{item.get('id', 'N/A')}" formatted_results.append(f"{idx}. 👤 {name}\n URI: {uri}") elif qtype == "album": title = item.get("name", "Unknown Album") uri = f"spotify:album:{item.get('id', 'N/A')}" formatted_results.append(f"{idx}. 💿 \"{title}\" by {get_artist_string(item)}\n URI: {uri}") elif qtype == "playlist": name = item.get("name", "Unknown Playlist") owner = item.get("owner", "Unknown Owner") is_owner = item.get("user_is_owner", False) total_tracks = item.get("total_tracks", "N/A") uri = f"spotify:playlist:{item.get('id', 'N/A')}" ownership_text = "✅ You own this playlist" if is_owner else "👤 Owned by someone else" formatted_results.append( f"{idx}. 📜 \"{name}\"\n" f" Owner: {owner} | Tracks: {total_tracks}\n" f" {ownership_text}\n" f" URI: {uri}" ) else: formatted_results.append(f"{idx}. Unsupported qtype: {qtype}") return [types.TextContent( type="text", text="\n".join(formatted_results) )] except Exception as e: logger.error(f"Search failed: {e}") return create_error_response(f"An error occurred during search: {str(e)}")
  • Pydantic input schema for the SpotifySearch tool, defining required 'query' and optional 'qtype' (default 'track') and 'limit' (default 10). Used to generate the tool schema via ToolModel.as_tool().
    class Search(ToolModel): """Search for tracks, albums, artists, or playlists on Spotify.""" query: str = Field(description="query term") qtype: Optional[str] = Field(default="track", description="Type of items to search for (track, album, artist, playlist, " + "or comma-separated combination)") limit: Optional[int] = Field(default=10, description="Maximum number of items to return")
  • Registration of the SpotifySearch tool in the MCP list_tools handler. Search.as_tool() creates the types.Tool with name="SpotifySearch", added to the list of available tools.
    Playback.as_tool(), Search.as_tool(), Queue.as_tool(), GetInfo.as_tool(), Playlist.as_tool(), ]
  • Core search implementation in SpotifyClient.smart_search, called indirectly via search(). Performs optional local search, falls back to Spotify API search (self.sp.search), parses results with utils.parse_search_results, merges local results if available, deduplicates by ID.
    def smart_search( self, query: str, qtype: str = 'track', limit: int = 10, ) -> dict: try: local_resp = requests.get( LOCAL_SEARCH_URL, params={'q': query, 'type': qtype}, timeout=5 ) local_resp.raise_for_status() local_data = local_resp.json().get("documents", []) self.logger.info(local_data) except RequestException as e: self.logger.info(f"[local search failed] {e}") local_data = None self.logger.info("Falling back to online Spotify search") online_results = self.sp.search(q=query, type=qtype, limit=limit,market=SPOTIFY_COUNTRY) parsed_results = utils.parse_search_results(online_results, qtype, self.username) if local_data and isinstance(local_data, list) and len(local_data) > 0 and (qtype == "track" or qtype == "playlist"): self.logger.info("Loading local results") local_results = utils.parse_local_documents(local_data, qtype) if local_results: for key in local_results: all_items = local_results[key] + parsed_results.get(key, []) # Remove duplicates using dict keyed by 'id' deduped = {item['id']: item for item in all_items if 'id' in item} parsed_results[key] = list(deduped.values()) return parsed_results
  • Utility function parse_search_results used by smart_search to parse raw Spotify search API results into simplified dictionaries for tracks, artists, albums, playlists using helper parse_* functions.
    def parse_search_results(results: Dict, qtype: str, username: Optional[str] = None): _results = defaultdict(list) # potential # if username: # _results['User Spotify URI'] = username for q in qtype.split(","): match q: case "track": for idx, item in enumerate(results['tracks']['items']): if not item: continue _results['tracks'].append(parse_track(item)) case "artist": for idx, item in enumerate(results['artists']['items']): if not item: continue _results['artists'].append(parse_artist(item)) case "playlist": for idx, item in enumerate(results['playlists']['items']): if not item: continue _results['playlists'].append(parse_playlist(item, username)) case "album": for idx, item in enumerate(results['albums']['items']): if not item: continue _results['albums'].append(parse_album(item)) case _: raise ValueError(f"Unknown qtype {qtype}") return dict(_results)

Other Tools

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

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