Show HN: Upload training plans defined in natural language into you Garmin watch

3 months ago 1

A Python CLI tool that schedules marathon training plans from markdown files to Garmin Connect using the Garmin Workouts MCP server.

  • Parses structured markdown tables containing training plan data
  • Converts natural language workout descriptions to Garmin-compatible format
  • Schedules workouts automatically to Garmin Connect
  • Idempotent scheduling: Skips workouts that already exist and match
  • Post-scheduling validation: Verifies all workouts are correctly scheduled
  • Provides dry-run mode for testing
  • Beautiful terminal output with progress tracking
  • Retry logic for failed operations
  1. Install the package with its dependencies:
  1. Set up Garmin Connect credentials (same as for the MCP server):
export GARMIN_EMAIL="[email protected]" export GARMIN_PASSWORD="your_password"

Schedule a training plan from a markdown file:

python -m garmin_workouts_mcp.schedule_training_plan training_plan.md

Preview what will be scheduled without making changes:

python -m garmin_workouts_mcp.schedule_training_plan training_plan.md --dry-run

Get detailed logging information:

python -m garmin_workouts_mcp.schedule_training_plan training_plan.md --verbose

The training plan should be formatted as markdown tables with the following columns:

Date Day Session Distance Heart Rate Target Garmin MCP Description Time
Jul 21 Mon Recovery Run 8km Zone 1: <125 bpm "8km recovery run at zone 1 heart rate under 125bpm" 7:00 AM
  • Date: Format as "Mon DD" (e.g., "Jul 21")
  • Day: Day of week
  • Session: Name of the workout
  • Distance: Distance with unit (e.g., "8km", "21km")
  • Heart Rate Target: Target heart rate or zone
  • Garmin MCP Description: Natural language description in quotes
  • Time: Time of day (optional)

The scheduler uses claude code cli to inteligently interpret and create various workout types:

  • Recovery runs: "8km recovery run at zone 1"
  • Easy runs: "10km easy run at zone 2"
  • Long runs: "30km long run at zone 2"
  • Tempo runs: "3km warmup, 6km tempo at 162-168bpm, 3km cooldown"
  • Intervals: "2km warmup, 6x(1km at 170bpm, 90sec recovery), 2km cooldown"
  • Norwegian 4×4: "3km warmup, 4x(4min at 175-180bpm, 3min recovery), 2km cooldown"
  • Zones: "zone 1", "zone 2", etc.
  • Ranges: "162-168bpm"
  • Limits: "under 125bpm", "below 135bpm"
  1. models.py: Pydantic models for training data
  2. utils.py: Markdown parsing and workout conversion
  3. schedule_training_plan.py: Main CLI implementation

The scheduler is idempotent, meaning you can run it multiple times safely:

  • Checks if a workout already exists on each date
  • Compares existing workouts with planned workouts
  • Only schedules new workouts or replaces non-matching ones
  • Skips scheduling if the existing workout matches

After scheduling, the tool validates all workouts:

  • Verifies each training date has a scheduled workout
  • Checks that workouts can be retrieved from Garmin
  • Reports any missing or invalid workouts
  • Provides a validation summary at the end
  • Validates markdown format before processing
  • Handles authentication failures gracefully
  • Retries failed operations up to 3 times
  • Provides clear error messages
╭──────────────────────────────────────────────────────────────────────────────╮ │ Marathon Training Plan Scheduler │ │ │ │ Reading: training_plan.md │ ╰──────────────────────────────────────────────────────────────────────────────╯ Training Plan Summary ┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Property ┃ Value ┃ ┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ Title │ Marathon Training Plan │ │ Start Date │ 2025-07-21 │ │ End Date │ 2025-09-28 │ │ Total Weeks │ 10 │ │ Total Sessions │ 70 │ └────────────────┴─────────────────────────────────────────────────────────────┘ Scheduling workouts... ✓ Scheduled 2025-07-21: Recovery Run ⟳ Exists 2025-07-22: Tempo Run (matched) ✓ Scheduled 2025-07-23: Easy Aerobic ... Scheduling Summary: ✓ Newly scheduled: 45 ⟳ Already existed (matched): 25 ○ Rest days: 2 ✗ Failed: 0 Validating scheduled workouts... ✓ Validated 2025-07-21: Recovery Run ✓ Validated 2025-07-22: Tempo Run ... Validation Summary: ✓ Validated: 70 ✗ Validation failed: 0

Example session uploaded to Garmin Connect

Here' the first session of my plan uploaded to Garmin Connect:

Example Session

Read Entire Article