Skip to main content
Glama

Jupiter Broadcasting Podcast Data MCP Server

by Red5d

get_episode

Retrieve detailed podcast episode information including title, description, hosts, and media files by specifying show name and episode number.

Instructions

Get detailed information about a specific episode.

Args: show_name: Name of the show episode_number: Episode number

Returns: Episode data including title, description, hosts, enclosures, etc.

Input Schema

NameRequiredDescriptionDefault
show_nameYes
episode_numberYes

Input Schema (JSON Schema)

{ "properties": { "episode_number": { "type": "string" }, "show_name": { "type": "string" } }, "required": [ "show_name", "episode_number" ], "type": "object" }

Implementation Reference

  • MCP tool handler for 'get_episode', decorated with @mcp.tool() for automatic registration and schema inference from type hints. Delegates to rss_parser for core logic and handles errors.
    @mcp.tool() def get_episode(show_name: str, episode_number: str) -> Dict[str, Any]: """Get detailed information about a specific episode. Args: show_name: Name of the show episode_number: Episode number Returns: Episode data including title, description, hosts, enclosures, etc. """ try: episode = rss_parser.get_episode(show_name, episode_number) if episode: return episode else: return {"error": f"Episode '{episode_number}' not found in show '{show_name}'"} except Exception as e: return {"error": f"Failed to retrieve episode: {str(e)}"}
  • Core helper method in PodcastRSSParser class that fetches the RSS feed and finds the episode matching the given number via GUID or podcast:episode tag.
    def get_episode(self, show_name: str, episode_number: str) -> Optional[Dict[str, Any]]: """Get specific episode data.""" feed_root = self._get_feed(show_name) if feed_root is None: return None # Find all item elements (episodes) items = feed_root.xpath('//item') for item in items: # Check GUID guid_elem = item.find('guid') if guid_elem is not None and guid_elem.text == episode_number: return self._parse_episode(show_name, item) # Check podcast:episode number episode_elem = item.find('.//{https://podcastindex.org/namespace/1.0}episode') if episode_elem is not None and episode_elem.text == episode_number: return self._parse_episode(show_name, item) return None
  • Private helper method that parses a single RSS item (episode) XML element into a structured dictionary, extracting all relevant Podcast 2.0 fields.
    def _parse_episode(self, show_name: str, item: etree._Element) -> Dict[str, Any]: """Parse a single episode entry from XML.""" # Helper function to get text content safely def get_text(element): return element.text if element is not None else "" # Helper function to get CDATA content safely def get_cdata_content(element): if element is not None: # Handle CDATA content if element.text: return element.text.strip() return "" # Basic episode information title_elem = item.find('title') guid_elem = item.find('guid') link_elem = item.find('link') pubdate_elem = item.find('pubDate') description_elem = item.find('description') # iTunes elements duration_elem = item.find('.//{http://www.itunes.com/dtds/podcast-1.0.dtd}duration') # Podcast namespace elements episode_num_elem = item.find('.//{https://podcastindex.org/namespace/1.0}episode') episode_data = { "show_name": show_name, "id": get_text(guid_elem) or get_text(episode_num_elem), "episode_number": get_text(episode_num_elem), "title": get_text(title_elem), "description": get_cdata_content(description_elem), "published_date": get_text(pubdate_elem), "link": get_text(link_elem), "duration": get_text(duration_elem), "hosts": [], "transcript_urls": [], "enclosures": [], "chapters_url": None, } # Parse enclosures (audio files) enclosure_elems = item.findall('enclosure') for enclosure in enclosure_elems: episode_data["enclosures"].append({ "url": enclosure.get("url", ""), "type": enclosure.get("type", ""), "length": enclosure.get("length", "0"), }) # Parse podcast:person elements (hosts, guests, etc.) person_elems = item.findall('.//{https://podcastindex.org/namespace/1.0}person') for person in person_elems: role = person.get("role", "") if role == "host": person_name = person.text if person_name: episode_data["hosts"].append(person_name.strip()) # Parse podcast:transcript elements transcript_elems = item.findall('.//{https://podcastindex.org/namespace/1.0}transcript') for transcript in transcript_elems: transcript_url = transcript.get("url") transcript_type = transcript.get("type", "") if transcript_url: episode_data["transcript_urls"].append({ "url": transcript_url, "type": transcript_type, "language": transcript.get("language", "en-us") }) # For backward compatibility, set transcript_url to the first available transcript if episode_data["transcript_urls"]: episode_data["transcript_url"] = episode_data["transcript_urls"][0]["url"] else: episode_data["transcript_url"] = None # Parse podcast:chapters chapters_elem = item.find('.//{https://podcastindex.org/namespace/1.0}chapters') if chapters_elem is not None: episode_data["chapters_url"] = chapters_elem.get("url") return episode_data

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/Red5d/jupiterbroadcasting_mcp'

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