garmin-personal-mcp
Provides read-only access to a user's Garmin Connect data through Garmin's Personal API, including activities and activity details/workouts/FIT files, daily wellness summaries, steps, stress, Body Battery, heart rate and HRV, blood oxygen, sleep, weigh-ins and body composition, fitness age, heart-rate zones, hydration, nutrition, profile settings, and menstrual cycle data.
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-personal-mcp
Connect your own Garmin Connect data to Claude (or another MCP client) and ask it about your sleep, training, heart rate, weight and more.
The connector runs as a Cloudflare Worker on the free plan. It uses Garmin's Personal API, which gives you read-only access to your own data with a key you create yourself. The whole server is one JavaScript file with no dependencies, so you can read it before you deploy it.
You don't need a server or a computer that stays on. Setup takes about 15 minutes.
What you need
A Garmin Connect account with data in it
A free Cloudflare account
A Claude plan that lets you add custom connectors (Settings → Connectors)
Related MCP server: Garmin MCP Worker
How it works
Claude ──MCP──▶ your Cloudflare Worker ──Personal API──▶ Garmin Connect
(OAuth sign-in with (your API key, stored as
your passphrase) a Cloudflare secret)Claude connects to your Worker's /mcp address. The first time, your Worker shows
a sign-in page where you type an owner passphrase that only you know. After that,
Claude calls the tools below, and the Worker fetches the data from Garmin with your
key.
Setup
1. Create a Garmin API key
Sign in at connect.garmin.com, open Settings → Personal API Key, or go straight to the key page.
Choose Create Key, accept the terms and pick an expiry. 90 days is a sensible start. Garmin emails you a week before it runs out.
Copy the key now and store it in a password manager. Garmin shows it only once.
2. Create an owner passphrase
Make a long random passphrase, for example five or more random words from your password manager's generator. You type it once, when you connect Claude. It stops anyone else from connecting to your Worker, even if they find its address. Don't reuse a password from somewhere else.
3. Deploy the Worker
Everything happens in the Cloudflare website. You don't need to install anything.
In the Cloudflare dashboard, open Workers & Pages, click Create application and choose Start with Hello World!. Name it
garmin-mcpand click Deploy.Click Edit code. Select everything in
worker.jsand delete it.In this repo, open
src/index.jsand click the Copy raw file button (top right of the file view). Paste it intoworker.jsand click Deploy.Open the Workers KV page, click Create instance, name it
OAUTH_KVand click Create.Go back to your
garmin-mcpWorker. Under Settings → Bindings, choose Add binding → KV namespace. Set the variable name toOAUTH_KV, pick theOAUTH_KVnamespace and click Add Binding.Under Settings → Variables and Secrets, click Add and enter these three, then click Add variables and deploy:
Key
Value
Type
GARMIN_API_KEYyour key from step 1
Secret
OWNER_PASSPHRASEyour passphrase from step 2
Secret
TIMEZONEyour time zone, e.g.
Europe/CopenhagenorAmerica/New_YorkText
Find your Worker's address on its overview page, for example
https://garmin-mcp.yourname.workers.dev. Open it in your browser. You should seePrivate Garmin MCP server.If you seeNot configured, a secret or the KV binding is missing.
4. Connect Claude
In Claude, open Settings → Connectors → Add custom connector.
Name:
Garmin. URL: your Worker's address with/mcpon the end, for examplehttps://garmin-mcp.yourname.workers.dev/mcp.Click Add, then Connect. Your Worker's sign-in page opens. Enter your owner passphrase and choose Allow read-only access.
The connector then works in Claude on the web, desktop and phone. In the connector's settings you can set each tool to Always or Ask.
Try: "How did I sleep this week?" or "Compare my resting heart rate this month with last month."
Updating
When this repo gets a new version, open your Worker in Cloudflare, click Edit
code, replace everything in worker.js with the new src/index.js
and click Deploy. Your key, passphrase and storage stay as they are. If the
new version adds or renames tools, disconnect and reconnect the connector in
Claude so it picks them up.
Tools
Each tool reads one part of Garmin's Personal API. Together they cover every endpoint in it.
Tool | Returns |
Activities | Activities in a date range: distance, time, pace, heart rate, time in each heart-rate zone, training effect and load. Takes Garmin's search filters. |
Activity details | One activity in full, with laps and splits |
Activity workouts | The structured workout you followed in an activity, step by step |
Activity file (FIT) | The original file your watch recorded, as a download |
Wellness activities | Activities Garmin records outside workouts |
Daily summaries | One row per day: steps, resting heart rate, calories, intensity minutes, stress, Body Battery, breathing, SpO2 |
Day details | Garmin's full wellness summary for one day |
Daily steps | Steps, distance and step goal per day |
Daily stress | Stress level and time at each stress level per day |
Body Battery | Charged, drained, highest and lowest per day, plus every reading |
Heart rate (one day) | A reading about every two minutes |
Heart-rate variability | Nightly HRV, 7-day average, baseline and status |
HRV readings (one night) | Every 5-minute HRV reading |
Blood oxygen (one day) | Hourly SpO2 averages and the day's figures |
Sleep | One row per night: score, stages, heart rate, breathing, SpO2 |
Sleep (one night) | Everything Garmin has on one night |
Weigh-ins | Every weigh-in with BMI and body composition |
Weight by day | Lowest, highest and latest weight per day |
Weight goal | Your weight goal |
Fitness age | Fitness age, achievable fitness age and what drives it |
Heart-rate zones | Your zones per sport |
Hydration | Water logged per day |
Nutrition log | Food logged for one day |
Profile settings | Units, time zone, training days |
Menstrual cycle summary | Cycle summary for a date |
Menstrual cycle day | Detailed cycle view for one day |
Dates are YYYY-MM-DD in your own time zone. Range tools accept an optional
fields list, so an app can ask for only the columns it needs.
Security
Read-only. Garmin's Personal API can't change, delete or post anything.
Only you can connect. Connecting requires your owner passphrase. After 10 wrong attempts in a day, sign-in locks until midnight UTC.
Sign-ins only go to approved apps. By default the Worker sends sign-ins only to
claude.aiandclaude.com.Your Garmin key stays secret. It lives in a Cloudflare secret, and the Worker sends it only to Garmin's token service.
Tokens are stored hashed. Someone who could read your KV storage still couldn't use the sign-in tokens in it.
Fewer personal details. The Worker removes GPS coordinates, routes, other people's names and likes, and account IDs from answers. "Activity details" can include start and end coordinates if you ask for them.
Cached answers. To spare Garmin's rate limit, the Worker keeps answers in memory for 5 minutes. It also stores answers that cover only past days in your KV for 6 hours. Only your Worker can read them.
Kill switches
To | Do this |
Stop all Garmin access at once | Delete the key in Garmin Connect → Settings → Personal API Key |
Sign every connected app out | Under Settings → Variables and Secrets, add a Text variable |
Remove everything | Delete the Worker and the |
Other MCP clients
The Worker speaks standard MCP (Streamable HTTP) with OAuth 2.1, dynamic client
registration and PKCE, so other MCP clients can use it too. Add the host your
client sends sign-ins back to as a Text variable under Settings → Variables
and Secrets: ALLOWED_REDIRECT_HOSTS, comma separated. Keep the defaults in the
list, for example claude.ai,claude.com,app.example.com. For a client that signs in
through localhost, such as some desktop and command-line apps, also add
ALLOW_LOCALHOST_REDIRECTS with the value true. Every client still needs your
passphrase to connect.
Cost
Nothing, for one person. Cloudflare's free plan allows 100,000 Worker requests a day, and Garmin's Personal API and Claude's custom connectors cost nothing extra. Cloudflare doesn't bill a free account when it hits a limit: requests fail until the next day.
Limits
Garmin's Personal API is for one person's own data. For apps that serve other people, Garmin points to its Developer Program. Run one Worker per person.
Garmin's Personal API has no endpoints for training status, race predictions or VO2 max history, and activities come back without their VO2 max value.
Garmin keys expire after at most a year. Create a new one and replace the
GARMIN_API_KEYsecret.Garmin limits how fast you can call it. The Worker waits and retries when Garmin answers 429, and caching keeps repeat questions cheap.
Blood oxygen for the current day can fail early in the morning, before Garmin has readings for it. Earlier days work.
Troubleshooting
You see | Fix |
| Add both secrets and the |
"Garmin rejected the API key" | The key expired or was deleted. Create a new one and replace |
"Garmin is rate-limiting requests" | Wait a few minutes and ask again |
"Redirect URI not allowed" on the sign-in page | Your app's host is missing from |
"Too many attempts" | Sign-in locks for the rest of the UTC day after 10 wrong passphrases |
New tools don't show up after an update | Disconnect and reconnect the connector in Claude |
Development
You only need this to work on the code, not to use it. With Node.js 20 or newer:
npm testThe tests run the Worker in Node.js against a simulated Garmin and a simulated OAuth client. They cover the sign-in flow, every tool, input checks, caching and retries.
License
MIT. This project is not affiliated with Garmin or Anthropic.
This server cannot be deployed
Maintenance
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.
Pace is a remote MCP server that exposes wearable and fitness data to Claude via the Model Context Protocol. It connects to Garmin, Oura, Whoop, Polar, Fitbit and 20+ devices and provides 15 tools for querying sleep, activity, recovery, and training data. Hosted on Google Cloud Run, OAuth 2.1 authentication, Streamable HTTP transport. Instructions: First you need to create an account at: https://pacetraining.co and connect your wearables. After that you can connect the remote Server via Custom Connector in Claude and OAuth 2.1 Flow startet.
tri-train is a training platform for triathletes that syncs activities from Strava and Garmin and exposes them to Claude through a remote MCP server. Ask Claude how your last block went, why your run pace dropped, or whether you are fresh enough for Sunday's race, and it answers from your real data: activities with laps and grade-adjusted pace, weekly load and the performance management chart (CTL/ATL/TSB), sleep, HRV and resting heart rate, and your race calendar with predictions. Claude can also act: create and adjust planned workouts with structured intervals, push them to your Garmin watch, add races and write notes. Every change is journaled and can be undone. Read and write access are separate OAuth scopes, and the server enforces them on every call. Built and hosted in Switzerland by a triathlete; data stays on our own servers (Swiss revDSG / GDPR).
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables users to connect ChatGPT or remote MCP clients to their own Garmin cloud health and activity data through a self-hosted, read-only OAuth-protected Cloudflare Worker.378 npmMIT
- AlicenseNot gradedqualityCmaintenanceA read-only remote MCP server that lets Claude query your own Garmin Connect data — sleep, HRV, Body Battery, stress, heart rate, and activities — through Garmin's official Personal API. It runs on Cloudflare Workers with OAuth sign-in, so it works from both the Claude mobile app and desktop.MIT
- AlicenseNot gradedqualityCmaintenanceA read-only remote MCP server that connects Claude to your own Garmin Connect account through Garmin's official Personal API, running on Cloudflare Workers with OAuth sign-in so it also works in the Claude mobile app. It lets you ask natural-language questions about sleep, HRV, resting heart rate, Body Battery, stress, daily summaries and activities across date ranges.MIT
- AlicenseNot gradedqualityCmaintenanceEnables Claude and other remote MCP clients to query your own read-only Garmin Connect data — recovery trends, sleep, HRV, Body Battery, stress, heart rate, and activities — through Garmin's official Personal API, with OAuth sign-in that works from the mobile apps as well as desktop. Deploys on Cloudflare Workers' free tier with no password sharing or scraping.MIT