Complete multi-athlete support
Multi-athlete support was half-shipped: activity and event tools honoured athlete_id while 19 others — fitness, wellness, curves, sport settings, gear, workout library — silently answered for the configured default athlete. A coach asking for an athlete's CTL/ATL/TSB got their own numbers back with no error — reported by @alexxsirko (#99). All 45 athlete-scoped tools now route athlete_id consistently, fitness responses name the athlete they describe, and the new icu_list_athletes tool finally makes ids discoverable — it lists every athlete the API key can reach with each one's access level and a can_write flag, so a model knows before writing whether it may. Safe-mode tool count goes 58 → 59 (61 → 62 in full mode).
Tools that never worked, fixed
A systematic audit of every API call against the OpenAPI spec — with each finding reproduced and each fix verified against the live API — turned up a family of tools that had been broken since they shipped:
icu_search_intervalsreturned HTTP 422 on every call: wrong query-param names, and two required parameters never sent. It now works bare or filtered,interval_typeis validated against the API's real target-type enum (AUTO/POWER/HR/PACE— it was never a workout-step label), newmin_intensity/max_intensityfilters are available, and results are projected from ~180-field activity objects down to the 8 fields that matter, keeping summaries like2x 8m 162w(#102).- Gear reminders (
icu_create_gear_reminder,icu_update_gear_reminder) called endpoints that don't exist and sent fields the API has never had — three stacked defects. Creating, updating, and listing reminders now works end-to-end, andicu_get_gear_listshows real reminder content includingpercent_usedinstead of a bare id (#107). - The gear model itself read invented field names, so every gear item listed as
type: null, active: nullwith no time or activity usage, andicu_create_gearcreated untyped gear. Gear now shows its real type, retirement state, purchase date, notes, and full usage;gear_typeaccepts any casing and maps to the API's real enum;activemaps to the API's retirement date. The API has nobrand/model/primaryfields at all — those parameters are still accepted but now honestly reported as ignored (#110). - The athlete id
i123456was rejected as a placeholder — but it's a real id that simply appears in.env.example. Its actual owner couldn't use a single tool. The special-case is gone; the API is the authority on credentials (#104).
Wellness data no longer dropped
- Athlete-defined custom wellness fields (REMSleep, ActiveEnergy, …) were parsed and then silently discarded; they now appear under
custom_fieldswith their original names. Contributed by @1781412-cpu (#98). - The subjective hydration rating was dropped the same way, one layer deeper. It now surfaces alongside the other subjective metrics with its scale (
1-4, higher = more dehydrated) and is writable via a newhydrationparameter onicu_update_wellness(#109).
Notes
- The gear
brand/model/primaryparameters are deprecated in place: the API cannot store them, responses say so in a warning, and they will be removed in the next major. - Response-shape changes in this release (projected interval-search results, richer gear and reminder payloads) preserve or add information — minor under the versioning contract adopted in 4.1.0.
Full Changelog: v4.3.2...v4.4.0