Garmin Health MCP Server
Garmin Health MCP Server
A remote MCP server that exposes your Garmin Connect health data as tools that Claude (or any MCP-compatible client) can call. Runs over Streamable HTTP so it can be added as a custom connector on claude.ai.
⚠️ Disclaimer: This project uses the unofficial
garminconnectlibrary, which authenticates with your Garmin email/password instead of Garmin's official OAuth partner API. This approach is common for personal projects but is against Garmin's Terms of Service — use it knowing that risk.
Features
10 ready-to-use health tools (steps, sleep, HR, HRV, stress, Body Battery, activities, and more)
Bearer-token auth so only you can access your data
Session caching — logs in once, reuses the token for months
Docker-ready for deployment on any host (Fly.io, Render, Railway, VPS, etc.)
Project structure
File | Purpose |
MCP server (FastMCP + Streamable HTTP) — defines all tools | |
Garmin session handling, retry-on-expiry | |
Run locally once to complete MFA and save the session | |
Sanity-check that the cached token is still valid | |
Container for deployment | |
Required environment variables |
Available tools
Tool | Description |
| Steps, calories, floors climbed, resting HR, distance |
| Resting HR, min/max, and full time-series |
| Duration, stages (Deep/Light/REM/Awake), sleep score |
| Body Battery (energy reserve) levels |
| Stress level readings throughout the day |
| Heart Rate Variability status |
| Weight, body fat %, muscle mass |
| Latest recorded workouts, newest first |
| Full details for one activity by ID |
| 7-day rollup of daily summaries |
All target_date / start_date parameters accept YYYY-MM-DD. Omit them to default to today.
Setup
1. Clone & install
git clone https://github.com/<you>/garmin-mcp-server.git
cd garmin-mcp-server
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt2. Configure environment
cp .env.example .env
# Edit .env — fill in GARMIN_EMAIL, GARMIN_PASSWORD, and MCP_AUTH_TOKENGenerate a strong MCP_AUTH_TOKEN:
python -c "import secrets; print(secrets.token_urlsafe(32))"3. Handle MFA locally (one-time)
Garmin may challenge the first login with an MFA code. A headless server can't answer that prompt, so do the interactive login on your own machine first:
python login_once.pyThis saves a garmin_tokens/ directory containing the session token. Garmin
tokens typically stay valid for months — the server auto-refreshes them.
Verify it worked:
python test_connection.py4. Deploy the server
Build and run locally:
docker build -t garmin-mcp .
docker run -d -p 8000:8000 \
-v $(pwd)/garmin_tokens:/data/garmin_tokens \
--env-file .env \
garmin-mcpFor cloud deployment (Fly.io, Render, Railway, etc.):
Mount a persistent volume at
/data— copy your localgarmin_tokens/folder into/data/garmin_tokenson it so the container resumes the session without needing a fresh login.Set these environment variables on the host:
GARMIN_EMAILandGARMIN_PASSWORD— fallback credentials for full re-loginMCP_AUTH_TOKEN— the secret you generated above
Expose port
8000. Your MCP endpoint will behttps://your-domain.com/mcp.
Connect to Claude
In claude.ai → Settings → Connectors → Add custom connector
Enter your server URL:
https://your-domain.com/mcpOpen Advanced settings → Request headers and add:
Key:
AuthorizationValue:
Bearer <your MCP_AUTH_TOKEN>
Save, then enable the connector in a conversation.
Note: Request-header auth is currently a beta feature on claude.ai. If you don't see it yet, check back soon or swap the middleware in
server.pyfor OAuth.
Running locally (without Docker)
source venv/bin/activate
python server.py
# Server starts at http://localhost:8000/mcpNotes & limitations
Single-user only — this server is designed for your personal Garmin account.
Unofficial API — Garmin may change internal endpoints at any time and break the
garminconnectlibrary. A quickpip install -U garminconnectusually fixes it.Keep your token secret — anyone with
MCP_AUTH_TOKENcan read your Garmin health data through this server. Treat it like a password.Token expiry — if Garmin invalidates your session (e.g. after a password change), re-run
login_once.pylocally and upload/mount the refreshed token store.
License
MIT
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/AryanP45/garmin-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server