coros-mcp
The coros-mcp server enables AI assistants to fully manage Coros fitness data and training. Using your Coros account (no API key needed), it supports:
Authentication: Log in via web or mobile API, check auth status and token validity.
Health & Training Metrics: Fetch daily metrics (HRV, resting heart rate, training load, VO2max, stamina, distance, etc.) and detailed nightly sleep data (deep, light, REM, awake, sleep HR) for up to 52 weeks.
Activity Data: List summarized activities for a date range and drill into a single activity with laps, HR/power zones, and sport-specific metrics.
Workout Templates: Browse, save, and delete reusable cycling, running, intervals, or strength templates from the Coros library.
Training Calendar: View, schedule (one-off or from templates), update, and remove planned workouts; add raw planned workouts and recalculate metrics.
Training Plans: List available training plans.
Exercise Catalogue: Browse Coros’s exercise library (especially for strength).
Local Cache & Sync: Backfill and sync data (daily metrics, sleep, activities) into a local SQLite cache for faster access; check cache coverage.
Utility: Get tool help and list available exercises.
Configuration: Optionally restrict the toolset (e.g., read-only mode) or hide authentication tools for security/autonomy.
Click on "Deploy 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., "@coros-mcp show my sleep data for the past week"
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.
coros-mcp
This is an unofficial, community-built project and is not affiliated with or endorsed by COROS.
COROS has since launched their official MCP server: coroslab/COROS-MCP. If you are looking for an officially supported integration, please use that instead.
This project continues to exist as a community alternative and may offer different or complementary features.
A Model Context Protocol (MCP) server that fetches sleep, HRV, and training data from the unofficial Coros API and exposes them to AI assistants like Claude.
No API key required. This server authenticates directly with your Coros Training Hub credentials. Your token is stored securely in your system keyring (or an encrypted local file as fallback), never transmitted anywhere except to Coros.
What You Can Do
Ask your AI assistant questions like:
"How much deep sleep and REM did I get last week?"
"What was my HRV trend over the last 4 weeks?"
"Show me my resting heart rate and training load for last week"
"How many steps did I average per day this month?"
"List my rides from last month"
"Show me the details of my last long ride"
"Create a 90-minute sweet spot workout for me"
"What's on my training calendar next week?"
"Schedule my VO2 workout for Thursday"
"Create a 20-minute strength circuit with squats, lunges, and planks"
Related MCP server: whoop-mcp
Features
Tool | Description |
| Log in with email and password — token stored securely in keyring |
| Log in to the mobile API only (useful for sleep data troubleshooting) |
| Check whether a valid auth token is present |
| Fetch daily metrics (HRV, resting HR, training load, VO2max, stamina, and more) for n weeks (default: 4) |
| Fetch nightly sleep stages (deep, light, REM, awake) and sleep HR for n weeks (default: 4) |
| List activities for a date range with summary metrics |
| Fetch full detail for a single activity (laps, HR zones, power zones) |
| List reusable workout templates saved in the library |
| Save a reusable cycling/intervals workout template (named steps, power targets) |
| Save a reusable strength workout template (sets, reps, or timed exercises) |
| Delete a saved workout template from the library |
| List planned workouts from the Coros training calendar |
| Schedule a one-off cycling/intervals workout for a date (no library entry) |
| Schedule a one-off strength workout for a date (no library entry) |
| Schedule an existing library template on a calendar day |
| Remove a scheduled workout from the calendar |
| Browse the Coros exercise catalogue, especially for strength workouts |
| Backfill all data into the local SQLite cache for a date range |
| Show coverage (record counts and date ranges) of the local cache |
Setup
Option A: Auto-Setup with Claude Code
If you have Claude Code, paste this prompt:
Set up the Coros MCP server from https://github.com/cygnusb/coros-mcp — clone it, create a venv, install it with pip install -e ., add it to my MCP config, then tell me to run 'coros-mcp auth' in my terminal to authenticate.Claude will handle the installation and guide you through configuration.
Option B: Manual Setup
Step 1: Install
git clone https://github.com/cygnusb/coros-mcp.git
cd coros-mcp
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .Or with uv:
uv pip install -e .Step 2: Add to Claude Code
claude mcp add coros -- /path/to/coros-mcp/.venv/bin/coros-mcp serveTo limit the MCP to a specific project only (recommended):
cd /path/to/your/project
claude mcp add --scope project coros -- /path/to/coros-mcp/.venv/bin/coros-mcp serveOr add to Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"coros": {
"command": "/path/to/coros-mcp/.venv/bin/coros-mcp",
"args": ["serve"]
}
}
}Step 3: Authenticate
Option A — .env file (recommended for project-scoped setups):
Create a .env file in your project directory:
COROS_EMAIL=you@example.com
COROS_PASSWORD=yourpassword
COROS_REGION=euThe server authenticates automatically on the first request and re-authenticates transparently whenever the token expires. No manual auth step needed.
Option B — Manual authentication:
Run the following command in your terminal — outside of any Claude session:
coros-mcp authYou will be prompted for your email, password, and region (eu, us, or asia). This stores both the Training Hub web token and the mobile API token (used for sleep data). Your credentials are sent directly to Coros and the tokens are stored securely in your system keyring (or an encrypted local file as fallback). You only need to do this once — the tokens persist across restarts.
Note: The mobile login (
apieu.coros.com) will log you out of the Coros mobile app on your phone. If you want to avoid this, usecoros-mcp auth-webinstead — it stores only the web token, and the mobile token will be obtained automatically when you first request sleep data.
Other auth commands:
coros-mcp serve # Start the MCP server (used by Claude Code / Claude Desktop)
coros-mcp auth-web # Web API only — skips mobile login (sleep data obtained lazily)
coros-mcp auth-mobile # Mobile API only (sleep data)
coros-mcp auth-status # Check if authenticated
coros-mcp auth-clear # Remove stored tokensStep 4 (optional): Restrict the toolset for autonomous agents
When the MCP client is an autonomous agent or a smaller open-weight model (e.g. hermes-agent with a DeepSeek/Hermes model), two env vars harden the server:
COROS_MCP_TOOLSET=readonly # expose only the 12 read tools
COROS_MCP_HIDE_AUTH_TOOLS=1 # hide authenticate_* (credentials never enter the model context)COROS_MCP_TOOLSET=readonlyhides everything that writes to your Coros account (save/schedule/update/delete tools) plus the low-level raw escape hatches, leaving:get_help,check_coros_auth,get_daily_metrics,get_sleep_data,list_activities,get_activity_detail,list_workout_templates,list_training_plans,list_planned_activities,list_exercises,sync_coros_data,get_cache_status. A smaller tool list also improves tool-calling reliability of non-frontier models. Default:full(all 26 tools).COROS_MCP_HIDE_AUTH_TOOLS=1removes the twoauthenticate_*tools so your password can never travel through the model context or agent logs. Authentication then happens exclusively via theCOROS_EMAIL/COROS_PASSWORDenv auto-login (or tokens stored beforehand withcoros-mcp auth).
All tools additionally carry MCP readOnlyHint / destructiveHint
annotations, so agent harnesses that honor them can require confirmation
for write actions.
Tool Reference
authenticate_coros
Log in with your Coros credentials. The auth token is stored securely in your system keyring (or an encrypted file as fallback).
{ "email": "you@example.com", "password": "yourpassword", "region": "eu" }Returns: authenticated, user_id, region, message
authenticate_coros_mobile
Authenticate with the Coros mobile API only. This is mainly useful if you need to restore sleep-data access without redoing full web authentication.
{ "email": "you@example.com", "password": "yourpassword", "region": "eu" }Returns: authenticated, user_id, region, message
check_coros_auth
Check whether valid web and mobile tokens are stored and how long the web token remains valid.
{}Returns: authenticated, user_id, region, expires_in_hours, mobile_authenticated, mobile_token_status
get_daily_metrics
Fetch daily metrics for a configurable number of weeks (default: 4).
{ "weeks": 4 }Returns: records (list), count, date_range
Each record includes:
Field | Source | Description |
| — | Date (YYYYMMDD) |
| dayDetail | Nightly HRV (RMSSD ms) |
| dayDetail | HRV rolling baseline |
| dayDetail | Resting heart rate (bpm) |
| dayDetail | Daily training load |
| dayDetail | Acute/chronic training load ratio |
| dayDetail | Fatigue rate |
| dayDetail | Acute / chronic training index |
| dayDetail | Distance (m) / duration (s) |
| analyse (merge) | VO2 Max (last ~28 days) |
| analyse (merge) | Lactate threshold heart rate (bpm) |
| analyse (merge) | Lactate threshold pace (s/km) |
| analyse (merge) | Base fitness level |
| analyse (merge) | 7-day fitness trend |
get_sleep_data
Fetch nightly sleep stage data for a configurable number of weeks (default: 4).
{ "weeks": 4 }Returns: records (list), count, date_range
Each record includes:
Field | Description |
| Date (YYYYMMDD) — the morning after the sleep |
| Total sleep in minutes |
| Deep sleep |
| Light sleep |
| REM sleep |
| Time awake during the night |
| Daytime nap time (null if none) |
| Average heart rate during sleep |
| Minimum heart rate during sleep |
| Maximum heart rate during sleep |
| Sleep quality score (null if not computed) |
Note: Sleep data is fetched from the Coros mobile API (
apieu.coros.com), which uses a separate token from the Training Hub web API.coros-mcp authobtains both tokens, but doing so logs you out of the Coros mobile app. Usecoros-mcp auth-webto skip mobile login — the mobile token is then obtained automatically on the first sleep data request. The token expires after ~1 hour but refreshes automatically on subsequent requests.
list_activities
List activities for a date range.
{ "start_day": "20260101", "end_day": "20260305", "page": 1, "size": 30 }Returns: activities (list), total_count, page
Each activity includes: activity_id, name, sport_type, sport_name, start_time, end_time, duration_seconds, distance_meters, avg_hr, max_hr, calories (in cal — divide by 1000 for kcal), training_load, avg_power, normalized_power, elevation_gain
get_activity_detail
Fetch full detail for a single activity. Requires the sport_type from list_activities.
{ "activity_id": "469901014965714948", "sport_type": 200 }Returns full activity data including laps, HR zones, power zones, and all sport-specific metrics.
Note: Large time-series arrays (
graphList,frequencyList,gpsLightDuration) are stripped from the response to keep it manageable.
list_workout_templates
List reusable workout templates saved in the Coros library.
{}Returns: workouts (list), count
Each entry includes: id, name, sport_type, sport_name, estimated_time_seconds, exercise_count, exercises (list of steps with name, intensity_low, intensity_high, sets, and exactly one duration key: duration_seconds, distance_meters, or duration_open)
save_workout_template
Save a reusable cycling/intervals workout template to the Coros library. The template appears in the Coros app and can be synced to the watch. Steps can be plain steps or repeat groups for intervals.
⚠️ This persists to the library indefinitely. For a one-off workout for a specific date, use
schedule_workoutinstead — it builds the workout inline and leaves no library entry.
Plain steps:
{
"name": "Sweet Spot 90min",
"sport_type": 2,
"steps": [
{"name": "15:00 Warmup", "duration_minutes": 15, "intensity_low": 148, "intensity_high": 192},
{"name": "20:00 Sweet Spot", "duration_minutes": 20, "intensity_low": 260, "intensity_high": 275},
{"name": "5:00 Rest", "duration_minutes": 5, "intensity_low": 100, "intensity_high": 150},
{"name": "20:00 Sweet Spot", "duration_minutes": 20, "intensity_low": 260, "intensity_high": 275},
{"name": "30:00 Cooldown", "duration_minutes": 30, "intensity_low": 100, "intensity_high": 192}
]
}With repeat groups (intervals):
{
"name": "3×10min Sweet Spot",
"sport_type": 2,
"steps": [
{"name": "Warmup", "duration_minutes": 10, "intensity_low": 150, "intensity_high": 200},
{"repeat": 3, "steps": [
{"name": "Sweet Spot", "duration_minutes": 10, "intensity_low": 265, "intensity_high": 285},
{"name": "Recovery", "duration_minutes": 3, "intensity_low": 150, "intensity_high": 175}
]},
{"name": "Cooldown", "duration_minutes": 11, "intensity_low": 150, "intensity_high": 200}
]
}Distance-based steps: use duration_meters instead of duration_minutes for a step that should end at a real distance regardless of pace, e.g. {"name": "1km @ 4:00/km", "duration_meters": 1000, "intensity_low": 235, "intensity_high": 245} (pace in sec/km with intensity_type: 3).
Open (lap-press) steps: use duration_open: true for a step with no clock and no distance cap — the watch shows no countdown and advances only when the athlete presses lap, e.g. {"name": "Warm-up", "duration_open": true, "intensity_low": 120, "intensity_high": 150}. Intensity bounds still show as a guide zone but never end the step. Because an open step's length is unknowable ahead of time, it counts toward neither total_minutes nor distance_meters_total, and the response carries a warning saying so.
Exactly one of the three keys (duration_minutes, duration_meters, duration_open) per step.
sport_type: 2 = Indoor Cycling (default), 200 = Road Bike
Returns: workout_id, name, total_minutes, distance_meters_total, steps_count, message
save_strength_workout_template
Save a reusable strength workout template to the Coros library. Exercises must come from the Coros exercise catalogue.
⚠️ This persists to the library indefinitely. For a one-off workout for a specific date, use
schedule_strength_workoutinstead — it builds the workout inline and leaves no library entry.
{
"name": "Leg Circuit",
"sets": 3,
"exercises": [
{
"origin_id": "54",
"name": "T1061",
"overview": "sid_strength_squats",
"target_type": 3,
"target_value": 12,
"rest_seconds": 45,
"sets": 3,
"weight_kg": 80
},
{
"origin_id": "130",
"name": "T1176",
"overview": "sid_strength_plank",
"target_type": 2,
"target_value": 60,
"rest_seconds": 30
}
]
}target_type: 2 = time in seconds, 3 = reps
sets (per exercise, optional): consecutive sets of that exercise before moving on. Use this instead of duplicating the exercise entry. Defaults to 1.
sets (top-level): full-circuit repetitions — repeats the entire exercise list. Defaults to 1.
Weight fields (per exercise, optional):
Field | Description |
| Prescribed weight in kg (e.g. |
| Prescribed weight in pounds (e.g. |
Omitting both fields renders the exercise as Bodyweight in the Coros app.
Setting
weight_kg: 0renders as "0.00 kg" — distinct from Bodyweight.For dumbbell exercises, the weight is per hand by convention (the app shows a single value).
kg and lbs can be mixed across exercises within the same workout.
Returns: workout_id, name, sets, exercise_count
delete_workout_template
Delete a saved workout template from the Coros library.
{ "workout_id": "476023839273435149" }The workout_id comes from list_workout_templates.
Returns: deleted, workout_id, message
list_planned_activities
List planned activities from the Coros training calendar.
{ "start_day": "20260309", "end_day": "20260316" }Returns: schedule (dict with entities and programs sub-lists), count (number of scheduled entities), date_range
schedule_workout
Schedule a one-off cycling/intervals workout for a specific date. Builds the workout inline and posts straight to the calendar — does not create a library entry. This is the common case.
Same parameters as save_workout_template, plus happen_day (YYYYMMDD) and an optional sort_no (order within the day).
{
"name": "Z2 Recovery",
"happen_day": "20260312",
"sport_type": 2,
"steps": [
{"name": "Easy spin", "duration_minutes": 60, "intensity_low": 150, "intensity_high": 200}
]
}Returns: scheduled, name, happen_day, total_minutes, steps_count, response
schedule_strength_workout
Schedule a one-off strength workout for a specific date. Builds the workout inline and posts straight to the calendar — does not create a library entry.
Same parameters as save_strength_workout_template, plus happen_day.
{
"name": "Push Day",
"happen_day": "20260312",
"sets": 1,
"exercises": [ ... ]
}Returns: scheduled, name, happen_day, sets, exercise_count, response
schedule_workout_template
Schedule an existing library template on a calendar day.
{ "workout_id": "1234567890", "happen_day": "20260312", "sort_no": 1 }The workout_id comes from list_workout_templates. For one-off workouts that don't need a library entry, use schedule_workout or schedule_strength_workout instead.
Returns: scheduled, workout_id, happen_day, response
remove_scheduled_workout
Remove a scheduled workout from the Coros training calendar.
{
"plan_id": "987654321",
"id_in_plan": "1234567890",
"plan_program_id": "1234567890"
}plan_id, id_in_plan, and plan_program_id come from list_planned_activities. If plan_program_id is missing, you can usually reuse id_in_plan.
Returns: removed, plan_id, id_in_plan
list_exercises
List the Coros exercise catalogue for a sport type. Default sport_type=4 returns strength exercises.
{ "sport_type": 4 }Returns: exercises (list), count, sport_type
sync_coros_data
Backfill all data into the local SQLite cache for a date range. After the first full sync, get_daily_metrics, get_sleep_data, and list_activities serve historical data from cache and only fetch the incremental tail from the API.
{ "start_day": "20230101", "end_day": "20260514" }Both parameters are optional and default to two years ago / today respectively. For large ranges (> 6 months) prefer the CLI:
coros-mcp sync --from 20230101Returns: daily (records synced), sleep (records synced), activities (records synced), errors (list), cache (coverage summary)
get_cache_status
Show what data is currently stored in the local SQLite cache.
{}Returns per data type: count, from (earliest date), to (latest date). Also includes db_path.
Requirements
Python ≥ 3.11
A Coros account (Training Hub)
Project Structure
coros-mcp/
├── coros_mcp/
│ ├── server.py # MCP server with tool definitions
│ ├── coros_api.py # Coros API client (auth, requests, parsers)
│ ├── models.py # Pydantic data models
│ ├── cli.py # CLI entry point (serve, auth, sync, cache-status, …)
│ ├── auth/ # Token storage (keyring + encrypted file fallback)
│ └── cache/ # SQLite cache layer (store, sync, utils)
├── tests/ # pytest test suite
├── pyproject.toml # Project metadata & dependencies
└── docs/
└── mobile-token.md # Mobile API token background (legacy reference)Dependencies
fastmcp — MCP framework
httpx — Async HTTP client
pydantic — Data validation
cryptography — AES encryption (mobile API auth + token file)
keyring — Secure token storage
python-dotenv —
.envsupport
Disclaimer
This project uses the unofficial Coros Training Hub API. The API may change at any time without notice. Use at your own risk.
Available Tools
26 toolsadd_planned_workoutA
Add an inline planned workout to the Coros training calendar.
This is a low-level escape hatch for callers that already hold raw entity / program objects (e.g. copied from list_planned_activities_raw). For the common case of building and scheduling a workout, prefer schedule_workout.
Inputs: entity (required), program (required), version_object. Returns: object
authenticate_corosA
Authenticate with the Coros Training Hub API and store the access token.
Inputs: email (required), password (required), region. Returns: object
authenticate_coros_mobileA
Authenticate with the Coros mobile API only and store the mobile token.
This is needed for sleep data (deep/light/REM/awake phases) which is only available through the mobile API (apieu.coros.com), not the Training Hub web API.
Inputs: email (required), password (required), region. Returns: object
calculate_workout_programARead-only
Recalculate a workout program after editing its exercises.
This calls Coros /training/program/calculate and returns the calculated metrics plus a copy of the supplied program with derived fields such as duration, estimated distance, training load, and exerciseBarChart applied. Feed the returned program into update_scheduled_workout when its exercises changed.
Inputs: program (required). Returns: object
check_coros_authARead-only
Check whether valid Coros access tokens are stored locally.
By default this is a LOCAL check only: authenticated: true means the stored
token has not passed its 24h TTL by the local clock — it does NOT confirm the
token is still accepted by Coros. A token can be revoked server-side (password
change, account lock) or invalidated early and still report authenticated here;
the next real data call would then fail with an auth error (which triggers a
re-login retry). expires_in_hours is likewise a local TTL estimate.
Inputs: verify_with_server. Returns: object
delete_workout_templateADestructive
Delete a saved workout TEMPLATE from the Coros library.
Inputs: workout_id (required). Returns: object
get_activity_detailARead-only
Fetch detail for a single Coros activity.
Inputs: activity_id (required), sport_type. Returns: object
get_cache_statusARead-only
Show what data is currently stored in the local cache.
Returns
dict with keys: daily_records, sleep_records, activities — each with:
count: number of cached records
from: earliest cached date (YYYYMMDD)
to: latest cached date (YYYYMMDD) Also includes db_path: absolute path to the SQLite file.
Inputs: no named parameters. Returns: object
get_daily_metricsARead-only
Retrieve nightly HRV and daily metrics from Coros for a configurable time range (up to 52 weeks).
Historical data is served from the local SQLite cache (fast); only the uncached tail is fetched from the Coros API. The underlying API endpoint supports up to 24 weeks per call; the cache layer fetches longer uncached ranges in 12-week chunks, so any range up to 52 weeks works even on a cold cache.
Inputs: weeks. Returns: object
get_helpARead-only
List all available Coros MCP tools with a short description of each.
Inputs: no named parameters. Returns: object
get_sleep_dataARead-only
Fetch nightly sleep data from Coros for a configurable time range.
Returns per-night sleep stage breakdown (deep, light, REM, awake) and sleep heart rate for each night. Data comes from the Coros mobile API (apieu.coros.com) which is separate from the Training Hub web API.
Inputs: weeks. Returns: object
list_activitiesCRead-only
List Coros activities for a date range.
Inputs: end_day (required), start_day (required), page, size. Returns: object
list_exercisesARead-only
List the exercise catalogue for a given sport type.
Useful for resolving strength/conditioning exercises (sport_type=4) that appear in planned workouts by name and ID.
Inputs: sport_type. Returns: object
list_planned_activitiesARead-only
List planned (scheduled) activities from the Coros training calendar.
Inputs: end_day (required), start_day (required). Returns: object
list_planned_activities_rawARead-only
List planned activities without stripping API fields.
Use this before updating an existing scheduled workout. The raw entity and program objects contain the identifiers and version fields required by update_scheduled_workout (planId, planProgramId, idInPlan, version, ...).
Inputs: end_day (required), start_day (required). Returns: object
list_training_plansBRead-only
List training plans in the Coros account.
Inputs: status_list. Returns: object
list_training_plans_rawARead-only
List training plans without stripping API fields.
Use this when the full plan payload is needed, including entities and programs (e.g. to drive update_scheduled_workout).
Inputs: status_list. Returns: object
list_workout_templatesARead-only
List reusable workout templates saved in the Coros library.
These are templates created by save_workout_template / save_strength_workout_template — schedulable later via schedule_workout_template. One-off workouts scheduled with schedule_workout / schedule_strength_workout do NOT appear here.
Returns
dict with keys: workouts (list), count Each entry contains: id, name, sport_type, sport_name, estimated_time_seconds, exercise_count, exercises (list of steps with name, intensity_low, intensity_high, sets, and either duration_seconds for time-based steps or distance_meters for distance-based steps)
Inputs: no named parameters. Returns: object
remove_scheduled_workoutADestructive
Remove a scheduled workout from the Coros training calendar.
Inputs: plan_id (required), id_in_plan (required), plan_program_id. Returns: object
save_strength_workout_templateA
Save a REUSABLE strength workout TEMPLATE to the Coros library.
⚠️ This persists to the library indefinitely. Use ONLY when the user explicitly asks to "save as a template", "create a workout in my library", "add to my workout list".
For a ONE-OFF workout for a specific date — the common case — use schedule_strength_workout instead. That tool builds the workout inline and leaves no library residue.
If the user's intent is unclear, ASK THEM: "Do you want this saved as a reusable template in your library, or just scheduled as a one-off for [date]?" Don't guess.
Inputs: name (required), exercises (required), sets. Returns: object
save_workout_templateA
Save a REUSABLE cycling/intervals/running workout TEMPLATE to the Coros library.
⚠️ This persists to the library indefinitely. Use ONLY when the user explicitly asks to "save as a template", "create a workout in my library", "add to my workout list", or otherwise indicates they want a reusable template.
For a ONE-OFF workout for a specific date — the common case — use schedule_workout instead. That tool builds the workout inline and leaves no library residue.
If the user's intent is unclear, ASK THEM: "Do you want this saved as a reusable template in your library, or just scheduled as a one-off for [date]?" Don't guess.
The saved template appears in the Coros app under Workouts and can be synced to the watch for guided execution.
Inputs: name (required), steps (required), sport_type, intensity_type. Returns: object
schedule_strength_workoutA
Schedule a ONE-OFF strength workout for a specific date.
This is the COMMON case. Use this whenever the user wants a strength workout on a specific date and doesn't explicitly ask for a reusable template. Does NOT save to the Coros library — leaves no template behind.
For a REUSABLE library template instead, use save_strength_workout_template (which saves it for re-scheduling later via schedule_workout_template).
If the user's intent is unclear, ASK THEM: "Do you want this saved as a reusable template in your library, or just scheduled as a one-off for [date]?" Don't guess.
Inputs: name (required), exercises (required), happen_day (required), sets, +1 more. Returns: object
schedule_workoutA
Schedule a ONE-OFF cycling/intervals/running workout for a specific date.
This is the COMMON case. Use this whenever the user wants a workout on a specific date and doesn't explicitly ask for a reusable template. Does NOT save to the Coros library — leaves no template behind.
For a REUSABLE library template instead, use save_workout_template (which saves it for re-scheduling later via schedule_workout_template).
If the user's intent is unclear, ASK THEM: "Do you want this saved as a reusable template in your library, or just scheduled as a one-off for [date]?" Don't guess.
Inputs: name (required), steps (required), happen_day (required), sort_no, +2 more. Returns: object
schedule_workout_templateA
Add an existing library workout TEMPLATE to the training calendar.
Use this only when scheduling a previously-saved template by ID. For a one-off workout that doesn't need to live in the library, use the inline tools instead: schedule_workout (cycling/intervals) or schedule_strength_workout (strength).
Inputs: happen_day (required), workout_id (required), sort_no. Returns: object
sync_coros_dataAIdempotent
Sync Coros data for a date range into the local SQLite cache.
After the first full sync, subsequent calls to get_daily_metrics, get_sleep_data, and list_activities will serve historical data from cache and only fetch the incremental tail from the API.
For large date ranges (> 6 months), call this tool in segments to avoid timeout (e.g. one segment per year). For the initial full historical backfill, use the CLI instead: coros-mcp sync --from 20230101
Inputs: end_day, start_day. Returns: object
update_scheduled_workoutADestructive
Update an existing scheduled workout on the Coros training calendar.
Workflow: fetch the day with list_planned_activities_raw, edit the entity / program objects, and (if exercises changed) run them through calculate_workout_program first to refresh derived metrics.
Inputs: entity (required), program (required), version_object. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 26 tools
Most tools have clearly distinct purposes, and the descriptions are careful to distinguish one-off scheduling from reusable templates and raw from cleaned list variants. However, the cluster of scheduling tools (schedule_workout, schedule_strength_workout, schedule_workout_template, add_planned_workout) and the paired raw/non-raw list tools still create some potential for misselection.
The vast majority of tools follow a clear verb_noun pattern (list_, get_, save_, schedule_, delete_, update_, remove_). Minor inconsistencies exist, such as add_planned_workout vs. schedule_workout and the raw suffix on only some list tools, but overall the naming is predictable and readable.
With 26 tools, the server crosses the threshold where the surface feels too heavy for an agent to navigate comfortably. Many tools are individually justified, but the raw variants, cache management utilities, and multiple scheduling entry points add notable bulk.
The tool set covers the core Coros workflows well: authentication, metrics and sleep retrieval, activity listing/detail, workout template CRUD, scheduled workout create/update/remove, and cache syncing. Minor gaps exist, such as no dedicated create/delete training plan tools or a single planned-activity getter, but raw list and calculate tools provide workarounds.
Maintenance
Related MCP Connectors
Adaptive running coach MCP server — training data, plans, and recovery for AI assistants.
Pace is a remote MCP server that exposes wearable and fitness data to Claude via the Model Context Protocol. It connects to Garmin, Oura, Whoop, Polar, Fitbit and 20+ devices and provides 15 tools for querying sleep, activity, recovery, and training data. Hosted on Google Cloud Run, OAuth 2.1 authentication, Streamable HTTP transport. Instructions: First you need to create an account at: https://pacetraining.co and connect your wearables. After that you can connect the remote Server via Custom Connector in Claude and OAuth 2.1 Flow startet.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Hosted Apple Health MCP: workouts, sleep and HRV in ChatGPT, Claude, Gemini, Grok. Free, no export.
Related MCP Servers
- AlicenseAqualityDmaintenanceA Model Context Protocol (MCP) server for Intervals.icu integration. Access your training data, wellness metrics, and performance analysis through Claude and other LLMs.4839MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server that gives Claude access to your WHOOP biometric data — recovery, sleep, strain, and workouts.39 npmMIT
- AlicenseNot gradedqualityDmaintenanceThis Model Context Protocol (MCP) server connects to Garmin Connect and exposes your fitness and health data to Claude and other MCP-compatible clients.1MIT
- AlicenseNot gradedqualityBmaintenanceA Model Context Protocol (MCP) server that brings your Withings health data into Claude, allowing natural conversation access to sleep patterns, body measurements, workouts, heart data, and more.45MIT