Skip to main content
Glama
Morozov90

Garmin Training MCP

by Morozov90

Garmin Training MCP

Read your Garmin activities, sleep, HRV and daily health summaries in Codex or Claude Code. The server runs locally on macOS and uses Garmin's official Python client and the official MCP Python SDK.

This project is unofficial and is not affiliated with Garmin.

Install

You need macOS, Python 3.12 or newer, uv, and a Garmin Connect Personal API Key. The examples use Python 3.13.

Check that the PyPI package launches:

uvx --python 3.13 --from garmin-training-mcp==0.1.1 garmin-mcp --help

You don't need to clone the repository. uvx downloads the package and dependencies on first launch, then uses its cache. garmin-training-mcp is the package name; garmin-mcp is the command it provides.

Related MCP server: garmin-mcp

Connect your client

Create a key on the Garmin Personal API Key page. Replace YOUR_GARMIN_PERSONAL_API_KEY below with your key in your local configuration. Keep it out of Git, chat messages and shared examples.

Codex

Add this entry to ~/.codex/config.toml, or update the existing garmin-training entry:

[mcp_servers.garmin-training]
command = "uvx"
args = ["--python", "3.13", "--from", "garmin-training-mcp==0.1.1", "garmin-mcp"]

[mcp_servers.garmin-training.env]
GARMIN_PERSONAL_API_KEY = "YOUR_GARMIN_PERSONAL_API_KEY"

Codex allows 60 seconds per tool call by default. If Garmin calls time out, add tool_timeout_sec = 180 under [mcp_servers.garmin-training], before the .env table. See the Codex timeout settings.

Claude Code and other JSON clients

Add this entry under mcpServers in your client's configuration. Claude Code uses ~/.claude.json for user settings.

{
  "mcpServers": {
    "garmin-training": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--python", "3.13",
        "--from", "garmin-training-mcp==0.1.1",
        "garmin-mcp"
      ],
      "env": {
        "GARMIN_PERSONAL_API_KEY": "YOUR_GARMIN_PERSONAL_API_KEY"
      }
    }
  }
}

If your client can't find uvx, run command -v uvx in Terminal and use the full executable path as command. Keep the package name in args as shown.

Fully quit and reopen your client, then try:

Use Garmin to compare my last two runs. What was my average pace?

Use Garmin to summarize my sleep from the last seven days.

Check the results against Garmin Connect. --help confirms installation; a successful Garmin tool call confirms authentication.

Save the key in a separate file

If you prefer to keep the key out of client configuration, run:

uvx --python 3.13 --from garmin-training-mcp==0.1.1 garmin-mcp setup

The prompt hides your input and saves the key to:

~/Library/Application Support/garmin-training-mcp/personal-api-key

Use the client examples above with the env block or .env table removed. An environment key overrides this file; an empty value is an error.

Available tools

Tool

Returns

list_activities

Activities in a date range, with distance, duration, speed, HR and power where available

get_activity

Activity metrics and a page of split summaries

get_sleep

Sleep duration, stages, scores and timestamps

get_hrv

Overnight and weekly HRV summaries, baseline and status

get_daily_summary

Steps, resting HR, stress and Body Battery

Fields depend on what Garmin provides for your account and device. Missing data isn't zero. Split summaries may group several splits. GPS tracks, detailed samples and training readiness are unavailable in v1.

Dates use Garmin's calendar dates. Wellness queries accept up to 31 days; activity queries accept up to 366 days. The server returns speed in meters/second, which the AI client can convert to pace. See the capability matrix for coverage and the reference for units, date handling and pagination.

Privacy

The server reads Garmin data and caches bearer tokens locally. It writes no health data files or telemetry. Keys and tokens are stored as plaintext with owner-only permissions, outside the repository. The credential directory has mode 700 and its files have mode 600. Keys in client configuration also need restricted access.

Your AI client can send retrieved health data to its provider and retain it in chat history. Local backups or sync tools may also copy credential files. Review your client's privacy settings. See the security audit for the reviewed controls and limitations.

Test and troubleshoot

For a live check, choose a date with synced activity and wellness data:

uvx --python 3.13 --from garmin-training-mcp==0.1.1 garmin-mcp check --date YYYY-MM-DD

The check prints availability counts and statuses. It needs a saved key file or a key available in Terminal; Terminal doesn't inherit a key from your client's env block. An empty date result can mean there is no data for that day.

Problem

What to check

Server won't start

Run --help, check the uvx executable path, then restart the client.

missing_credentials

Set the key in client configuration or run setup.

authentication

Replace an expired or revoked key, then restart.

rate_limited

Wait for the reported retry delay before trying again.

Missing records

Check the date and Garmin Connect sync status.

The reference covers all error codes.

Updates and development

To upgrade, change the version in your client's args, run --help with that version, and restart the client. Keep your existing credentials.

For local development, locked dependencies, tests and removal instructions, see the reference. uvx resolves dependencies separately from the project's uv.lock.

License

MIT. Dependencies retain their own licenses.

Available Tools

5 tools
get_activityA
Read-onlyIdempotent

Get summary plus one page of feature/group split summaries, not guaranteed laps.

activity_id is a positive decimal string. Samples/GPS are unsupported in v1: setting either include flag returns an explicit unsupported error. No location data is returned. Follow pagination.next_offset to retrieve more split summaries.

NameRequiredDescriptionDefault
activity_idYes
include_gpsNo
split_limitNo
split_offsetNo
include_samplesNo

Output Schema

NameRequiredDescription
statusYes
recordsYes
end_dateNo
timezoneYes
warningsNo
paginationNo
start_dateNo
retrieved_atYes
missing_datesNo
date_semanticsYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnly, idempotent, non-destructive, openWorld), so the bar is lower, and the description still adds real context: no GPS/location data is returned, setting either include flag yields an explicit unsupported error, results are paginated, and laps are not guaranteed. It does not mention auth requirements or rate limits, which keeps it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences with no filler, and the core purpose is front-loaded. The opening clause 'not guaranteed laps' is cryptic out of context, but every sentence carries information the agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return shape need not be described, and the description covers the important behavioral gaps: unsupported flags, absent location data, and pagination continuation. The remaining gap is page-size/offset semantics for split_limit and split_offset, which neither schema nor description explains.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning and it only partly does: it defines activity_id's format (positive decimal string) and the failure behavior of include_gps/include_samples, and implies split_offset via the next_offset instruction. split_limit and split_offset's own semantics (max page size 100, offset bounds) are never explained in prose.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: retrieves an activity summary plus one page of split summaries, and flags that laps are not guaranteed. The 'feature/group split summaries' phrasing is jargon-heavy, but combined with the tool name and sibling set (list_activities, get_sleep, get_hrv, get_daily_summary) an agent can still tell what this returns and how it differs from a listing tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete usage constraints for the include flags (samples/GPS unsupported in v1, will error) and tells the agent to follow pagination.next_offset — genuinely useful invocation guidance. However it never states when to choose get_activity over list_activities or get_daily_summary, so the sibling routing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_daily_summaryA
Read-onlyIdempotent

Daily steps, Garmin resting HR field (bpm), stress and Body Battery if present.

Inclusive ISO range <=31 days, end defaults to start. Garmin restingValue may fall back to absolute minimum HR. Stress/Body Battery retain Garmin's scale.

NameRequiredDescriptionDefault
end_dateNo
start_dateYes

Output Schema

NameRequiredDescription
statusYes
recordsYes
end_dateNo
timezoneYes
warningsNo
paginationNo
start_dateNo
retrieved_atYes
missing_datesNo
date_semanticsYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description goes beyond them with real interpretive caveats: fields appear only 'if present', Garmin's restingValue may fall back to absolute minimum HR, and stress/Body Battery keep Garmin's native scale. It doesn't say what happens when the 31-day cap is exceeded, but the domain caveats are genuinely useful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: what data first, then the range constraint, then data-quality caveats. Telegraphic style but every sentence carries distinct, non-redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return shape needn't be described, and annotations cover safety, so the description's job is range rules and field interpretation, which it does. The residual gap is sibling routing and the failure mode past 31 days.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description has to carry the load, and it does: ISO date format, inclusive bounds, the 31-day maximum, and end_date defaulting to start_date. Only start_date's role as the anchor of the range is left implicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the exact data returned (daily steps, Garmin resting HR in bpm, stress, Body Battery), which distinguishes it from siblings like get_sleep and get_hrv without ambiguity. It omits an explicit verb such as 'returns' and doesn't state the grain (per-day records) outright, but the resource is unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives the operative constraint for calling it: an inclusive ISO range capped at 31 days, with end_date defaulting to start_date. It offers no guidance on when to prefer this over get_hrv, get_sleep, or list_activities, so the agent must infer the boundary from the field list alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_hrvA
Read-onlyIdempotent

Reported overnight/weekly HRV averages and optional Garmin baseline/status.

Inclusive ISO range <=31 days, end defaults to start. Values retain Garmin's scale; units and sleep-start/wake-date association need live account verification.

NameRequiredDescriptionDefault
end_dateNo
start_dateYes

Output Schema

NameRequiredDescription
statusYes
recordsYes
end_dateNo
timezoneYes
warningsNo
paginationNo
start_dateNo
retrieved_atYes
missing_datesNo
date_semanticsYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, open-world semantics, and the description adds genuinely new context: a hard 31-day span limit, the end-date fallback, and a data-quality caveat that units and sleep-start/wake-date association are unverified. That caveat is behaviorally important since it warns the agent the values may not be directly comparable or time-aligned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with what is returned, followed by range rules and caveats. No filler; the only cost is the slightly awkward 'Reported overnight/weekly' phrasing, which takes a moment to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be explained, and the description instead covers the limits an agent could actually get wrong (span cap, default end date, unit ambiguity). What remains unstated is when baseline/status is or isn't included in the response, a minor gap for a read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load, and it does: ISO format, inclusive bounds, max 31-day span, and the end_date → start_date default. It stops short of clarifying null handling for end_date, but both parameters are otherwise meaningfully specified beyond the bare schema patterns.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the specific resource (HRV averages plus optional Garmin baseline/status), which is clearly distinct from siblings like get_sleep and get_daily_summary. The verb is only implied by 'Reported' rather than stated as an explicit action, so it's clear but not maximally crisp.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 31-day inclusive range and 'end defaults to start' give concrete calling constraints, implying a bounded date-range query. However, there is no explicit when-to-use vs. alternative guidance (e.g., HRV vs. get_sleep-derived metrics), leaving selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_sleepA
Read-onlyIdempotent

Sleep duration/stages in seconds, reported score components and window times.

Inclusive ISO range <=31 days, end defaults to start. Garmin calendarDate is preserved; wake-date versus sleep-start-date association requires live verification.

NameRequiredDescriptionDefault
end_dateNo
start_dateYes

Output Schema

NameRequiredDescription
statusYes
recordsYes
end_dateNo
timezoneYes
warningsNo
paginationNo
start_dateNo
retrieved_atYes
missing_datesNo
date_semanticsYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, non-destructive, open-world behavior, so the description's added value is the 31-day range ceiling, the end_date default, and the caveat that Garmin calendarDate is preserved while wake-date vs sleep-start-date association needs live verification. That is meaningful operational context an agent cannot get from structured fields. It does not mention failure behavior when the range is exceeded.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what is returned, then the range/default rules, then the calendarDate caveat — no filler. The final sentence is dense and slightly cryptic, but it is one line of real content rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, and the description covers range limits, defaults, and the date-association ambiguity. What is missing is error behavior past 31 days and any timezone note, which matters for a date-scoped sleep query.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry the parameters, and it does: dates are inclusive ISO dates, the range is capped at 31 days, and end_date defaults to start_date. The semantics of both parameters are clarified beyond the bare pattern in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states concretely what is returned: sleep duration/stages in seconds, score components, and window times. That is far more specific than the name alone, though it never explicitly distinguishes this from get_daily_summary, which likely overlaps on sleep content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a hard constraint (inclusive range of at most 31 days, end defaults to start) but no guidance on when to call this instead of get_daily_summary, get_hrv, or other siblings, and no exclusion conditions. The agent must infer the selection rule from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_activitiesA
Read-onlyIdempotent

List one activity page (max 100) within <=366 inclusive Garmin-local dates.

sport is a parent activity type key, e.g. running or cycling, not a subtype. Units: meters, seconds, m/s, bpm, watts. Follow pagination.next_offset.

NameRequiredDescriptionDefault
limitNo
sportNo
offsetNo
end_dateYes
start_dateYes

Output Schema

NameRequiredDescription
statusYes
recordsYes
end_dateNo
timezoneYes
warningsNo
paginationNo
start_dateNo
retrieved_atYes
missing_datesNo
date_semanticsYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, non-destructive, open-world, so the description's value-add is the page-size ceiling of 100, the 366-day maximum window, and the fact that dates are interpreted as Garmin-local. Those are genuine constraints beyond the annotations, though result ordering and empty-result behavior remain undisclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short, front-loaded lines with no filler; the hard constraints come first and the caveats follow. The "Units" sentence is terse to the point of ambiguity about which fields it applies to, which is a minor structural weakness rather than verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers the key caller-facing constraints for a paginated list tool with 0% schema description coverage. Gaps remain around offset interplay with next_offset and ordering, but nothing essential to a correct first call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden: it clarifies that `sport` is a parent activity type key rather than a subtype and gives examples, and it bounds the date window and page size. `limit` and `offset` semantics are only obliquely implied by "max 100" and "pagination.next_offset", leaving two of five parameters weakly documented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List one activity page") plus concrete scope constraints (max 100, <=366 inclusive Garmin-local dates), which an agent can act on immediately. It implies a paged-collection read distinct from the sibling get_activity, but never names or contrasts with that sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Follow pagination.next_offset" gives real operational guidance for iterating pages, and the sport note steers callers away from passing subtypes. However, there is no statement of when to use this tool versus get_activity or get_daily_summary, and no prerequisites or exclusions are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.0
    • First observedget_activity
    • First observedget_daily_summary
    • First observedget_hrv
    • First observedget_sleep
    • First observedlist_activities

TDQS

A3.8/5.0

Scored across 5 tools

Disambiguation4/5

Each tool maps to a distinct resource: activity listing, single-activity detail, sleep, HRV, and daily summary. The only mild overlap is that get_daily_summary, get_sleep, and get_hrv all return daily wellness data, but the descriptions make the boundaries clear (steps/stress vs. sleep stages vs. HRV averages). list_activities vs. get_activity is a standard, unambiguous list/detail pair.

Naming Consistency5/5

All five names follow the same snake_case verb_noun pattern (list_activities, get_activity, get_sleep, get_hrv, get_daily_summary). The singular/plural distinction (list_activities vs. get_activity) matches the collection-vs-single semantics rather than breaking the convention.

Tool Count4/5

Five focused read-only tools is a lean but defensible scope for a Garmin data server, and each tool earns its place. It sits at the thin end of the ideal 3-15 range given the breadth of the Garmin domain, but nothing is redundant or filler.

Completeness3/5

The read surface covers activities, sleep, HRV, and daily wellness, but notable gaps remain: workout/course data, training status/readiness, stress-only detail, body composition, and device info are absent. Activity samples/GPS are explicitly unsupported and lap retrieval is not guaranteed, creating potential dead ends for agents wanting intra-activity detail.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    B
    maintenance
    Enables retrieval of Garmin Connect data such as activities, sleep, heart rate, and body battery levels using unofficial API through MCP tools.
    4
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Provides read access to Garmin Connect health and training data (sleep, heart rate, stress, HRV, activities) and supports writes like creating workouts, editing activities, and exporting files.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Gives any MCP client local access to Garmin Connect sleep and nap data, recovery and Body Battery, training readiness and load, running tolerance, VO2 Max, race predictions, gear mileage and running summaries. It runs over stdio or Streamable HTTP and includes a credential-free demo mode with fictional sample data.
    2
    MIT