A real-time AI race engineer for live iRacing sessions
A voice-driven AI race engineer for iRacing: the driver asks over push-to-talk and gets an F1-radio answer in under two seconds, grounded in live telemetry read through 19 MCP tools.
- Stack
- Python · asyncio · OpenAI · FastMCP · SQLite · Whisper
- Latency
- answers in under 2 s
- Scale
- 19 MCP tools · 64 cars · 100 ms polling
An LLM that answers a moving car in under two seconds
We built a production AI agent that acts as a real-time race engineer during live motorsport sessions. The driver speaks to it over push-to-talk: the voice is transcribed by Whisper, processed by an OpenAI agent with access to 19 live telemetry tools, and answered back via TTS in F1-radio style.
The agent sees lap times, tyre wear, fuel levels, competitor gaps, track flags and pit service status — all updated in real time from iRacing's SDK. The core engineering constraint sets the whole design: an LLM that must answer in under two seconds, working from data that is stale by definition, without hallucinating numbers it does not actually have.

Telemetry as a tool layer the agent can call
The telemetry layer is exposed to the agent through FastMCP — a server implementing the Model Context Protocol with 19 structured tools across six categories: raw telemetry values, session info, leaderboard, flags, pit commands, and lap statistics. The MCP client converts tool schemas automatically from MCP's JSON Schema into OpenAI function-calling definitions, so there is no manual mapping to keep in sync.
The agent decides which tools to call, and in which order, from the driver's question. "Should I pit this lap?" triggers get_current_pit_service_status, get_car_average_lap_time, get_leaderboard and get_my_car_damage_report in a single reasoning loop before it answers. MCP runs as a separate process over stdio — clean process isolation, no shared-memory race conditions between the agent and the live data feed. The same wiring applies to a CRM, an ERP or a ticketing system: we wrote up how to connect AI agents to your data without handing the model a copy of it.

A lap time from 30 seconds ago is already wrong
The obvious approach — keep the full tool-call chain in conversation history — poisons the next question: the agent reasons from a lap time that was captured 30 seconds ago and is already wrong. Stale data carried forward is worse than no data.
The fix is a sliding window. Only the driver's question and the agent's final text response are persisted (MAX_HISTORY = 4); every intermediate tool call runs fresh each turn and is then discarded, and the system prompt is pinned as the first message. Session state lives separately: a TelemetryWorker polls iRacing at 100 ms intervals and writes completed laps for all 64 cars into SQLite — historical lap data without bloating the LLM context.
RAG over live structured data, with a gate on pit commands
Instead of a vector store, the system does real-time structured retrieval through the MCP tools. Before every response it fetches the relevant data fresh: lap history from SQLite, a live telemetry snapshot from the iRacing SDK, and session standings from the in-memory leaderboard. An ExtendedTelemetryFacade acts as retrieval middleware — it hides the data sources behind one interface and decides whether to read from the live SDK, the lap database, or the snapshot. It is the same pattern as RAG over documents — retrieve at query time, inject, discard — applied to structured real-time data instead of text chunks.
Reading is autonomous; acting is not. High-risk pit commands pass through a human-in-the-loop gate before execution — the agent can recommend and prepare a stop, but the driver confirms it before anything is sent to the car.
See what this would look like in your operations.
30 minutes · we map your 3 best automation opportunities · no obligation