Skip to main content
Glama
r-huijts

FirstCycling MCP Server

by r-huijts

search_race

Find cycling races by name to retrieve their IDs and countries. Use this tool to search for races like Tour de France or Giro d'Italia and get structured information for further operations.

Instructions

Search for cycling races by name. This tool helps find races by their name, returning a list of matching races with their IDs and countries. This is useful when you know a race's name but need its ID for other operations.

Example usage: - Search for "tour" to find Tour de France and other tours - Search for "giro" to find Giro d'Italia Returns a formatted string with: - List of matching races - Each race's ID, name, and country - Number of matches found

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes

Implementation Reference

  • Core implementation of search_race tool: sends HTTP GET request to FirstCycling's race.php search endpoint with query parameters and returns raw HTML response.
    def search_race(self, query="", year=None, category="1"): return self._get_resource_response(self['race.php'], q=query, y=year, c=category)
  • Supporting helper function that parses the HTML from search_race to extract the best matching race ID using fuzzy string matching on race titles.
    def search_race_id(query, html, threshold=0.7): """ Zoekt naar de race id binnen de HTML-respons door de titels fuzzy te matchen met de query. Parameters: query (str): De zoekopdracht, bv. "Milan Sanremo". html (str): De HTML-respons van fc.search_race. threshold (float): De minimale overeenkomst (0.0 tot 1.0) om als match te beschouwen. Returns: int of None: Het race-ID als er een match is, anders None. """ soup = BeautifulSoup(html, "html.parser") norm_query = normalize(query) matches = [] # Zoek naar alle <a>-tags die een href bevatten met race.php?r= for a in soup.find_all("a", href=re.compile(r"race\.php\?r=")): title = a.get("title") if title: norm_title = normalize(title) ratio = difflib.SequenceMatcher(None, norm_query, norm_title).ratio() if ratio >= threshold: # Extraheer de race id uit de URL, bv. race.php?r=4&y=2025 m = re.search(r"r=(\d+)", a["href"]) if m: race_id = int(m.group(1)) matches.append((race_id, title, ratio)) if matches: # Geef de beste match (met de hoogste overeenkomst) terug best_match = max(matches, key=lambda x: x[2]) return best_match[0] return None
  • High-level class method that implements race search by calling search_race to get HTML, then search_race_id to find matching race ID, returning structured result.
    @classmethod def search(cls, query, year=None, category="1"): """ Search for races by name using fuzzy matching. Parameters ---------- query : str The search query string. year : int The year to search for races (e.g., 2025). If None, uses current year. category : str Category code - e.g., "1" for WorldTour, "2" for ProSeries. Returns ------- list A list containing one dictionary with the race id and query as name if a match is found, or an empty list otherwise. """ try: # Get HTML content using search_race API call html = fc.search_race(query, year, category) # Find best matching race ID using fuzzy matching race_id = search_race_id(query, html) if race_id is not None: # Return a dictionary with all expected keys return [{ 'id': race_id, 'name': query, 'country': '', 'date': '', 'category': category }] else: return [] except Exception as e: print(f"Error in Race.search: {str(e)}") return []

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/r-huijts/firstcycling-mcp'

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