How I Accidentally Built an AI Cycling Coach

Article summary

This spring I built myself an AI cycling coach. It reads my actual ride data, knows what my week looks like and writes my training around both. I’m not a developer. I’m a Delivery Lead – I bring the files to the customers so the engineers don’t have to. I spend all day around people who build software and personally build none of it. Code was a line I didn’t cross. Not because I couldn’t learn it, but because every time I ran the math on what it would take, the answer came back the same: not worth it, not right now.

Then AI got good. Recently, really good. The version of this story from even a couple years ago ends at the first error message. My motivation was never the missing piece. What changed is that the cost of each next step dropped low enough that I could actually pursue it.

Context

Some context first: I race long mountain bike events, the kind measured in hours, where the training is a year-round thing whether you like it or not. In Michigan, the winter portion of “year-round” happens in my basement, on a trainer, riding a bike that goes nowhere. That’s where this starts: a long, easy trainer ride on a Tuesday morning in late March, the season suddenly weeks away instead of months, feeling like I needed to get a semblance of a plan together but not excited about any of my options.

Where the digicoach was born

Every tool handed me a plan.

It’s not that I hadn’t tried the normal options. I had, kind of exhaustively: TrainerRoad, Xert, TrainerDay, IntervalCoach, and a stretch of going manual with the Time-Crunched Cyclist book and a spreadsheet. None of these are bad tools. All of them handed me a plan that worked to varying degrees, but my actual life ended up not fitting it like I wanted it to.

The plans couldn’t see my week. They didn’t know about my Thursday group ride, which sometimes is casual and sometimes a knife fight. They didn’t know my commute is a 20-30 minute ride each way. Real training volume that, as far as the plan was concerned, didn’t really exist. Every week started a little disconnected from reality, and once life got busy, that disconnection made skipping sessions easier.

What I really wanted was structure that could bend around a real week. The customization of a human coach without the human coach cost. And (this mattered more than I expected) something that could teach me why a plan was structured the way it was and how much a particular session mattered.

The thing that bugged me the most seemed smaller than any of that: when I missed a session, the tools would dutifully reshuffle my week, but none of them could tell me what the miss actually cost. Make it up? Let it slide? No opinion. That annoyance stuck with me long enough that it got written into my coach as a literal hardcoded principle: life stress = training stress. But we’ll get there.

“Educate yourself first.”

Somewhere in that basement ride, curiosity won. My laptop was on a stand next to the trainer (it runs Zwift, the app that turns basement riding into a video game).  I opened Claude in another window, still pedaling. It was not “build me a training plan.” After years of being handed plans, that was the last thing I wanted. Instead, I told it to educate itself: go learn from the Cyclist’s Training Bible, the Time-Crunched Cyclist, the Duchy Cycle Coaching blog. I picked Duchy because it’s where I’d first run into the idea that to our bodies, stress from life counts the same as stress from training. It was a source of nuance and balance. Feeding it Duchy’s takes, not just the textbooks, is part of why the coach came out feeling like a coach instead of a calculator.

Connecting to intervals.icu

All my ride data lives on a site called intervals.icu: every ride, every heart rate number, years of it. Mostly on a whim, I asked: can you actually connect to that?

It could. There’s a thing called an MCP server (for our purposes here, a connector that lets Claude read my real data instead of me describing it), and the moment that clicked, the project got much bigger than the one I’d sat down with. A coach that could see every ride I’d ever done. That could adjust based on what actually happened this week instead of what was supposed to happen, and could build out each week of my plan as we went and land it directly on my training calendar.

So I set it up. Right there, still riding. It was the first time I’d ever tried setting up something like this. I followed the instructions blind, hit errors I did not remotely understand (a placeholder file path I was apparently supposed to replace, commands run from the wrong directory), and pasted each one back to Claude, which calmly cleared them one at a time. Somewhere past the hour mark, it connected. I know exactly what I typed, because it’s in the transcript: “woohoo it’s working!”

The whole thing took one ride. Ninety-six minutes, per Strava. I got on the bike annoyed at training plans and got off with an AI coach hooked into five years of my own data.

14 kudos, zero takers ¯\_(ツ)_/¯

“Just point the robot at it”

It kept working for about a day. Then I started hitting bugs. Not in my setup this time, but in the server’s own code. The intervals.icu API had changed at some point and a bunch of different calls (get activity, full stream view, that kind of thing) were broken. This was the oh-shit moment. Following instructions and pasting back error messages was one thing. The code itself being broken was, as far as I was concerned, the end of the experiment. That was developer territory.

Then I remembered a line from a coworker: “Just point the robot at it and ask it to fix it.” So I did, half-expecting to watch it flail. It read through the code, found the problem, and fixed it. It took some back and forth, but it worked.

I want to be clear about the size of my contribution here: I typed a sentence a coworker gave me and hit enter to see what would happen. The robot did the rest.

So what changed?

Within a few weeks, the coach was real. It tells me what a missed session actually costs. And when work or sleep goes sideways, it adjusts the week with my input. The hardcoded principle, doing its job. Along the way I bumbled through forking the repo and sending the fixes I (okay, the robot) had made back to the developer who maintains the server; brace yourselves, lifelong developers.

(The coach system grew until it fell over, and the whole system had to grow up and be refactored. That’s a story for another day.)

It turns out I learn best when the problem is mine. No one’s tutorial was going to hold my attention like this. My own training data did.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *