Garmin Personal MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GARMIN_BASE_URL | No | The Personal API host. | https://personal.connectapi.garmin.com |
| GARMIN_DATA_DIR | No | The data folder. | ~/workspace/garmin-data |
| GARMIN_API_KEY_FILE | No | The file with the API key. | ~/.config/garmin-mcp/api-key |
| GARMIN_PERSONAL_API_KEY | No | The personal API key. It has priority over the key file. |
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
} |
| prompts | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| listActivitiesA | List the user's Garmin activities (most recent first) as a compact summary: id, name, type, local start time, distance (km), moving duration, average pace, average/max heart rate, cadence, ascent; when Garmin has them: elapsed time (if longer than moving time), race flag, Garmin training load, aerobic/anaerobic training effect and label, seconds in HR zones 1-5, calories, moderate/vigorous intensity minutes, body battery change, steps, swim SWOLF, pool length, lengths and strokes, power, running form (stride, ground contact, vertical oscillation and ratio), grade-adjusted pace, best efforts (1k, mile, 5k, 10k, half, marathon) and run/walk segments. Dates are yyyy-MM-dd. Set raw=true for Garmin's full JSON. |
| getActivityA | Get the full detail of one activity (summary, metadata, splits/laps) as JSON. |
| getActivityWorkoutsA | The planned workout that an activity followed, as created in Garmin Connect: its steps in order, each with its intensity (warmup/active/rest/recovery/cooldown), its duration (time in seconds, reps, or open), its target (cadence, heart rate, pace, or open, with low and high values), the exercise for strength steps, and the coach's notes. A step with durationType REPEAT_UNTIL_STEPS_CMPLT repeats the steps from stepIndex durationValue up to it, targetValue times in all. Compare it with getActivitySets or getActivityLaps for plan against done. An empty list means the activity followed no planned workout. Null fields are left out. |
| downloadActivityFitA | Download the ORIGINAL .FIT file of an activity and save it on the user's computer. Returns the absolute path of the saved .fit file (second-by-second HR, cadence, speed, laps). |
| getActivityLapsA | Laps of an activity as recorded by the watch (manual laps, auto-lap every km, or workout steps), read from the original .FIT file. One row per lap: distance (km), timer time, pace (min/km, foot sports) or speed (km/h), average/max HR, cadence (spm for running), ascent/descent, average power, running form (gctMs, vertRatioPct, vertOscCm, strideCm), intensity (active, interval, rest, recovery, warmup, cooldown; the auto laps of a free run can be interval), lap trigger, and the step of the planned workout (step: the reps of one drill share it). Use it for intervals and per-km splits; getActivity does not have them. |
| getActivitySetsA | Strength training sets of an activity, read from the original .FIT file. One entry per exercise, in the order first done, with its movement category, its primary and secondary muscles (from Garmin's exercise catalogue) and its active sets: reps, weight (kg, absent when none was recorded), set time in seconds and the rest after the set (restSec). Exercise names are stable across sessions, so they can be used for per-exercise trends. Edits made later in Garmin Connect (renamed exercises, corrected reps or weights) are not in the .FIT file. |
| getHrvRangeC | Daily HRV (overnight) summaries for a date range, yyyy-MM-dd. |
| getDailyHeartRateB | Daily heart rate for one date (includes resting heart rate), yyyy-MM-dd. |
| getSleepA | Sleep for one night (date: the morning you woke up), or for up to 14 nights (fromDate and toDate), yyyy-MM-dd, as one compact row per night: bedtime and wake (local HH:mm), hours of sleep, deep, light, REM and awake, the sleep score and its quality, the sleep need (hours), average heart rate, average and lowest SpO2, average respiration, awake count, average sleep stress and Garmin's feedback. Missing values are left out, and a night without sleep data has only its date. Set raw=true for Garmin's JSON. |
| getWeightA | Weight for a date range, yyyy-MM-dd: the latest weight of each day (with body fat, muscle and bone mass, BMI and body water when a scale records them), the average of the range, and the last weight before and the first after the range. Set includeAll=true for every entry of each day. Weight, muscle mass and bone mass are in grams. |
| getBodyBatteryA | Body Battery for up to 14 days, yyyy-MM-dd: for each day how much it charged and drained, its readings through the day, and the events that changed it (sleep, activities, stress, naps) with their impact. |
| getHeartRateZonesB | Heart rate zones currently configured in Garmin Connect. |
| getFitnessAgeB | Garmin fitness age for a date, yyyy-MM-dd: fitness age vs chronological age, the achievable fitness age, and its components (body fat, vigorous days and minutes per week, resting HR) with the targets Garmin suggests. |
| getDailySummaryA | Daily user summary (steps, calories, stress, body battery, resting HR) for one date, or for up to 14 days (fromDate and toDate; the range answer has Garmin's v2 field names), yyyy-MM-dd. |
| garminGetA | Generic read-only GET on the Garmin Connect Personal API, for endpoints not covered by the other tools or when a query parameter name has to be adjusted. 'path' is relative and starts with '/', e.g. /fitnessage-service/fitnessage/v2/2026-10-25 . 'query' is an optional URL query string without '?', e.g. date=2026-10-25&foo=bar . |
| getDashboardDataA | All the data of the training dashboard in one call: HR zones, fitness age, the activities of the
last |
| writeDashboardA | Writes the training dashboard page (default /garmin-dashboard.html) with the data of the
last |
| editDashboardA | Changes the layout, the custom widgets or the languages of the dashboard page (a page from the
template; call writeDashboard first). Without arguments it only reads: the reply has the layout, the
custom widgets, the missing texts of each language, the catalogue of built-in widgets and |
| scheduleDashboardRefreshA | Turns on, changes or stops the automatic refresh of a dashboard page. Use it only when the user
asks for it or says yes to the question of a dashboard prompt. A job in the scheduler of the
computer (launchd, cron or Task Scheduler) replaces the data of the page at the given times, also
with no assistant open. The refresh removes the coach notes, because old notes do not agree
with new data. The computer must be on at that time. The page must exist (writeDashboard first).
|
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| training-dashboard | Build a personal training + recovery dashboard (volume, load, HRV, sleep) from Garmin data |
| training-dashboard-update | Update the training dashboard with the new Garmin data; it keeps the layout, widgets and languages |
| dashboard-widget | Make a new widget for the training dashboard from your idea |
| dashboard-setup | Set up a dashboard: title, sports, the data it shows (e.g. for a coach), languages, themes, file |
| dashboard-language | Add a language to the training dashboard (the assistant translates its texts) |
| run-review | Review a run as a coach: planned workout against the laps, rep fade, HR drift, recovery |
| strength-review | Review a strength session as a coach: planned sets against done, top sets, rest, recovery |
| race-readiness | Check if you are ready for a race: training block, taper, predicted time, recovery, race plan |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 19 tools
Most tools target clearly distinct resources or actions, especially the activity-detail tools and the health metric getters. There is some intentional overlap between the aggregate getDashboardData/garminGet tools and the specialized getters, and writeDashboard vs editDashboard could be confused at first glance, but the descriptions clarify their roles.
Most names follow a predictable camelCase verb_noun pattern: getActivity, getSleep, listActivities, writeDashboard, editDashboard, scheduleDashboardRefresh. garminGet is an outlier in both prefix and verb-order convention, and downloadActivityFit is a slight deviation, but the set remains readable and mostly consistent.
With 19 tools, the server is slightly above the typical 3-15 range, but the domain is broad: health metrics, activity detail, FIT files, dashboard generation, editing, and scheduling. Most tools have a clear purpose, so it is not excessively bloated.
The server covers core read paths for activities, sleep, HRV, heart rate, body battery, weight, fitness age, zones, and dashboard lifecycle operations, with garminGet as a read-only fallback for uncovered endpoints. Minor gaps remain, such as direct write/update operations for many health metrics and dashboard deletion/cleanup, but these are not major workflow blockers.