garmin-coach
Provides read access to Garmin Connect health and training data, including daily health metrics, sleep, HRV, stress, heart rate, workouts, activities, and exercise history. With writes enabled, it can also create, schedule, and push workouts to Garmin devices.
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-coachHow did I sleep and what's my training readiness today?"
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-coach
A local stdio MCP server that gives Claude Code read access to your Garmin Connect account, plus a gated, allow-listed path for creating and scheduling workouts. Intended as the data layer for an AI training/fat-loss coach.
Architecture
Claude Code
↓ MCP (stdio, local subprocess — no network)
garmin_mcp.server 25 read-only tools (+6 when writes are enabled)
↓
garmin_mcp.client token-only auth, error normalisation
↓ python-garminconnect 0.3.11
Garmin Connect (HTTPS)
↓ device sync
Garmin Forerunner 970Everything runs on your Mac. The only network traffic is normal HTTPS to Garmin. Nothing is sent to a third party.
Related MCP server: Garmin Health MCP Server
Install
cd ~/Developer/garmin-coach
uv syncPython is pinned to 3.12 via .python-version. garminconnect requires ≥3.12.
Initial Garmin login — run this yourself
Credentials are only ever entered interactively, in your own terminal:
cd ~/Developer/garmin-coach
uv run python scripts/garmin_login.pyIt prompts for your email, then your password via getpass (hidden, never in
shell history), and handles an MFA code if Garmin asks. On success it mints
OAuth tokens and does a small harmless read to prove the session works.
If Garmin starts rate limiting, the script stops and tells you to wait — it does not retry in a loop, which is what gets accounts throttled harder.
Token storage and security
Tokens live in
~/.garmin-coach/tokens— outside the project, so they can never be swept into git.The directory is forced to
0700, every file inside to0600.Your password is used exactly once, to mint tokens. It is never stored, never written to
.env, never in MCP config, never in the repo.Token contents are never logged. Logging goes to stderr only (stdout is the MCP protocol channel).
Override the location with
GARMIN_TOKENSTORE=/some/path.
Treat ~/.garmin-coach/tokens as equivalent to your password. Anyone with
those files has full read/write access to your Garmin account.
Test the MCP
uv run python scripts/smoke_test.pyStage 1 runs without any Garmin auth — it exercises the stdio transport, tool discovery, the bundled exercise catalog, the workout builder, and the error paths. Stage 2 runs the live read tools, and is skipped automatically until you have logged in.
Connect to Claude Code
Already registered user-scoped (available in every project):
claude mcp add --scope user garmin -- \
/opt/homebrew/bin/uv run --directory ~/Developer/garmin-coach \
python -m garmin_mcp.server
claude mcp get garmin # check statusuv run --directory resolves the project's own virtualenv, so you never need
to activate anything manually.
Tools
Health — garmin_today, garmin_sleep, garmin_hrv, garmin_stress,
garmin_body_battery, garmin_heart_rate, garmin_recovery
Training — garmin_training_readiness, garmin_training_status,
garmin_hr_zones, garmin_performance_metrics, garmin_recent_activities,
garmin_activities_by_date, garmin_activity, garmin_strength_sets,
garmin_exercise_history
Workout library (read-only) — garmin_workouts, garmin_workout,
garmin_scheduled_workouts, garmin_search_exercises,
garmin_exercise_categories, garmin_resolve_exercise,
garmin_workout_step_formats, garmin_devices,
garmin_preview_strength_workout
All dates are ISO YYYY-MM-DD and default to today. Responses are normalised
and compact; a value Garmin did not return is omitted rather than guessed,
so "field absent" and "value is zero" stay distinguishable.
Write tools (disabled by default)
Not registered at all unless GARMIN_MCP_ENABLE_WRITES=1 is in the server
environment, and independently re-checked at call time:
garmin_create_strength_workout, garmin_create_cardio_workout,
garmin_update_workout, garmin_schedule_workout,
garmin_unschedule_workout, garmin_push_workout_to_device
This is an allow-list, not a passthrough. Deleting activities, gear, or
profile data is not exposed. garmin_unschedule_workout additionally requires
confirm=true.
To enable:
claude mcp remove garmin -s user
claude mcp add --scope user garmin -e GARMIN_MCP_ENABLE_WRITES=1 -- \
/opt/homebrew/bin/uv run --directory ~/Developer/garmin-coach \
python -m garmin_mcp.serverUse garmin_preview_strength_workout first — it builds and renders the exact
payload without uploading. Verify the structure before anything reaches your
calendar or watch.
Known Garmin limitations
The unofficial API does not expose everything the watch shows. The full
matrix — what's on the watch vs in Garmin Connect vs reachable via
python-garminconnect — is in docs/forerunner-970.md.
The ones that shape the coaching design:
No RIR/RPE field exists. Garmin has nowhere to put it.
Garmin stores one concrete rep target per set, not a range. A "5–8 @ 1 RIR" prescription cannot round-trip — push the concrete target (e.g. 6) and keep the programming rule in the coaching layer. Garmin is the execution interface, not the source of truth for the program.
Per-set heart rate is not available; HR is session-level only.
Auto-detected reps are often wrong for machines/cables until corrected in Garmin Connect.
Use
garmin_hr_zones, never computed zones. Zone 2 is a heart-rate range from your Garmin profile, not a hard-coded pace.
Re-authenticate or revoke
rm -rf ~/.garmin-coach/tokens # revoke locally
uv run python scripts/garmin_login.py # re-authenticateTokens auto-refresh, so this is only needed if the refresh token expires or you revoke it. To revoke server-side, change your Garmin password — that invalidates the tokens.
Remove from Claude Code
claude mcp remove garmin -s userThat only unregisters the server. To fully remove: also delete
~/.garmin-coach and ~/Developer/garmin-coach.
Troubleshooting
Symptom | Cause / fix |
| Run |
| Refresh token expired/revoked — log in again |
| Wait 15–30 min. Do not retry in a loop |
| Network down, or Garmin maintenance |
Tool returns | Garmin genuinely has no data for that date |
MCP not detected |
|
Set GARMIN_MCP_LOG_LEVEL=DEBUG for verbose stderr logging.
Garmin-MCP
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
- AlicenseBqualityAmaintenanceConnects Claude Desktop to Garmin Connect, enabling natural language queries of fitness activity data, health metrics, sleep analysis, workout management, and device information with 94 available tools.1101MIT
- AlicenseAqualityDmaintenanceEnables Claude Desktop to access and analyze Garmin wearable health data including sleep, HRV, Body Battery, and activity metrics. Users can query their health trends, track recovery, and generate interactive HTML dashboards using natural language.96MIT
- FlicenseNot gradedqualityCmaintenanceConnects Garmin watch data to Claude Desktop, allowing users to ask natural language questions about their health and activity data from Garmin Connect.
- AlicenseAqualityCmaintenanceEnables users to analyze their own Garmin Connect data—activities, sleep, HRV, Body Battery, training readiness—directly inside Claude Desktop.132MIT
Related MCP Connectors
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
Garmin data in Claude: 135 tools — activities, sleep, HRV, training, workouts. Free, open source.
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/Nahom101-1/Garmin-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server