Domestique
Retrieves planned workouts from TrainerRoad calendars and integrates them with workout planning views
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Domestiqueshow me my fitness trends for the last month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Domestique
A TypeScript MCP (Model Context Protocol) server that integrates with Intervals.icu, Whoop and TrainerRoad to provide unified access to fitness data across all activities and sports.
Features
Completed workouts from Intervals.icu with matched Whoop strain
Recovery, HRV, sleep, and strain from Whoop
Planned workouts from TrainerRoad and Intervals.icu
Sync TrainerRoad running workouts to Intervals.icu (for Zwift/Garmin)
Fitness trends (CTL/ATL/TSB) and detailed workout analysis with intervals, notes, and weather
Heat strain and heat adaptation score from a CORE Body Temperature sensor
Weather, AQI, and pollen forecasts up to 10 days out for Intervals.icu weather locations or any geocoded place
Generates activity descriptions for Strava (swim, bike, and run activities only)
Note: Workouts imported from Strava can't be analyzed due to API restrictions. Sync them from Zwift, Garmin Connect, Dropbox, etc. instead.
Related MCP server: Pierre Fitness Platform MCP Server
Available Tools
Today's Data
get_todays_summary- Full snapshot of today: recovery, sleep, HRV, strain, fitness (CTL/ATL/TSB), wellness, completed and planned workouts, race, calendar annotations (sick/injured/holiday/notes), and weather.get_todays_activities- Today's completed and planned workouts, race, and calendar annotations (sick/injured/holiday/notes). Leaner alternative toget_todays_summary.
Profile & Settings
get_athlete_profile- Athlete profile, unit preferences, age, and location.get_sports_settings- FTP, zones, and thresholds per sport.
Historical/Trends
get_strain_history- Whoop strain and activities over a date range.get_activity_history- Past completed workouts with matched Whoop strain and calendar annotations.get_recovery_trends- HRV, sleep, and recovery patterns over time.get_wellness_trends- Daily Intervals.icu wellness metrics over a date range.get_activity_totals- Aggregated totals over a date range: duration, distance, training load, and zone distributions by sport.
Planning
get_upcoming_activities- Planned workouts (TrainerRoad + Intervals.icu) and races for a future date range, plus calendar annotations.
Workout Management
create_workout- Create a structured cycling/running/swimming workout from a plain-language description.update_workout- Update a Domestique-created workout..delete_workout- Delete a Domestique-created workout.sync_trainerroad_runs- Sync running workouts from TrainerRoad to Intervals.icu, detecting changes and orphans.set_workout_intervals- Set intervals on a completed activity.update_activity- Update name and/or description of a completed activity.regenerate_descriptions- Regenerate the descriptions of a day's completed activities, or a single activity by ID.
Calendar Annotations
create_annotation- Add a sick/injured/holiday/note annotation to the Intervals.icu calendar.update_annotation- Update a Domestique-created annotation.delete_annotation- Delete a Domestique-created annotation.
Analysis
get_training_load_trends- CTL, ATL, TSB, ramp rate, and ACWR over time.get_workout_details- All details for one workout: intervals, notes, weather, zones, music, and matched Whoop strain.
Performance Curves
get_power_curve- Best watts at various durations with W/kg, estimated FTP, and period comparison.get_pace_curve- Best running/swimming times at key distances.get_hr_curve- Max sustained HR at various durations.
Weather
get_weather_forecast- Forecast for a date and optional location, with AQI and pollen.
Setup
Prerequisites
Node.js 20+
Intervals.icu account with API key
Whoop account with OAuth credentials
TrainerRoad account with calendar feed URL
Environment Variables
Copy .env.example to .env and fill in your credentials:
cp .env.example .envRequired variables:
MCP_AUTH_TOKEN- Secret token for MCP authentication. You can quickly generate one with:
openssl rand -hex 32For Intervals.icu integration:
INTERVALS_API_KEY- Your Intervals.icu API keyINTERVALS_ATHLETE_ID- Your Intervals.icu athlete ID
For Whoop integration:
WHOOP_CLIENT_IDWHOOP_CLIENT_SECRETREDIS_URL- Required for token storage (e.g.,redis://localhost:6379)WHOOP_REDIRECT_URI- Optional. Auto-detected based on environment:On Fly.io:
https://{FLY_APP_NAME}.fly.dev/callbackOtherwise:
http://localhost:3000/callback
For TrainerRoad integration:
TRAINERROAD_CALENDAR_URL- Private iCal feed URL
For weather forecasts (optional):
GOOGLE_API_KEY- Google Cloud API key with the Weather, Air Quality, Pollen, Elevation, Geocoding, and Time Zone APIs enabled.
For Last.fm integration (optional):
LASTFM_USERNAME- Last.fm username.LASTFM_API_KEY- Last.fm API key.
When both are set, get_workout_details and get_todays_activities include tracks played during the workout. ("Why not use Spotify?" you may be wondering. Ingesting Spotify data into AI is against their developer policy.)
For Anthropic API integration:
ANTHROPIC_API_KEY- Required forcreate_workoutandupdate_workouton cycling and running (server converts the plain-languagestructurefield into Intervals.icu workout-doc syntax). Also enables, when set, Claude for TrainerRoad annotation categorization (Sick/Injured/Holiday/Note), triathlon race priority extraction (A/B/C from the umbrella description), auto-generated activity descriptions onworkout.updatedWhoop webhooks, and debug token counting.ANTHROPIC_CLASSIFIER_MODEL- Optional override for the model used by the annotation and race-priority classifiers. Defaults toclaude-haiku-4-5.ANTHROPIC_DESCRIPTION_MODEL- Optional override for the model used by the activity-description generator. Defaults toclaude-sonnet-4-6.ANTHROPIC_WORKOUT_MODEL- Optional override for the model used by thecreate_workout/update_workoutstructure-to-syntax converter. Defaults toclaude-sonnet-4-6.ANTHROPIC_TOKEN_COUNTER_MODEL- Optional override for the model used by dev-only debug token counting. Defaults toclaude-haiku-4-5.
For the /api endpoints (optional):
API_SECRET- Authenticates the/apiendpoints viaAuthorization: Bearer. Generate withopenssl rand -hex 32.
For error reporting (optional):
BUGSNAG_API_KEY- Reports upstream API failures (Intervals.icu, Whoop, TrainerRoad) to Bugsnag.
Whoop OAuth Setup
Whoop uses OAuth 2.0 with single-use refresh tokens stored in Redis. One-time setup:
Create a Whoop developer app at https://developer.whoop.com to get your
WHOOP_CLIENT_IDandWHOOP_CLIENT_SECRET.Ensure Redis is running and
REDIS_URLis set in.env.Start Docker:
docker compose up -dRun the OAuth script:
docker compose exec domestique npm run whoop:authOpen the displayed URL, authorize, and paste the resulting code back into the script.
The server refreshes tokens automatically thereafter.
Whoop Webhooks (optional)
When Whoop is configured, Domestique exposes POST /webhooks/whoop and uses it to:
Sync the day's Whoop strain to Intervals.icu wellness.
Set per-workout Whoop strain on the matching Intervals.icu activity.
Auto-generate a description for the completed activity (requires
ANTHROPIC_API_KEY).
One-time setup in Intervals.icu — create these custom fields:
Wellness:
WhoopStrain(Number)Activity:
WhoopWorkoutStrain(Number)
One-time setup in Whoop — in your Whoop developer dashboard, add the webhook URL https://{your-host}/webhooks/whoop and select Model Version: v2.
/api endpoints (optional)
When API_SECRET is set, Domestique exposes two HTTP endpoints for callers like iOS Shortcuts, authenticated with Authorization: Bearer <API_SECRET>:
PUT /api/location— sets the athlete's current location from a JSON body{ "latitude", "longitude" }(also requiresGOOGLE_API_KEY). Same as theupdate_locationtool.POST /api/activities/descriptions— regenerates a day's activity descriptions. Optional JSON body{ "date": "YYYY-MM-DD" }(defaults to today) or{ "activity_id": "..." }to regenerate a single activity (takes precedence overdate). Same as theregenerate_descriptionstool.
Local Development
Recommended: docker compose up (hot reload, server at http://localhost:3000). Use docker compose exec domestique <command> to run commands inside the container (e.g., npm run typecheck, npm run whoop:auth).
Without Docker:
npm install
npm run dev # hot reload
npm run build && npm startTesting with MCP Inspector
npx @modelcontextprotocol/inspector --server-url "http://localhost:3000/mcp?token=YOUR_SECRET_TOKEN"Debug Token Counting
In development mode, set ANTHROPIC_API_KEY to include a token_count field in _meta on tool responses. _meta is out-of-band per the MCP spec, so it isn't shown to the model.
MCP Request Logging
Set LOG_MCP_REQUESTS=true to log incoming JSON-RPC requests on /mcp.
Deployment to Fly.io
Install Fly CLI and log in:
curl -L https://fly.io/install.sh | sh && fly auth loginDeploy Redis (required for Whoop tokens):
cd fly-redis fly apps create domestique-redis fly volumes create redis_data --region iad --size 1 fly deploy cd ..Deploy Domestique:
fly apps create domestique fly secrets set MCP_AUTH_TOKEN=... INTERVALS_API_KEY=... INTERVALS_ATHLETE_ID=... \ WHOOP_CLIENT_ID=... WHOOP_CLIENT_SECRET=... REDIS_URL=redis://domestique-redis.internal:6379 fly deployWhoop tokens (if using Whoop):
fly ssh console -C "npm run whoop:auth". The redirect URI is auto-set tohttps://{your-app}.fly.dev/callback— register it in your Whoop app.
Connecting to Claude
Add as a connector with: https://{FLY_APP_NAME}.fly.dev/mcp?token=YOUR_SECRET_TOKEN (substitute your MCP_AUTH_TOKEN and host).
Example Queries
"How did my workout go today?"
"What's my recovery like this morning?"
"Show me my fitness trends for the last month"
"How has my HRV trended compared to my training load?"
"What's my power curve for the last 90 days?"
"Show me my running pace curve—what's my best 5km time?"
"How has my weight changed over the last 30 days?"
"Sync my TrainerRoad runs to Intervals.icu"
"What's the weather like for my race in Boulder next Saturday?"
MCP Client Compatibility Notes
Tested with Claude and ChatGPT. Notes:
Tool responses: Every tool declares an
outputSchemaper the 2025-11-25 MCP spec. The payload is returned asstructuredContentand also serialized intocontentfor older clients. Field descriptions are delivered viatools/list, not embedded per response._metafields: ChatGPT provides_meta(location, locale, etc.) on tool inputs; Claude doesn't.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
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/gesteves/domestique'
If you have feedback or need assistance with the MCP directory API, please join our Discord server