Skip to main content
Glama
hhopke
by hhopke

Icu Update Sport Settings

icu_update_sport_settings
Idempotent

Update FTP, FTHR, pace and swim thresholds or explicit heart-rate/power zones for a sport; changes apply to future activities while past activities keep their original zones.

Instructions

Update sport settings: FTP, FTHR, pace/swim thresholds, or explicit HR/power zones.

Explicit zones replace the threshold-derived ones (e.g. to match a lab test). Changes apply from now on; past activities keep the zones they were analysed with. To re-zone past activities, tell the user to use Update zones in the Intervals.icu activity list view (not in the API).

Input Schema

NameRequiredDescriptionDefault
ftpNoFunctional Threshold Power in watts (for cycling)
fthrNoFunctional Threshold Heart Rate in bpm
max_hrNoMax HR in bpm. Optional with hr_zones (taken from the last bound); if sent, it must equal that bound
hr_zonesNoExplicit HR zone upper bounds in bpm, strictly increasing (e.g. lab VT1/VT2). The last bound is the max HR: Intervals.icu sets max_hr to it
sport_idYesID of the sport settings to update
athlete_idNoAthlete ID (for coaches managing multiple athletes)
indoor_ftpNoIndoor Functional Threshold Power in watts (for cycling)
hr_zone_namesNoOne name per hr_zones bound
pace_thresholdNoThreshold pace in min/km (e.g., 4.5 for 4:30/km)
sweet_spot_maxNoSweet spot upper bound, % of FTP
sweet_spot_minNoSweet spot lower bound, % of FTP
swim_thresholdNoSwim threshold in min/100m (e.g., 1.5 for 1:30/100m)
recalc_hr_zonesNoRescale HR zones when fthr changes. Explicit lab zones are rescaled too; pass false to keep them. Zones sent in the same call are kept either way
power_zone_namesNoOne name per power_zones_percent_ftp bound
power_zones_percent_ftpNoExplicit power zone upper bounds as % of FTP (not watts), strictly increasing, each <= 200; a final 999 makes the top zone open-ended

Output Schema

NameRequiredDescriptionDefault
resultYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv5.4.0
    • changedInput schema / properties / hr_zones / description
      Previous value: -"Explicit HR zone upper bounds in bpm, strictly increasing (e.g. lab VT1/VT2). The last bound becomes max_hr"New value: +"Explicit HR zone upper bounds in bpm, strictly increasing (e.g. lab VT1/VT2). The last bound is the max HR: Intervals.icu sets max_hr to it"
    • changedInput schema / properties / max_hr / description
      Previous value: -"Max HR in bpm; must equal the last hr_zones bound"New value: +"Max HR in bpm. Optional with hr_zones (taken from the last bound); if sent, it must equal that bound"
    • changedInput schema / properties / power_zones_percent_ftp / description
      Previous value: -"Explicit power zone upper bounds as % of FTP (not watts), strictly increasing; 999 as the last value makes the top zone open-ended"New value: +"Explicit power zone upper bounds as % of FTP (not watts), strictly increasing, each <= 200; a final 999 makes the top zone open-ended"
  2. Changed8 schema fields changedv5.2.0
    • addedInput schema / properties / hr_zone_names
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "One name per hr_zones bound"
      +}
    • addedInput schema / properties / hr_zones
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "integer"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Explicit HR zone upper bounds in bpm, strictly increasing (e.g. lab VT1/VT2). The last bound becomes max_hr"
      +}
    • addedInput schema / properties / max_hr
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Max HR in bpm; must equal the last hr_zones bound"
      +}
    • addedInput schema / properties / power_zone_names
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "One name per power_zones_percent_ftp bound"
      +}
    • addedInput schema / properties / power_zones_percent_ftp
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "integer"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Explicit power zone upper bounds as % of FTP (not watts), strictly increasing; 999 as the last value makes the top zone open-ended"
      +}
    • changedInput schema / properties / recalc_hr_zones / description
      Previous value: -"Recalculate HR zones from the updated threshold heart rate"New value: +"Rescale HR zones when fthr changes. Explicit lab zones are rescaled too; pass false to keep them. Zones sent in the same call are kept either way"
    • addedInput schema / properties / sweet_spot_max
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Sweet spot upper bound, % of FTP"
      +}
    • addedInput schema / properties / sweet_spot_min
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Sweet spot lower bound, % of FTP"
      +}
  3. Changed1 schema field changedv5.0.1
    • addedInput schema / properties / athlete_id
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Athlete ID (for coaches managing multiple athletes)"
      +}
  4. Changed2 schema fields changedv4.2.0
    • addedInput schema / properties / indoor_ftp
      Added value: +{
      +  "anyOf": [
      +    {
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "default": null,
      +  "description": "Indoor Functional Threshold Power in watts (for cycling)"
      +}
    • addedInput schema / properties / recalc_hr_zones
      Added value: +{
      +  "default": true,
      +  "description": "Recalculate HR zones from the updated threshold heart rate",
      +  "type": "boolean"
      +}
  5. First observedv0.1.0

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly=false, destructive=false, idempotent=true, openWorld=true), so the description's value-add is the mutation semantics it discloses: explicit zones replace threshold-derived zones, and changes are forward-only with past activities retaining their original zones. Missing only permission/auth context, which openWorldHint partly signals.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the resource and field list, then consequences, then the workaround. No filler, though the parenthetical '(e.g. to match a lab test)' is decorative rather than load-bearing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations are present, so the remaining burden is mutation semantics — and one key question is unanswered: whether omitted optional parameters are left untouched or cleared, and whether sending only ftp triggers any zone recalculation. For a 15-parameter mutation tool that gap matters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each of the 15 parameters is documented with units and formats, so the baseline is 3. The description adds one genuine concept the schema does not — that hr_zones/power_zones_percent_ftp override the threshold-derived zones rather than composing with them — but offers no guidance on the threshold-vs-indoor or sweet-spot parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ('update') plus resource ('sport settings') immediately followed by the exact set of updatable fields (FTP, FTHR, pace/swim thresholds, HR/power zones). The verb distinguishes it cleanly from the siblings icu_get_sport_settings and icu_create_sport_settings without needing to open any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a strong 'when-not': changes only apply going forward, and past re-zoning must be done by the user in the Intervals.icu activity list view, not via the API. That prevents a whole class of failed attempts, though it doesn't state prerequisites such as when athlete_id is needed or when to prefer create_sport_settings over update.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools