Skip to main content
Glama
omniwaifu

arr-assistant-mcp

by omniwaifu

search_and_add_show

Search for TV shows with natural language queries and optionally add results to Sonarr, streamlining media library management with precise metadata matching.

Instructions

Search for TV shows using natural language description and optionally add to Sonarr.

Args: description: Natural language description of the TV show (e.g., "British time travel show with the Doctor") auto_add: If True and only one result found, automatically add to Sonarr

Returns: List of matching TV shows with metadata

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
auto_addNo
descriptionYes

Implementation Reference

  • The primary handler function for the 'search_and_add_show' MCP tool. It uses the Sonarr API to search for TV shows matching the given description, returns up to 5 results as MediaSearchResult objects, and optionally auto-adds the single best match to Sonarr if auto_add is True.
    @mcp.tool async def search_and_add_show( description: str, auto_add: bool = False ) -> List[MediaSearchResult]: """ Search for TV shows using natural language description and optionally add to Sonarr. Args: description: Natural language description of the TV show (e.g., "British time travel show with the Doctor") auto_add: If True and only one result found, automatically add to Sonarr Returns: List of matching TV shows with metadata """ if not config: raise ValueError("Server not configured. Please set up Sonarr API key.") api = MediaServerAPI(config) # Search for TV shows using Sonarr lookup tv_results = await api.search_sonarr_shows(description) results = [] for show in tv_results[:5]: # Limit to top 5 results result = MediaSearchResult( title=show.get("title", "Unknown"), year=show.get("year"), overview=show.get("overview", "No overview available"), tmdb_id=show.get("tmdbId"), tvdb_id=show.get("tvdbId"), poster_path=show.get("remotePoster"), media_type="tv" ) results.append(result) # Auto-add if requested and only one result if auto_add and len(results) == 1: show = results[0] if show.tvdb_id: add_result = await api.add_series_to_sonarr(show.tvdb_id, show.title, show.tmdb_id) logger.info(f"Auto-add result: {add_result}") else: logger.warning(f"Cannot auto-add '{show.title}' - no TVDB ID available") return results
  • Pydantic schema/model defining the structure of each media search result returned by the search_and_add_show tool.
    class MediaSearchResult(BaseModel): title: str year: Optional[int] = None overview: str tmdb_id: Optional[int] = None tvdb_id: Optional[int] = None poster_path: Optional[str] = None media_type: str # "movie" or "tv"
  • The @mcp.tool decorator registers the search_and_add_show function as an MCP tool with FastMCP (tool name matches function name).
    @mcp.tool
  • Helper method in MediaServerAPI class that performs the actual Sonarr API search for TV shows, called by the tool handler.
    async def search_sonarr_shows(self, query: str) -> List[Dict[str, Any]]: """Search for TV shows using Sonarr's built-in lookup""" url = f"{self.config.sonarr_url}/api/v3/series/lookup" headers = {"X-Api-Key": self.config.sonarr_api_key} params = {"term": query} logger.info(f"Sonarr lookup request: {url} with term='{query}'") try: response = await self.client.get(url, params=params, headers=headers) logger.info(f"Sonarr response status: {response.status_code}") if response.status_code == 401: logger.error("Sonarr authentication failed - check your API key") raise Exception("Sonarr authentication failed - verify your API key is correct") elif response.status_code == 404: logger.error("Sonarr lookup endpoint not found") raise Exception("Sonarr lookup endpoint not found") response.raise_for_status() results = response.json() logger.info(f"Sonarr returned {len(results)} results for query '{query}'") if results: logger.info(f"First result: {results[0].get('title')} ({results[0].get('year', 'No year')})") return results except Exception as e: logger.error(f"Sonarr lookup error for query '{query}': {e}") raise e
  • Helper method in MediaServerAPI class that adds a TV series to Sonarr using TVDB ID, called during auto-add in the tool handler.
    async def add_series_to_sonarr(self, tvdb_id: int, title: str, root_folder: Optional[str] = None) -> AddMediaResponse: """Add TV series to Sonarr using TVDB ID""" url = f"{self.config.sonarr_url}/api/v3/series" headers = {"X-Api-Key": self.config.sonarr_api_key} payload = { "title": title, "tvdbId": tvdb_id, "qualityProfileId": self.config.quality_profile_id, "monitored": True, "seasonFolder": True, "addOptions": { "searchForMissingEpisodes": True } } # Set root folder (parameter > config > auto-detect) if root_folder: payload["rootFolderPath"] = root_folder logger.info(f"Using specified root folder: {root_folder}") elif self.config.sonarr_root_folder: payload["rootFolderPath"] = self.config.sonarr_root_folder logger.info(f"Using configured root folder: {self.config.sonarr_root_folder}") else: # Auto-detect first available root folder root_folders = await self.get_sonarr_root_folders() if root_folders: payload["rootFolderPath"] = root_folders[0]["path"] logger.info(f"Using auto-detected Sonarr root folder: {root_folders[0]['path']}") else: logger.warning("No Sonarr root folders found - series may fail to add") try: response = await self.client.post(url, json=payload, headers=headers) if response.status_code == 201: result = response.json() return AddMediaResponse( success=True, message=f"Successfully added '{title}' to Sonarr", media_id=result.get("id") ) else: return AddMediaResponse( success=False, message=f"Failed to add series: {response.text}" ) except Exception as e: logger.error(f"Sonarr API error: {e}") return AddMediaResponse( success=False, message=f"Error communicating with Sonarr: {str(e)}" )

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/omniwaifu/arr-assistant-mcp'

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