garmin-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| JWT_SECRET | No | Secret used to sign JWT access tokens issued by the HTTP server. Must be a sufficiently random value; can be generated with 'openssl rand -base64 48'. | |
| GARMIN_EMAIL | No | Garmin account email used for re-authentication when session tokens expire, and required for HTTP mode to authenticate with Garmin. Anyone with access to this variable can see the email address. | |
| MCP_ISSUER_URL | No | The issuer URL for the built-in OAuth 2.1 authorization server in HTTP mode. Typically the URL where the server is hosted (e.g., http://localhost:8080 or your Cloud Run URL). | |
| GARMIN_PASSWORD | No | Garmin account password used for re-authentication when session tokens expire, and required for HTTP mode to authenticate with Garmin. Anyone with access to this variable can see the password; consider using a dedicated Garmin account. | |
| MCP_AUTH_PASSWORD | No | Password that users (e.g., Claude.ai) must enter to authenticate via the OAuth flow when connecting to the HTTP server. Anyone with this password can read your Garmin data. | |
| GARMIN_WRITE_ENABLED | No | Set to '1' to enable write tools (currently only creating strength workouts). All other tools remain read-only regardless of this setting. | 0 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_sleepA | Sleep duration, sleep stages, sleep score, and overnight HRV. Args: date: Calendar date in YYYY-MM-DD format. Defaults to last night (yesterday). Pass today's date to get the most recent recorded sleep when you wake up. |
| get_recent_activitiesA | List recent activities with type, duration, distance, and average heart rate. Args: limit: How many of the most recent activities to return. Capped at 50. |
| get_activity_detailsA | Detailed metrics for one activity, including splits and HR zones. Args:
activity_id: The activity's numeric Garmin ID, as returned by
|
| get_training_loadB | Daily training load with acute and chronic load and current status. Args: days: Number of recent days to summarise. Capped at 28. |
| get_hrv_statusA | Current HRV status, baseline range, and the last 7 nights of readings. |
| get_body_batteryA | Body battery values across the day, plus min, max, charged, and drained totals. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_steps_and_caloriesA | Daily step total, distance, calories, floors, and intensity minutes. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_resting_heart_rateA | Resting heart rate trend over the last Args: days: How many recent days to include. Capped at 28. |
| get_stressB | Stress levels across the day with average, max, and time-in-zone breakdown. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_training_readinessA | Daily training readiness score (0-100) with contributing factors. The score reflects how prepared the user is to train, drawing on sleep, HRV status, recovery time, and recent training load. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_daily_briefingA | One-call morning snapshot: sleep, HRV, Body Battery, readiness, load, and RHR. Fuses the individual recovery and training-load tools into a single payload so
you can reason across them in one shot instead of making six separate calls.
Each section is fetched independently and concurrently; a section that fails
comes back The server returns facts only and computes no training advice — interpret the numbers yourself (e.g. weigh readiness, HRV status, and Body Battery together). Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. The sleep, Body Battery, and training-readiness sections honour this date; the HRV, training-load, and resting-HR sections always report their own most-recent trailing window. For the default (this-morning) call everything lines up; passing a past date yields a mixed snapshot. |
| get_fitness_metricsA | VO2 max (running and cycling), fitness age, and predicted race times. Combines Garmin's "max metrics" tile (VO2 max, fitness age) with current race-time predictions for 5K, 10K, half marathon, and marathon. Args: date: Calendar date for the VO2 max snapshot in YYYY-MM-DD format. Defaults to today. |
| get_personal_recordsA | Personal records across activity types (fastest 1K/5K/10K, longest run, etc.). |
| get_body_compositionA | Weight, body fat, and muscle-mass trend over recent days. Returns one row per day Garmin has a reading for, plus the latest weight and average over the window. Args: end_date: End of the window in YYYY-MM-DD format. Defaults to today. days: Window size in days. Capped at 90. |
| get_respirationA | Daily respiration rate: average, min, max, and waking vs. sleeping averages. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_weekly_summaryA | Weekly aggregates for a single metric. Args: metric: One of "steps", "stress", or "intensity_minutes". weeks: How many recent weeks to include. Capped at 12. end_date: End of the window in YYYY-MM-DD format. Defaults to today. |
| get_strength_setsA | Set-by-set breakdown of a logged strength session: exercises, reps, and weight. Parses Garmin's recorded sets for one Args:
activity_id: The activity's numeric Garmin ID, from |
| get_endurance_scoreA | Garmin endurance score with its activity-type contributors. The endurance score reflects accumulated aerobic capacity across activities. It only updates after qualifying activities, so a given day may have no value. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_hill_scoreA | Garmin hill score (climbing strength + endurance) for a date. Combines a strength and an endurance component into an overall hill score.
Requires qualifying climbing efforts, so it is often empty for flat-terrain
athletes — an empty result is reported via Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_activity_weatherA | Weather conditions recorded during an activity (temp, humidity, wind). Units follow your Garmin account's measurement system (US accounts report degrees Fahrenheit and mph). Args:
activity_id: The activity's numeric Garmin ID, from |
| preview_strength_workoutA | Assemble a strength workout and show what WOULD be created — no network call. Resolves each exercise name to Garmin's catalog and returns a readable
summary, the resolved Garmin name + confidence per exercise, warnings for
anything that did not map cleanly, and a Args: workout: the workout definition (name, blocks of sets/exercises). |
| create_strength_workoutA | Create a strength workout in your Garmin Connect library (a WRITE). Requires writes to be enabled (GARMIN_WRITE_ENABLED) and a matching
Args:
workout: the workout definition (same shape as preview).
confirmation_token: token returned by |
| list_workoutsA | List workouts saved in your Garmin Connect library (id, name, sport). These are workout templates in the library — the source the watch syncs
from — not logged activities. Use the ids with Args: limit: maximum number of workouts to return (default 50). |
| delete_workoutA | Delete ONE workout from your Garmin Connect library (a WRITE, irreversible). Preview-then-confirm: call without a token first — that call deletes
nothing and returns the workout's name plus a Args:
workout_id: id from |
| preview_running_workoutA | Assemble a running workout and show what WOULD be created — no network call. Validates the structure (one end condition per step, paired pace bounds,
pace format) and returns a readable summary, sanity warnings, and a
Args: workout: the workout definition (name, steps and/or repeat groups). |
| create_running_workoutA | Create a structured running workout in your Garmin Connect library (a WRITE). Supports warmup/cooldown/interval/recovery steps, repeat groups for
intervals, and optional pace targets ('M:SS' per km). Requires writes to be
enabled (GARMIN_WRITE_ENABLED) and a matching Args:
workout: the workout definition (same shape as preview).
confirmation_token: token returned by |
| schedule_workoutA | Put an existing library workout on a Garmin Connect calendar date (a WRITE). Works for any workout type (running, strength, ...). A scheduled workout is
pushed to the watch automatically on its next sync — no "Send to Device"
needed. Reversible with Args: workout_id: id from create_running_workout / create_strength_workout / list of workouts in Garmin Connect. date: calendar date, YYYY-MM-DD. |
| unschedule_workoutA | Remove a scheduled workout from the calendar (a WRITE; keeps the template). The workout stays in your library — only the calendar entry is removed. Args:
schedule_id: id returned by |
| get_heart_rate_timelineA | Intraday heart rate for a day, including the most recent reading the watch synced. Use this for "what is my heart rate now / this morning / at 15:30". The last_reading fields give the newest value Garmin has; readings are downsampled to ~max_points evenly spaced samples. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. max_points: Maximum number of readings to return (default 96, i.e. ~15 min apart). |
| get_daily_summaryA | Everything Garmin records for one day in a single call. Steps, distance, calories (active/BMR/total), floors, intensity minutes, heart rate (resting/min/max/last), stress, Body Battery, SpO2, respiration, sleep seconds and more. Best first call for "how was my day". Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_steps_timelineA | Steps in 15-minute buckets across the day, with activity level per bucket. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_floorsB | Floors climbed and descended for a day, with the intraday timeline. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_intensity_minutesA | Moderate and vigorous intensity minutes for a day and the weekly goal progress. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_spo2A | Blood oxygen (SpO2 / pulse ox) for a day: average, lowest, latest, sleep average, timeline. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_hydrationA | Hydration log for a day: intake in ml, goal, sweat loss estimate. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_body_battery_eventsA | Body Battery charge/drain events for a day (sleep, activities, stress) with their impact. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_all_day_eventsA | Timeline of everything Garmin detected during the day: activities, naps, sleep, stress events. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_stats_and_bodyA | Daily stats merged with body composition (weight, BMI, body fat) for a date. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_lifestyle_logA | Lifestyle logging entries for a day (caffeine, alcohol, illness, travel, mood, etc.). Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_nutritionA | Food log and meals for a day (calories, macros) if nutrition tracking is used. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_menstrual_dataB | Menstrual cycle tracking data for a date, if the feature is used. Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_daily_steps_rangeA | Steps, distance and step goal per day over a date range (default last 14 days). Args: start_date: YYYY-MM-DD. Defaults to 14 days ago. end_date: YYYY-MM-DD. Defaults to today. |
| get_weigh_insA | Every weigh-in (weight, BMI, body fat, muscle mass...) in a date range (default last 30 days). Args: start_date: YYYY-MM-DD. Defaults to 30 days ago. end_date: YYYY-MM-DD. Defaults to today. |
| get_blood_pressureB | Blood pressure readings logged in Garmin Connect over a date range (default last 30 days). Args: start_date: YYYY-MM-DD. Defaults to 30 days ago. end_date: YYYY-MM-DD. Defaults to today. |
| get_progress_summaryA | Totals per activity type between two dates: distance, duration, elevation gain or moving time. Use for "how many km did I run this month" or "hours of cycling this year". Args: start_date: YYYY-MM-DD. Defaults to 30 days ago. end_date: YYYY-MM-DD. Defaults to today. metric: One of distance, duration, movingDuration, elevationGain, elevationLoss. |
| get_running_toleranceA | Garmin running tolerance (weekly mileage your body tolerates) over a range (default 12 weeks). Args: start_date: YYYY-MM-DD. Defaults to 84 days ago. end_date: YYYY-MM-DD. Defaults to today. |
| get_activities_by_dateA | Activities between two dates, optionally filtered by type (running, cycling, swimming, ...). Args: start_date: YYYY-MM-DD. Defaults to 30 days ago. end_date: YYYY-MM-DD. Defaults to today. activity_type: Garmin type key such as running, cycling, walking, strength_training. |
| get_last_activityA | The most recent activity recorded, with its summary metrics. |
| get_activity_timeseriesA | Second-by-second chart data of an activity as named series (heart rate, pace, altitude, cadence, power, temperature...), downsampled to max_points. Args: activity_id: Garmin activity ID (from get_recent_activities). max_points: Maximum samples per series (default 120). |
| get_activity_power_zonesB | Time spent in each power zone for a cycling or running-power activity. Args: activity_id: Garmin activity ID. |
| get_activity_split_summariesB | Per-split summaries of an activity (laps, intervals, rest) with pace, HR and power. Args: activity_id: Garmin activity ID. |
| get_activity_typed_splitsC | Typed splits of an activity (e.g. climb/descent segments, swim lengths, interval work/rest). Args: activity_id: Garmin activity ID. |
| get_activity_gearB | Gear (shoes, bike) linked to an activity. Args: activity_id: Garmin activity ID. |
| get_lactate_thresholdA | Latest lactate threshold estimate (heart rate and pace/power) from Garmin. |
| get_cycling_ftpC | Cycling Functional Threshold Power (FTP) and power zones. |
| get_fitness_ageB | Garmin fitness age with its components (VO2 max, BMI/body fat, RHR, vigorous days). Args: date: Calendar date in YYYY-MM-DD format. Defaults to today. |
| get_scheduled_workoutsA | Training calendar for a month: scheduled workouts, completed activities, plan items. Args: year: Four-digit year. Defaults to the current year. month: 1-12. Defaults to the current month. |
| get_training_plansB | Training plans the user is enrolled in (Garmin Coach and custom plans). |
| get_goalsA | Goals set in Garmin Connect (steps, distance, weight...) with progress. Args: status: active, future or past. Defaults to active. |
| get_badgesA | Badges earned and badges in progress, with points and dates. |
| get_devicesA | Registered Garmin devices and the last-used device with its last sync time. Use this to know how fresh the data is: if the watch has not synced recently, intraday values will be stale. |
| get_gearB | Gear registered in Garmin Connect (shoes, bikes) with total distance and activity counts. |
| get_user_profileB | User profile basics: display name, unit system, birth year, gender, height, weight. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 63 tools
Many tools have fuzzy boundaries: get_daily_summary, get_daily_briefing, and get_stats_and_body all return overlapping daily snapshots, and get_recent_activities, get_activities_by_date, and get_last_activity serve nearly the same retrieval purpose. Activity-level tools like get_activity_details, get_activity_timeseries, get_activity_split_summaries, and get_activity_typed_splits also overlap enough that an agent could easily select the wrong one.
The tool names follow a very consistent verb_noun pattern: nearly all reads are get_* and writes use preview_, create_, delete_, schedule_, unschedule_, and list_. All names are snake_case with predictable prefixes, making the naming style highly uniform across the entire set.
63 tools is far beyond the 3-15 well-scoped range and well into the 50+ extreme-mismatch territory. While Garmin has a broad data surface, this many tools creates navigational overhead and many could be consolidated into parameterized or grouped endpoints.
The read surface is exhaustive, covering sleep, HRV, body battery, stress, activities, workouts, nutrition, menstrual data, and more. The write surface covers workout preview/create/list/schedule/unschedule/delete, with the main gap being no workout update or edit flow.