garmin-unofficial-mcp
Provides tools for retrieving health and training data from Garmin Connect, including sleep, HRV, body battery, training load, run details, body metrics, and training analysis.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@garmin-unofficial-mcpHow is my recovery and training load this week?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
garmin-unofficial-mcp

A local, single-user, read-only MCP server that gives Claude access to your own Garmin health and training data. It exposes composite tools — health snapshot, training status, recent runs, run detail, body metrics and training analysis — so Claude can ground recovery advice and workout recommendations in your actual sleep, HRV, training load and run history instead of guessing. Everything Garmin returns is cached day-by-day in a local SQLite database, so repeated questions don't repeatedly hit Garmin's servers.
Before you start
This uses the unofficial garminconnect library, which signs in with your
Garmin password and MFA code — not OAuth. There is no scoped, read-only
Garmin grant available to third-party apps today, so the token this stores is
full-account access. It is stored only on your own machine.
The server never writes to your Garmin account: no set_, add_, delete_,
upload_, import_, create_ or remove_ call exists anywhere in it,
deliberately.
See docs/privacy.md for exactly what is stored and where.
Related MCP server: Garmin Connect MCP Server
Requirements
Python 3.12 or newer
A Garmin Connect account
Optionally, the
claudeCLI, soinstall.shcan register the server for you
Install
git clone https://github.com/danielsuri/garmin-unofficial-mcp.git
cd garmin-unofficial-mcp
./install.sh
.venv/bin/garmin-unofficial-mcp login you@example.com
.venv/bin/garmin-unofficial-mcp doctorlogin prompts for your password and, if enabled, an MFA code. It needs a real
terminal — getpass fails without a TTY. doctor then checks that the stored
tokens are accepted, that a live call works, and that the cache directory is
writable.
install.sh creates .venv, installs the package into it, and finds the
claude CLI to register the server at user scope if found. It's idempotent —
safe to re-run any time; it never clobbers an existing venv or registration it
doesn't own. Pass --dev to also install the test extras, --dry-run to
preview every action without doing it, or --help for the full rundown.
On success, tokens are written to ~/.garminconnect. They're good for roughly
a year; after that (or if Garmin invalidates them) re-run login.
Check the install
.venv/bin/garmin-unofficial-mcp doctordoctor checks three things: that the stored tokens are accepted, that a live
call to Garmin actually succeeds, and that the cache directory
(~/.garmin-unofficial-mcp/) is writable. Healthy output looks like:
auth: OK (tokenstore accepted)
live call: OK (userProfileId=12345678)
cache path: OK (/Users/you/.garmin-unofficial-mcp/cache.db)Any FAIL line points at what to fix — usually re-running login if auth
fails, or a permissions problem if the cache path fails.
Register with Claude Code
install.sh does this automatically when it can find the claude CLI. To do
it by hand instead (or if it couldn't find claude):
claude mcp add -s user garmin-unofficial -- <your/install/dir>/garmin-unofficial-mcp/.venv/bin/garmin-unofficial-mcp serveThis runs the server over stdio. Once registered, a fresh Claude Code session will have the tools below available — MCP servers are loaded at startup, so the session you register from won't see them.
-s user matters: without it claude mcp add defaults to local scope, and
the tools appear only when you're working inside this repo. User scope makes
them available in every project, which is what you want for a personal health
server.
Note the registration is an absolute path into this repo's venv, so moving
or deleting the repo breaks it (re-run install.sh, or the command above,
after moving it). Tokens (~/.garminconnect) and the cache
(~/.garmin-unofficial-mcp/cache.db) live outside the repo and are unaffected by scope.
The tools
get_health_snapshot(days=7)— sleep (total/deep/light/REM/awake minutes, sleep score), HRV, body battery (the day's true high and low), resting heart rate, and stress over the window, plus rolling baselines. Use this to judge how recovered you are.get_training_status(weeks=4)— acute and chronic training load, the acute:chronic load ratio, VO2max, and training readiness score per day. Use this to judge whether training load is ramping safely.get_recent_runs(n=10)— your lastnruns with pace (average, moving, grade-adjusted, best), heart-rate zones, training effect and training load, VO2max, fastest splits, PR flag, calories, body-battery cost and elevation, plus weekly mileage rollups and race-time predictions. Use this to spot trends and prescribe a specific run.get_run_detail(activity_id=None)— one run in full: everythingget_recent_runsreports for that run, plus running dynamics (ground contact time and balance, vertical oscillation and ratio, stride length), power (average/normalized/max watts and power zones), respiration (average/max/min breaths per minute), min/max temperature, lap count, step count, activity name, and run/walk/idle time detection (run_walk: seconds spent running vs. walking vs. stopped, from Garmin's typed splits). Omitactivity_idfor the most recent run found in the last 56 days. Use this to deep-dive a specific run. Costs one extra Garmin API call beyondget_recent_runs(typed splits, for run/walk detection) — each of the other fields comes from the same activity recordget_recent_runsalready fetches.get_body_metrics(days=30)— weight, body fat, steps, calories, floors climbed, and intensity minutes, with simple weight and step trends.get_training_analysis(weeks=8)— the marathon-block view: within-run form indicators (efficiency factor, aerobic decoupling, ground-contact-time drift, duty factor, split pattern) for every run in the window, plus across-block trends (weekly mileage, ramp rate with the base it was computed from, HR-zone polarization, efficiency and decoupling trend, recovery coupling, VO2max trend). It computes; it does not advise. Costs two extra Garmin API calls per run it hasn't seen before (laps and typed splits), both cached permanently.
Arguments are clamped to a range the server can actually serve — days to
1–365, weeks to 1–52, n to 1–100, activity_id to a non-negative
64-bit value — so an out-of-range value narrows or widens to the nearest
bound (or, for an activity_id that matches nothing, yields a clean
all-null result) rather than failing.
Every tool returns a partial: true flag when it couldn't be certain all of
its data is fresh or complete — see Troubleshooting below.
Testing
.venv/bin/pytestThe suite covers the MCP tools, cache, fetcher and assemblers with fake Garmin clients — no network, no real account required.
Troubleshooting
Auth errors / "Garmin rejected the stored tokens" — your tokens expired or were revoked. Re-run
garmin-unofficial-mcp login you@example.comfrom a real terminal.partial: truein a tool's response — Garmin rate-limited a request or a connection failed transiently. The tool still returns whatever it has cached; treat the numbers as possibly incomplete or stale and try again later rather than assuming Garmin has no data.Weight fields are
null— this is normal on any day without a weigh-in.weight_kg,body_fat_pct, and the weight trend fields inget_body_metricsonly populate on days you actually stepped on a connected scale.
Licence
MIT — see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceA Model Context Protocol (MCP) server for Garmin Connect integration. Access your activities, health data, training metrics, and more through Claude and other LLMs.2250MIT
- Alicense-qualityDmaintenanceAn MCP server that gives Claude access to your Garmin Connect fitness and health data, including steps, sleep, activities, heart rate, and more.1MIT
- AlicenseAqualityBmaintenanceA read-only MCP server that gives Claude Desktop access to your Garmin Connect data — daily health metrics, sleep, activities, training status, and body composition.6MIT
- AlicenseAqualityBmaintenanceLocal MCP server that connects Claude Desktop with Garmin and Apple Health data to read training and recovery, estimate heart rate and pace zones, analyze performance, and create structured workouts.22MIT
Related MCP Connectors
Garmin data in Claude: 135 tools — activities, sleep, HRV, training, workouts. Free, open source.
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Danielsuri/garmin-unofficial-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server