garmin-personal-api-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GARMIN_PERSONAL_API_KEY | No | Your Garmin Connect Personal API key. The server reads the key from $GARMIN_PERSONAL_API_KEY, the macOS Keychain, or ~/.config/garmin/connect-personal-api-key, so this environment variable is one of several ways to provide it. |
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": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| garmin_get_profileA | The user's Garmin profile settings (units, weight, height, birth year, lactate threshold where set) plus their heart-rate zones. Call this first when you need zones or units to interpret other data. |
| garmin_list_activitiesA | List recorded activities (runs, gym sessions, rides…), newest first, with distance, time, pace, heart rate, training effect and Garmin's training load. Examples:
|
| garmin_get_activityA | Garmin's computed summary for one activity: distance, durations, pace/speed, HR, cadence, elevation, training effect, calories. For per-km splits use garmin_get_activity_splits. |
| garmin_get_activity_splitsA | Downloads the original .FIT recording and computes exact distance splits (default 1 km, interpolated at each boundary, pauses excluded), per-split HR, cadence and climb, the device laps, and a pacing verdict (even, negative split, faded). Use this for "how was my pacing", "did I go out too fast", "compare km 1 to km 5". Works for any GPS or footpod activity recorded on a Garmin device. |
| garmin_get_performance_metricsA | Garmin's own VO2 max, read the way Garmin Connect shows it, plus per-activity aerobic/anaerobic training effect, recovery time and performance condition. Decoded from the original .FIT files, since the Personal API has no VO2 max endpoint. Returns the current VO2 max (whole number, as Garmin's apps round it, plus the precise value), every new VO2 max reading in the window (Garmin only updates it on qualifying runs and power-meter rides), and a row per activity. Examples:
|
| garmin_download_activity_fitA | Saves an activity's original file (Garmin's ZIP containing the .fit) to a folder on this computer, for import into other tools such as Runalyze or Golden Cheetah. Returns the saved path. |
| garmin_get_dayA | Everything for one day in one call: daily summary (steps, calories, resting HR, stress, intensity minutes), sleep, overnight HRV, Body Battery and activities. Best first call for 'how recovered am I today' or 'how was yesterday'. Parts Garmin has no data for are omitted. |
| garmin_get_daily_summariesA | Per-day totals: steps, distance, active and total calories, resting/min/max heart rate, average and max stress, intensity minutes, floors, Body Battery high/low. Best tool for trends across weeks. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_sleepA | Per-night sleep: duration, deep/light/REM/awake time, sleep score, and timing. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_hrvA | Per-night heart-rate variability: last-night average, weekly average, baseline range and status (balanced, unbalanced, low). Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_body_batteryA | Per-day Body Battery: charged, drained, highest and lowest values. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_stressA | Per-day all-day stress levels. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_stepsA | Per-day step totals and goals. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_hydrationA | Per-day logged water intake and goal. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_weightA | Every weigh-in in the range (Garmin usually reports weight in grams: divide by 1000 for kg), with BMI, body fat, muscle mass and water where a smart scale recorded them. Use for bulk/cut progress. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_weight_goalsB | Weight goals in effect during the range. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_wellness_activitiesA | Wellness activity summaries (e.g. breathwork and relaxation sessions) for the range. Long ranges are fetched in chunks automatically (up to 366 days). |
| garmin_get_sleep_detailA | One night's sleep in full: stages timeline, sleep score breakdown, respiration, restless moments, SpO2 and HR during sleep. |
| garmin_get_heart_rateB | One day's resting HR and the all-day heart-rate samples. |
| garmin_get_spo2C | One day's SpO2 readings and acclimation. |
| garmin_get_fitness_ageB | Garmin's fitness age estimate and its inputs for a date. |
| garmin_get_nutritionA | Foods and macros logged in Garmin Connect's nutrition log for one day. |
| garmin_api_getA | Call any documented Personal API endpoint directly, for data the other tools don't cover (e.g. menstrual cycle summaries, activity workouts). Path must start with one of: /activity-service/, /activitylist-service/, /biometric-service/, /fitnessage-service/, /goal-service/, /hrv-service/, /nutrition-service/, /periodichealth-service/, /sleep-service/, /usersummary-service/, /userprofile-service/, /weight-service/, /wellness-service/, /wellnessactivity-service/. Example: path="/activity-service/activity/123456/workouts" |
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 23 tools
Tools are organized around a clear pattern: one aggregated day tool plus per-metric range getters, which keeps most purposes distinct. A few boundaries could confuse an agent—garmin_get_day vs garmin_get_daily_summaries, and garmin_get_sleep vs garmin_get_sleep_detail—but the descriptions explicitly differentiate the aggregate vs range vs single-night-detail cases.
Nearly all tools follow garmin_get_<resource> or garmin_<verb>_<noun> (garmin_list_activities, garmin_download_activity_fit), which is predictable. The one deviation is garmin_api_get, which uses noun_verb ordering as a generic escape hatch, a minor inconsistency.
At 23 tools the surface is on the heavy side for the domain, though each metric-specific getter earns a reasonable place. The breadth of Garmin data (sleep, HRV, stress, activities, weight, nutrition) justifies most of them, but the aggregate plus per-metric split inflates the count.
Coverage is broad: profile, daily summaries, sleep (summary and detail), HRV, Body Battery, stress, steps, hydration, activities (list/get/splits/FIT download), performance metrics, weight and goals, SpO2, fitness age, and nutrition. The generic garmin_api_get escape hatch fills any remaining gaps, so there are no dead ends.