MCP server that integrates with Garmin Connect to manage workouts, activities, and calendar data. Allows listing workouts, scheduling workouts, uploading custom workouts, retrieving activity details, and accessing calendar information.
This server has moderate definition quality with notable gaps. 10 tools are registered with descriptions and schemas, but many descriptions are perfunctory, parameter descriptions lack depth, and output schemas are not formally documented. Naming is verb-correct (list_, get_, create_, schedule_, delete_, upload_) but descriptions fall short of LLM-optimization standards. No enum constraints for activityType despite a long list of valid values in the description. Error handling is present but not recovery-focused. Schema completeness varies, some tools have rich input parameters (list_activities, get_calendar), while others have minimal or missing descriptions. Output shapes are not formalized, forcing LLMs to infer response structure. The server follows FastMCP conventions well but lacks production-grade polish in parameter documentation and output contracts.
Delete a workout from Garmin Connect. Args: workout_id: ID of the workout to delete. Returns: True if the deletion was successful, False otherwise.
Generate prompt for LLM to create structured workout data based on a natural language description.
Get details of a specific activity by its ID. An activity represents a completed run, ride, swim, etc. Args: activity_id: ID of the activity to retrieve. As returned by the `get_calendar` tool. Returns: Activity details as a dictionary.
Get weather information for a specific activity. Args: activity_id: ID of the activity to retrieve weather for. Returns: Weather details as a dictionary containing temperature, conditions, etc.
Get calendar data from Garmin Connect for different time periods. Args: year: Year (e.g., 2025) month: Month (1-12) day: Day of month (1-31). If provided, gets corresponding weekly view that includes this day. If omitted, gets monthly view for the entire month. start: Day offset for weekly queries (defaults to 1). Controls which day of the week the 7-day period begins. Each increment shifts the start date forward by one day: - start=0: Week starts on Sunday - start=1: Week starts on Monday (DEFAULT) - start=2: Week starts on Tuesday - start=3: Week starts on Wednesday - start=4: Week starts on Thursday And so on. Different start values return different 7-day windows with varying calendar items, useful for different training schedules and calendar preferences. Returns: Calendar data with workouts and activities for the specified period. Raises: ValueError: If any of the date parameters are invalid.
Output schemas not formally documented. Tool descriptions state 'Returns: A dictionary' or 'Returns: Workout details as a dictionary' but never specify field names, types, or structure. LLMs cannot infer downstream tool parameter compatibility or plan multi-step chains.
activityType parameter in list_activities has inline enum documentation in the description string ('auto_racing', 'backcountry_skiing_snowboarding_ws', ..., 'yoga') instead of a formal enum constraint in the schema. JSON Schema supports enum arrays; LLMs cannot parse description text as constraints and will hallucinate values.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 48 | - | v1 |
Get details of a specific workout by its ID. Args: workout_id: ID of the workout to retrieve. Returns: Workout details as a dictionary.
List activities (completed runs, rides, swims, etc.) from Garmin Connect. Args: limit: Number of activities to return (default=20) start: Starting position for pagination (default=0) activityType: Filter by activity type. Accepted values include: - "auto_racing", "backcountry_skiing_snowboarding_ws", "bouldering", "breathwork" - "cross_country_skiing_ws", "cycling", "diving", "e_sport", "fitness_equipment" - "hiking", "indoor_climbing", "motorcycling", "multi_sport", "offshore_grinding" - "onshore_grinding", "other", "resort_skiing_snowboarding_ws", "running" - "safety", "skate_skiing_ws", "surfing", "swimming", "walking" - "windsurfing", "winter_sports", "yoga" search: Search for activities containing this string in their name Returns: A dictionary containing a list of activities and pagination info.
List all workouts available on Garmin Connect. Returns: A dictionary containing a list of workouts.
Schedule a workout on Garmin Connect. Args: workout_id: ID of the workout to schedule. date: Date to schedule the workout in ISO format (YYYY-MM-DD). Returns: workoutScheduleId: ID of the scheduled workout. Raises: ValueError: If the date format is incorrect. Exception: If scheduling the workout fails.
Uploads a structured workout to Garmin Connect. Args: workout_data: Workout data in JSON format to upload. Use the `generate_workout_data_prompt` tool to create a prompt for the LLM to generate this data. Returns: The uploaded workout's ID on Garmin Connect. Raises: Exception: If the upload fails or the workout ID is not returned.
Parameter descriptions are minimal or absent. 'workout_id' in get_workout has only 'ID of the workout to retrieve.', no guidance on format (UUID? numeric?), whether it comes from list_workouts or elsewhere, or what happens if invalid. Baseline for A+ tools: 100% of params have rich descriptions.
Error handling is present in code (ValueError for date format in schedule_workout, try/except in delete_workout) but not surfaced to LLM in descriptions. 'Raises: ValueError' and 'Raises: Exception' appear in docstrings but are not recovery-focused. No description of what to do if a workout ID is invalid, if scheduling fails, or if a delete returns False.
Tool names and descriptions do not signal which operations are read-only vs. destructive. Delete_workout is marked DESTRUCTIVE in risk, but the description does not warn 'This permanently removes the workout.' Schedule_workout is marked WRITE but not clearly distinguished from other write operations in the tool landscape.
generate_workout_data_prompt is a meta-tool that returns a prompt string for the LLM to use. Its description and input are vague. 'Generate prompt for LLM to create structured workout data based on a natural language description.', but what format is the prompt? What is the expected output? How does the LLM use it? This breaks composition: the agent does not know what to do with the result.
No pagination guidance in list_workouts and get_calendar descriptions. List_activities documents limit and start params but does not state a default limit, warn about token cost, or document total count in the response. Get_calendar accepts year/month/day but does not explain the response size or whether results are paginated.
Parameter types are defined in schema but not always documented in descriptions. 'day' and 'start' in get_calendar are integers with default values, but the description does not specify range (e.g., 'day must be 1-31' or 'start must be 0-7'). Unbounded integers invite LLM errors.