A single-user Garmin Connect MCP service that writes native strength and pool-swim workouts to Garmin Connect and serves Garmin wellness reads (daily summary, sleep, HRV, stress, body battery).
Garmin MCP demonstrates solid tool design with comprehensive parameter schemas and clear naming conventions. All 14 tools follow verb_noun patterns (create_, get_, list_, schedule_, unschedule_, update_, delete_). Descriptions are present and substantive (avg ~150 chars), exceeding the 10-char minimum. Input schemas are well-structured with JSON Schema types and descriptions for all parameters. However, output schemas are not documented, responses are inferred from code but not formally specified in tool definitions. Error handling lacks recovery guidance (no 'try X instead' patterns). Dry-run and confirmation patterns are present on write operations, which is excellent. The FlexInt/FlexBool/FlexFloat types show thoughtful handling of stringified inputs from some MCP clients, but this complexity is not documented in descriptions.
Create a strength workout with named exercises, reps, weight, and sets. Steps are expanded into discrete steps. Optionally schedule the workout on the Garmin calendar in one call.
Create a pool-swim workout with strokes, drills, equipment, pace targets, and heart-rate zones. Repeats are expanded into discrete steps. Optionally schedule the workout on the Garmin calendar in one call.
Delete a saved workout by ID.
Get the body-battery timeline over an inclusive date range.
Read scheduled items for a month.
Get daily wellness summary: steps, calories, intensity minutes, resting heart rate, and body battery range for a day.
Output schemas not documented. Tool descriptions state what is returned (e.g., 'compact {workout_id, name, sport, schedule_date, scheduled} summary') but formal response schemas are absent from tool definitions. LLMs cannot plan downstream calls or extract fields reliably without documented output structure.
Error handling lacks recovery guidance. No tool description includes 'If X fails, try Y' patterns. Errors are likely raw API responses without actionable next steps for the LLM (e.g., 'workout not found' vs 'Workout not found. Call list_workouts() to see available IDs').
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Get overnight heart-rate variability (status and readings) for a date.
Get sleep stages, duration, and sleep score for a date.
Get the daily stress timeline for a date.
Fetch one workout's full JSON by ID.
List the user's saved workouts (id, name, type), newest first, up to limit entries.
Schedule an existing saved workout on the Garmin calendar for a given date.
Remove a scheduled calendar entry by its workoutScheduleId. The saved workout itself is untouched.
Update the name of an existing saved workout.
Pagination not documented for list_workouts. Tool accepts 'limit' but no 'offset', 'cursor', or 'total_count' is mentioned. Large result sets could exhaust context; no guidance on how to iterate through workouts beyond the limit.
FlexInt/FlexBool/FlexFloat stringification handling is undocumented. Code shows these types accept stringified inputs ('true', '5') to work around MCP client quirks, but tool descriptions do not mention this. LLMs may not know they can pass strings for numeric/boolean fields.
Date validation is client-side only (regex check in validateDate). No enum or pattern constraint in JSON Schema. LLMs may pass invalid dates; error messages are not documented.