Skip to main content
Glama
Branuvg

mcp_f1_strategy

by Branuvg

mcp_f1_strategy

A local Model Context Protocol server that gives an LLM-based race engineer chatbot real, calculated Formula 1 pit-stop strategy tools: tire degradation modeling, optimal pit windows, undercut/overcut simulation, and finish-position projection - all computed deterministically from real session data, not guessed by the language model.

Built for Project 1 ("Uso de un protocolo existente") of CC3067 Redes at Universidad del Valle de Guatemala. It's a standard local (stdio) MCP server, so it works with any MCP-compatible host - Claude Desktop, a custom console chatbot, or any other client that speaks the protocol - not just one specific host application.

Protocol implementation: this server speaks JSON-RPC 2.0 directly over stdio (src/jsonrpc_mcp.py) — newline-delimited JSON messages implementing initialize, notifications/initialized, tools/list, and tools/call by hand. It does not depend on the official mcp Python SDK (or any other MCP SDK); the only dependencies are fastf1 and numpy.

Overview

Ask an LLM directly "should I pit now?" and it will guess, based on vague pattern-matching from its training data. This server instead:

  1. Pulls real lap-by-lap timing data for a given circuit/season/session from FastF1.

  2. Fits a parametric tire degradation curve (lap_time = base_pace + degradation_rate * tire_age^k) per compound and circuit, by regression on real stint data.

  3. Runs a deterministic strategy simulation on top of that curve to answer: what's the optimal pit window, does an undercut or overcut work against a specific rival, how do N hypothetical strategies compare, and where does a planned strategy project to finish.

The LLM's job is to call the right tool with the right arguments and explain the result to the strategy engineer - not to invent the numbers.

Scope note: this is not live timing

FastF1 only exposes completed sessions with official data - there is no real-time F1 live-timing feed here. "Live race" is simulated by replaying a real, past session lap by lap: the current_lap / lap parameter plays the role of "where the race currently is." This is an explicit, accepted limitation (see Out of scope), not a bug - it's called out here so the scope is unambiguous.

Related MCP server: mcp-f1analisys

Tools (9)

All tools take a FastF1-style circuit name (e.g. "Monza", "Silverstone", "Bahrain" - FastF1 does fuzzy matching on event names, so close spellings usually resolve, but a genuinely wrong circuit will eventually fail to find any session), a season (year), and a session code ("FP1", "FP2", "FP3", "Q", "R") where applicable - common natural-language names are also accepted and normalized ("Race" -> "R", "Qualifying"/"Quali" -> "Q", "Practice 1" -> "FP1", case-insensitive), since an LLM caller is more likely to guess those than the short code. Tire compound similarly accepts single-letter TV-graphic codes and plurals ("S"/"Softs" -> "SOFT", "M" -> "MEDIUM", etc.). Drivers can be given as FastF1's 3-letter code ("LEC"), a car number ("16"), a last or full name ("Leclerc", "Charles Leclerc"), or a close misspelling of one — resolved against that session's actual entry list, with a clear error listing the session's real drivers if nothing matches.

Tool

Purpose

get_race_state

Positions, gaps, compound and tire age for every driver at a given lap.

get_tire_degradation_curve

Calibrated degradation model (base pace + rate) for a compound at a circuit.

get_pit_loss_time

Time lost by pitting at a circuit, from real data when available.

get_pit_window

Optimal pit-stop window for a driver, plus a traffic-risk read for the pit exit.

simulate_undercut_overcut

Compares pitting before (undercut) vs. after (overcut) a named rival.

compare_strategy_options

Projects total time for N arbitrary hypothetical strategies.

get_historical_strategies

Real stint breakdown and finish position from past races at a circuit.

predict_finish_position

Projects finishing position/time for a planned strategy for the rest of the race.

generate_strategy_report

Formats a Markdown report from a host/LLM-curated decision log (no summarization).

Full input/output JSON shapes for every tool are below.

Tool reference

get_race_state

Raw state of the session at a given lap: positions, gaps, compound and tire age for every driver.

input:  { circuit: str, season: int, session: "R"|"Q"|"FP1"|"FP2"|"FP3", lap: int }
output: {
  lap: int,
  drivers: [
    { driver: str, position: int, gap_to_leader_s: float, gap_to_ahead_s: float,
      compound: str, tire_age_laps: int }
  ]
}

get_tire_degradation_curve

Calibrated degradation model parameters for a compound + circuit.

input:  { compound: "SOFT"|"MEDIUM"|"HARD"|"INTERMEDIATE"|"WET", circuit: str, season?: int }
output: {
  compound: str, circuit: str,
  base_pace_s: float,
  degradation_rate_s_per_lap: float,
  model_type: "linear"|"quadratic",
  r_squared: float,
  sample_size_laps: int,
  data_source: "fastf1_real" | "insufficient_data_fallback",
  warning?: str
}

get_pit_loss_time

input:  { circuit: str, season?: int }
output: { circuit: str, pit_loss_time_s: float, source: "fastf1_real"|"generic_fallback", warning?: str }

get_pit_window

Optimal pit-stop window for a driver, with traffic risk at the pit exit.

input:  { driver: str, circuit: str, season: int, session: str, current_lap: int }
output: {
  driver: str, current_lap: int,
  optimal_window: { start_lap: int, end_lap: int },
  reasoning: str,
  traffic_risk: "low"|"medium"|"high",
  traffic_risk_reason: str,
  warning?: str
}

simulate_undercut_overcut

Compares pitting before (undercut) or after (overcut) a named rival.

input:  { own_driver: str, rival_driver: str, circuit: str, season: int, session: str, current_lap: int }
output: {
  undercut: { pit_lap: int, projected_time_delta_s: float, net_position_gain: bool },
  overcut:  { pit_lap: int, projected_time_delta_s: float, net_position_gain: bool },
  recommendation: "undercut"|"overcut"|"stay_out"|"no_clear_advantage",
  reasoning: str
}

compare_strategy_options

Generalizes undercut/overcut: compares N hypothetical strategies (pit laps + compounds) for one driver.

input:  {
  driver: str, circuit: str, season: int, session: str, current_lap: int,
  strategies: [ { label: str, pit_laps: [int], compounds: [str] } ]
}
output: {
  results: [ { label: str, projected_total_time_s: float } ],
  best_strategy: str
}

get_historical_strategies

input:  { circuit: str, seasons?: [int], drivers?: [str] }
output: {
  circuit: str,
  races: [
    { season: int, driver: str,
      stints: [ { compound: str, start_lap: int, end_lap: int } ],
      finish_position: int }
  ]
}

predict_finish_position

Projects finishing position/time for a planned strategy for the rest of the race.

input:  { driver: str, circuit: str, season: int, session: str, current_lap: int,
          planned_strategy: { pit_laps: [int], compounds: [str] } }
output: {
  driver: str,
  projected_finish_position: int,
  projected_total_time_s: float,
  confidence: "low"|"medium"|"high",
  key_assumptions: [str]
}

key_assumptions always declares the model's limitations explicitly (e.g. "assumes constant rival pace", "does not consider safety car/VSC", "does not consider changing weather").

generate_strategy_report

Formats a Markdown report from an already-curated decision log. Does not summarize or interpret - that's the LLM/host's job during the conversation; this tool only formats deterministically.

input:  {
  race_context: { circuit: str, season: int },
  decisions: [ { lap: int, tool_used: str, summary: str } ]
}
output: { markdown_report: str, filename_suggestion: str }

Error vs. warning policy

Every tool follows the same rule:

  • Explicit tool error (isError: true, clear message) when the base data genuinely doesn't exist - the driver never took part in the session, the circuit/season/session combination has no data in FastF1, or a requested lap is out of range. The LLM is expected to relay this to the user, not paper over it.

  • Successful result with a warning field when the data exists but the model's confidence is low (e.g. a compound was barely used at that circuit, so the degradation fit has a low r_squared and small sample_size_laps). The raw confidence indicators (r_squared, sample_size_laps, data_source) are always included so the LLM - and the engineer - can judge for themselves.

Methodology & known limitations

  • Degradation curves are fit per compound + circuit, pooling laps across every driver who used that compound in the queried event (race + practice sessions) and, if needed, the same circuit in up to two prior seasons. This is what the spec asks for, but it means the fit mixes different cars/drivers/fuel loads together - real F1 lap times are dominated by fuel burn-off, traffic and driver pace, not just tire wear, so r_squared for a single event is often genuinely low (this has been observed directly against real data, e.g. 2023 Monza MEDIUM: r_squared ≈ 0.04). That's not a bug: it's why the warning/r_squared/sample_size_laps transparency fields exist, instead of a single opaque number.

  • Pit loss time is the median of real in-lap+out-lap time lost (relative to that driver's own green-flag pace) across every stop in the queried race; it falls back to a generic ~22.5s estimate below 3 real samples.

  • Undercut/overcut and pit-window simulation use a fixed short evaluation horizon (6 laps) and assume the tire fitted after any hypothetical stop is FastF1's compound-agnostic "alternative" pick (the harder of the two compounds not currently mounted, unless already on HARD, in which case MEDIUM).

  • predict_finish_position assumes every rival holds their last 3 laps' average pace for the rest of the race with no further pit stops, and that a faster projected time converts directly into position - it does not model overtaking difficulty. These are declared explicitly in the tool's own key_assumptions output field, per spec.

Prerequisites

  • Python 3.10+ (developed and tested on 3.14)

  • uv for dependency/environment management

  • Internet access on first query per circuit/season/session (FastF1 downloads and caches official timing data under ./cache/; repeat queries to the same session are served from that local cache with no network call)

Installation

git clone <your-repo-url>
cd mcp_f1_strategy
uv sync

uv sync installs fastf1, numpy, and the test dependencies declared in pyproject.toml. No MCP SDK is installed — the protocol layer (src/jsonrpc_mcp.py) is hand-written JSON-RPC 2.0.

Running standalone

The server speaks MCP over stdio - it isn't meant to be run interactively by itself, but you can smoke-test it directly:

uv run python src/server.py

It will sit there waiting for JSON-RPC messages on stdin (that's expected - this is how an MCP host talks to it). Press Ctrl+C to stop it.

Adding this server to an MCP host

This server uses the stdio transport, so any MCP host that can launch a local subprocess and speak MCP over its stdin/stdout can use it. Almost every MCP host (Claude Desktop, Cursor, and most custom chatbot hosts, including student-built ones for this course) reads its server list from a JSON config shaped like this - often called mcpServers:

{
  "mcpServers": {
    "f1_strategy": {
      "command": "uv",
      "args": [
        "run",
        "--project", "/absolute/path/to/mcp_f1_strategy",
        "python", "/absolute/path/to/mcp_f1_strategy/src/server.py"
      ]
    }
  }
}

Replace /absolute/path/to/mcp_f1_strategy with wherever you cloned this repository (e.g. C:\Users\you\projects\mcp_f1_strategy on Windows, /home/you/projects/mcp_f1_strategy on Linux/macOS). Using an absolute path means the entry works regardless of the host's own working directory. uv handles creating the virtual environment and installing dependencies on first launch - no manual uv sync step is required by the host, though running it once yourself (see Installation) is a good sanity check.

Running without uv

uv isn't part of the MCP protocol - it's just the tool this project uses to manage its virtual environment. A host that doesn't have uv installed can still run this server with a plain Python venv:

# Windows PowerShell
cd mcp_f1_strategy
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install fastf1 numpy

# Linux / macOS
cd mcp_f1_strategy
python3 -m venv .venv
source .venv/bin/activate
pip install fastf1 numpy

([tool.uv] package = false in pyproject.toml means this project is never installed as a package itself - only its two dependencies need to be present, listed above (the MCP protocol layer is hand-written, not a dependency); uv sync installs the exact same two packages under the hood.)

Then point the host's mcpServers entry directly at that venv's Python interpreter instead of at uv:

{
  "mcpServers": {
    "f1_strategy": {
      "command": "/absolute/path/to/mcp_f1_strategy/.venv/Scripts/python.exe",
      "args": ["/absolute/path/to/mcp_f1_strategy/src/server.py"]
    }
  }
}

(use .venv/bin/python instead of .venv\Scripts\python.exe on Linux/macOS). No uv involvement at all from here on - the host just launches that interpreter directly, the same way it would launch any other local executable.

For Claude Desktop specifically, this same JSON block goes under mcpServers in its config file (claude_desktop_config.json - on Windows, %APPDATA%\Claude\claude_desktop_config.json; on macOS, ~/Library/Application Support/Claude/claude_desktop_config.json), then restart Claude Desktop.

Once connected, the host discovers all 9 tools via MCP's list_tools - no code changes to the host are needed.

Example scenario

With this server wired into your host of choice:

You: I'm racing at Monza 2023, currently on lap 20 as LEC on 20-lap-old MEDIUM tires.
     What's my pit window, and would an undercut on VER make sense right now?

The LLM will call get_pit_window and simulate_undercut_overcut (chaining get_race_state / get_tire_degradation_curve / get_pit_loss_time as needed for context), then explain the recommendation

  • including surfacing any low-confidence warning honestly rather than hiding it.

Running tests

uv run pytest

Tests cover the pure-math layer (models/degradation.py, models/pit_loss.py, models/strategy_sim.py, reports/report_builder.py) against synthetic, hand-checkable inputs - this layer has no FastF1/MCP dependency by design, so it needs no network access or fixtures to test. The data (data/) and protocol (tools/) layers were validated manually against real FastF1 sessions (see the spec's methodology section above for what was observed).

Project structure

mcp_f1_strategy/
├── src/
│   ├── server.py              # MCP entrypoint: registers the 9 tools, stdio transport
│   ├── jsonrpc_mcp.py         # hand-rolled JSON-RPC 2.0 / MCP protocol layer (no SDK)
│   ├── data/
│   │   └── fastf1_client.py   # the only module that imports fastf1/pandas
│   ├── models/
│   │   ├── degradation.py     # tire degradation curve fitting (pure math)
│   │   ├── pit_loss.py        # pit loss time estimation (pure math)
│   │   └── strategy_sim.py    # pit window / undercut-overcut / strategy simulation engine
│   ├── tools/
│   │   └── f1_tools.py        # the 9 MCP tool definitions; only layer that knows MCP
│   └── reports/
│       └── report_builder.py  # generate_strategy_report Markdown formatting
├── cache/                      # FastF1 local cache (gitignored)
├── tests/                      # pytest unit tests for models/ and reports/
├── pyproject.toml
└── README.md

Out of scope

  • No real live timing - FastF1 exposes completed sessions only (see Scope note).

  • No custom database for historicals - get_historical_strategies reads directly through FastF1's own cache.

  • No special fallback for network/FastF1 failures - any MCP host using this server already requires internet for its own LLM API calls, so this doesn't add a new failure mode.

  • predict_finish_position does not model safety cars, VSC, weather changes, or non-deterministic rival behavior - declared explicitly in its key_assumptions output.

  • No HTTP/SSE transport - this server is local/stdio only; a remote MCP server is a separate deliverable of this project.

Available Tools

9 tools
compare_strategy_optionsA

Projects total remaining-race time for N hypothetical strategies (each: a label, a list of pit laps, and a list of compounds — one more compound than pit laps) for the same driver.

ParametersJSON Schema
NameRequiredDescriptionDefault
driverYes
seasonYes
circuitYes
sessionYes
strategiesYes
current_lapYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden. It discloses that this is a projection/calculation rather than a mutating action, restricts the comparison to a single driver, and surfaces the key invariant that each strategy must have exactly one more compound than pit laps. It does not discuss modeling assumptions, but the core behavior is transparent enough.

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 dense sentence that front-loads the core result and then adds only the necessary strategy-shape detail. There is no filler, repetition, or irrelevant background.

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

Completeness3/5

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

The description is adequate for a projection tool, and an output schema exists to cover return values. However, with six required parameters and no annotations, it leaves notable gaps around the meaning of 'session', the exact property names for each strategy object, and explicit guidance on when this tool is the right choice versus its siblings.

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 0%, so the description must compensate. It does clarify the complex 'strategies' parameter by specifying label, pit laps, and compounds with a count relationship. Other parameters like driver, circuit, season, session, and current_lap are only implied by the remaining-race-time context and their names, leaving some ambiguity, especially for 'session' and the exact expected keys inside each strategy object.

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 names a specific action ('Projects total remaining-race time') and resource ('N hypothetical strategies') for one driver, with enough structural detail to distinguish it from siblings like simulate_undercut_overcut or generate_strategy_report. It is not a tautology and clearly states what the tool computes.

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

Usage Guidelines3/5

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

Usage context is implied: use this when you need to compare multiple hypothetical pit/compound strategies and see projected remaining-race time. However, it does not explicitly state when to choose this over sibling tools, nor does it provide exclusions or alternative routing guidance.

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

generate_strategy_reportA

Formats a Markdown strategy report from an LLM/host-curated list of decisions. Purely deterministic formatting — no summarization here.

ParametersJSON Schema
NameRequiredDescriptionDefault
decisionsYes
race_contextYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations, the description carries the behavioral burden. It discloses a key trait: the tool is purely deterministic and performs no summarization. This is the core behavioral information an agent needs to avoid treating this as a generative or analytical tool.

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?

Two concise sentences with no filler. The core purpose is front-loaded, and the clarifying determinism caveat is placed immediately after.

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?

An output schema exists, so return values are less critical, but the description omits the meaning of 'race_context' and expected decision-object structure. For a two-parameter tool with zero schema coverage and no annotations, this is too incomplete for reliable invocation.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate. It only characterizes 'decisions' as an LLM/host-curated list and says nothing about 'race_context', the shape of decision items, or required fields. An agent cannot correctly construct inputs from this alone.

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 states a specific verb and resource: 'Formats a Markdown strategy report' from a curated decisions list. It also clarifies the scope ('LLM/host-curated list of decisions') and separates this formatting tool from the analysis/simulation siblings.

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

Usage Guidelines4/5

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

The description gives clear context: use this when a report needs to be produced from an already-curated decisions list. 'Purely deterministic formatting — no summarization here' provides a boundary, but it does not explicitly name alternatives or when-not-to-use conditions, so it is not a 5.

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

get_historical_strategiesA

Real stint breakdown (compound, start/end lap) and finish position from past race sessions at this circuit.

ParametersJSON Schema
NameRequiredDescriptionDefault
circuitYes
driversNo
seasonsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral disclosure burden. It communicates that the data is historical, real, and circuit-scoped, but it does not clarify default behavior for optional drivers or seasons filters, nor any other operational constraints.

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, front-loaded sentence with no filler. Every part contributes useful information about what the tool returns and its scope.

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

Completeness3/5

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

The output schema covers return shape, so that is not a gap. However, with no annotations and minimal usage or parameter-filter guidance, the description is only adequate for safe selection and invocation, not fully self-sufficient.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate. It only maps the 'circuit' parameter via 'at this circuit'; 'drivers' and 'seasons' are left undocumented in both the schema and the description, even though their names suggest filtering behavior.

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 names a specific resource: real stint breakdown including compound and start/end lap, plus finish position, scoped to past race sessions at a circuit. It clearly separates this from sibling simulation/prediction tools by emphasizing 'real' and 'past' data.

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

Usage Guidelines3/5

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

The phrase 'past race sessions at this circuit' implies the tool is for historical data, but it does not explicitly say when to prefer it over siblings such as simulate_undercut_overcut or predict_finish_position. No exclusions or alternative-routing guidance is provided.

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

get_pit_loss_timeA

Time lost by pitting at this circuit (in-lap + pit lane + out-lap, minus a green-flag lap), from real FastF1 data when available.

ParametersJSON Schema
NameRequiredDescriptionDefault
seasonNo
circuitYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

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

Even though no annotations are provided, the description usefully discloses the calculation method, the data source ('real FastF1 data'), and a limitation ('when available'). It does not detail fallback behavior when data is unavailable, but for a read-only getter the core behavioral traits are well covered.

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?

A single, tightly written sentence with the formula in parentheses is efficient and easy to parse. No filler or redundant restatement of the tool name.

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

Completeness3/5

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

The description defines the output concept well and the output schema exists, so return formatting need not be explained. However, with no annotations and no usage guidance, the description leaves room for ambiguity about what happens when FastF1 data is unavailable and how season affects the result.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate for parameter meaning. It explains the meaning of the result with respect to the circuit, but it does not clarify the 'season' parameter, valid circuit values, or defaults beyond what the schema already shows.

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 names the exact metric ('time lost by pitting at this circuit') and defines it explicitly with a formula. This clearly distinguishes it from sibling tools like get_pit_window or simulate_undercut_overcut.

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?

The description gives no guidance on when to use this tool versus the many strategy-related siblings. It implies a use case through its purpose but does not state any context, prerequisites, or alternative tools.

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

get_pit_windowB

Optimal pit window for driver, weighing tire degradation against pit loss time, plus a traffic-risk read on the car right behind.

ParametersJSON Schema
NameRequiredDescriptionDefault
driverYes
seasonYes
circuitYes
sessionYes
current_lapYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3/5.0
Behavior3/5

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

With no annotations provided, the description must carry the behavioral disclosure burden. It does reveal the core methodology—weighing tire degradation against pit loss time and considering traffic risk—but does not describe assumptions, limitations, or how the output should be interpreted.

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, front-loaded sentence that efficiently conveys the tool's core purpose and distinguishing factors without filler. Every phrase contributes substantive meaning.

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?

For a tool with five required parameters, no annotations, and no parameter documentation, the description is too sparse. It does not explain how to choose among sibling strategy tools, what qualifies as 'optimal', or what values are expected for fields like session and circuit, even though an output schema exists.

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

Parameters2/5

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

Schema description coverage is 0%, so the description needs to compensate for the five undocumented parameters. It only adds context for 'driver' and the general concept; circuit, season, session, and current_lap are left entirely to their names and types, which is insufficient for correct invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool computes an optimal pit window for a driver by weighing tire degradation against pit loss time and adding a traffic-risk assessment. It identifies a specific resource and unique calculation logic, though it does not explicitly name or contrast sibling tools.

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?

The description provides no guidance on when to use this tool versus alternatives like simulate_undercut_overcut, compare_strategy_options, or generate_strategy_report. The intended use is only implied by the tool's purpose, with no exclusions or decision rules.

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

get_race_stateC

Raw session snapshot at a given lap: position, gap to leader/car ahead, tire compound and tire age for every driver still classified.

ParametersJSON Schema
NameRequiredDescriptionDefault
lapYes
seasonYes
circuitYes
sessionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

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

With no annotations, the description must carry the burden of disclosing side effects. It implies a read-only operation but never explicitly states that it does not modify data or that it is safe to call repeatedly. No mention of rate limits, authentication, or other behavioral traits.

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 concise and well-structured, conveying the essential information in two short sentences without unnecessary verbosity.

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?

While the output schema exists (so return value details are not required), the description lacks sufficient context for correct usage: no parameter meanings, no usage differentiation, and no side-effect disclosure. The tool is simple but the description leaves too much unstated.

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

Parameters1/5

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

The schema has zero descriptions for the four parameters. The description only mentions 'given lap' but does not explain what 'circuit', 'season', or 'session' refer to (e.g., whether session is race/qualifying/practice). This leaves the agent guessing about required input semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns a raw session snapshot with specific fields (position, gaps, tire compound/age). It is specific enough to understand the tool's core function, though it does not explicitly contrast with sibling tools.

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 versus the analytical sibling tools (e.g., get_tire_degradation_curve, simulate_undercut_overcut). The implied use case (retrieving raw data) is not made explicit.

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

get_tire_degradation_curveB

Calibrated tire degradation model (base pace + degradation rate) for a compound at a circuit, fit on real FastF1 lap data.

ParametersJSON Schema
NameRequiredDescriptionDefault
seasonNo
circuitYes
compoundYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

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

With no annotations, the description carries the full burden and does add useful context by stating the model is calibrated and fit on real FastF1 lap data, and that it provides base pace and degradation rate. However, it does not disclose behavior around the optional season, data availability, or input constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and information-dense, with no wasted words. It front-loads the main concept and supports it with the data-source detail, though a leading verb like 'Returns' would make it even easier to parse.

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

Completeness3/5

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

An output schema exists, so return-value detail is not required. Still, the description leaves the season parameter's effect and the tool's relationship to sibling strategy tools implicit, making this adequate but not fully complete.

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?

The description adds meaning to compound and circuit by explaining they define the model scope. Schema coverage is 0%, so the description partially compensates, but the season parameter remains semantically undefined beyond being a nullable integer with a null default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies a calibrated tire degradation model as the resource, scoped by compound and circuit. It distinguishes this tool from sibling tools about pit loss, pit window, and strategy simulation by focusing on the degradation curve itself. It lacks an explicit verb, but the artifact and scope are unmistakable.

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

Usage Guidelines3/5

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

The intended use is implied: retrieve a tire degradation model for strategy analysis. However, there is no explicit statement of when to use this tool instead of related siblings like get_historical_strategies or simulate_undercut_overcut, nor any exclusions.

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

predict_finish_positionA

Projects driver's finishing position and total time for a planned strategy, assuming rivals hold their recent pace with no further stops.

ParametersJSON Schema
NameRequiredDescriptionDefault
driverYes
seasonYes
circuitYes
sessionYes
current_lapYes
planned_strategyYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of explaining behavior. It accurately communicates that this is a projection/calculation tool with no side effects, and it discloses the key modeling assumption about rivals' pace. It does not explicitly state that it is read-only, but the verb 'projects' strongly implies a non-mutating operation.

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, well-structured sentence that front-loads the core action and output, then efficiently states the key assumption. There is no redundant or extraneous wording, making it easy to parse quickly.

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?

Given the tool has six required parameters, a nested object, and several closely related sibling tools, the description leaves important gaps. It does not clarify what 'planned_strategy' should contain, how 'current_lap' relates to the projection, or whether 'session' refers to race, qualifying, or practice. The output schema exists but is not shown, so the agent still lacks sufficient context to construct a correct call confidently.

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

Parameters2/5

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

The schema provides no descriptions for the six parameters, and the description only explicitly clarifies the meaning of 'driver' and 'planned_strategy'. It does not explain the role or expected values of 'season', 'circuit', 'session', or 'current_lap', nor does it describe the shape or fields of the nested 'planned_strategy' object. Since schema coverage is 0%, the description needed to compensate but only covers about a third of the parameters.

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 the tool's primary function: projecting a driver's finishing position and total time based on a planned strategy. It also names the key entity (driver) and the specific output (finishing position and total time), making it distinct from general race-state or strategy-comparison tools.

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

Usage Guidelines3/5

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

The description implies a usage scenario by stating the key assumption ('assuming rivals hold their recent pace with no further stops'), which helps the agent know when the projection is valid. However, it does not explicitly say when to use this tool over siblings like simulate_undercut_overcut or compare_strategy_options, nor does it provide guidance on alternative tools.

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

simulate_undercut_overcutB

Compares pitting own_driver before rival_driver (undercut) against staying out longer than them (overcut).

ParametersJSON Schema
NameRequiredDescriptionDefault
seasonYes
circuitYes
sessionYes
own_driverYes
current_lapYes
rival_driverYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It communicates that the tool performs a comparison/simulation, but it does not describe side effects, assumptions, data dependencies, or what kind of result the comparison produces beyond the output schema.

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 focused sentence with no filler. It front-loads the main operation and defines the two compared strategies compactly, making it very easy to scan.

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

Completeness3/5

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

The core operation is understandable and the output schema exists to fill in return-value details, so this is minimally viable. However, with six required parameters, no parameter descriptions, and no usage guidance relative to siblings, an agent must rely heavily on parameter names and general racing knowledge to invoke it correctly.

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

Parameters2/5

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

Schema description coverage is 0%, and the description does not explain most parameters. It does add some semantic meaning by clarifying that own_driver and rival_driver determine which action counts as an undercut or overcut, but circuit, season, session, and current_lap are left entirely to name-based inference.

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 states a specific verb ('Compares') and a precise resource: pitting own_driver before rival_driver (undercut) versus staying out longer (overcut). This clearly differentiates the tool from the more generic sibling compare_strategy_options by naming the exact strategic matchup it handles.

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

Usage Guidelines3/5

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

The intended use is implied by the description: use this when you need an undercut-versus-overcut comparison between two specific drivers. However, there is no explicit statement about when not to use it, nor any mention of the alternative compare_strategy_options for broader strategy comparisons.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 9 tool updatesv0.1.0
    • First observedcompare_strategy_options
    • First observedgenerate_strategy_report
    • First observedget_historical_strategies
    • First observedget_pit_loss_time
    • First observedget_pit_window
    • First observedget_race_state
    • First observedget_tire_degradation_curve
    • First observedpredict_finish_position
    • First observedsimulate_undercut_overcut

TDQS

A3.6/5.0

Scored across 9 tools

Disambiguation4/5

Most tools have clear, separate roles: data retrieval (race state, degradation, pit loss), tactical comparison (pit window, undercut/overcut), and broader strategy projection (compare strategies, predict finish). There is minor overlap among the strategy-decision tools—compare_strategy_options could technically reproduce an undercut/overcut comparison—but descriptions distinguish intent well enough.

Naming Consistency5/5

All tools follow a consistent snake_case verb_noun pattern, dominated by get_ for data/model lookups and simulate/compare/predict/generate for analysis actions. No style or verb inconsistency exists.

Tool Count5/5

Nine tools is well-scoped for an F1 strategy assistant: a handful of data/model inputs, a few decision/analysis operators, and one report formatter. Each tool earns its place without redundancy.

Completeness4/5

The set covers the core strategy workflow—reading session state, modeling tires/pit loss, evaluating windows and under/overcuts, comparing multi-stop strategies, predicting finish, and producing a report. Obvious peripheral gaps like weather or fuel effects are absent, but they are not essential to the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    Provides advanced Formula 1 analytics including real-time telemetry processing, tire degradation modeling, weather impact analysis, and Monte Carlo race strategy simulation for comprehensive F1 data analysis.
    13
    5
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Formula 1 data analysis through natural language, providing tools like track dominance, lap time analysis, and team performance comparisons.
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    A local MCP server that gives Claude (or any MCP-compatible AI client) access to Formula 1 race data. Load any session from 2018 onwards, ask questions in natural language, and get answers backed by real telemetry, timing, and strategy data.
    4
    17
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A real-time Formula 1 analytics server that lets you ask natural language questions about races, lap times, tyre strategies, pit stops, and more using live data from the OpenF1 API.
    -