Skip to main content
Glama
coros-training-mcp

coros-training-mcp

by dholliday3

coros-training-mcp

Running-first MCP server for COROS. Author, edit, and schedule running workouts — pace-based intervals, distance targets, repeat groups, clone-and-swap edits — plus sleep, HRV, training load, and activity exports.

Runs locally as a stdio subprocess of your AI assistant. No API key required, no public endpoint. Credentials live in your OS keyring; traffic is outbound only, directly to COROS.

Landing page & screenshots: https://dholliday3.github.io/coros-training-mcp/

Install

uv tool install coros-training-mcp
coros-mcp setup

(pipx install coros-training-mcp works too.) The wizard asks for your COROS email, password, and region, verifies them against the API, stores them in your system keyring, detects which AI assistants you have installed (Claude Code, Claude Desktop, Codex CLI, Cursor), writes the MCP entry for each one you pick (preserving any existing entries), and runs a smoke test.

Requirements: Python ≥ 3.11 (uv tool install fetches it automatically), a COROS Training Hub account, macOS / Linux / Windows.

Lifecycle:

coros-mcp setup --reconfigure   # change credentials or add more assistants
coros-mcp uninstall             # remove from assistants, optionally clear keyring
coros-mcp auth-status           # check stored tokens
uv tool upgrade coros-training-mcp

Related MCP server: garmin-coach-mcp

What you can ask

Running workouts (the focus):

  • "Create a 5×1km threshold workout at 4:05–4:15/km with 2-minute jog recovery"

  • "Change my Tuesday VO2 workout to 6 reps instead of 5"

  • "Build a 90-minute long run with 4×8min at marathon pace in the middle"

  • "Move Thursday's tempo run to Friday"

  • "Replace my scheduled Sunday long run with a 16km progression at easy→steady"

Recovery & training data:

  • "How much deep sleep and REM did I get last week?"

  • "What was my HRV trend over the last 4 weeks?"

  • "Show me resting HR and training load for last week"

Activities, schedule, and other sports:

  • "List my rides from last month"

  • "Export my Saturday long run to GPX"

  • "What's on my training calendar next week?"

  • "Create a 90-minute sweet spot workout"

  • "Create a 20-minute strength circuit with squats, lunges, and planks"

Tools

Tool

Description

create_run_workout

Create a run with pace/HR/distance targets, repeat groups

update_run_workout

Clone-and-edit a running workout using run-specific step patches

get_run_workout_schema

Shared run-step schema used by create + update

create_bike_workout

Create a cycling workout with power/HR/time/distance targets, repeat groups

update_bike_workout

Clone-and-edit a cycling workout using bike-specific step patches

get_bike_workout_schema

Shared bike-step schema used by create + update

create_strength_workout

Build a strength circuit from the COROS exercise catalog

get_strength_workout_schema

Strength-step schema (reps, time, rest, exercise swap)

update_workout

Generic clone-and-patch primitive (strength & cycling)

create_workout

Generic time-and-power builder (legacy cycling path — prefer create_bike_workout)

list_workouts / get_workout / delete_workout

Manage the library

list_scheduled_workouts / schedule_workout

Calendar read & add

move_scheduled_workout

Move a scheduled entry to another day

replace_scheduled_workout

Swap a scheduled entry for a different workout

remove_scheduled_workout

Remove a scheduled entry

get_daily_metrics

HRV, resting HR, training load, VO₂max, stamina (n weeks)

get_sleep_data

Deep / light / REM / awake minutes, sleep HR (n weeks)

list_activities / get_activity_detail

Completed activity listing + detail

export_activity_file

Download a completed activity as GPX / FIT / TCX / KML / CSV

list_exercises

Browse the COROS exercise catalog

get_workout_builder_catalog

Live-extracted enum registry for workout authoring

authenticate_coros / check_coros_auth

Explicit login & status (usually automatic)

Workout taxonomy

Three distinct objects that are easy to confuse:

  • Library workout — reusable program in your account. Queried by list_workouts.

  • Scheduled entry — calendar occurrence of a workout on a specific day. Queried by list_scheduled_workouts. Has different IDs than its source workout.

  • Plan container — higher-level training plan that owns scheduled entries.

Full detail: docs/workout-taxonomy.md. Enum-extraction mechanics: docs/enum-extraction.md.

Export (GPX / FIT / TCX / KML / CSV) applies to completed activities only — structured library workouts use a separate share flow in the COROS app. The MCP writes to COROS server state; device sync is still handled by the app/watch.

Privacy & data handling

  • Credentials: system keyring (macOS Keychain / Windows Credential Manager / freedesktop Secret Service). If the keyring is unavailable (headless Linux, some VMs), the wizard falls back to an AES-encrypted file at ~/.coros-mcp/credentials.enc and tells you.

  • Assistant config entries: live in each assistant's own config file. Only a coros entry is added or replaced; other MCP entries are never touched.

  • Network: outbound TLS only, directly to teamapi.coros.com / teameuapi.coros.com / apieu.coros.com. No telemetry, no analytics, no third-party services.

  • Binary: coros-mcp lives in the uv tool / pipx isolated venv at an absolute path that MCP clients pin to.


Tool reference

Auth — authenticate_coros, authenticate_coros_mobile, check_coros_auth

You normally don't call these directly — credentials from the keyring or .env are picked up automatically. They exist for explicit login/reauth ({ "email", "password", "region" }) and status checks (check_coros_auth returns authenticated, expires_in_hours, mobile_authenticated, mobile_token_status). authenticate_coros_mobile is useful for restoring sleep-data access without redoing web auth.

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

—

Date (YYYYMMDD)

avg_sleep_hrv

dayDetail

Nightly HRV (RMSSD ms)

baseline

dayDetail

HRV rolling baseline

rhr

dayDetail

Resting heart rate (bpm)

training_load

dayDetail

Daily training load

training_load_ratio

dayDetail

Acute/chronic training load ratio

tired_rate

dayDetail

Fatigue rate

ati / cti

dayDetail

Acute / chronic training index

distance / duration

dayDetail

Distance (m) / duration (s)

vo2max

analyse (merge)

VO2 Max (last ~28 days)

lthr

analyse (merge)

Lactate threshold heart rate (bpm)

ltsp

analyse (merge)

Lactate threshold pace (s/km)

stamina_level

analyse (merge)

Base fitness level

stamina_level_7d

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, count, date_range. Each record includes date, total_duration_minutes, phases.{deep,light,rem,awake,nap}_minutes, avg_hr, min_hr, max_hr, quality_score.

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 auth obtains both, but doing so logs you out of the COROS mobile app on your phone. Use coros-mcp auth-web (or let the wizard's default skip-mobile choice stand) — the mobile token is then fetched lazily on the first sleep-data request and refreshed automatically.

list_activities

{ "start_day": "20260101", "end_day": "20260305", "page": 1, "size": 30 }

Returns: activities, 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, training_load, avg_power, normalized_power, elevation_gain.

get_activity_detail

{ "activity_id": "469901014965714948", "sport_type": 200 }

Full activity data including laps, HR zones, power zones, and sport-specific metrics. Large time-series arrays (graphList, frequencyList, gpsLightDuration) are stripped to keep the response manageable.

export_activity_file

{
  "activity_id": "469901014965714948",
  "sport_type": 100,
  "file_type": "gpx",
  "output_path": "/tmp/morning-run.gpx"
}

file_type: gpx, fit, tcx, kml, or csv. Returns activity_id, sport_type, file_type, file_url, output_path, downloaded.

list_workouts

{}

Returns workouts, count. Each workout includes id, name, sport_type, sport_name, estimated_time_seconds, exercise_count, exercises (steps with name, duration_seconds, power_low_w, power_high_w).

create_run_workout

Run-native step kinds (warmup, training, rest, cooldown), distance / time / open targets, optional pace / HR intensity ranges, nested repeat groups.

{
  "name": "Tuesday Threshold",
  "steps": [
    {"kind": "warmup",   "name": "Warm-up",  "target_type": "distance", "target_distance_meters": 2000},
    {"repeat": 5, "name": "Main Set", "steps": [
      {"kind": "training", "name": "Rep",      "target_type": "distance", "target_distance_meters": 1000,
       "intensity_type": 3, "intensity_value": 245, "intensity_value_extend": 255, "intensity_display_unit": 2},
      {"kind": "rest",     "name": "Recovery", "target_type": "time",     "target_duration_seconds": 120}
    ]},
    {"kind": "cooldown", "name": "Cool-down", "target_type": "distance", "target_distance_meters": 1500}
  ]
}

Pace targets use intensity_type: 3 with intensity_value / intensity_value_extend as seconds-per-km and intensity_display_unit: 2. Friendly pace strings like "4:05-4:15/km" or "5:30/mi" are also accepted on any run step as a "pace" field. For the full field vocabulary (HR zones, percent-of-LT, named intensity presets) call get_run_workout_schema or see run_workout_schema.py.

Open steps. "target_type": "open" is the Training Hub "Open" target (COROS targetType=1, manualEnd): the step has no target and runs until the athlete presses the lap button. Omit target_duration_seconds / target_distance_meters — they're ignored. This is how you author an open warm-up or cool-down so the athlete, not the watch, decides the length:

{
  "name": "Sub-T 3×6min",
  "steps": [
    {"kind": "warmup", "name": "WU open", "target_type": "open"},
    {"repeat": 3, "steps": [
      {"kind": "training", "name": "Sub-T 6min", "target_type": "time", "target_duration_seconds": 360,
       "intensity_label": "Heart Rate", "intensity_value": 168, "intensity_value_extend": 175},
      {"kind": "rest", "name": "Jog", "target_type": "time", "target_duration_seconds": 120}
    ]},
    {"kind": "cooldown", "name": "CD open", "target_type": "open"}
  ]
}

Open steps contribute nothing to the workout's estimated time/distance — only the targeted steps do. "manual" and "lap" are accepted aliases. Works the same on create_bike_workout, and on the update_* patch path (switching a step to open clears its stale target).

Returns: workout_id, sport_type, estimated_time_seconds, estimated_distance_meters, steps_count, message.

update_run_workout

Clone-and-edit an existing running workout. Select each step by step_name, step_id, or step_index and patch it with any run-step field used by create_run_workout. Original is preserved; a new workout ID is returned. If the original was scheduled, use replace_scheduled_workout (or schedule_workout) to swap the calendar entry.

{
  "workout_id": "476023839273435149",
  "name": "Tuesday Threshold (6×1km)",
  "step_updates": [
    {"step_name": "Main Set", "repeat": 6},
    {"step_name": "Rep", "target_distance_meters": 1000, "intensity_value": 240, "intensity_value_extend": 250}
  ]
}

Returns: new_workout_id, original_workout_id, name, steps_count, message.

get_run_workout_schema

Returns the shared schema used by create_run_workout and update_run_workout: allowed step kinds, target types, intensity presets pulled from the live Training Hub builder, and required vs. optional fields. Call this before authoring to avoid guessing.

create_bike_workout

Bike-native step kinds (warmup, training, rest, cooldown), time / distance / open targets, optional power / HR / cadence / FTP-percent intensity, nested repeat groups. Sets sportType=2 so warm-up / training / rest / cool-down segments render correctly on the watch (unlike create_workout, which builds flat training blocks).

{
  "name": "3×15 Sweetspot",
  "steps": [
    {"kind": "warmup",   "name": "Warm-up",  "target_type": "time", "target_duration_seconds": 600, "power": "120-160W"},
    {"repeat": 3, "name": "Main Set", "steps": [
      {"kind": "training", "name": "Sweetspot", "target_type": "time", "target_duration_seconds": 900, "power": "230-260W"},
      {"kind": "rest",     "name": "Recovery",  "target_type": "time", "target_duration_seconds": 180}
    ]},
    {"kind": "cooldown", "name": "Cool-down", "target_type": "time", "target_duration_seconds": 600}
  ]
}

Power targets use intensity_type: 6 with intensity_value / intensity_value_extend in watts. Friendly strings like "220W" or "220-260W" are also accepted on any bike step as a "power" field. Raw intensity fields work for HR, cadence, FTP-percent, and speed targets. For the full field vocabulary call get_bike_workout_schema or see bike_workout_schema.py.

Returns: workout_id, sport_type, sport_name, estimated_time_seconds, estimated_distance_meters, steps_count, message.

update_bike_workout

Clone-and-edit an existing cycling workout. Select each step by step_name, step_id, or step_index and patch it with any bike-step field used by create_bike_workout. Original is preserved; a new workout ID is returned. If the original was scheduled, use replace_scheduled_workout (or schedule_workout) to swap the calendar entry.

{
  "workout_id": "476023839273435149",
  "name": "4×15 Sweetspot",
  "step_updates": [
    {"step_name": "Sweetspot", "target_duration_seconds": 900, "power": "240-270W"}
  ]
}

get_bike_workout_schema

Returns the shared schema used by create_bike_workout and update_bike_workout. Intensity label presets (Power, %FTP, Heart Rate, Cadence, Speed, etc.) are pulled from the checked-in live Training Hub builder catalog. If the catalog hasn't yet been recaptured to include bike correlations, the preset list will be empty and you should pass the raw intensity_* fields or use the power ergonomic directly.

create_workout

Generic time-and-power builder (legacy cycling path). For cycling, prefer create_bike_workout — it understands segment kinds (warm-up / training / rest / cool-down) and renders them correctly on the watch. For running, use create_run_workout.

{
  "name": "3×10min Sweet Spot",
  "sport_type": 2,
  "steps": [
    {"name": "Warmup",   "duration_minutes": 10, "power_low_w": 150, "power_high_w": 200},
    {"repeat": 3, "steps": [
      {"name": "Sweet Spot", "duration_minutes": 10, "power_low_w": 265, "power_high_w": 285},
      {"name": "Recovery",   "duration_minutes":  3, "power_low_w": 150, "power_high_w": 175}
    ]},
    {"name": "Cooldown", "duration_minutes": 11, "power_low_w": 150, "power_high_w": 200}
  ]
}

sport_type: 2 = Indoor Cycling (default), 200 = Road Bike.

update_workout

Lower-level clone-and-patch primitive used by update_run_workout and for strength edits. Patch steps/exercises by step_name, step_id, step_index, or origin_id (strength exercise swap). Supports rest_seconds, target_type (time|reps|distance), and any field the create side accepts.

delete_workout

{ "workout_id": "476023839273435149" }

list_planned_activities / list_scheduled_workouts

{ "start_day": "20260309", "end_day": "20260316" }

Returns scheduled entries for the window, including library-sourced and plan-embedded programs. Use list_scheduled_workouts for the canonical MCP-facing shape.

schedule_workout

{ "workout_id": "1234567890", "happen_day": "20260312", "sort_no": 1 }

move_scheduled_workout

Move a scheduled entry to a new day without losing the underlying workout. Handles both library-sourced entries and plan-embedded programs (which have no library counterpart).

{ "plan_id": "987654321", "id_in_plan": "1234567890", "new_happen_day": "20260314" }

replace_scheduled_workout

Swap a scheduled entry for a different workout (typically a freshly updated clone) in-place. Preserves the calendar slot and sort order.

{ "plan_id": "987654321", "id_in_plan": "1234567890", "replacement_workout_id": "476023839273435149" }

remove_scheduled_workout

{ "plan_id": "987654321", "id_in_plan": "1234567890", "plan_program_id": "1234567890" }

If plan_program_id is missing from list_planned_activities, reuse id_in_plan.

create_strength_workout

Structured strength workout with repeated sets. Exercises come from the COROS catalog (list_exercises).

{
  "name": "Leg Circuit",
  "sets": 3,
  "exercises": [
    {"origin_id": "54",  "name": "T1061", "overview": "sid_strength_squats", "target_type": 3, "target_value": 12, "rest_seconds": 45},
    {"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.

list_exercises

{ "sport_type": 4 }

sport_type=4 is strength. Returns exercises, count, sport_type.


Manual setup (advanced)

If you're not using one of the auto-detected assistants, install the server and point any MCP client at it:

uv tool install coros-training-mcp
coros-mcp auth          # interactive login, stores tokens in keyring
which coros-mcp         # absolute path for the config below
{ "mcpServers": { "coros": { "command": "/absolute/path/to/coros-mcp", "args": ["serve"] } } }

Developer setup

git clone https://github.com/dholliday3/coros-training-mcp.git
cd coros-training-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -e .[dev]
pytest

CLI reference

coros-mcp setup                 # first-time interactive setup
coros-mcp setup --reconfigure   # re-run wizard
coros-mcp uninstall             # remove from assistants
coros-mcp serve                 # start the MCP server (what MCP clients run)
coros-mcp auth                  # re-authenticate (web + mobile)
coros-mcp auth-web              # web token only (sleep data lazy-loads)
coros-mcp auth-mobile           # mobile token only
coros-mcp auth-status           # check stored tokens
coros-mcp auth-clear            # remove stored tokens

Built on top of cygnusb/coros-mcp, kept as an upstream reference.

Disclaimer

Uses the unofficial COROS Training Hub API. The API may change at any time without notice. Not affiliated with or endorsed by COROS. Use at your own risk.

Available Tools

29 tools
authenticate_corosAuthenticate CorosC

Authenticate with the Coros Training Hub API and store the access token.

Inputs: email (required), password (required), region. Returns: object

authenticate_coros_mobileAuthenticate 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

check_coros_authCheck Coros AuthA

Check whether valid Coros access tokens are stored locally.

Inputs: no named parameters. Returns: object

create_bike_workoutCreate Bike WorkoutA

Create a cycling workout with explicit bike-step semantics.

Use get_bike_workout_schema for the exact accepted fields.

Each plain step uses the shared bike-step contract:

  • kind: warmup, training, rest, cooldown, interval

  • target_type: time, distance, or open

  • target_duration_seconds or target_distance_meters (omit both for open steps — an open step has no target and runs until the athlete presses the lap button)

Optional fields include:

  • name

  • overview

  • intensity_label (values come from the checked-in live Training Hub bike correlations — common labels: Power, %FTP, Heart Rate, % Max Heart Rate, % Lactate Threshold HR, Cadence, Speed)

  • power: human string like '220W' or '220-260W', expands to intensity_type=6 with watts in intensity_value / intensity_value_extend

  • raw intensity fields like intensity_type, hr_type, is_intensity_percent, intensity_percent, intensity_percent_extend, intensity_value, intensity_value_extend, intensity_display_unit

  • rest_type

  • rest_value

  • sets

Repeat groups use:

  • repeat

  • steps

Notes:

  • The tool sets COROS cycling sportType = 2.

  • If bike intensity_label presets aren't available yet (catalog not captured), pass the raw intensity fields directly or use power.

Inputs: name (required), steps (required). Returns: object

create_run_workoutCreate Run WorkoutA

Create a running workout with explicit run-step semantics.

Use get_run_workout_schema for the exact accepted fields.

Each plain step uses the shared run-step contract:

  • kind: warmup, training, rest, cooldown, interval

  • target_type: time, distance, or open

  • target_duration_seconds or target_distance_meters (omit both for open steps — an open step has no target and runs until the athlete presses the lap button, which is how you author an open warm-up or cool-down)

Optional fields include:

  • name

  • overview

  • intensity_label

  • raw intensity fields like intensity_type, hr_type, is_intensity_percent, intensity_percent, intensity_percent_extend, intensity_value, intensity_value_extend, intensity_display_unit

  • rest_type

  • rest_value

  • sets

Repeat groups use:

  • repeat

  • steps

Repeat groups use:

  • repeat

  • steps

Notes:

  • intensity_label can now use the checked-in live Training Hub labels such as Pace, % Threshold Pace, Heart Rate, or % Max Heart Rate.

  • The tool sets COROS running sportType = 1.

Inputs: name (required), steps (required). Returns: object

create_strength_workoutCreate Strength WorkoutC

Create a new structured strength workout program.

Inputs: name (required), exercises (required), sets. Returns: object

create_workoutCreate WorkoutB

Create a new structured workout in the Coros account.

The workout appears in the Coros app under Workouts and can be synced to the watch for guided execution.

Inputs: name (required), steps (required), sport_type. Returns: object

delete_workoutDelete WorkoutC

Delete a workout program from the Coros account.

Inputs: workout_id (required). Returns: object

export_activity_fileExport Activity FileB

Export a completed Coros activity file and save it locally.

Inputs: sport_type (required), activity_id (required), file_type, output_path. Returns: object

get_activity_detailGet Activity DetailB

Fetch full detail for a single Coros activity.

Inputs: activity_id (required), sport_type. Returns: object

get_bike_workout_schemaGet Bike Workout SchemaA

Return the shared bike-step contract used by create_bike_workout and update_bike_workout.

This includes:

  • the plain-step fields accepted by create_bike_workout

  • the selector + patch fields accepted by update_bike_workout

  • the checked-in live Training Hub bike intensity labels (if captured) and their raw COROS presets

  • the human power input format ('220W', '220-260W') which expands into intensity_type=6 with watts in intensity_value / intensity_value_extend

Inputs: no named parameters. Returns: object

get_daily_metricsGet Daily MetricsA

Retrieve nightly HRV and daily metrics from Coros for a configurable time range (up to 24 weeks).

Uses the /analyse/dayDetail/query endpoint which returns daily records including HRV, resting heart rate, training load, and fatigue rate.

Inputs: weeks. Returns: object

get_run_workout_schemaGet Run Workout SchemaA

Return the shared run-step contract used by create_run_workout and update_run_workout.

This includes:

  • the plain-step fields accepted by create_run_workout

  • the selector + patch fields accepted by update_run_workout

  • the checked-in live Training Hub intensity labels and their raw COROS presets

  • the human pace input format ('4:05-4:15/km', '5:30/mi') which expands into intensity_type=3 with ms/km intensity_value / intensity_value_extend

Inputs: no named parameters. Returns: object

get_sleep_dataGet Sleep DataA

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

get_strength_workout_schemaGet Strength Workout SchemaA

Return the strength-workout field vocabulary.

This includes:

  • the exercise fields accepted by create_strength_workout

  • the step_updates patch fields accepted by update_workout when the target is a strength program (strength reuses the generic update_workout tool)

  • the target_type aliases ('time', 'reps') and how to look up exercises via list_exercises(sport_type=4)

Use this before authoring or editing a strength workout so the patch vocabulary is explicit rather than guessed.

Inputs: no named parameters. Returns: object

get_workoutGet WorkoutA

Fetch one saved workout program in detail.

Inputs: workout_id (required). Returns: object

get_workout_builder_catalogGet Workout Builder CatalogB

Return the checked-in workout builder catalog and enum registry.

The catalog combines:

  • static Training Hub enum extraction from public frontend bundles

  • live builder correlations captured from Training Hub draft calculate payloads

Inputs: sport. Returns: object

list_activitiesList ActivitiesC

List Coros activities for a date range.

Inputs: end_day (required), start_day (required), page, size. Returns: object

list_exercisesList ExercisesA

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_activitiesList Planned ActivitiesC

List planned (scheduled) activities from the Coros training calendar.

Inputs: end_day (required), start_day (required). Returns: object

list_scheduled_workoutsList Scheduled WorkoutsB

List scheduled workout entries in a calendar-friendly format.

These are calendar occurrences, not just library workouts. Each scheduled item carries plan-specific identifiers needed for move/remove/replace flows.

Inputs: end_day (required), start_day (required). Returns: object

list_workoutsList WorkoutsA

List all saved library workout programs in the Coros account.

Inputs: no named parameters. Returns: object

move_scheduled_workoutMove Scheduled WorkoutA

Move a scheduled workout to a new day.

The source-of-truth is the existing scheduled entry identified by (plan_id, id_in_plan). Its embedded program is used to re-schedule on happen_day, which supports both library workouts AND plan-embedded programs from subscribed training plans (which have no library entry).

Order of operations is schedule-new → remove-old, so a failure leaves a duplicate rather than losing the workout. A pre-flight lookup verifies the scheduled entry exists before anything destructive runs.

Inputs: plan_id (required), happen_day (required), id_in_plan (required), sort_no, +3 more. Returns: object

remove_scheduled_workoutRemove Scheduled WorkoutB

Remove a scheduled workout from the Coros training calendar.

Inputs: plan_id (required), id_in_plan (required), plan_program_id. Returns: object

replace_scheduled_workoutReplace Scheduled WorkoutA

Replace a scheduled workout by cloning the library workout, applying edits, scheduling the replacement, and removing the old scheduled entry.

Inputs: plan_id (required), happen_day (required), id_in_plan (required), name, +7 more. Returns: object

schedule_workoutSchedule WorkoutC

Add an existing workout from the library to the Coros training calendar.

Inputs: happen_day (required), workout_id (required), sort_no. Returns: object

update_bike_workoutUpdate Bike WorkoutA

Clone a cycling workout, apply bike-specific edits, and create a replacement.

Use get_bike_workout_schema for the exact accepted fields.

Each update item requires one selector:

  • step_index

  • step_id

  • step_name

After that, it accepts the same bike-step fields as create_bike_workout, including kind, target_type, target_duration_seconds, target_distance_meters, intensity_label, power, and the raw COROS intensity fields.

Inputs: workout_id (required), name, step_updates, delete_original, +2 more. Returns: object

update_run_workoutUpdate Run WorkoutA

Clone a running workout, apply run-specific edits, and create a replacement.

Use get_run_workout_schema for the exact accepted fields.

Each update item requires one selector:

  • step_index

  • step_id

  • step_name

After that, it accepts the same run-step fields as create_run_workout, including kind, target_type, target_duration_seconds, target_distance_meters, intensity_label, and the raw COROS intensity fields.

Inputs: workout_id (required), name, step_updates, delete_original, +2 more. Returns: object

update_workoutUpdate WorkoutA

Clone an existing workout, apply edits, and create a replacement workout.

Sport-agnostic: works for running, cycling, and strength library workouts. For strength-specific field vocabulary and examples, call get_strength_workout_schema. For run-specific schema, use get_run_workout_schema.

This does not mutate the original workout in place. The replacement workout is created in the library, and the caller can optionally delete the old workout afterward.

Inputs: workout_id (required), name, step_updates, delete_original, +2 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 29 tools

    Disambiguation3/5

    Most tools have distinct purposes, but there is real overlap between generic create_workout/update_workout and the sport-specific create_run_workout, create_bike_workout, create_strength_workout, update_run_workout, and update_bike_workout tools. list_planned_activities and list_scheduled_workouts also have fuzzy boundaries, and the catalog/schema tools require careful reading to distinguish.

    Naming Consistency5/5

    Tool names consistently use snake_case with a verb_noun pattern, such as list_activities, get_activity_detail, create_run_workout, and delete_workout. A few names are longer or slightly differently ordered, but the convention is predictable throughout.

    Tool Count2/5

    With 29 tools, the surface is heavy for the server's scope and likely could be consolidated. Sport-specific create/update variants plus separate schema/catalog tools and multiple scheduling tools push the count above what is comfortably scannable.

    Completeness4/5

    The server covers auth, daily metrics, sleep, activities, workout library CRUD, sport-specific workout authoring, scheduling, and exercise lookup. Minor gaps remain, such as no dedicated strength-specific update tool and limited scheduled-entry detail, but most workflows can be worked around.

    Maintenance

    ActivityInactive
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      A
      maintenance
      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, enabling natural language queries about fitness metrics and workout management.
      26
      125
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      MCP server for intervals.icu that reads training data (activities, wellness, calendar) and creates structured workouts on the calendar, which are pushed to devices like Garmin, Wahoo, Zwift, Coros, Suunto via the official API.
      136 npm
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables creating, previewing, scheduling, and managing Garmin Connect workouts, plus reading activities and health metrics, all through a local MCP server.
      11
      MIT