Skip to main content
Glama
notsedano

Formula One MCP Server

by notsedano

compare_drivers

Compare Formula One driver performance by analyzing race results, qualifying times, and session data for specific seasons and events.

Instructions

Compare performance between multiple Formula One drivers

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
yearYesSeason year (e.g., 2023)
event_identifierYesEvent name or round number (e.g., 'Monaco' or '7')
session_nameYesSession name (e.g., 'Race', 'Qualifying', 'Sprint', 'FP1', 'FP2', 'FP3')
driversYesComma-separated list of driver codes (e.g., 'HAM,VER,LEC')

Implementation Reference

  • Core handler function that implements the compare_drivers tool logic using FastF1 to load session data, extract laps for multiple drivers, compute performance metrics like fastest lap, average lap time, and total laps, and return structured comparison data.
    def compare_drivers(year, event_identifier, session_name, drivers):
        """
        Compare performance between multiple Formula One drivers.
    
        Args:
            year (int or str): The year of the F1 season
            event_identifier (str): Event name or round number
            session_name (str): Session type (Race, Qualifying, Sprint, etc.)
            drivers (str): Comma-separated list of driver codes
    
        Returns:
            dict: Status and driver comparison data or error information
        """
        try:
            year = int(year)
            drivers_list = drivers.split(",")
    
            session = fastf1.get_session(year, event_identifier, session_name)
            session.load()
    
            driver_comparisons = []
    
            for driver in drivers_list:
                # Get laps and fastest lap for each driver
                driver_laps = session.laps.pick_driver(driver)
                fastest_lap = driver_laps.pick_fastest()
    
                # Calculate average lap time
                valid_lap_times = []
                for _, lap in driver_laps.iterrows():
                    if lap["LapTime"] is not None and not pd.isna(lap["LapTime"]):
                        valid_lap_times.append(lap["LapTime"].total_seconds())
    
                avg_lap_time = (
                    sum(valid_lap_times) / len(valid_lap_times) if valid_lap_times else None
                )
    
                # Format lap time as string
                formatted_fastest = None
                fastest_lap_number = None
                if fastest_lap is not None:
                    formatted_fastest = (
                        str(fastest_lap["LapTime"])
                        if not pd.isna(fastest_lap["LapTime"])
                        else None
                    )
                    fastest_lap_number = (
                        int(fastest_lap["LapNumber"])
                        if not pd.isna(fastest_lap["LapNumber"])
                        else None
                    )
    
                # Compile driver data
                driver_data = {
                    "DriverCode": driver,
                    "FastestLap": formatted_fastest,
                    "FastestLapNumber": fastest_lap_number,
                    "TotalLaps": len(driver_laps),
                    "AverageLapTime": avg_lap_time,
                }
    
                driver_comparisons.append(driver_data)
    
            return {"status": "success", "data": driver_comparisons}
        except Exception as e:
            return {"status": "error", "message": str(e)}
  • Dispatch logic in the MCP server's call_tool handler that routes requests for 'compare_drivers' to the actual implementation function.
    elif name == "compare_drivers":
        result = compare_drivers(
            sanitized_args["year"],
            str(arguments["event_identifier"]),
            str(arguments["session_name"]),
            str(arguments["drivers"]),
        )
  • MCP tool registration in list_tools() that defines the compare_drivers tool name, description, and input schema for validation.
    types.Tool(
        name="compare_drivers",
        description=(
            "Compare performance between multiple Formula One drivers"
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "year": {
                    "type": "number",
                    "description": "Season year (e.g., 2023)",
                },
                "event_identifier": {
                    "type": "string",
                    "description": (
                        "Event name or round number (e.g., 'Monaco' or '7')"
                    ),
                },
                "session_name": {
                    "type": "string",
                    "description": (
                        "Session name (e.g., 'Race', 'Qualifying', "
                        "'Sprint', 'FP1', 'FP2', 'FP3')"
                    ),
                },
                "drivers": {
                    "type": "string",
                    "description": (
                        "Comma-separated list of driver codes "
                        "(e.g., 'HAM,VER,LEC')"
                    ),
                },
            },
            "required": [
                "year",
                "event_identifier",
                "session_name",
                "drivers",
            ],
        },
    ),
  • Secondary registration of compare_drivers in the FastAPI bridge's tool_functions mapping for direct HTTP tool calls.
    tool_functions = {
        'get_championship_standings': get_championship_standings,
        'get_event_schedule': get_event_schedule,
        'get_event_info': get_event_info,
        'get_session_results': get_session_results,
        'get_driver_info': get_driver_info,
        'analyze_driver_performance': analyze_driver_performance,
        'compare_drivers': compare_drivers,
        'get_telemetry': get_telemetry
    }
  • Client-side TypeScript schema reference for the compare_drivers tool.
    name: 'compare_drivers',

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

B3.2/5.0
Behavior2/5

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

With no annotations, the description should disclose behavioral traits like side effects, rate limits, or return format, but it only states the purpose. It does not indicate that the tool is read-only or what performance metrics are compared.

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 a single concise sentence with no wasted words, achieving efficient communication of the tool's purpose.

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

Completeness2/5

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

The description is minimal given the tool's complexity (4 required parameters, no output schema, multiple siblings). It does not explain what 'performance' entails, how comparison is presented, or any constraints like driver codes.

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

Parameters3/5

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

Schema description coverage is 100%, so each parameter already has a description. The tool description adds no additional meaning to the parameters; baseline score of 3 is appropriate.

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 'Compare performance between multiple Formula One drivers' with a specific verb and resource, and it distinguishes from siblings like 'get_driver_info' or 'analyze_driver_performance' by focusing on comparison across multiple drivers.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool vs alternatives such as 'analyze_driver_performance' or 'get_session_results'. The description does not mention context or exclusions.

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