Skip to main content
Glama

garmin-mcp

Garmin Connect data (activities, sleep, heart rate, body battery) as MCP tools.

An MCP server built on the unofficial garminconnect library, which authenticates via the same SSO flow as the Garmin Connect mobile app. There's no official public API for personal Garmin data, so this reverse-engineered client is the standard approach.

Setup

1. Install dependencies

cd /Users/ronkatz/tools/garmin-mcp
uv pip install -e .

2. Set credentials

This account has no MFA, so there's no token setup step — every consumer just logs in with plain credentials on first use:

export GARMIN_EMAIL=you@example.com
export GARMIN_PASSWORD=yourpassword

3. Register with Claude

Add to ~/.claude.json under mcpServers (same pattern as google-docs):

"garmin": {
  "command": "uvx",
  "args": ["--from", "/Users/ronkatz/tools/garmin-mcp", "garmin-mcp"],
  "env": {
    "GARMIN_EMAIL": "you@example.com",
    "GARMIN_PASSWORD": "yourpassword"
  }
}

Restart Claude Code / Claude Desktop after adding this.

Related MCP server: Garmin Cache MCP Server

Tools

  • get_activities(limit=10) — recent workouts/activities

  • get_resting_heart_rate(cdate=None) — heart rate data for a date (defaults to today)

  • get_sleep(cdate=None) — sleep data for a date (defaults to today)

  • get_body_battery(startdate=None, enddate=None) — body battery levels for a date range (defaults to today)

Architecture

Auth and login logic (garmin_auth.py) is shared by every consumer in this repo:

garmin_auth.py  (get_client())
   ├── server.py               MCP server (stdio) — used by local Claude Code sessions
   ├── scripts/fetch.py        plain CLI, no MCP — ad hoc data pulls
   └── scripts/sync_calendar.py  daily Garmin -> Google Calendar sync,
                                  run by .github/workflows/garmin-calendar-sync.yml

scripts/fetch.py:

python3 -m scripts.fetch activities [--limit N]
python3 -m scripts.fetch resting-hr [--date YYYY-MM-DD]
python3 -m scripts.fetch sleep [--date YYYY-MM-DD]
python3 -m scripts.fetch body-battery [--start YYYY-MM-DD] [--end YYYY-MM-DD]

Garmin → Google Calendar sync

scripts/sync_calendar.py runs daily on a free GitHub Actions cron (.github/workflows/garmin-calendar-sync.yml, workflow_dispatch also available for manual runs). It's a plain deterministic script — no LLM involved at runtime:

  • Pulls Garmin activities from the last 2 days.

  • Matches each one to an existing calendar event by time overlap (±60 min on the same day); creates a new event at the activity's real start/end time if nothing matches.

  • Applies the standing convention: colorId "5" (yellow), title {activityName} ({distance}km), description Auto-added from Garmin: {distance}km, {duration} min, pace {pace}, {calories} cal.

Required GitHub repo secrets (Settings → Secrets and variables → Actions):

  • GARMIN_EMAIL, GARMIN_PASSWORD — same as local auth, no token needed.

  • GOOGLE_SERVICE_ACCOUNT_JSON — full JSON key of a Google Cloud service account with the Calendar API enabled. Share the target calendar with the service account's email address (Settings and sharing → Add people → grant "Make changes to events").

  • GOOGLE_CALENDAR_ID — the calendar to write to.

Local test run:

GARMIN_EMAIL=you@example.com \
GARMIN_PASSWORD=yourpassword \
GOOGLE_SERVICE_ACCOUNT_JSON="$(cat service-account.json)" \
GOOGLE_CALENDAR_ID=you@example.com \
.venv/bin/python3 scripts/sync_calendar.py

This replaced an earlier claude.ai scheduled routine that ran the same logic as an inline, un-versioned prompt script. That approach depended on a Garmin session token surviving between runs (via a GARMIN_TOKENS_B64 env var, later a dedicated git branch pushing/pulling the cached token file) and kept breaking: Garmin's refresh token is single-use, so any failed push left the next run stuck on an already-dead token. Since this account has no MFA, garmin_auth.py just logs in fresh with plain credentials every run instead — nothing cached, nothing to expire or desync between runs or consumers.

If Garmin ever adds MFA to this account, plain credential login will stop working unattended (no TTY to prompt for a code), and some form of token caching + refresh will need to come back for this workflow.

Credential rotation

If the Garmin password ever changes, update the GARMIN_PASSWORD GitHub secret — no other file or token needs to change, since nothing is cached.

Notes

  • This library is unofficial and reverse-engineered from Garmin's mobile app; it can break when Garmin changes internal endpoints.

  • Credentials live in ~/.claude.json's local env block, the remote routine's own env var settings, or a local, gitignored .env — never committed to main.

Available Tools

4 tools
get_activitiesC

Get recent Garmin activities/workouts.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax number of activities to return (default 10)

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations, the description carries full burden. It does not disclose behavioral traits like what 'recent' means (time frame), if it requires authentication, or any rate limits. The minimal description leaves ambiguity about the tool's behavior.

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?

Single sentence, no wasted words, and front-loaded. While concise, it could be slightly expanded without becoming verbose.

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

Completeness3/5

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

Given simple tool with 1 parameter and output schema, the description is adequate but lacks context on what 'recent' encompasses. Siblings are not discussed, so completeness is average.

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 coverage is 100% with the 'limit' parameter fully described. The tool description adds no extra meaning beyond the schema, so baseline 3 applies.

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 'Get recent Garmin activities/workouts' clearly states the verb and resource, distinguishing it from sibling tools that return different data (heart rate, sleep, body battery). However, it lacks specificity on whether it returns summaries or full details.

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?

No guidance on when to use this tool versus alternatives like get_resting_heart_rate. The description implies it returns recent activities but does not explain when a user should choose this over other tools.

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

get_body_batteryB

Get body battery levels for a date range.

ParametersJSON Schema
NameRequiredDescriptionDefault
enddateNoEnd date in YYYY-MM-DD format. Defaults to startdate.
startdateNoStart date in YYYY-MM-DD format. Defaults to today.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior2/5

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

No annotations are provided, so the description carries full burden. It only states the action without disclosing behavioral traits like authentication requirements, rate limits, or whether the operation is read-only. The description does not go beyond the basic purpose.

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?

The description is a single, clear sentence with no unnecessary words. It is appropriately front-loaded, conveying the tool's purpose immediately and efficiently.

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

Completeness3/5

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

The tool has a simple interface with two optional parameters and an output schema, so the description is adequate but not comprehensive. It does not explain what 'body battery' represents or specify data granularity (e.g., daily or hourly). However, since the output schema exists, return values are covered.

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?

The input schema already has 100% coverage with descriptions for both parameters (startdate and enddate). The description adds 'date range' but does not provide additional meaning beyond the schema, so a baseline score of 3 is appropriate.

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

Purpose5/5

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

The description clearly states the verb 'Get' and the resource 'body battery levels' along with the scope 'for a date range'. It is specific and distinguishes from sibling tools like get_activities, get_resting_heart_rate, and get_sleep, which target different health metrics.

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?

The description provides no guidance on when to use this tool versus alternatives, nor does it mention any prerequisites or exclusions. Given the simple retrieval nature, some context on typical use cases would be helpful.

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

get_resting_heart_rateC

Get heart rate data (including resting HR) for a date.

ParametersJSON Schema
NameRequiredDescriptionDefault
cdateNoDate in YYYY-MM-DD format. Defaults to today.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.8/5.0
Behavior1/5

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

No annotations provided, and description gives no behavioral details (e.g., read-only, authorization, rate limits). The description carries full burden for behavioral transparency but fails to disclose even basic traits like idempotency.

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?

Single sentence of 10 words, front-loaded and to the point. No wasted words. Could be slightly more informative without damaging conciseness.

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

Completeness3/5

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

Given simple 1-param tool with output schema and different siblings, the description is minimal but adequate. Tells what and when (date). Lacks behavioral context, but completeness is not severely lacking for a straightforward read tool.

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 100% (parameter 'cdate' has clear description). The description adds no parameter-specific meaning beyond schema; 'including resting HR' adds context for the tool but not for the parameter. Baseline 3.

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?

Describes verb 'Get', resource 'heart rate data (including resting HR)', and scope 'for a date'. Distinguishes from siblings (activities, sleep, body battery). Minor ambiguity about whether it returns only resting HR or broader HR data, but clear overall.

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?

No explicit guidance on when to use this tool versus alternatives. Only implicit context from date parameter. Siblings are different domains, so conflict is low, but no when/not-to-use info.

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

get_sleepB

Get sleep data for a date.

ParametersJSON Schema
NameRequiredDescriptionDefault
cdateNoDate in YYYY-MM-DD format. Defaults to today.

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries full burden. It does not disclose behavioral traits such as read-only nature, potential caching, or data freshness. The description is too minimal to inform an agent of side effects or safety.

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?

The description is a single sentence with no wasted words. It is front-loaded with the essential purpose.

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

Completeness5/5

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

Given the simplicity of the tool (one parameter with full schema documentation, plus an output schema), the description is complete enough. The purpose and parameter format are clear, and return information is handled by the output schema.

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?

The input schema has 100% coverage with a description for the single parameter cdate. The tool description adds no extra meaning beyond the schema, but the schema itself is sufficient. Baseline 3 applies.

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 clearly states the verb 'Get' and resource 'sleep data' with scope 'for a date'. It distinguishes from sibling tools (get_activities, etc.) which are about different health metrics.

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?

No guidance is provided on when to use this tool versus alternatives. The description does not mention prerequisites, exclusion criteria, or typical use cases.

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. Dates show when Glama detected each change.

  1. 4 tool updatesv0.1.0
    • First observedget_activities
    • First observedget_body_battery
    • First observedget_resting_heart_rate
    • First observedget_sleep

TDQS

B3.4/5.0
Disambiguation5/5

Each tool targets a distinct health metric (activities, resting HR, sleep, body battery) with no overlap, making them easily distinguishable.

Naming Consistency5/5

All tools follow a consistent 'get_' prefix with snake_case noun patterns, e.g., get_activities, get_sleep.

Tool Count4/5

4 tools is slightly minimal for a health data server, but each tool covers a core metric and the set is well-scoped without being cluttered.

Completeness3/5

The server provides read-only access to a few common metrics, but lacks many standard Garmin data like steps, calories, or stress; notable gaps exist.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes personal Garmin wellness data through MCP tools for accessing summary, sleep, HRV, heart rate, stress, body battery, and historical data.
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables multi-user Garmin Connect API with local SQLite caching, providing activity, daily summary, and heart rate data via MCP tools.
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Exposes Garmin Connect health and activity data (steps, sleep, heart rate, etc.) via MCP tools, with built-in login and MFA support.
    -
  • F
    license
    A
    quality
    C
    maintenance
    Provides read-only access to your Garmin Connect health data, including sleep, HRV, body battery, stress, training readiness, and activities, through an MCP server.
    14
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ronkatz29/garmin-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server