MCP server for Iridium fitness data — connects AI agents to your workout, nutrition, and training data
Strong foundation with 17 tools, comprehensive descriptions, and clear parameter documentation. Most tools follow verb_noun naming convention (get_*, log_*, update_*). Descriptions are thorough and contextual, well above the 194-char baseline. Input schemas are present for all tools with proper type declarations. However, output schemas are not documented in the source, and some edge cases in parameter relationships lack explicit documentation. Error handling guidance is minimal, tools lack recovery hints, retryability classification, and actionable error messages. Security practices are sound (credentials injected via environment variables), but no audit trail documentation or tool permission declarations visible. Overall, this is a well-executed integration tool with good definition quality but missing advanced error-handling and security-audit patterns.
Get body measurement history including weight, body fat percentage, and other measurements over time. Dates accept 'today', 'yesterday', 'YYYY-MM-DD', or ISO 8601; bare dates are whole days in the user's local timezone. Each measurement carries its own `unit` — mass types are converted to the user's preference, while circumference measurements have a null unit because the app records the number without a unit.
Get performance history and 1RM trends for a specific exercise. Shows recent sets, weight progression, and estimated one-rep max over time.
Get full individual food entries with name, macros, and all nutrients — plus hydration entries and a `hydrationByDay` rollup with consumed water and saved daily goals when available — for a single day or a date range (up to 90 days). Use this when the user asks about WHAT they ate ("what did I eat yesterday?", "show me everything I logged this week", "what was my dinner Tuesday?") or when you need entry-level detail for analysis (meal patterns, top sources of a macro, identifying repeat items, etc.). For daily totals / goal tracking / trends, use `get_nutrition_log` instead. Pass EITHER `date` (single day) OR `from` + `to` (range). Date parameters accept 'today', 'yesterday', 'YYYY-MM-DD', or full ISO timestamps; bare dates are interpreted in the user's LOCAL timezone so late-night meals correctly land on the same day the user went to bed. Ranges are inclusive on both ends and capped at 90 days; results are capped at 1000 entries with a `truncated` flag if that cap hits.
Output schemas not documented in source code. Tool descriptions state what is returned but JSON Schema for responses is not visible or specified in tool registration. LLMs cannot reliably plan downstream tool calls or extract required fields without documented return types.
No error handling guidance in tool descriptions. Tools like log_hydration mention deduplication behavior and date parsing but do not document what errors can occur, how to distinguish retryable from fatal errors, or what recovery steps are available. Agents cannot handle failures gracefully.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 63 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Get the user's water intake — individual hydration entries plus per-day totals against their saved hydration goal. Use this for 'how much water have I had today?', 'am I hitting my hydration goal?', or any question about fluid intake. Each day in `byDay` carries `consumedML`/`consumedOz`, `goalML`/`goalOz`, `remainingML`, and `progress` (0-1) when a goal exists for that day. Compare `consumedML` against `goalML`, and report in whichever unit the user speaks in. Note this covers hydration only — it does NOT include the water content of foods, which the Iridium app also excludes from the hydration ring. Dates accept 'today', 'yesterday', 'YYYY-MM-DD', or ISO 8601; bare dates are whole days in the user's local timezone. Pass EITHER `date` for a single day OR `from` + `to` for a range.
Get the user's current nutrition intent — what they are trying to do with food right now. Returns: `goalType` (lose | maintain | gain), `weeklyWeightChangeGoal` (e.g. -1 for losing 1 per week; negative means loss, positive means gain) with `weeklyWeightChangeUnit` (lbs or kg), daily targets `calorieGoal` / `proteinGoal` / `carbGoal` / `fatGoal` (grams for macros), hydration fields when available (`hydrationGoalML`, `hydrationGoalOz`, and `hydration` for today's consumed/goal/progress), and mode context (`calorieGoalMode`, `macroDistributionMode`, `macroPriority`, `macroPresetSplit`). IMPORTANT — `calorieGoal` is the LIVE EFFECTIVE target for today, matching what the Iridium app shows on the Nutrition tab. In automatic + HealthKit-active mode this includes today's active calories burned, so it changes throughout the day as the user moves. The static base (BMR ± deficit, before activity) is exposed separately as `calorieGoalBase`. When you compare consumed vs target, ALWAYS use `calorieGoal` (not `calorieGoalBase`). The optional `todaySnapshot` field breaks down where the number came from: `restingEnergyBurned` (BMR), `activeCalories`, `goalMode`, `hydration`, and `lastUpdated` (the iOS sync timestamp — be aware the active-calories and hydration numbers may be a few minutes stale). Use this when coaching the user ("am I on track?", "how much room for dinner?", "is this deficit aggressive or conservative?"), or whenever your recommendation depends on whether they are cutting, bulking, or maintaining. Combine with `get_food_entries(date: today)` for what has already been consumed.
Get DAILY NUTRITION SUMMARIES over a date range — one row per day with the user's actual consumed totals (live, computed from the food log on every call), their goals and targets for that day, hydration intake/goal when available, and any day notes (e.g. 'I didn't log everything today', 'was sick'). Use this for daily check-ins, trends, goal checking, and weekly/monthly review. For individual food-level detail (name + all nutrients per entry), use `get_food_entries` instead. Dates accept 'today', 'yesterday', 'YYYY-MM-DD', or full ISO timestamps; bare dates are interpreted in the user's local timezone. IMPORTANT — each summary row includes: (a) `consumed` — an object with the day's actual totals (calories, protein, carbs, fat, fiber, sugar, sodium, cholesterol, saturatedFat, transFat); always live, includes food logged via this tool earlier even before the iOS app has synced, (b) `calorieGoal` — the static BASE: BMR ± weight-goal deficit, BEFORE activity, (c) `effectiveCalorieGoal` — the real daily target that includes activeCalories burned and the daily-minimum floor; matches what the Iridium app actually displays. (d) `hydration` — an object with `consumedML`, `goalML`, `remainingML`, `progress`, and individual hydration `entries` when hydration data exists. ALWAYS compare `consumed.calories` vs `effectiveCalorieGoal`, not vs `calorieGoal`. For water/hydration, compare `hydration.consumedML` vs `hydration.goalML` when `goalML` is present. Some rows may have `consumed` populated but no goal fields — that's a day where food was logged before any goal-bearing data existed for that day; fall back to the top-level `goals` for targets. The same applies to the `goals` object at the top level for today.
Get personal records (PRs) across all exercises or for a specific exercise. Shows best 1RM, heaviest weight, most reps, and when each PR was set. The response's `weightReview` metadata reports whether ambiguous historical base-equipment sets were excluded.
Get the user's profile including demographics, training goals, methodology, experience level, and app settings.
Get weekly AI trainer analysis logs containing training recommendations, progress assessments, and coaching insights.
Get aggregate training statistics including total workouts, exercise frequency, streaks, and workout patterns.
Get volume adaptation records showing how training volume has been adjusted for each muscle group over time, including fatigue levels and recovery decisions.
Get the planned weekly training schedule showing which muscle groups or workout types are assigned to each day.
Get full details of a specific workout including all exercises, sets, weights, reps, RPE, and block structure.
Get recent workout history with optional filtering by date range or category. Returns workout summaries including date, exercises performed, duration, and completion status. Dates accept 'today', 'yesterday', 'YYYY-MM-DD', or a full ISO 8601 timestamp; bare dates are interpreted as whole days in the user's LOCAL timezone, so an early-morning session and a late-evening one on the same day both come back from a single-day query. To ask about one specific day, pass the SAME date as both `from` and `to`. IMPORTANT: a day often contains MORE THAN ONE workout — report every workout in the response, not just the first or the most recent.
Log a single food entry (cheeseburger, snack, meal, etc.) into the user's Iridium food diary. Required: name + calories + protein + carbs + fat (grams). IMPORTANT: calories and macros MUST be the totals for the amount actually consumed, NOT per-serving values. If the user ate 2 servings of a 200-cal item, send calories: 400. Optional: any micros you are confident about (fiber, sugar, sodium, vitamins, etc.) — omit values you don't know rather than guessing. WATER: do NOT log drinking water here. This tool is for food entries; use `log_hydration` instead.
Log water (or any hydrating drink volume) into the user's Iridium hydration tracker. USE THIS — not `log_food_entry` — whenever the user says they drank water, e.g. 'I had a glass of water', 'log 16 oz of water', 'just finished my water bottle'. The `water` field on a food entry is the water CONTENT of that food and does NOT count toward the hydration ring the user sees in the app; only this tool does. Pass EITHER `amountOz` OR `amountML` — give whichever unit the user used and the server stores both. Common volumes: a cup is 8 oz, a pint 16 oz, a standard bottle 16.9 oz (500 mL), a litre 33.8 oz. If the user drank something that is both food and fluid (a protein shake, juice, milk), log the calories and macros with `log_food_entry` AND the fluid volume with this tool — they are separate records and the app expects both. Plain water needs only this tool. DATE/TIMEZONE: `date` accepts 'today', 'yesterday', 'YYYY-MM-DD', 'today T14:00', 'yesterday 14:30', or a full ISO 8601 timestamp; bare and relative forms resolve in the user's local timezone. Defaults to now. DEDUPLICATION: identical calls within an hour are treated as the same entry. For a genuine second drink, pass a more specific `date` or a distinguishing `note`.
Correct a hydration entry you previously logged via `log_hydration` — e.g. "that was a 32 oz bottle, not 16". Required: id (from the prior log_hydration response). Only pass what you want to change. This only works on entries logged via chat; water added in the Iridium app itself returns a 404 and has to be edited there.
Permission declarations missing. No scope or permission metadata (e.g., 'read:fitness', 'write:nutrition') declared for any tool. Agents cannot be configured with least-privilege permissions, and audit trails cannot record what capabilities were requested.
Tool annotations missing. No readOnlyHint, destructiveHint, or idempotentHint annotations on tool definitions. Agents cannot automatically infer safety properties, e.g., log_hydration and log_food_entry are write operations but the schema does not declare this via tool annotations.
Some parameter descriptions incomplete. Tools like get_profile, get_training_summary, and get_weekly_schedule have minimal or missing descriptions for their inputs. Their descriptions are generic ('Get user profile', 'Get aggregate training statistics') without explaining dependencies, filters, or expected use cases.
No confirmation/dry-run step for write operations. log_hydration and log_food_entry are write tools that modify user data but lack a dry-run or preview mode. Agents cannot validate input before committing, risking silent data corruption if the LLM misinterprets user intent.
Pagination not visible in parameter schemas. Some read tools (get_workout_history) accept limit and offset, but pagination guidance is minimal. No mention of maximum result limits, when to paginate, or how to detect if results are truncated in the tool descriptions shown.