fastf1-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FASTF1_MCP_LOG_LEVEL | No | Python logging level | INFO |
| FASTF1_MCP_FASTF1_CACHE_PATH | No | Disk cache for FastF1 session files | ~/.fastf1_cache |
| FASTF1_MCP_MAX_CACHED_SESSIONS | No | Max sessions held in memory (LRU) | 10 |
| FASTF1_MCP_MAX_TELEMETRY_SAMPLES | No | Hard cap on telemetry sample points | 500 |
| FASTF1_MCP_DEFAULT_TELEMETRY_SAMPLES | No | Default telemetry sample points | 200 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_scheduleA | Get the F1 race calendar for a season. Data source: Ergast API (via FastF1) Coverage: 1950-present Args: year: Season year (1950-present) Returns: List of events with: round, raceName, circuitName, country, date, time (if available) Example: get_schedule(2024) → [ {"round": 1, "raceName": "Bahrain Grand Prix", ...}, ... ] |
| get_driver_standingsA | Get driver championship standings. Data source: Ergast API (via FastF1) Coverage: 1950-present Args: year: Season year after_round: Standings after specific round (default: latest) Returns: Ordered list of drivers with: position, driver code, full name, team, points, wins Example: get_driver_standings(2024) → [ {"position": 1, "code": "VER", "name": "Max Verstappen", "team": "Red Bull", "points": 575, "wins": 19}, ... ] |
| get_constructor_standingsA | Get constructor championship standings. Data source: Ergast API (via FastF1) Coverage: 1958-present (constructor championship started 1958) Args: year: Season year after_round: Standings after specific round (default: latest) Returns: Ordered list of constructors with: position, name, nationality, points, wins |
| get_driver_infoA | Get driver information. Data source: Ergast API (via FastF1) Coverage: 1950-present Args: driver_id: Ergast driver ID (e.g., "max_verstappen", "hamilton") If None, returns all drivers year: Filter to drivers who raced in this season Returns: Driver info: driverId, code, givenName, familyName, dateOfBirth, nationality, permanentNumber Note: Use get_session_results to find driver codes, then use this for biographical details. |
| get_race_results_historicalA | Get historical race results (pre-2018 or when session data unavailable). Data source: Ergast API (via FastF1) Coverage: 1950-present Args: year: Season year round_num: Round number Returns: Results with: position, driver, constructor, grid, laps, status, time (if finished), fastestLapTime, fastestLapRank Note: For 2018+ races, prefer get_session_results which has more detail. |
| get_circuit_infoA | Get circuit information. Data source: Ergast API (via FastF1) Args: circuit_id: Ergast circuit ID (e.g., "monaco", "silverstone") If None, returns all circuits year: Filter to circuits used in this season Returns: Circuit info: circuitId, circuitName, locality, country, lat, long |
| get_session_resultsA | Get session classification/results. Data source: FastF1 Live Timing Coverage: 2018-present Args: year: Season year (2018+) event: Race name (e.g., "Monaco") or round number session: Session type — R, Q, S, SQ, FP1, FP2, FP3 Returns: Ordered classification with: position, driverCode, fullName, teamName, gridPosition, time/status, points Example: get_session_results(2024, "Monaco", "R") → [ {"position": 1, "driverCode": "LEC", "fullName": "Charles Leclerc", "teamName": "Ferrari", "time": "1:45:12.345", ...}, ... ] Note: Requires year >= 2018. For historical results use get_race_results_historical. |
| get_lap_timesA | Get all lap times for a driver in a session. Data source: FastF1 Live Timing Coverage: 2018-present Set Args:
year: Season year (2018+)
event: Race name or round number
session: Session type (R, Q, S, FP1, FP2, FP3)
driver: Driver code (e.g., "VER") or number (e.g., "1")
include_deleted: Include deleted lap times (default False)
export_path: If True, write the full per-lap array to a CSV in the
configured export directory (default Returns: Default (no export): { "driver": "VER", "fullName": "Max Verstappen", "teamName": "Red Bull Racing", "summary": {...}, "laps": [{"lapNumber": 1, "lapTime": "0:01:30.456", ...}, ...] } Note:
Deleted laps (e.g., track limits violations) are excluded by default.
Set include_deleted=True to include them.
|
| get_fastest_lapsA | Get fastest laps in a session, one per driver. Data source: FastF1 Live Timing Coverage: 2018-present Args: year: Season year (2018+) event: Race name or round number session: Session type (default "R") top_n: Number of fastest laps to return (default 10) Returns: Fastest laps sorted by time: lapNumber, lapTime, sector1, sector2, sector3, compound Example: get_fastest_laps(2024, "Monaco", "R", 5) → [ {"lapNumber": 67, "lapTime": "0:01:15.456", "compound": "SOFT", ...}, ... ] Note: Returns one fastest lap per driver. Only accurate laps are included. |
| get_race_paceA | Calculate average race pace for all drivers. Data source: FastF1 Live Timing Coverage: 2018-present Args: year: Season year (2018+) event: Race name or round number exclude_first_laps: Number of opening laps to exclude (default 2) exclude_sc_laps: Exclude laps behind safety car or VSC (default True) exclude_pit_laps: Exclude in-laps and out-laps (default True) min_laps: Minimum valid laps required to include a driver (default 10) Returns: { "filters": { "excludeFirstLaps": 2, "excludeSafetyCarLaps": true, "excludePitLaps": true, "minLaps": 10 }, "drivers": [ {"driver": "LEC", "fullName": "Charles Leclerc", "teamName": "Ferrari", "avgLapTime": "0:01:15.678", "lapCount": 52, "deltaToFastestSec": 0.0, ...}, ... ] } Note:
SC/VSC filter uses track status "1" (green flag only).
Drivers with fewer than min_laps valid laps are excluded.
The |
| get_stint_analysisA | Analyze tire stints for a race. Data source: FastF1 Live Timing Coverage: 2018-present Set Args:
year: Season year (2018+)
event: Race name or round number
driver: Optional driver code to filter (default: all drivers)
export_path: If True, write the full per-stint array to a CSV in
the configured export directory (default
Returns: Default (no export): { "summary": {...}, "stints": [{"driver": "LEC", "stintNumber": 1, ...}, ...] } Note:
Only accurate laps are included in pace calculations.
Stint numbers match FastF1's internal stint counter.
Phantom lap-1 stints (single-lap entries with no recorded lap time,
paired with the lap-1 pit-stop artifact) are filtered out.
The |
| get_pit_stopsA | Get all pit stops from a race. Data source: FastF1 Live Timing Coverage: 2018-present Args: year: Season year (2018+) event: Race name or round number Returns: Pit stops sorted by lap: driver (code), fullName, teamName, lap, stopNumber, duration, tyreFrom, tyreTo Example: get_pit_stops(2024, "Monaco") → [ {"driver": "LEC", "fullName": "Charles Leclerc", "teamName": "Ferrari", "lap": 28, "stopNumber": 1, "duration": 23.4, "tyreFrom": "MEDIUM", "tyreTo": "HARD"}, ... ] Note: Duration is calculated from PitInTime (end of in-lap) to PitOutTime (start of out-lap), in seconds. Stops with implausibly long durations (>120s) are filtered as FastF1 data artifacts — commonly a phantom lap-1 entry tied to session start, not a real pit stop. |
| get_qualifying_breakdownA | Get qualifying results split by Q1/Q2/Q3. Data source: FastF1 Live Timing Coverage: 2018-present Args: year: Season year (2018+) event: Race name or round number Returns: { "Q1": [{"driver": "VER", "bestTime": "1:10.123", "lapNumber": 3}, ...], "Q2": [...], "Q3": [...], "eliminated_Q1": ["driver1", "driver2", ...], "eliminated_Q2": ["driver3", "driver4", ...] } Example: get_qualifying_breakdown(2024, "Monaco") → { "Q1": [...20 drivers sorted by best time...], "Q2": [...15 drivers...], "Q3": [...10 drivers...], "eliminated_Q1": ["5 driver codes"], "eliminated_Q2": ["5 driver codes"] } Note: Uses laps.split_qualifying_sessions() to split by session time. Drivers with no recorded lap time in a segment are omitted from that segment's list. |
| list_eventsA | List all events in a season. Data source: Ergast API (via FastF1) Coverage: 1950-present Args: year: Season year (1950-present) Returns: Events with: round, eventName, country, circuitName, date Example: list_events(2024) → [ {"round": 1, "eventName": "Bahrain Grand Prix", "country": "Bahrain", "circuitName": "Bahrain International Circuit", "date": "2024-03-02"}, ... ] Note: Minimal version of get_schedule — useful for discovering valid event names to pass to other tools. |
| list_driversA | List all drivers in a season, optionally filtered to a specific event. Data source: Ergast API (season list) or FastF1 session (event filter) Coverage: 1950-present (season); 2018-present (event filter) Args: year: Season year event: Optional race name or round number to filter by event (returns only drivers who participated in that session) Returns: Drivers with: code, fullName, nationality, team, number Example: list_drivers(2024) → [ {"code": "VER", "fullName": "Max Verstappen", "nationality": "Dutch", "team": "Red Bull Racing", "number": "1"}, ... ] Note: When event is provided, data comes from FastF1 session results (requires year >= 2018). Without event, uses Ergast season data. |
| get_cache_statusA | Check server in-memory session cache status. Returns: { "sessions_cached": 3, "max_sessions": 10, "cached_sessions": [ {"year": 2024, "event": "Monaco", "session": "R", "loaded_at": "2024-05-26T14:00:00"}, ... ], "fastf1_cache_path": "~/.fastf1_cache", "fastf1_cache_size_mb": 1234.5 } Example: get_cache_status() → {"sessions_cached": 2, "max_sessions": 10, ...} Note: Reports in-memory LRU cache only. The FastF1 disk cache (used for raw timing data) is reported separately as size_mb. |
| clear_cacheA | Clear cached sessions from in-memory storage. Args: year: Optional year filter — only clear sessions for this year event: Optional event filter — requires year to be set Returns: {"cleared": 3, "remaining": 2} Example: clear_cache() → {"cleared": 5, "remaining": 0} clear_cache(2024, "Monaco") → {"cleared": 1, "remaining": 4} Note: Clears the in-memory LRU cache only. The FastF1 disk cache (raw timing files) is preserved and unaffected. |
| get_lap_telemetryA | Get telemetry data for a specific lap. Data source: FastF1 Live Timing Coverage: 2018-present Set Args:
year: Season year (2018+)
event: Race name or round number
session: Session type (R, Q, S, FP1, FP2, FP3)
driver: Driver code (e.g., "VER")
lap: Lap number or "fastest" (default)
sample_size: Number of telemetry points to return (default 200, max 500)
export_path: If True, write the sampled Returns: { "driver": "VER", "lapNumber": 42, "lapTime": "0:01:23.456", "summary": { "samplePoints": 200, "maxSpeedKph": 327.5, "minSpeedKph": 80.2, "avgSpeedKph": 218.1, "maxGear": 8, "brakingZones": 7, "fullThrottlePct": 64.5 }, "data": [ {"distance": 0.0, "speed": 280.0, "throttle": 95.0, "brake": false, "gear": 7, "drs": 0}, ... ] } Example: get_lap_telemetry(2024, "Monaco", "Q", "VER") → fastest Q lap telemetry get_lap_telemetry(2024, "Monaco", "R", "VER", lap=45) → lap 45 telemetry Note:
Raw telemetry has 5000+ points per lap. Response is sampled to
sample_size evenly-spaced distance points (capped at 500).
|
| compare_telemetryA | Compare telemetry between two drivers on the same session. Data source: FastF1 Live Timing Coverage: 2018-present Set Args:
year: Season year (2018+)
event: Race name or round number
session: Session type (R, Q, S, FP1, FP2, FP3)
driver1: First driver code (e.g., "VER")
driver2: Second driver code (e.g., "LEC")
lap: Lap number or "fastest" — applied independently to each driver
sample_size: Telemetry points per driver (default 200, max 500)
export_path: If True, write the per-distance Returns: { "driver1": {"code": "VER", "lapNumber": 18, "lapTime": "1:10.123"}, "driver2": {"code": "LEC", "lapNumber": 20, "lapTime": "1:10.456"}, "comparison": [ {"distance": 0.0, "speed1": 280.0, "speed2": 275.0, "speedDelta": 5.0, "timeDelta": 0.0}, ... ], "summary": { "lapTimeDeltaSec": 0.333, "maxSpeedDelta": 8.2, "sectors": { "S1": {"driver1": "0:00:28.123", "driver2": "0:00:28.456", "deltaSec": -0.333}, "S2": {...}, "S3": {...} }, "driver1Telemetry": {"maxSpeedKph": 325.0, "brakingZones": 7, ...}, "driver2Telemetry": {"maxSpeedKph": 320.5, "brakingZones": 8, ...} } } Example: compare_telemetry(2024, "Monaco", "Q", "VER", "LEC") Note: timeDelta is the cumulative time gap at each distance point, computed from speed integration. Positive = driver1 is ahead. Comparison is aligned to driver1's distance axis. |
| get_speed_trap_dataA | Get speed trap and top-speed data for all drivers in a session. Data source: FastF1 Live Timing (session results) Coverage: 2018-present Args: year: Season year (2018+) event: Race name or round number session: Session type (R, Q, S, FP1, FP2, FP3) Returns: { "source": "results" | "laps", "drivers": [ {"driver": "VER", "fullName": "Max Verstappen", "teamName": "Red Bull Racing", "speedTrap": 298.5, "speedFL": 187.2, "speedI1": 245.0, "speedI2": 268.5}, ... ] } Example: get_speed_trap_data(2024, "Monza", "Q") → {"source": "results", ...} Note: SpeedST = official speed trap measurement. SpeedFL = speed at the finish line. SpeedI1/I2 = sector intermediate speed measurements. Values are in km/h. |
| get_sector_timesA | Get best sector times and theoretical best lap for each driver. Data source: FastF1 Live Timing Coverage: 2018-present Set Args:
year: Season year (2018+)
event: Race name or round number
session: Session type (R, Q, S, FP1, FP2, FP3)
driver: Optional driver code to filter (default: all drivers)
include_laps: If True, include a Returns:
For each driver: driver (code), fullName, teamName, bestS1, bestS2,
bestS3, theoreticalBest, actualBest, gapSec. With Example: get_sector_times(2024, "Monaco", "Q") → [ {"driver": "VER", "fullName": "Max Verstappen", "teamName": "Red Bull Racing", "bestS1": "0:00:22.123", "bestS2": "0:00:24.456", "bestS3": "0:00:21.789", "theoreticalBest": "0:01:08.368", "actualBest": "0:01:08.570", "gapSec": -0.202}, ... ] Note: A negative gapSec means the theoretical best (sum of individual sector bests) is faster than the actual best lap — typical, since sector bests usually come from different laps. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| race_recap | Generate a comprehensive race summary. |
| qualifying_analysis | Analyze qualifying session performance. |
| driver_comparison | Compare two drivers across a season. |
| strategy_analysis | Deep dive into race strategy. |
| weekend_preview | Generate a race weekend preview. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| circuits_resource | All circuits that have hosted F1 races. Returns JSON array of circuits with id, name, locality, country, latitude, and longitude. |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Surya96t/fastf1-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server