| name | garmin-connect |
| description | Retrieve, analyse, and reason about personal health, training, well-being, and fitness data from Garmin Connect using the python-garminconnect library and the shared garmin_client package at ~/.garmin.
Use this skill when the user asks to: - fetch or display health data (steps, heart rate, sleep, HRV, stress, body battery, SpO2, respiration, hydration) - analyse training or activity data (cycling, running, workouts, training load, training effect, HR zones) - query fitness metrics (VO2max, lactate threshold, intensity minutes, floors, calories) - write code that fetches data from Garmin Connect - debug Garmin Connect authentication (429 errors, rate limiting, token issues, browser cookies) - set up or install the garmin_client package
|
Garmin Connect Skill
Provides access to personal health, training, and fitness data via python-garminconnect and the
shared garmin_client package installed at ~/.garmin.
Setup
pip install -e ~/.garmin
from garmin_client import get_client
from datetime import date
client = get_client()
Required env vars (first run only):
GARMIN_CONNECT_USER — Garmin account email
GARMIN_CONNECT_PASSWORD — Garmin account password
GARMIN_TOKEN_PATH overrides the default ~/.garmin/tokens.json.
Fetching Data
All methods take a date string "YYYY-MM-DD". Use date.today().isoformat() for today.
today = date.today().isoformat()
stats = client.get_stats(today)
hr = client.get_heart_rates(today)
sleep = client.get_sleep_data(today)
hrv = client.get_hrv_data(today)
stress = client.get_stress_data(today)
bb = client.get_body_battery(today)
steps = client.get_steps_data(today)
hydra = client.get_hydration_data(today)
acts = client.get_activities(0, 20)
splits = client.get_activity_splits(activity_id)
zones = client.get_activity_hr_in_timezones(activity_id)
prof = client.get_user_profile()
For full field descriptions and all available fields: see references/api.md.
Analysing Data
When the user asks to analyse or summarise data, fetch the relevant endpoint(s) and reason directly
over the returned dicts/lists. Key patterns:
Daily snapshot:
s = client.get_stats(today)
print(s["totalSteps"], s["restingHeartRate"], s["bodyBatteryMostRecentValue"], s["averageStressLevel"])
Sleep quality:
sl = client.get_sleep_data(today)
dto = sl.get("dailySleepDTO", {})
deep = (dto.get("deepSleepSeconds") or 0) / 3600
light = (dto.get("lightSleepSeconds") or 0) / 3600
rem = (dto.get("remSleepSeconds") or 0) / 3600
total = deep + light + rem
HRV status:
hrv = client.get_hrv_data(today)
summary = hrv.get("hrvSummary", {})
print(summary.get("status"), summary.get("weeklyAvg"), summary.get("lastNightAvg"))
Recent training load:
acts = client.get_activities(0, 10)
for a in acts:
print(a["startTimeLocal"], a["activityType"]["typeKey"],
a["distance"]/1000, a.get("activityTrainingLoad"))
Body battery trend (intraday):
bb = client.get_body_battery(today)[0]
readings = bb["bodyBatteryValuesArray"]
Auth Issues
If authentication fails (429, token errors, library login failures): see references/auth-troubleshooting.md.
Quick reference:
- 429 on login — Rate limit or library bug (
impersonate="safari"). Use get_client(), never client.login().
- Tokens expire — Access token: ~28h, auto-refreshed. Refresh token: effectively permanent.
- 403 after auth —
display_name not set, or token stale. get_client() handles both.
- Browser cookies → 403 — IP-bound session cookie. Cannot be reused from a different host.