Garmin MCP Worker
Provides read-only access to a Garmin Connect account through Garmin's official Personal API, exposing tools for morning recovery trends (overnight HRV with baseline and status, sleep score/stages, resting HR, Body Battery, stress), per-day summaries, detailed sleep and HRV data, body battery and stress reports, heart rate, activity search with compact rows (distance, pace, HR, cadence, power, elevation, training effect/load), full activity details with splits, profile info such as units, time zone and heart rate zones, plus a raw read-only GET escape hatch for any Personal API path.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Garmin MCP Worker
Ask Claude about your own Garmin data — from your phone or your desktop.
A read-only remote MCP server that connects Claude (or any MCP client with remote OAuth support) to your Garmin Connect account through Garmin's official Personal API. It runs on Cloudflare Workers' free tier and signs you in with OAuth, so it works in the Claude mobile app, not just on a desktop.
"Should I do intervals today?" · "How has my HRV trended this month?" · "Compare my last three long runs." · "Did short sleep hurt my next-day runs?"
Why this one
Official API | Works on phone | Auth | |
Local Personal API servers (stdio) | ✅ | ❌ desktop only | none — must not be exposed |
Cloud servers using Garmin's private login | ❌ breaks when Garmin changes login | ✅ | varies |
This project | ✅ | ✅ | OAuth 2.1 + PKCE |
Stable: Garmin's documented Personal API with a revocable key. No password, no scraping.
Free: fits comfortably in Cloudflare's free tier.
Model-friendly: compact rows, long ranges split for you, bulky sample arrays left out unless asked.
Current protocol: speaks MCP
2026-07-28(stateless,server/discover) and2025-03-26…2025-11-25.
Related MCP server: garmin-mcp-server
Tools
Tool | Returns |
| One row per morning: overnight HRV with status and personal baseline, sleep score/stages/need, resting HR, Body Battery, stress, intensity minutes. The best first call for "should I train hard today?" |
| Everything for one date: summary, sleep, HRV, Body Battery, activities |
| One night in detail · up to a year of nightly HRV |
| One night: score, sub-scores, stages, overnight vitals |
| Daily reports and events; optional hourly chunks |
| Raw daily wellness totals |
| Daily heart rate · daily stress |
| Compact activity rows: distance, pace/speed, HR, cadence, power, elevation, training effect, training load |
| One activity in full, with splits |
| Units, time zone and heart rate zones |
| Read-only GET on any Personal API path (escape hatch) |
All tools are annotated readOnlyHint: true.
Deploy
You need a free Cloudflare account and a Garmin Personal API key: sign in to Garmin Connect on the web, open Settings → Personal API, choose Create Key and copy it (it's shown once; pick up to a year of validity).
Option A — one click
Press Deploy to Cloudflare above. Cloudflare copies the repo to your GitHub account, creates the KV namespace, and asks for:
GARMIN_API_KEY— your Personal API keyLOGIN_PASSWORD— a long password you'll type when connecting ClaudeTIMEZONE— e.g.Europe/London(used for "today")
Option B — command line
Requires Node.js 20+.
git clone https://github.com/wesleysui/garmin-mcp-worker && cd garmin-mcp-worker
npm install
npx wrangler login
npx wrangler secret put GARMIN_API_KEY
npx wrangler secret put LOGIN_PASSWORD
npm run deploy # the KV namespace is created automaticallySet your time zone in wrangler.jsonc (vars.TIMEZONE) before deploying.
Connect Claude
In Claude (web), open the connector settings and choose Add custom connector.
URL:
https://garmin-mcp.<your-subdomain>.workers.dev/mcpPress Connect, enter your
LOGIN_PASSWORDon the sign-in page, choose Allow.Enable the connector in a chat. Connectors added on the web also appear in the mobile apps.
Other MCP clients that support remote servers with OAuth work the same way.
What the Personal API doesn't have
Training Readiness, Training Status, race predictions — not exposed. Use
garmin_get_recovery_trendand let the model reason from HRV, sleep and resting HR instead.VO2max — Garmin currently strips it from API data; read it from your watch.
Writing anything — the API is read-only, so no pushing workouts or courses to the watch.
Push notifications — data is pulled on request; new activities appear after your watch syncs.
Security
OAuth 2.1 with PKCE via Cloudflare's
workers-oauth-provider; tokens are stored only as hashes.The consent page shows which app is asking and where tokens go, can't be framed, and uses a one-time, browser-bound form.
One owner password, compared in constant time; 5 wrong attempts lock sign-in for 15 minutes.
The Garmin key lives only in Worker secrets and never appears in responses or logs.
Only
GETrequests ever reach Garmin; the token endpoint is blocked from the raw reader.
Found a problem? Please open a private security advisory rather than a public issue.
Maintenance
Key expiry: Garmin emails you about a week before. Create a new key and run
npx wrangler secret put GARMIN_API_KEY— no need to reconnect Claude.Staying signed in: Claude refreshes its access automatically; after 30 idle days you'll be asked for the password again.
Logs:
npx wrangler tail
Development
npm install
cp .dev.vars.example .dev.vars # fill in real values for local runs
npm run dev # http://localhost:8787
npm run typecheck
npm test # needs Bun; end-to-end with a fake Garmin API, no account neededThe test walks the whole path a client takes: discovery → dynamic client registration → consent page → password → token exchange → MCP calls in both protocol eras.
Layout: src/index.ts wiring · src/auth.ts sign-in and consent · src/mcp.ts protocol · src/tools.ts tools · src/garmin.ts API client · src/dates.ts date ranges.
Garmin's response shapes are only partly documented. If a field comes back empty for your device, open an issue with the tool name and (redacted) response.
Credits
Built on ideas and endpoint knowledge from garmin/connect-personal-api-python (Garmin's official client), Mason-Levyy/garmin-personal-mcp and Janhsen/ha-garmin-personal.
Disclaimer
This is an independent project, not affiliated with or endorsed by Garmin Ltd. Garmin and Garmin Connect are trademarks of Garmin Ltd. or its subsidiaries. Use it only with your own account, in line with Garmin's Personal API terms. Not medical advice.
License
Related MCP Connectors
MCP server for Withings health data — sleep, activity, heart, and body metrics.
Remote MCP server for training, nutrition, wellness, and performance data with OAuth 2.0.
Private health and fitness analytics through a secure remote MCP connection.
Adaptive running coach MCP server — training data, plans, and recovery for AI assistants.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceMCP server to interact with Garmin Connect, enabling retrieval of health, activity, and device data through natural language.65MIT
- FlicenseAqualityDmaintenanceMCP server that connects AI assistants to Garmin Connect health and fitness data, enabling natural language queries about workouts, sleep, heart rate, and more.29-
- AlicenseAqualityDmaintenanceMCP server that exposes Garmin Connect health and activity data (steps, sleep, stress, activities, etc.) via tools for querying, analysis, and visualization.17Apache 2.0
- AlicenseAqualityDmaintenanceMCP server for reading and querying Garmin Connect data, including activities, strength history, recovery, trends, and optionally creating workouts.12MIT