← All articles
wahoomcpclaudechatgptcyclingpowerelemntkickr

Wahoo MCP Server: Connect Wahoo to Claude and ChatGPT

Give Claude or ChatGPT live access to every ride on your ELEMNT and KICKR, with normalized power, TSS, your power zones and the lap structure of each session.

Wahoo
wahoo
Power output
athletedata
AI coach
Power outputHeart rateCadenceSpeedDistanceElevationTSS

You ask Claude whether the block worked and it asks you what you did

You have ridden a Wahoo setup for two seasons. An ELEMNT on the bars outdoors, a KICKR in the garage from November to March, a TICKR under the jersey. Every interval you have ever done sits in that account with per-second power attached.

So you open Claude and ask whether your last eight weeks of sweet spot work actually moved anything. And it asks you to describe your training.

You type a paragraph. Four rides a week, two of them structured, FTP around 265 in April. The model gives you a thoughtful answer built on that paragraph. It does not know your normalized power on the Tuesday sessions climbed 9 watts across the block while your average heart rate at that power fell 4 beats. It does not know that the last three long rides all ended with a 20-minute stretch where power held and cadence collapsed.

The model is not being lazy. It is blind. And you cannot type your way out of blindness, because the thing you would need to type is a spreadsheet.

An MCP server closes that gap at the root. Instead of you summarizing the block, the model reads it.

What MCP actually is

The Model Context Protocol is an open standard for letting AI assistants call external tools. Anthropic published it in late 2024, and adoption spread past Claude quickly. ChatGPT, Cursor and Perplexity all speak it now.

The protocol itself is boring, which is the point. A server advertises a list of tools, each with a name and a schema describing what it takes and returns. The model decides when to call one. Results come back as structured data rather than prose, so the model reasons over numbers instead of parsing a description of numbers.

For cycling data that shape is exactly right. You do not want two seasons of rides pasted into a context window, going stale the moment you finish tomorrow's session. You want the model to ask a question when it needs an answer, the same way you would open the Wahoo app and scroll to a specific week.

So "Wahoo MCP server" means a server that exposes your Wahoo history as tools. Ask "did my 20-minute power improve across this block, and what did my heart rate do at that power?" and the model fetches both ends of the block and does the comparison against real rides.

What the Wahoo connector exposes

Once Wahoo is connected, the model gets two layers of tools, and the distinction matters more than it first looks.

The Wahoo layer. Four tools, each mapping onto something the Wahoo Cloud API actually returns.

wahoo_get_workouts lists your sessions for a date range. The range genuinely filters, including years back, so "how many rides did I do in 2023" is an answerable question rather than a shrug. The response carries both a total count across all time and how many fell inside the window you asked for, which is what lets the model tell the difference between "you did not ride" and "I only looked at March".

wahoo_get_workout returns one session's basics: sport, duration, distance, route.

wahoo_get_workout_summary is the one that earns its place. It returns the aggregate metrics for a single ride: average and normalized power, intensity factor, TSS, average and maximum heart rate, cadence, speed, and total work in kilojoules. This is the tool a model reaches for when you ask why a ride felt harder than the numbers suggest, because the gap between average power and normalized power is usually the answer. The training stress score guide covers what the load numbers mean; the point here is that the model can fetch eight of them and compare, rather than explain the concept back to you.

wahoo_get_power_zones returns your Wahoo power zones, Z1 through Z7 in the Coggan style, anchored to the FTP configured in your Wahoo account. That last part is quietly important. If your FTP says 265 in Wahoo and 248 somewhere else, a session prescribed as "sweet spot" means two different efforts depending on which anchor you used. A model that can read the zones your head unit is actually pacing against will not give you the wrong wattage. If you are not sure which anchor to trust, the FTP versus critical power guide is the place to start.

The derived layer. These are not Wahoo fields at all. They are computed across everything you have connected, and they are usually where the conversation gets interesting: get_pmc_status for fitness and fatigue balance, get_power_curve for best efforts by duration, get_training_trends, get_load_balance across sports, get_readiness_today, get_daily_metrics for HRV and resting heart rate series, and get_activity_detail for one session in depth.

Wahoo will show you a ride. It will not answer "is my 42-day ramp steeper than the two blocks that preceded my last two flat spots", because that is a question about the shape of a season rather than the contents of a file.

Why the FIT file matters more than the summary

Most connectors stop at the summary numbers, and the result is a power curve that quietly lies to you.

Here is the failure, described precisely because it is easy to miss. If all you have per ride is one average power figure, a mean maximal power curve built from that data has nothing to distinguish a 5-minute best from a 60-minute best. Every duration inherits the same number from whichever ride happened to be longest. A rider opens their analytics page and sees identical wattage at 5, 10, 20, 30, 45 and 60 minutes, which is not a power curve. It is one ride wearing six hats.

The fix is to parse the ride itself. Wahoo's workout summary endpoint returns a link to the ride's FIT file, and file downloads do not count against the API rate limit, so pulling it is close to free. The connector downloads and parses it at ingest, which gets you two things.

Per-second power, so your best rolling 5-minute effort is a real 5-minute window inside a real ride, and get_power_curve compares like with like across your history.

Lap structure, so get_activity_detail can serve the actual work and recovery boundaries the head unit recorded rather than per-kilometre splits that cut across your reps. Ask "how much did power fade from rep one to rep six?" and there are six laps to answer with.

That distinction is the difference between an assistant that can discuss your training and one that can audit it.

What lands and what does not

Being precise here matters more than it sounds, because the failure mode is not an error message. It is a confident answer built on a field that was never there.

Lands: rides and workouts with power, heart rate, cadence, speed, distance, elevation and duration. Normalized power, intensity factor and TSS per ride, taken from Wahoo's own computation rather than recomputed. Your FTP-anchored power zones. Lap structure and per-second streams from the FIT file. The full workout list goes all the way back rather than covering a rolling window, so a long Wahoo history arrives as history.

Does not land: sleep, HRV, resting heart rate, recovery scores, body composition. None of this is a connector limitation. Wahoo builds head units, trainers and heart rate straps, and none of them measure your night. If you want the recovery half of the picture, that has to come from a wearable, and the same connector reads Garmin, WHOOP, Oura, Withings, Apple Health and others through the same connection.

One quirk worth knowing about: your Wahoo collection also holds planned workouts that are sitting on the head unit waiting to be ridden. Those come back flagged as scheduled but not recorded, and they are not sessions you did. The flag exists because counting them would inflate your volume with rides that never happened, and a model reading the raw list without it would congratulate you on a week you have not ridden yet.

Setting it up

The whole flow takes about five minutes, and most of it is Wahoo's authorization screen.

1. Connect Wahoo. Sign in at athletedata.health, open the Wahoo integration page, and click Connect. You will be sent to Wahoo to sign in and approve the requested permissions. Approve all of them: each one maps to a specific capability, and a partial grant silently removes the feature it belongs to rather than warning you.

2. Let the backfill run. The list pass covers your whole archive, and the deeper enrichment pass, the one that pulls FIT files for per-second power and laps, works through recent rides first. It is worth letting the first pass finish before asking anything comparative, or you will get a confident answer about a partially loaded season.

3. Copy your MCP URL. From the dashboard, use the Copy MCP URL button. It produces a URL of the form https://mcp.athletedata.health/mcp?apiKey=sk_soma_.... The key is yours alone and revocable from the same page, so treat the whole URL like a password.

4. Add it to your AI client. In Claude, follow the Claude Desktop connector walkthrough: open Settings, then Connectors, then Add custom connector. Name it athletedata, paste the URL, and click Add. It should show as Connected. ChatGPT, Cursor and Perplexity each have an equivalent panel, and there are step-by-step pages for all of them in the MCP setup section.

5. Ask something specific. Open a new chat and ask a question that needs data you have never typed. "Across my last eight structured rides, what happened to normalized power and to heart rate at that power?" You will see the tool calls fire before the answer arrives. That is the confirmation that it is reading rather than guessing.

The reconnect that catches long-time Wahoo users

This one deserves its own section because it looks like a bug and is not.

OAuth scopes freeze at authorization time. Whatever permissions you granted on the day you connected are the permissions the grant carries forever, and adding new capabilities on our side does not retroactively widen an existing grant.

Two capabilities landed in August 2026. The first is offline_data, which is the permission that makes Wahoo send us a push when you finish a ride. Without it nothing is broken, but your rides arrive on the next scheduled sync rather than within a minute of you stopping the recording. The second is the pair of plan-writing scopes that make planned-workout push possible at all.

If you connected Wahoo before that, your grant predates both. The fix is one reconnect from the integrations page, which takes about thirty seconds and does not disturb your history. If your rides seem to show up late, or a pushed workout never appears on the head unit, this is the first thing to check.

Pushing a workout back the other way

Reading is the main event, but the connection is not one-directional.

A structured session can be pushed to your ELEMNT or RIVAL as a native Wahoo plan, scheduled on a date. That is meaningfully different from exporting a file and dragging it into the head unit's plans folder, in two ways that are properties of the file format rather than the device.

A side-loaded workout file collapses each target to a single number, so a session authored as 83 to 93 percent of FTP arrives as one wattage and the head unit falls back to drawing the enclosing zone. Wahoo's own plan format carries a low and high bound per target, so the band the coach actually wrote survives the trip.

And a side-loaded file is not a Wahoo planned workout, so the ride records as one undifferentiated lap. A scheduled plan is executed natively and laps at each interval boundary, which means the rep structure is in the file afterwards, which means the next conversation about that session has something to read.

Bike and run are supported, because those are the two workout families Wahoo's plan header can express. Swim and strength are refused with a reason rather than half-encoded into something the hardware would render wrong.

The limits worth knowing about

Wahoo is a training source, not a recovery source. Covered above, but it is the single most common expectation mismatch. If your question is about readiness, the answer has to come from a device that watches you sleep.

Strava is not available over MCP. Strava's API terms do not permit serving Strava data to third-party AI platforms and tools, so it is excluded from the connector. If you ride a Wahoo this changes very little, since your rides already arrive from Wahoo directly and at higher fidelity than Strava would give you.

Tool access is not a coach. The connector answers questions you ask. It does not notice that your normalized power at a given heart rate has been sliding for three weeks and message you about it, because nothing runs between your conversations. That is the real difference between the two products. The MCP tier at $9/month, or $69/year, is for querying your own data in your own AI client. The full coaching plan at $39/month adds a coach that watches continuously, adjusts your plan, and starts the conversation itself. Both include a 7-day free trial.

Wahoo is one source among many. The same connector exposes Garmin, WHOOP, Oura, Hevy, Withings, Apple Health, intervals.icu, TrainingPeaks, COROS, Polar and others through one connection. The cross-source questions are where the answers get genuinely hard to get anywhere else, because no single app holds both halves. The Garmin MCP server guide covers the equivalent setup on that side, and the general guide to connecting training data to ChatGPT or Claude has the full source list.

Putting it together: a Wahoo MCP setup checklist

  1. Connect Wahoo from the integrations page and approve every permission on Wahoo's screen. A partial grant removes a feature silently rather than warning you.
  2. If you connected Wahoo before August 2026, reconnect once. That is what picks up live ride pushes and planned-workout sync, and nothing else will.
  3. Let the initial backfill finish before asking anything that compares two periods. A partially loaded history produces a confidently wrong comparison.
  4. Copy your MCP URL from the dashboard and treat it like a password, because your API key is embedded in it.
  5. Add it as a custom connector in Claude, ChatGPT, Cursor or Perplexity, and confirm it shows as connected.
  6. Check your FTP in Wahoo before you ask for a prescribed session, since wahoo_get_power_zones reads the anchor your head unit is pacing against and a stale FTP moves every zone with it.
  7. Start with a question you could not answer yourself in under ten minutes. "What did my normalized power and heart rate do across my last eight threshold rides?" is a good first test, because the answer requires eight tool calls and a comparison.
  8. When the answer surprises you, ask for the ride ids behind it. A model with tools can show its work, and checking that once is how you learn to trust it.

Your power meter has been recording the answer for two seasons. The only thing missing was something willing to read all of it at once.

Questions

what is a wahoo mcp server?+

It is a server that speaks the Model Context Protocol and exposes your Wahoo workout history as callable tools. When you ask Claude or ChatGPT about last week's intervals, the model calls those tools and reasons over your real power, heart rate and cadence numbers. Without it the model only knows what you type.

can claude read my wahoo data?+

Yes, once you connect Wahoo to AthleteData and add the MCP connector to Claude. Claude can then pull your rides, per-ride normalized power and TSS, and your configured power zones whenever a question needs them. The same connector works in ChatGPT, Cursor and Perplexity, because MCP is a shared standard rather than a Claude feature.

what does wahoo tss mean and where does the number come from?+

Training Stress Score is a single number for how much a ride cost you, built from normalized power, your FTP and the ride's duration. Wahoo computes it per workout and returns it on the workout summary endpoint, so the connector serves Wahoo's own figure rather than a recomputed one. An hour at exactly your FTP is 100 by definition.

does the connector see my wahoo normalized power?+

Yes. The wahoo_get_workout_summary tool returns average and normalized power, intensity factor, TSS, average and maximum heart rate, cadence, speed and total work in kilojoules for a single ride. Normalized power is the number worth asking about on a variable ride, because average power understates a session full of surges.

can it push a workout to my elemnt?+

Yes, if your Wahoo grant carries the plans_write and workouts_write scopes. A structured session built in conversation is uploaded as a native Wahoo plan and scheduled on a date, so the head unit executes it and laps at each interval boundary. Grants created before August 2026 predate those scopes and need one reconnect.

garmin vs wahoo, which works better with an ai coach?+

Both work, and you do not have to choose. Garmin gives you sleep, HRV and all-day physiological data that Wahoo has no equivalent for; Wahoo gives you a cleaner power story from the head unit and trainer you actually ride. Connecting both is common, and the connector merges the duplicate ride so it is not counted twice.

Related

A coach that texts you first.

After every workout and night of sleep, it messages you with the analysis - and what to change. Free for 7 days.

Used by runners, cyclists, and triathletes worldwide