Skip to main content
Glama

get_circuit

Retrieve Formula 1 circuit layouts, corner details, or real-time track status including flags and safety car periods for specific Grand Prix events.

Instructions

Get circuit layout, corners, or track status (flags, safety car).

Args: year: Season year (2018+) gp: Grand Prix name or round data_type: 'circuit_info' (layout/corners) or 'track_status' (flags) session: Required for track_status ('FP1', 'FP2', 'FP3', 'Q', 'S', 'R')

Returns: CircuitDataResponse with circuit details or track status changes

Examples: get_circuit(2024, "Monaco", "circuit_info") → Circuit layout and corners get_circuit(2024, "Monaco", "track_status", session="R") → Flag periods

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
yearYes
gpYes
data_typeNocircuit_info
sessionNo

Implementation Reference

  • Main handler function implementing the get_circuit tool logic. Fetches circuit layout, corners, and track status data using FastF1 client.
    def get_circuit( year: int, gp: Union[str, int], data_type: Literal["circuit_info", "track_status"] = "circuit_info", session: Optional[str] = None, ) -> CircuitDataResponse: """ Get circuit layout, corners, or track status (flags, safety car). Args: year: Season year (2018+) gp: Grand Prix name or round data_type: 'circuit_info' (layout/corners) or 'track_status' (flags) session: Required for track_status ('FP1', 'FP2', 'FP3', 'Q', 'S', 'R') Returns: CircuitDataResponse with circuit details or track status changes Examples: get_circuit(2024, "Monaco", "circuit_info") → Circuit layout and corners get_circuit(2024, "Monaco", "track_status", session="R") → Flag periods """ # Get event information event = fastf1_client.get_event(year, gp) if data_type == "circuit_info": # Load a session to get circuit info (use Race or first available session) if session: session_obj = fastf1_client.get_session(year, gp, session) else: # Try to get race session, fallback to any available try: session_obj = fastf1_client.get_session(year, gp, 'R') except Exception: try: session_obj = fastf1_client.get_session(year, gp, 'Q') except Exception: session_obj = fastf1_client.get_session(year, gp, 1) session_obj.load() # Get circuit information try: circuit_info = session_obj.get_circuit_info() # Extract corner information corners_list = [] if circuit_info.corners is not None and len(circuit_info.corners) > 0: for idx, corner in circuit_info.corners.iterrows(): corners_list.append( CornerInfo( number=int(corner['Number']) if pd.notna(corner.get('Number')) else idx, letter=str(corner['Letter']) if pd.notna(corner.get('Letter')) else None, distance=float(corner['Distance']) if pd.notna(corner.get('Distance')) else None, x=float(corner['X']) if pd.notna(corner.get('X')) else None, y=float(corner['Y']) if pd.notna(corner.get('Y')) else None, ) ) circuit_details = CircuitDetails( circuit_key=int(circuit_info.circuit_key) if hasattr(circuit_info, 'circuit_key') and circuit_info.circuit_key else None, circuit_name=str(event['EventName']) if event is not None else None, location=str(event['Location']) if event is not None else None, country=str(event['Country']) if event is not None else None, rotation=float(circuit_info.rotation) if hasattr(circuit_info, 'rotation') and circuit_info.rotation else None, corners=corners_list if corners_list else None, ) except Exception as e: # If circuit info not available, provide basic event info circuit_details = CircuitDetails( circuit_name=str(event['EventName']) if event is not None else None, location=str(event['Location']) if event is not None else None, country=str(event['Country']) if event is not None else None, ) return CircuitDataResponse( year=year, event_name=str(event['EventName']) if event is not None else "", session_name=None, circuit_details=circuit_details, data_type=data_type, ) elif data_type == "track_status": if not session: raise ValueError("session parameter is required for track_status data type") # Load session with track status data session_obj = fastf1_client.get_session(year, gp, session) session_obj.load() # Get track status data track_status_df = session_obj.track_status track_status_list = [] if track_status_df is not None and len(track_status_df) > 0: for idx, row in track_status_df.iterrows(): # Map status codes to messages status_code = str(row['Status']) status_messages = { '1': 'Green Flag / Track Clear', '2': 'Yellow Flag / Caution', '3': 'Green Flag (after SC)', '4': 'Safety Car', '5': 'Red Flag / Session Stopped', '6': 'Virtual Safety Car (VSC)', '7': 'VSC Ending', } message = status_messages.get(status_code, f'Status Code {status_code}') track_status_list.append( TrackStatusInfo( time=str(row['Time']) if pd.notna(row.get('Time')) else "", status=status_code, message=message, ) ) return CircuitDataResponse( year=year, event_name=str(event['EventName']) if event is not None else "", session_name=session_obj.name if hasattr(session_obj, 'name') else session, track_status=track_status_list, data_type=data_type, )
  • Pydantic BaseModel definitions for the tool's input parameters (via function signature) and output response (CircuitDataResponse and supporting models).
    from pydantic import BaseModel, Field from typing import Optional class CornerInfo(BaseModel): """Information about a corner on the circuit.""" number: int = Field(..., description="Corner number") letter: Optional[str] = Field(None, description="Corner letter (if applicable)") distance: Optional[float] = Field(None, description="Distance from start line in meters") x: Optional[float] = Field(None, description="X coordinate") y: Optional[float] = Field(None, description="Y coordinate") class CircuitDetails(BaseModel): """Detailed circuit information.""" circuit_key: Optional[int] = Field(None, description="Circuit key/ID") circuit_name: Optional[str] = Field(None, description="Circuit name") location: Optional[str] = Field(None, description="Circuit location") country: Optional[str] = Field(None, description="Country") rotation: Optional[float] = Field(None, description="Circuit rotation angle") corners: Optional[list[CornerInfo]] = Field(None, description="List of corners on the circuit") class TrackStatusInfo(BaseModel): """Track status information during a session.""" time: str = Field(..., description="Time of status") status: str = Field(..., description="Track status code (1=Green, 2=Yellow, 4=SC, 5=Red, 6=VSC, 7=VSC Ending)") message: Optional[str] = Field(None, description="Human-readable status message") class CircuitDataResponse(BaseModel): """Response containing circuit and track information.""" year: int = Field(..., description="Season year") event_name: str = Field(..., description="Event name") session_name: Optional[str] = Field(None, description="Session name (if session-specific)") # Circuit details circuit_details: Optional[CircuitDetails] = Field(None, description="Circuit layout and corner information") # Track status (session-specific) track_status: Optional[list[TrackStatusInfo]] = Field(None, description="Track status changes during session") # Metadata data_type: str = Field(..., description="Type: 'circuit_info' or 'track_status'")
  • server.py:165-165 (registration)
    Registration of the get_circuit tool using the FastMCP decorator mcp.tool().
    mcp.tool()(get_circuit)

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/praneethravuri/pitstop'

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