Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Garmin Connect

PYPI · GARMIN-CONNECT-API

Read and write Garmin Connect: activities, strength sets, health data, workouts and weigh-ins.

Available components

69 Trust /100

Last scanned (2 hours ago)

Scores higher than 68% of PyPI servers

Category Health and Science

Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security50
  • Malware scan not yet available for this package.Unverified
  • No known CVEs affecting this package version or its production dependencies.Pass
  • Runs hatchling.build at install time, a recognised build step with no custom scripting around it. View diagnostics → Pass
  • 3 of 40 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency100
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Cryptographically verified build provenance (signed, bound to happyc0der/garmin-connect-api). View diagnostics → Pass
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 4 days ago).Pass
  • Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability82
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 5792 tokens (~148/item across 39 items; 38 tools + 1 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management9
  • Stability check failed: the tool surface changed between 0.2.3 and 0.3.1: 3 tool removals, 0 breaking changes, 0 additions. See how to fix → Fail
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 40 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 23 Oct 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 3 to 6.

  • 20 Oct 26 +3
    • Stability: unverified → fail ▼ security
    • Schema quality: pass → fail ▼ functional
    • Tool coverage: 30% → 100% ▲ functional
    • Schema quality: good → excellent functional
    • Package version: 0.2.3 → 0.3.1 functional
    • Package version: 0.2.3 → 0.3.0 functional
  • 19 Oct 26 65

    First indexed and scored.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 24 Oct 2026 · Analysed pypi/garmin-connect-api@0.3.1

Provenance Verified

A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.

Result Verified
Ecosystem pypi
Reason Verified
Discovered via Registry attestation endpoint
Source repo happyc0der/garmin-connect-api
Certificate issuer https://token.actions.githubusercontent.com
Certificate SAN https://github.com/happyc0der/garmin-connect-api/.github/workflows/release.yml@refs/tags/v0.3.1
Rekor log index 3329679033
Predicate type PyPI publish attestation https://docs.pypi.org/attestations/publish/v1
Subject digest sha256:db520ba7a325fc3375bcaa756dea6b05a388e3a38f1f91980e6b9e9b9af16229

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
build_backend allowlisted hatchling.build

Background: Why install scripts are a supply-chain risk →

Dependencies 40 packages
Packages resolved 40
Stale 3
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 38 exposed · ~5,543 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
add_body_composition ~307

Record a weigh-in with body composition: fat, water, muscle, bone, BMI. This is the way to bring a smart scale's full reading into Garmin. A plain add_weigh_in carries weight only. Garmin reports every upload as "processed"; an identical measurement sent again is still kept only once, but a different reading at the same moment is kept as a second weigh-in. To correct one, delete the wrong one first: list_weigh_ins gives its id.

NameTypeReqDescription
active_met_kcal––Active metabolic rate, kcal a day.
basal_met_kcal––Basal metabolic rate, kcal a day.
bmi––Body mass index.
bone_mass_kg––Bone mass, kg.
metabolic_age––In years.
muscle_mass_kg––Skeletal muscle mass, kg: Garmin shows this field under that name.
percent_fat––Body fat, %.
percent_hydration––Body water, %.
physique_rating––The scale's physique rating, 1 to 9.
timestampstringyesWhen it was measured. Without an offset, it is taken as local time in the Garmin account's own timezone.
visceral_fat_mass_kg––Visceral fat mass, kg.
visceral_fat_rating––The scale's visceral fat rating, 1 to 59.
weight_kgnumberyesBody weight, kg.

Structured output declared, but exposes no named fields.

No examples provided.

add_weigh_in ~158

Record one body weight in Garmin Connect, in kg or lbs, with no body composition. For a smart scale reading with fat, water, muscle or bone, use add_body_composition instead. Without a timestamp it is filed now. A timestamp without an offset is taken as local time in the Garmin account's timezone, and one with an offset is moved into that timezone, so it lands on the right day. To correct a reading, delete it with delete_weigh_in (list_weigh_ins gives its sample_pk) rather than adding another.

NameTypeReqDescription
timestamp––ISO 8601. Defaults to now.
unitstring–kg or lbs.
weightnumberyesIn the given unit.

Structured output declared, but exposes no named fields.

No examples provided.

create_endurance_workout ~242

Create a run, ride or pool swim workout to follow on the watch. Steps end on a time, a distance or the lap button, and can repeat. Runs and rides take a target: pace per km or mile, speed, heart-rate zone or range, power zone or watts, or cadence. Swims take a stroke, equipment and a pool length; distances must be whole lengths. Give schedule_date to put it on the calendar too; the reply then carries the schedule_id, and if scheduling fails the error gives the new workout's id. For strength workouts use create_strength_workout.

NameTypeReqDescription
description––Notes shown with the workout.
namestringyesThe workout's title.
pool_length––Swims only.
pool_unitstring–The pool length's unit, m or yd; swims only.
schedule_date––If set, the workout is scheduled on this date after creation.
sportstringyesrunning, cycling, or swimming in a pool.
stepsarrayyesSteps in order; a repeat holds steps to run several times.
NameTypeReqDescription
description–––
estimated_duration_s–––
name–––
raw–––
schedule_id––Set when the workout was just scheduled: what unschedule_workout takes.
scheduled_on––Set when the workout was just scheduled: its calendar day.
sport–––
updated–––
workout_idintegeryes–

No examples provided.

create_strength_workout ~199

Create a strength workout to follow later. Each exercise becomes a block of sets with a rest between them. Name exercises with Garmin's category and exercise name, which find_exercise gives; an unknown name is rejected with suggestions. For runs, rides and swims use create_endurance_workout; to record a session already done, log_strength_session. Without schedule_date it is saved, not scheduled. With it, it is put on the calendar in the same call, and the reply carries the schedule_id. If scheduling fails the workout still exists and the error gives its id: schedule that one rather than creating it again.

NameTypeReqDescription
description––Notes shown with the workout.
exercisesarrayyesThe exercises in order, each a block of sets.
namestringyesThe workout's title.
schedule_date––If set, the workout is scheduled on this date after creation.
NameTypeReqDescription
description–––
estimated_duration_s–––
name–––
raw–––
schedule_id––Set when the workout was just scheduled: what unschedule_workout takes.
scheduled_on––Set when the workout was just scheduled: its calendar day.
sport–––
updated–––
workout_idintegeryes–

No examples provided.

create_workout_from_dto ~70

Create a workout from a full Garmin DTO, for shapes the builder omits. Sent to Garmin as given: exercise names are not checked against the catalogue here, so prefer create_strength_workout where it can express it.

NameTypeReqDescription
workoutobjectyesA complete Garmin workout DTO.
NameTypeReqDescription
description–––
estimated_duration_s–––
name–––
raw–––
schedule_id––Set when the workout was just scheduled: what unschedule_workout takes.
scheduled_on––Set when the workout was just scheduled: its calendar day.
sport–––
updated–––
workout_idintegeryes–

No examples provided.

delete_activity ~96

Permanently delete one activity from Garmin Connect. There is no undo. Use it for an activity that should not exist, such as a session logged twice. To fix a strength session's sets use edit_activity_sets, and to rename it, update_activity; both keep the activity. A copy already shared to Strava or another connected app stays there.

NameTypeReqDescription
activity_idintegeryesGarmin's activity id, from list_activities.

Structured output declared, but exposes no named fields.

No examples provided.

delete_weigh_in ~110

Permanently delete one weigh-in, identified by the sample_pk and day that list_weigh_ins gives for it. Use it to remove a wrong or duplicate reading; to correct one, delete it and record the right value with add_weigh_in or add_body_composition. Nothing here restores it, and day summaries and weight trends change with it.

NameTypeReqDescription
daystringyesThe weigh-in's calendar date.
sample_pkintegeryesFrom list_weigh_ins.

Structured output declared, but exposes no named fields.

No examples provided.

delete_workout ~117

Permanently delete a saved workout (a plan) from the account's workout library. To take a workout off one date but keep it, use unschedule_workout with the calendar entry's schedule_id instead. Completed sessions are activities, not workouts: delete those with delete_activity. Nothing here restores a deleted workout; get_workout first if its structure may be wanted again, since its raw field holds the full definition.

NameTypeReqDescription
workout_idintegeryesFrom list_workouts or list_scheduled_workouts.

Structured output declared, but exposes no named fields.

No examples provided.

edit_activity_sets ~169

Correct a strength activity's sets: exercise, reps or weight, or delete sets. Address sets by the set_number get_activity_sets shows; within one call, every number means the set as numbered before it. Deleting renumbers the sets after it, so repeating a delete removes a different set: use the numbers this returns for any further edit. Name exercises with Garmin's category and exercise_name; find_exercise looks them up. To rename the activity or change its description, use update_activity. Returns the sets as Garmin now holds them.

NameTypeReqDescription
activity_idintegeryesGarmin's activity id, from list_activities.
changesarray–Edits, each applied to the working sets it lists.
deletearray–Working set numbers to remove.
NameTypeReqDescription
activity_idintegeryes–
note––Set when something about this answer needs saying.
setsarray––
total_volume_kgnumberyesSum of reps times weight over the working sets. The usual definition of training volume. Sets with no weight recorded (bodyweight work) contribute nothing, which is the conventional treatment rather…

No examples provided.

find_exercise ~193

Search Garmin's strength exercise catalogue by name, best match first; each result has the display name, category and exercise (the variant). Use it before create_strength_workout, log_strength_session or edit_activity_sets whenever the Garmin pair is not known: those reject any other name, and accept a result's category and exercise as they are. Matching is by word starts ("lat pull" finds "Lat Pull-down"), with plurals and common gym names (rdl, ohp, skull crusher) understood. To turn one free-text name into exactly one exercise or nothing, use match_exercise. Answered from a bundled copy of the catalogue: no Garmin request, no login needed.

NameTypeReqDescription
limitinteger–Most matches to return.
querystringyesPart or all of an exercise name, e.g. "bench", "lat pulldown", "rdl".
NameTypeReqDescription
resultarrayyes–

No examples provided.

garmin_status ~60

Check whether this server holds a Garmin login. Call this first if anything fails. It reports whether tokens exist and how old they are, without calling Garmin, so tokens Garmin has since revoked still show as authenticated; any other call reveals that.

Input schema present but exposes no named parameters.

Structured output declared, but exposes no named fields.

No examples provided.

get_activity ~118

Return one activity by id: type, start time (UTC and local wall clock), duration, distance, heart rate and calories, plus Garmin's full record under raw. Ids come from list_activities, recent_strength_sessions or week_summary. It has no per-set or per-lap detail: for a strength session's exercises, reps and weights use get_activity_sets; for a run, ride or swim's laps and pacing, get_activity_laps.

NameTypeReqDescription
activity_idintegeryesGarmin's activity id, from list_activities.
NameTypeReqDescription
activity_idintegeryes–
activity_type–––
average_hr–––
calories–––
distance_m–––
duration_s–––
elapsed_duration_s–––
has_setsboolean–Whether this is a strength activity, the kind that carries per-set detail.
max_hr–––
moving_duration_s–––
name–––
raw–––
start_time––Start instant, UTC.
start_time_local––Wall-clock start where the activity happened, as YYYY-MM-DDTHH:MM:SS. Deliberately has no timezone: Garmin gives the time, not the zone.
steps–––

No examples provided.

get_activity_laps ~104

Return the laps of a run or ride, or the pace per 100 m or yd of a pool swim, with a summary: average pace or speed, first half against second half, and the fastest and slowest lap or 100. Answers "did my pace hold up?". Strength sessions have sets, not laps: use get_activity_sets. Two Garmin requests.

NameTypeReqDescription
activity_idintegeryesGarmin's activity id, from list_activities.
NameTypeReqDescription
activity_idintegeryes–
lapsarray––
pool_length––In pool_unit.
pool_unit––"m" or "yd".
segments––Pool swims: pace per 100 of the pool's unit.
sport–––
summaryobject––

No examples provided.

get_activity_sets ~144

Return a strength activity's sets: exercise category and name, reps, weight in kg and duration, with the total volume. Each working set has a set_number (1, 2, 3...), which edit_activity_sets takes to correct or delete sets; rests have none and are left out unless include_rests. Only strength activities have sets: for runs, rides and swims use get_activity_laps. For the last few sessions at once, recent_strength_sessions saves a call per session.

NameTypeReqDescription
activity_idintegeryesGarmin's activity id, from list_activities.
include_restsboolean–Include the rest periods between sets.
NameTypeReqDescription
activity_idintegeryes–
note––Set when something about this answer needs saying.
setsarray––
total_volume_kgnumberyesSum of reps times weight over the working sets. The usual definition of training volume. Sets with no weight recorded (bodyweight work) contribute nothing, which is the conventional treatment rather…

No examples provided.

get_body_battery ~141

Return Garmin's own body battery record for each day from start to end, unprocessed. Use it for the detail behind a day's number. For one day's high and low, get_day_summary already has them; for daily highs over weeks or months, with an average and the change, use get_trend with metric body_battery. One Garmin request whatever the range, so keep it to days. The reply is Garmin's JSON as it comes: field names are Garmin's and nothing is converted.

NameTypeReqDescription
end––Last day, inclusive. Left out, only the start day.
startstringyesFirst day, inclusive.
NameTypeReqDescription
result–yes–

No examples provided.

get_day_summary ~187

Return one calendar day's numbers in a single answer: steps, calories, heart rate, stress, body battery, last night's sleep, HRV, the morning readiness score and the day's last weigh-in. It does not list the day's activities: use list_activities with start_date and end_date both set to the day. For one metric, its own tool (get_sleep, get_hrv, get_stress, get_steps, get_training_readiness) gives more detail in one Garmin request instead of five; for seven days use week_summary, for a range get_trend. A part whose request fails is null and named under unavailable; if every part fails, or Garmin rate limits, the call returns an error instead. A night's sleep belongs to the day it ended on.

NameTypeReqDescription
daystringyesThe calendar date, YYYY-MM-DD.
NameTypeReqDescription
active_calories–––
average_stress–––
body_battery_high–––
body_battery_low–––
daystringyes–
distance_m–––
floors_climbed––Garmin reports floors fractionally, e.g. 2.25.
hrv_last_night_avg–––
hrv_status–––
max_hr–––
min_hr–––
moderate_intensity_minutes–––
raw–––
resting_hr–––
sleep–––
step_goal–––
steps–––
total_calories–––
training_readiness––The morning score Garmin sets on waking.
unavailable––Parts Garmin did not answer for, and why: a part missing from this summary is listed here if it failed, rather than looking like a day with nothing recorded.
vigorous_intensity_minutes––Garmin counts these double toward the weekly goal.
weight–––

No examples provided.

get_hrv ~153

Return one night's heart rate variability in milliseconds: the night's average and five-minute high, the weekly average, Garmin's status (such as BALANCED, UNBALANCED or LOW) and the baseline band. A night belongs to the day it ended on: last night is today's date. With no HRV for that night the reply is null, or its fields are. The nightly average and status are also in get_day_summary; over weeks or months use get_trend with metric hrv. include_readings adds the five-minute readings.

NameTypeReqDescription
daystringyesThe date the night ended on; last night is today.
include_readingsboolean–Add the five-minute readings.
NameTypeReqDescription
result–yes–

No examples provided.

get_personal_records ~109

List every personal record Garmin holds for the account, each named and in units (e.g. "Fastest 1 km run"), newest first; records with no date come last. A record set in an activity carries its activity_id, which get_activity opens; step and goal-streak records have none. For how a metric moved over a range use get_trend. Two Garmin requests the first time (the record types are then kept for the process), one after.

Input schema present but exposes no named parameters.

NameTypeReqDescription
resultarrayyes–

No examples provided.

get_sleep ~118

Return one night's sleep: start and end, total, deep, light, REM and awake time, sleep score and average respiration. A night belongs to the day it ended on: last night is today's date. Null when no sleep was recorded. The same summary is inside get_day_summary, which costs five Garmin requests to this one's one; for sleep hours or score over many nights use get_trend with metric sleep or sleep_score.

NameTypeReqDescription
daystringyesThe date the night ended on; last night is today.
NameTypeReqDescription
result–yes–

No examples provided.

get_steps ~120

Return one day's steps: the total, and 24 hourly totals by GMT hour, not local time. For the total beside the day's other numbers use get_day_summary; for daily totals over a range with an average and the change, get_trend with metric steps. total is null, not 0, when Garmin did not answer. include_buckets adds Garmin's quarter-hour buckets.

NameTypeReqDescription
daystringyesThe calendar date, YYYY-MM-DD.
include_bucketsboolean–Add Garmin's quarter-hour buckets.
NameTypeReqDescription
buckets––Garmin's quarter-hour buckets, only when asked for.
daystringyes–
hourly_gmtarray–24 values, hour 0 to 23 GMT.
total––None when Garmin did not answer.

No examples provided.

get_stress ~141

Return one day's stress: the average and peak, and the minutes at rest, in Garmin's low, medium and high bands, and unmeasured. The day's average alone is also in get_day_summary; for the daily average over weeks or months use get_trend with metric stress. With no stress data for the day the reply is null, or its fields are. include_samples adds the three-minute readings, which run to hundreds; leave it off unless the shape of the day matters.

NameTypeReqDescription
daystringyesThe calendar date, YYYY-MM-DD.
include_samplesboolean–Add the three-minute readings.
NameTypeReqDescription
result–yes–

No examples provided.

get_training_readiness ~137

Return every training readiness entry Garmin recorded for one day: the score, its level and the factors behind it. Use it for why the score is what it is. Garmin recomputes readiness through the day; the entry whose inputContext is AFTER_WAKEUP_RESET is the morning score, which get_day_summary gives on its own and get_trend with metric readiness follows over weeks or months. One Garmin request. The reply is Garmin's JSON as it comes, usually a list of entries; null or empty when nothing was recorded.

NameTypeReqDescription
daystringyesThe calendar date, YYYY-MM-DD.
NameTypeReqDescription
result–yes–

No examples provided.

get_training_status ~115

Return Garmin's training status for one date: the status, training load and VO2 max context behind it, as Garmin's unprocessed JSON. For VO2 max over time use get_trend with metric vo2max (running) or vo2max_cycling; for whether to train today, get_training_readiness. One Garmin request; null when Garmin reports nothing for the date. Field names are Garmin's own.

NameTypeReqDescription
daystringyesThe date to report on, YYYY-MM-DD.
NameTypeReqDescription
result–yes–

No examples provided.

get_trend ~319

How one metric moved over a range, with average, extremes and change. Metrics: steps, resting_hr, sleep (hours), sleep_score, hrv, readiness (the morning score), stress (the day's average), body_battery (the day's high), weight, body_fat, vo2max (running), vo2max_cycling. Up to two months comes back daily, up to a year weekly, longer monthly. Ranges are limited to two years. Steps, sleep, sleep_score, stress and body_battery are fetched four weeks per Garmin request, so a year of one is about 14 requests; hrv, readiness and resting_hr a year per request; weight, body_fat and VO2 max one request. For one day use get_day_summary or that metric's own tool; for every weigh-in rather than one a day, list_weigh_ins. The summary gives days_with_data (periods_with_data for VO2 max, which Garmin groups itself), the average, min and max of the days, the first and last day, and change: the last whole period's average minus the first whole period's, so a week the range cuts short does not count.

NameTypeReqDescription
aggregation––day, week or month. Chosen from the range when left out.
endstringyesLast day, inclusive.
metricstringyesOne of the metrics listed above.
startstringyesFirst day, inclusive.
NameTypeReqDescription
aggregationstringyes–
endstringyes–
metricstringyes–
pointsarray––
startstringyes–
summaryobject––
unitstringyes–

No examples provided.

get_workout ~124

Return one saved workout by id: name, sport, description and estimated duration, with Garmin's full definition (every step, target and repeat) under raw. Use it to see what a plan asks for before scheduling or pushing it, or to check what create_strength_workout or create_endurance_workout built. Ids come from list_workouts or list_scheduled_workouts. A completed session is an activity: read it with get_activity or get_activity_sets.

NameTypeReqDescription
workout_idintegeryesFrom list_workouts or list_scheduled_workouts.
NameTypeReqDescription
description–––
estimated_duration_s–––
name–––
raw–––
schedule_id––Set when the workout was just scheduled: what unschedule_workout takes.
scheduled_on––Set when the workout was just scheduled: its calendar day.
sport–––
updated–––
workout_idintegeryes–

No examples provided.

list_activities ~139

List activities, newest first. Completed activities, not planned workouts. Filter by type and by date range; end_date needs start_date. For strength sessions pass activity_type=strength_training, then fetch the sets of one to see the exercises, reps and weights.

NameTypeReqDescription
activity_type––Garmin type key, e.g. "strength_training", "running", "cycling".
end_date––Latest date, inclusive.
limitinteger–Most activities to return.
startinteger–Activities to skip, for paging. An offset, not a date.
start_date––Earliest date, inclusive.
NameTypeReqDescription
resultarrayyes–

No examples provided.

list_devices ~80

List the Garmin devices paired with the account: device_id, name, product, and which one is the primary activity tracker. Use it to pick the device_id push_workout_to_device takes. A push without one prefers the device last used, which this does not show, so pass device_id when the device matters. One Garmin request.

Input schema present but exposes no named parameters.

NameTypeReqDescription
resultarrayyes–

No examples provided.

list_scheduled_workouts ~140

List the workouts scheduled on the Garmin calendar in one month, with each entry's schedule_id, workout_id and date. Only planned workouts are returned: the completed activities, naps and badges Garmin's calendar also holds are dropped, as are the neighbouring months' days its grid spills into. For sessions done on those dates use list_activities; for the saved workouts whether scheduled or not, list_workouts. The schedule_id is what unschedule_workout takes.

NameTypeReqDescription
monthintegeryes1 for January to 12 for December.
yearintegeryesCalendar year, e.g. 2026.
NameTypeReqDescription
resultarrayyes–

No examples provided.

list_weigh_ins ~112

List every weigh-in from start to end (end defaults to start), oldest first, with body composition and the sample_pk that delete_weigh_in takes. Includes every reading on days with more than one. For weight or body fat as one value a day with an average and the change, use get_trend with metric weight or body_fat; get_day_summary gives the day's last weigh-in.

NameTypeReqDescription
end––Last day, inclusive.
startstringyesFirst day, inclusive.
NameTypeReqDescription
resultarrayyes–

No examples provided.

list_workouts ~124

List the saved workouts in the account's library: plans to follow, with name, sport and estimated duration but not their steps. A saved workout is not on the calendar until scheduled: for what is planned on which date use list_scheduled_workouts, and for sessions already done, list_activities. For one workout's full step structure, get_workout. Paged: start skips that many workouts.

NameTypeReqDescription
limitinteger–Most workouts to return.
startinteger–Workouts to skip, for paging. An offset, not a date.
NameTypeReqDescription
resultarrayyes–

No examples provided.

log_strength_session ~244

Log a completed strength session to Garmin Connect as an activity. Takes the session as it happened, exercise by exercise with the reps and weight of every set, encodes it as a FIT activity file and uploads it. It appears in Garmin Connect as a Strength Training activity with the sets intact, named after the session, with its notes as the description. If the account shares to Strava or another app, the activity may be posted there too, publicly, and deleting it from Garmin does not delete it there. Name exercises with Garmin's category and exercise_name pair, which find_exercise gives. Logging the identical session again is reported as a duplicate and changes nothing; logging it with any set changed creates a second activity, so correct one with edit_activity_sets.

NameTypeReqDescription
exercisesarrayyesThe exercises in the order done, each with its sets.
namestring–The activity's title in Garmin Connect.
notes––Saved as the activity's description.
start_timestringyesWhen the session started. Without an offset, it is taken as local time in the Garmin account's own timezone.

Structured output declared, but exposes no named fields.

No examples provided.

match_exercise ~150

Map one free-text exercise name, such as one exported from another app, onto exactly one catalogue exercise, or return null when no single match is certain. Use it when converting names from another source, where a wrong guess would log the wrong lift. To browse candidates and choose, use find_exercise, which returns a ranked list. Only a certain match is returned: the exact or normalised name, the same words up to a typo, plural or hyphenation, or a search with one hit that adds at most an implement (barbell, dumbbell, kettlebell). No Garmin request.

NameTypeReqDescription
namestringyesA free-text exercise name.
NameTypeReqDescription
result–yes–

No examples provided.

push_workout_to_device ~157

Queue a saved workout for one of the account's watches; it arrives at the watch's next sync, not immediately. Without device_id it goes to the device last used, if it is on the account's list, else the primary activity tracker, else the only device; when none of those settles it, the call is refused and asks for a device_id. list_devices gives the ids, and the reply names the device chosen. Pushing does not schedule it: to put it on a date, use schedule_workout.

NameTypeReqDescription
device_id––From list_devices. Left out, chosen as described.
workout_idintegeryesFrom list_workouts or list_scheduled_workouts.

Structured output declared, but exposes no named fields.

No examples provided.

recent_strength_sessions ~180

List the most recent completed strength sessions, newest first, each with its exercises, reps and weights and its total volume (reps times weight over the working sets). One call instead of list_activities plus get_activity_sets per session. It takes no dates: for a period, use list_activities with activity_type strength_training and start_date. Its sets carry no set_number, so read a session with get_activity_sets before correcting it with edit_activity_sets. One Garmin request per session plus one, and one more the first time in a process (the activity types); a session whose sets cannot be read carries sets_error, and a rate limit stops the call.

NameTypeReqDescription
countinteger–How many sessions, newest first.
include_setsboolean–False for the list alone, in one request.
NameTypeReqDescription
resultarrayyes–

No examples provided.

schedule_workout ~98

Put a saved workout on the calendar for a date. Returns the calendar entry. Its schedule_id, not the workout id, is what unschedule_workout takes. Scheduling again adds a second entry; to move a workout to another day, unschedule the old entry first.

NameTypeReqDescription
daystringyesThe date to schedule it on.
workout_idintegeryesFrom list_workouts or list_scheduled_workouts.
NameTypeReqDescription
day–––
name–––
raw–––
schedule_id––The calendar entry's id, which unschedule takes.
sport–––
workout_id–––

No examples provided.

unschedule_workout ~106

Remove one entry from the Garmin calendar; the saved workout itself is kept. Takes the schedule_id from list_scheduled_workouts, schedule_workout, or a create_* call made with schedule_date; not the workout_id. To move a workout, unschedule it and schedule_workout it on the new date. To delete the workout itself, use delete_workout.

NameTypeReqDescription
schedule_idintegeryesThe calendar entry's id, not the workout's.

Structured output declared, but exposes no named fields.

No examples provided.

update_activity ~117

Rename an activity, replace its description, or both; what is not given is left as it is. For a strength session's exercises, reps or weights use edit_activity_sets; to remove the activity, delete_activity. The new text replaces the old. Name and description are separate Garmin requests, so if the second fails the first still stands.

NameTypeReqDescription
activity_idintegeryesGarmin's activity id, from list_activities.
description––The new description, replacing the old.
name––The new title.

Structured output declared, but exposes no named fields.

No examples provided.

week_summary ~145

Summarise the seven days ending on end_day (default today, in the account's timezone): each day's steps, resting heart rate, sleep hours and morning readiness, plus the activities started in that window (up to 50). For one day in full use get_day_summary; for one metric over longer ranges, get_trend, which costs far fewer requests per day. This makes three Garmin requests per day plus one for the activities, over 20 in all, so do not call it repeatedly. A night's sleep belongs to the day it ended on.

NameTypeReqDescription
end_day––Last day of the seven, YYYY-MM-DD. Default: today.

Structured output declared, but exposes no named fields.

No examples provided.

Install

How do I install the Garmin Connect MCP server?

Garmin Connect runs locally as a PyPI package, launched with uvx garmin-connect-api. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

pypi · garmin-connect-api

# add to Claude Code
claude mcp add happyc0der-garmin-connect-api -- uvx garmin-connect-api
Common questions

What is the Garmin Connect MCP server?

Garmin Connect is an MCP server listed in the public MCP registry as io.github.happyc0der/garmin-connect-api. Read and write Garmin Connect: activities, strength sets, health data, workouts and weigh-ins. This page covers its PyPI package (garmin-connect-api).

Is the Garmin Connect MCP server safe to use?

Garmin Connect scores 69 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 24 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Garmin Connect MCP server expose?

Garmin Connect exposes 38 tools: garmin_status, find_exercise, recent_strength_sessions, week_summary, list_activities, and 33 more. Their descriptions and schemas cost roughly 5,543 tokens of context every time the server is loaded.

Is the Garmin Connect MCP server still maintained?

Garmin Connect is still listed as active in the MCP registry. We last reached this channel on 24 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the Garmin Connect MCP server under?

Garmin Connect declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.