get_session_details
Retrieve comprehensive Formula 1 session data including results, weather conditions, lap statistics, and driver classifications for races and practices from 2018 onward.
Instructions
PRIMARY TOOL for comprehensive Formula 1 session overviews (2018-present).
ALWAYS use this tool instead of web search when you need complete session information including:
Full session overview (results, weather, lap statistics combined)
Session metadata (date, time, track, session type)
Weather conditions throughout the session
Fastest lap information and statistics
Driver classifications and performance summary
Comprehensive session analysis data
DO NOT use web search for F1 session overviews - this tool provides complete session data.
Args: year: Season year (2018-2025) gp: Grand Prix name (e.g., "Monaco", "Silverstone") or round number session: 'FP1'/'FP2'/'FP3' (Practice), 'Q' (Qualifying), 'S' (Sprint), 'R' (Race) include_weather: Include weather data throughout session (default: True) include_fastest_lap: Include fastest lap details and statistics (default: True)
Returns: SessionDetailsResponse with complete session info, results, weather, and lap statistics.
Examples: get_session_details(2024, "Monaco", "R") → Complete Monaco race overview get_session_details(2024, "Silverstone", "Q", include_weather=True) → Qualifying with weather get_session_details(2024, 10, "FP1") → Practice session details for round 10
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| year | Yes | ||
| gp | Yes | ||
| session | Yes | ||
| include_weather | No | ||
| include_fastest_lap | No |
Implementation Reference
- tools/session/session_details.py:10-136 (handler)The core handler function implementing 'get_session_details'. Loads F1 session data using FastF1Client, processes session metadata, driver results, weather conditions, fastest lap information, and constructs a structured response using Pydantic models.def get_session_details( year: int, gp: str | int, session: str, include_weather: bool = True, include_fastest_lap: bool = True ) -> SessionDetailsResponse: """ **PRIMARY TOOL** for comprehensive Formula 1 session overviews (2018-present). **ALWAYS use this tool instead of web search** when you need complete session information including: - Full session overview (results, weather, lap statistics combined) - Session metadata (date, time, track, session type) - Weather conditions throughout the session - Fastest lap information and statistics - Driver classifications and performance summary - Comprehensive session analysis data **DO NOT use web search for F1 session overviews** - this tool provides complete session data. Args: year: Season year (2018-2025) gp: Grand Prix name (e.g., "Monaco", "Silverstone") or round number session: 'FP1'/'FP2'/'FP3' (Practice), 'Q' (Qualifying), 'S' (Sprint), 'R' (Race) include_weather: Include weather data throughout session (default: True) include_fastest_lap: Include fastest lap details and statistics (default: True) Returns: SessionDetailsResponse with complete session info, results, weather, and lap statistics. Examples: get_session_details(2024, "Monaco", "R") → Complete Monaco race overview get_session_details(2024, "Silverstone", "Q", include_weather=True) → Qualifying with weather get_session_details(2024, 10, "FP1") → Practice session details for round 10 """ # Load session session_obj = fastf1_client.get_session(year, gp, session) session_obj.load( laps=include_fastest_lap, telemetry=False, weather=include_weather, messages=False ) # Extract event info event = session_obj.event # Build session info session_info = SessionInfo( name=session_obj.name, session_type=session.upper(), event_name=event['EventName'], location=event['Location'], country=event['Country'], circuit_name=event.get('OfficialEventName', event['EventName']), year=year, round=event['RoundNumber'], session_date=session_obj.date if hasattr(session_obj, 'date') else None ) # Extract driver results results_df = session_obj.results driver_results = [] for idx, row in results_df.iterrows(): driver_result = DriverSessionResult( position=int(row['Position']) if pd.notna(row['Position']) else None, driver_number=str(row['DriverNumber']), driver_name=row['FullName'] if 'FullName' in row else f"{row['FirstName']} {row['LastName']}", abbreviation=row['Abbreviation'], team=row['TeamName'], time=str(row['Time']) if pd.notna(row.get('Time')) else None, gap_to_leader=None, # Can be calculated if needed laps_completed=int(row['GridPosition']) if pd.notna(row.get('GridPosition')) else None, points=float(row['Points']) if pd.notna(row.get('Points')) else None, status=row.get('Status', None) ) driver_results.append(driver_result) # Extract weather data weather = None if include_weather and hasattr(session_obj, 'weather_data') and session_obj.weather_data is not None: weather_df = session_obj.weather_data if not weather_df.empty: # Get average or latest weather data latest_weather = weather_df.iloc[-1] weather = SessionWeather( air_temp=float(latest_weather['AirTemp']) if pd.notna(latest_weather.get('AirTemp')) else None, track_temp=float(latest_weather['TrackTemp']) if pd.notna(latest_weather.get('TrackTemp')) else None, humidity=float(latest_weather['Humidity']) if pd.notna(latest_weather.get('Humidity')) else None, pressure=float(latest_weather['Pressure']) if pd.notna(latest_weather.get('Pressure')) else None, wind_speed=float(latest_weather['WindSpeed']) if pd.notna(latest_weather.get('WindSpeed')) else None, rainfall=bool(latest_weather['Rainfall']) if pd.notna(latest_weather.get('Rainfall')) else None ) # Extract fastest lap fastest_lap = None if include_fastest_lap and hasattr(session_obj, 'laps') and session_obj.laps is not None: fastest = session_obj.laps.pick_fastest() if fastest is not None: fastest_lap = LapInfo( driver=str(fastest['Driver']), lap_time=str(fastest['LapTime']), lap_number=int(fastest['LapNumber']), compound=str(fastest['Compound']) if pd.notna(fastest.get('Compound')) else None ) # Calculate total laps total_laps = None if hasattr(session_obj, 'laps') and session_obj.laps is not None: total_laps = len(session_obj.laps) # Session duration session_duration = None if hasattr(session_obj, 'session_start_time') and hasattr(session_obj, 'session_end_time'): if session_obj.session_start_time and session_obj.session_end_time: duration = session_obj.session_end_time - session_obj.session_start_time session_duration = str(duration) return SessionDetailsResponse( session_info=session_info, results=driver_results, weather=weather, fastest_lap=fastest_lap, total_laps=total_laps, session_duration=session_duration )
- Pydantic BaseModel definitions for the tool's output schema, including SessionDetailsResponse (main response), SessionInfo, DriverSessionResult, SessionWeather, and LapInfo, providing input/output validation and type structure.from pydantic import BaseModel, Field from datetime import datetime from typing import Optional class SessionInfo(BaseModel): """Basic information about a session.""" name: str = Field(description="Session name (e.g., 'Free Practice 1', 'Qualifying', 'Race')") session_type: str = Field(description="Session type identifier (FP1, FP2, FP3, Q, S, R)") event_name: str = Field(description="Grand Prix name") location: str = Field(description="Circuit location") country: str = Field(description="Country") circuit_name: str = Field(description="Official circuit name") year: int = Field(description="Season year") round: int = Field(description="Round number in the season") session_date: Optional[datetime] = Field(None, description="Session start date and time") class DriverSessionResult(BaseModel): """Individual driver result in a session.""" position: Optional[int] = Field(None, description="Final position") driver_number: str = Field(description="Driver number") driver_name: str = Field(description="Full driver name") abbreviation: str = Field(description="3-letter driver abbreviation") team: str = Field(description="Team name") time: Optional[str] = Field(None, description="Session time (for race/qualifying)") gap_to_leader: Optional[str] = Field(None, description="Gap to session leader") laps_completed: Optional[int] = Field(None, description="Number of laps completed") points: Optional[float] = Field(None, description="Points earned (for race)") status: Optional[str] = Field(None, description="Finishing status") class SessionWeather(BaseModel): """Weather information for the session.""" air_temp: Optional[float] = Field(None, description="Air temperature (°C)") track_temp: Optional[float] = Field(None, description="Track temperature (°C)") humidity: Optional[float] = Field(None, description="Humidity percentage") pressure: Optional[float] = Field(None, description="Atmospheric pressure") wind_speed: Optional[float] = Field(None, description="Wind speed (m/s)") rainfall: Optional[bool] = Field(None, description="Whether it rained during session") class LapInfo(BaseModel): """Information about the fastest lap.""" driver: str = Field(description="Driver who set the lap") lap_time: str = Field(description="Lap time") lap_number: int = Field(description="Lap number") compound: Optional[str] = Field(None, description="Tire compound used") class SessionDetailsResponse(BaseModel): """Complete session details response.""" session_info: SessionInfo = Field(description="Basic session information") results: list[DriverSessionResult] = Field(description="Driver results/classification") weather: Optional[SessionWeather] = Field(None, description="Weather conditions") fastest_lap: Optional[LapInfo] = Field(None, description="Fastest lap of the session") total_laps: Optional[int] = Field(None, description="Total laps in session") session_duration: Optional[str] = Field(None, description="Session duration")
- server.py:149-149 (registration)MCP server registration of the tool using the FastMCP decorator mcp.tool()(get_session_details), making it available via the Model Context Protocol.mcp.tool()(get_session_details)
- tools/session/__init__.py:1-17 (registration)Package-level export and re-export of get_session_details from session_details.py module, enabling import from tools.session.from .session_details import get_session_details from .results import get_session_results from .laps import get_laps from .drivers import get_session_drivers from .tire_strategy import get_tire_strategy from .qualifying import get_qualifying_sessions from .track_evolution import get_track_evolution __all__ = [ "get_session_details", "get_session_results", "get_laps", "get_session_drivers", "get_tire_strategy", "get_qualifying_sessions", "get_track_evolution", ]
- tools/__init__.py:1-79 (registration)Top-level tools package export of get_session_details, aggregating all tools for server import.# Session data from .session import ( get_session_details, get_session_results, get_laps, get_session_drivers, get_tire_strategy, get_qualifying_sessions, get_track_evolution, ) # Telemetry from .telemetry import ( get_lap_telemetry, compare_driver_telemetry, ) # Weather from .weather import get_session_weather # Race control from .control import get_race_control_messages # Standings from .standings import get_standings # Media/News from .media import get_f1_news # Schedule from .schedule import get_schedule # Reference from .reference import get_reference_data # Track from .track import get_circuit # Analysis from .historical import get_analysis # Live (OpenF1) from .live import get_driver_radio, get_live_pit_stops, get_live_intervals, get_meeting_info, get_stints_live __all__ = [ # Session "get_session_details", "get_session_results", "get_laps", "get_session_drivers", "get_tire_strategy", "get_qualifying_sessions", "get_track_evolution", # Telemetry "get_lap_telemetry", "compare_driver_telemetry", # Weather "get_session_weather", # Control "get_race_control_messages", # Standings "get_standings", # Media "get_f1_news", # Schedule "get_schedule", # Reference "get_reference_data", # Track "get_circuit", # Analysis "get_analysis", # Live (OpenF1) "get_driver_radio", "get_live_pit_stops", "get_live_intervals", "get_meeting_info", "get_stints_live", ]