Content
# Garmin MCP
A Model Context Protocol server that exposes your Garmin Connect data
(steps, sleep, HR, HRV, stress, body battery, activities, training
readiness, body composition) to any MCP-compatible client.
Built with [FastMCP](https://gofastmcp.com) and
[python-garminconnect](https://github.com/cyberjunky/python-garminconnect).
Runs over HTTP with bearer-token auth — ready to deploy to Render.
## Tools
| Tool | What it returns |
| --- | --- |
| `get_user_profile` | Display name, full name, unit system |
| `get_daily_stats` | Steps, calories, resting HR, stress, body battery, intensity minutes |
| `get_steps_intraday` | Per-bucket step samples for one day |
| `get_daily_steps` | Daily totals across a date range |
| `get_heart_rates` | HR samples + resting HR |
| `get_sleep_data` | Stages, scores, SpO2, HRV, respiration |
| `get_stress_data` | Stress levels, rest vs. active durations |
| `get_body_battery` | Body battery values |
| `get_body_composition` | Weight, BMI, body fat, muscle mass |
| `get_floors` | Floors ascended / descended |
| `get_hrv_data` | Overnight HRV |
| `get_training_readiness` | Training readiness scores |
| `get_recent_activities` | Most recent activities |
| `get_activities_by_date` | Activities in a date range, optional type filter |
| `get_last_n_days_summary` | Daily stats for the last N days |
## Local dev (macOS / Linux)
```bash
pip install -r requirements.txt
cp .env.example .env
# fill in GARMIN_EMAIL, GARMIN_PASSWORD, MCP_BEARER_TOKEN
set -a && source .env && set +a
python server.py
```
## Local dev (Windows / PowerShell)
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
# set credentials for this PowerShell session
$env:GARMIN_EMAIL = "you@example.com"
$env:GARMIN_PASSWORD = "your-garmin-password"
$env:MCP_BEARER_TOKEN = "a-long-random-string" # optional
python server.py
```
If `Activate.ps1` is blocked, run once:
`Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`.
To load variables from a `.env` file instead of setting them inline:
```powershell
Copy-Item .env.example .env # then edit .env
Get-Content .env | Where-Object { $_ -match '^\s*[^#].+=' } | ForEach-Object {
$name, $value = $_ -split '=', 2
Set-Item "Env:$($name.Trim())" $value.Trim()
}
```
The token cache path is OS-aware (it lands in your Windows temp dir), so no
extra config is needed. Override it with the `GARMINTOKENS` env var if you
want the tokens to persist somewhere permanent.
## Verify it's running
Hit `http://localhost:8000/mcp` to confirm the server is responding (you'll
get a 4xx from a plain GET — that's expected; MCP clients do POST/SSE).
## Deploy to Render
[](https://render.com/deploy?repo=https://github.com/nmldias/GARMIN-MCP)
One click deploys the `render.yaml` blueprint — Render then prompts you for the
environment variables below. Or do it manually:
1. Push this repo to GitHub.
2. On [render.com](https://render.com): **New → Web Service → Connect GitHub →
pick this repo**. Render auto-detects `render.yaml`.
3. In the Environment tab, fill in:
- `GARMIN_EMAIL`
- `GARMIN_PASSWORD`
- `GARMINTOKENS_BASE64` (only if your account has MFA — see below)
- `MCP_BEARER_TOKEN` is auto-generated; copy it from the dashboard.
4. Deploy. When the build is green, your URL is
`https://<service>.onrender.com/mcp`.
### Handling MFA
The server runs non-interactively, so it can't prompt for an MFA code.
Bootstrap the tokens once locally:
```bash
pip install garminconnect
python bootstrap_tokens.py
# enter email + password + MFA code when asked
# copy the printed GARMINTOKENS_BASE64 blob into Render
```
The Garmin OAuth refresh token is good for ~1 year — set it once and forget.
## Connect an MCP client
Add the server as a custom connector in any MCP-compatible client:
- **URL**: `https://<service>.onrender.com/mcp`
- **Name**: `Garmin`
- **Authentication**: Bearer token → use `MCP_BEARER_TOKEN`
Enable the connector to use the tools.
## Security notes
- `MCP_BEARER_TOKEN` is the only thing between the internet and your
Garmin data — generate a long random value and rotate if leaked.
- Garmin credentials are kept in env vars, never written to the repo.
- Token cache lives under `/tmp/.garminconnect` on the server; Render's
filesystem is ephemeral, so the server re-uses cached tokens within an
instance lifetime and re-bootstraps from `GARMINTOKENS_BASE64` on cold
starts.
Connection Info
You Might Also Like
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...
pdf-mcp
Production-ready MCP server for PDF processing with intelligent caching....
kotadb
Local-only code intelligence API for AI developer workflows (Bun +...
gemini-api-docs-mcp
A remote HTTP MCP server for searching Google Gemini API documentation.