Skip to main content
Glama

get_crypto_rss_list

Retrieve cryptocurrency RSS feeds from OPML files, optionally filtered by keyword to find relevant market updates and news sources.

Instructions

Retrieve a list of available cryptocurrency RSS feeds from a local or remote OPML file, optionally filtered by keyword.

Parameters:
    keyword (str, optional): Filter feeds where the keyword appears in the description or category (case-insensitive).
    opml_file (str, optional): Path to a local OPML file to read feeds from. If not provided, fetches from the remote OPML URL.

Returns:
    str: A formatted string listing each RSS feed URL, its description, and category, parsed from the OPML file.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
keywordNo
opml_fileNoRAW.opml

Implementation Reference

  • Registers the get_crypto_rss_list tool with the FastMCP server.
    @mcp.tool()
  • Defines the input parameters, docstring describing usage, parameters, and return type for the tool.
    async def get_crypto_rss_list(keyword: str = None, opml_file: str = "RAW.opml") -> str:
        """
        Retrieve a list of available cryptocurrency RSS feeds from a local or remote OPML file, optionally filtered by keyword.
        
        Parameters:
            keyword (str, optional): Filter feeds where the keyword appears in the description or category (case-insensitive).
            opml_file (str, optional): Path to a local OPML file to read feeds from. If not provided, fetches from the remote OPML URL.
        
        Returns:
            str: A formatted string listing each RSS feed URL, its description, and category, parsed from the OPML file.
        """
  • Executes the tool logic: loads feeds from OPML, filters by keyword if provided, formats and returns the list as a string.
    feeds = load_rss_feeds_from_opml(opml_file=opml_file)
    if keyword:
        keyword = keyword.lower()
        feeds = [
            feed for feed in feeds
            if keyword in feed['description'].lower() or keyword in (feed['category'] or '').lower()
        ]
    result = "Available Cryptocurrency RSS Feeds:\n\n"
    if not feeds:
        result += "No feeds found matching the keyword.\n"
    for feed in feeds:
        result += f"Category: {feed['category'] or 'Uncategorized'}\n"
        result += f"URL: {feed['url']}\n"
        result += f"Description: {feed['description']}\n\n"
    return result
  • Helper function called by the handler to parse the OPML file and extract list of RSS feeds with URLs, descriptions, and categories.
    def load_rss_feeds_from_opml(opml_file: str) -> List[dict]:
        """Load RSS feeds from an OPML file."""
        try:
            outline = opml.parse(opml_file)
            feeds = []
            def parse_outline(items, category: str = ""):
                for item in items:
                    print(item, hasattr(item, "__iter__"))
                    if hasattr(item, "xmlUrl") and item.xmlUrl:
                        # Collect feed with URL, description, and optional category
                        feeds.append({
                            "url": item.xmlUrl,
                            "description": item.title or item.text or "No description available",
                            "category": category
                        })
                    # Recursively process nested outlines
            def parse_outline(items, category: str = ""):
                for item in items:
                    if hasattr(item, "xmlUrl") and item.xmlUrl:
                        # Collect feed with URL, description, and optional category
                        feeds.append({
                            "url": item.xmlUrl,
                            "description": item.title or item.text or "No description available",
                            "category": category
                        })
                    # Recursively process nested outlines (children)
                    try:
                        # Iterate over item as a container of child outlines
                        parse_outline(item, category=item.title or item.text or category)
                    except TypeError:
                        # If item is not iterable, skip to next item
                        continue
                    
            # Start parsing from top-level outlines
            parse_outline(outline)
            return feeds
        except FileNotFoundError:
            raise RuntimeError(f"OPML file not found: {OPML_FILE}")
        except Exception as e:
            raise RuntimeError(f"Failed to parse OPML file: {str(e)}")
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses key behaviors: fetching from remote or local sources, case-insensitive keyword filtering, and returning a formatted string. However, it lacks details on error handling, rate limits, authentication needs, or what happens if the file is missing, leaving gaps for a tool with mutation-like operations (file reading).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded: the first sentence states the core purpose, followed by bullet-like sections for parameters and returns. Every sentence adds value without redundancy, making it efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, 0% schema coverage, and no output schema, the description does well by explaining parameters and return format. However, for a tool that reads files and fetches remote data, it lacks details on error cases (e.g., invalid file paths) and behavioral constraints, leaving some contextual gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate fully. It adds significant meaning beyond the schema: explains that 'keyword' filters by description/category case-insensitively, and 'opml_file' specifies a local path with a default remote fetch. This provides essential context not in the schema, fully compensating for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Retrieve a list'), resource ('available cryptocurrency RSS feeds'), and source ('from a local or remote OPML file'). It distinguishes from the sibling tool 'get_rss_feed' by specifying cryptocurrency feeds and OPML file parsing, providing specific verb+resource differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for usage: retrieving feeds from OPML files with optional filtering. However, it does not explicitly state when to use this tool versus the sibling 'get_rss_feed' or specify any exclusions or prerequisites, missing explicit alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/kukapay/crypto-rss-mcp'

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