Repository navigation
Conversation
…y volume Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ummary Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…and drift, hard days Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… eFTP trend Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d URLs Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tivity Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
[intervals-mcp-server] Add get_coach_report with deterministic coaching metrics
get_event_by_id called /athlete/{id}/event/{eventId}, which returns 404; the
Intervals.icu endpoint is /events/{eventId} like update and delete. Event
details now show category, sport, planned load and planned time, and detect
races from the RACE_A/B/C category.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The event list of the API has no workout object, so every event was shown as "Type: Other". Summaries now use category, type, icu_training_load and moving_time (N/A when missing), and detect races from RACE_A/B/C. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Updates sent description/moving_time/distance as null, always set category WORKOUT and moved the event to today when no date was given, so renaming an event cleared its description or turned a NOTE into a WORKOUT. None values are now dropped, category/type/date/color are only sent on update when passed, and workout_type is optional so an event can be renamed. add_or_update_event takes an optional category (e.g. RACE_A). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A future end_date treated planned days as rest days (ACWR/deload/HRV false alarms) and labelled CTL values that already included planned workouts as recomputed_without_planned. In projection mode, sections from completed training end at the last completed day, recovery refers to today, CTL/ATL/TSB at the end date are reported as api_incl_planned with load.actual and load.projected, and a plan section summarises planned workouts per week and sport (planned load, rest days, missing loads, projected CTL/ramp/TSB, races). New flags ramp_planned_high, tsb_planned_low and planned_rest_days_low; flags carry basis actual/projection. Reports without a future end date are unchanged apart from schema_version and period.mode (snapshot test). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
[intervals-mcp-server] Fix calendar tools and add planning projection to the coach report
MINS_KM, MINS_MILE, SECS_100M and SECS_500M were written as bare
numbers ("335"), which Intervals.icu does not parse as pace. They are
now written as "5:35/km Pace", with ranges like "5:30-5:40/km Pace".
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
[intervals-mcp-server] Format absolute pace targets in workout steps
get_coach_report takes an optional athlete_id (default: ATHLETE_ID). resolve_athlete_id now validates a passed ID before it reaches a URL path and treats an empty ID as the default. get_activity_details looks up gear with the athlete who owns the activity. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
futureweb
added a commit
to futureweb/intervals-mcp-server
that referenced
this pull request
Oct 9, 2026
Fixes two bugs reported in [mvilanova/intervals-mcp-server#150](mvilanova/intervals-mcp-server#150) by @morritter that also exist here: - **Event and note updates were destructive.** `add_or_update_event` / `add_or_update_note` sent unset fields as null, always set the category to WORKOUT and moved the event to today when no date was given. Renaming an event therefore cleared its description, moved it, or turned a NOTE into a WORKOUT. Updates now send only the fields that were passed; creating still needs a name and gets the defaults. New optional `category` (WORKOUT, RACE_A/B/C, TARGET, NOTE, HOLIDAY, SICK, INJURED). - **Absolute pace targets** (MINS_KM, MINS_MILE, SECS_100M, SECS_100Y, SECS_500M) were written as bare numbers that Intervals.icu does not parse; now `5:35/km Pace`, ranges `5:30-5:40/km Pace`. 16 new regression tests; 375 tests, ruff, mypy, pylint gate green. Also records the evaluation of the coach report from #150 in UPSTREAM_AUDIT and credits the reporter. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
futureweb
added a commit
to futureweb/intervals-mcp-server
that referenced
this pull request
Oct 9, 2026
… tools (after #150 by morritter) (#15) Phase 4: evidence-based training load and intensity metrics as separate read-only tools. The metric set, edge cases and quality filters come from the coach report proposed by **@morritter in upstream mvilanova/intervals-mcp-server#150**; it is re-implemented here as reusable tools on pure metric modules, with sample sizes, coverage and cited reference ranges, without flags or verdicts. ## New tools (all `read`, `output_format="json"`, `detail_level` compact/standard/full) | Tool | What it does | API calls | | --- | --- | --- | | `get_training_load` | Acute/chronic Intervals.icu load (7/28 d, configurable), coupled ACWR, Foster monotony + strain over 7 days with rest days as 0, 7-day load vs chronic weekly mean (deload-like <= 80 %), per sport family with primary sport and its own monotony (cross-training floor caveat), ISO week table, CTL/ATL/form/ramp (today recomputed without planned-but-not-done load), device loads summed separately | activities (field selection), wellness, custom items + sport settings (cached) | | `get_intensity_distribution` | Three-zone model from power/HR/pace zones with a mapping by zone count, Treff et al. 2019 polarization index (Z3 < 1 %, Z1 = 0, Z2 = 0 edge cases), class + zone order, hard sessions/days, drift between the halves, per sport and ISO week, coverage | 1 | | `get_durability` | Aerobic decoupling of steady long sessions with a quality filter (duration, pauses, HR, power/VI, temperature, indoor/outdoor), excluded sessions per reason, median/IQR, count > 5 %, last 7 d vs window with a +/- 1 pp band, EF trend (+/- 2 %), note for several bikes | 1 | | `get_load_projection` | CTL/ATL/form projected over planned WORKOUT loads (42/7-day model), missing planned loads reported, race days, Intervals.icu's own projection and a model check | 3 | | `get_coach_context` | Compact weekly overview (~2k chars): load, fitness, intensity 7/28 d, HRV/RHR/sleep vs 42-day baselines (numbers only), durability, top sessions, plan of the next 7 days | 3 | Plus the prompt `training_load_review`; `weekly_training_review` and `intervals://guide` mention the new tools. ## Adopted from #150 / changed - Adopted: ACWR (coupled), Foster monotony/strain with rest days, primary-sport monotony, 80 % deload rule, PI formula and edge cases, class rules, durability filter (60 min, moving/elapsed 0.85, VI 1.20, 25 °C) and 1 pp band, EF trend, top sessions (highest IF kept), recomputing today's CTL/ATL without planned load, "no activity today -> windows end yesterday". - Changed: separate tools instead of one report; no alarm/warning flags (reference ranges with sources and "inside/above/below" only); zone mapping chosen by the athlete's zone count (power, HR, pace; unmapped models reported, never counted as easy time); hard sessions defined on the three-zone Z3 (>= 10 min) or IF >= 0.85 on >= 20 min; drift compares the two halves of the period; all cycling/running types with the steadiness filter deciding; device loads reported on their own scale; projection computed by us with a model check and Intervals.icu's own projection side by side; sport families from `utils.sports`; English internals. ## Testing - `pytest` 404 passed (new: `tests/test_load_metrics.py` pure metrics with edge cases, `tests/test_load_tools.py` tool level incl. MCP layer), `ruff`, `mypy src tests`, pylint gate exit 0 (no new duplicate-code messages). - Live read-only check against the account (activities, wellness, events, custom items; GET only): all five tools in text and JSON; model check reproduces the stored CTL/ATL within 0.00. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.