Guide · Developers
Garmin MCP for Claude Code, Cursor and any MCP client
Garmin Community MCP is a standard remote MCP server over Streamable HTTP. If your client can add a remote server, it can talk to your Garmin. Here are the exact snippets.
Your two URL forms
| Form | Use when | Value |
|---|---|---|
| Header | The client can send custom headers (Claude Code, Cursor, most IDEs) | https://mcp.garmincommunitymcp.com/mcp + Authorization: Bearer gm_live_… |
| URL token | The client only takes a URL (Claude custom connectors, some web clients) | https://mcp.garmincommunitymcp.com/mcp/gm_live_… |
Both are on your dashboard. Prefer the header form where possible; URLs end up in logs more often than headers do.
Claude Code
claude mcp add --transport http garmin https://mcp.garmincommunitymcp.com/mcp \
--header "Authorization: Bearer gm_live_XXXXXXXXXXXXXXXXXXXXXXXX"
Add --scope user to make it available in every project. Check with /mcp inside Claude Code. Then try:
Pull my last 30 days of runs with get_garmin_data and write a small HTML dashboard of weekly volume and average HR.
Or in .mcp.json at the repo root (shared with your team, token via env):
{
"mcpServers": {
"garmin": {
"type": "http",
"url": "https://mcp.garmincommunitymcp.com/mcp",
"headers": { "Authorization": "Bearer ${GARMIN_MCP_TOKEN}" }
}
}
}
Cursor
~/.cursor/mcp.json (global) or .cursor/mcp.json (project):
{
"mcpServers": {
"garmin": {
"url": "https://mcp.garmincommunitymcp.com/mcp",
"headers": { "Authorization": "Bearer gm_live_XXXXXXXXXXXXXXXXXXXXXXXX" }
}
}
}
Open Settings → MCP to confirm the tools loaded. In Agent mode, ask it to call daily_overview.
Windsurf, Cline, Continue, Zed
All accept the same shape: a server with a url (or serverUrl) and a headers map. Where a client has no headers field, use the URL-token form:
{ "garmin": { "url": "https://mcp.garmincommunitymcp.com/mcp/gm_live_XXXXXXXXXXXXXXXXXXXXXXXX" } }
Perplexity, Le Chat and other chat apps
Any chat product with a "custom connector" or "remote MCP" option works. If it asks for OAuth, choose "no authentication" and use the URL-token form.
Tool reference
| Tool | Plan | Does |
|---|---|---|
today | All | Today's date in your time zone |
list_garmin_endpoints | All | The 50 catalogued data sources and the args each needs |
get_garmin_data | All | Fetch any endpoint, e.g. {endpoint:"sleep", args:{date:"2026-10-03"}} |
daily_overview | All | Summary, sleep, HRV, stress, Body Battery, readiness, status in one call (long time series omitted) |
garmin_api_get | All | Raw GET of any connectapi.garmin.com path |
create_workout | Athlete+ | Structured workout from a step spec; optional schedule_date |
create_workout_raw, update_workout | Athlete+ | Full Garmin JSON in / replace steps or name |
schedule_workout, unschedule_workout | Athlete+ | Calendar add / remove |
log_weight, log_hydration, log_blood_pressure | Athlete+ | Manual health entries |
update_activity, create_manual_activity, set_activity_gear | Athlete+ | Activity edits |
garmin_api_write | Athlete+ | Raw POST/PUT (DELETE only when deletes are enabled) |
delete_* | Athlete+, toggle | Permanent deletes; off by default |
list_athletes | Coach | Accounts in the workspace |
Every tool has MCP annotations (readOnlyHint, destructiveHint), so agentic clients can gate writes.
Workout spec
{
"name": "5x1k intervals",
"sport": "running",
"steps": [
{ "kind": "warmup", "duration": { "type": "time", "seconds": 600 }, "target": { "type": "heart_rate_zone", "zone": 2 } },
{ "kind": "repeat", "times": 5, "steps": [
{ "kind": "interval", "duration": { "type": "distance", "meters": 1000 }, "target": { "type": "pace", "fastest": "4:30", "slowest": "4:45" } },
{ "kind": "recovery", "duration": { "type": "time", "seconds": 90 } }
]},
{ "kind": "cooldown", "duration": { "type": "lap_button" } }
]
}
Sports: running, cycling, swimming, strength_training, cardio_training, hiit, yoga, pilates, mobility, multi_sport, other. Durations: time, distance, lap_button, calories, reps. Targets: pace, heart_rate_zone, heart_rate, power_zone, power, cadence, speed.
Rate limits and errors
- Read: 300 tool calls/day. Athlete: 1,000/day. Coach: 1,000/day per account. Over the limit, tools return a clear error with the upgrade link; nothing is silently dropped.
- Garmin-side errors are passed through with the HTTP status. A 429 from Garmin means back off; the client usually does.
- Garmin changes its private API occasionally. We publish incidents on the status page and patch quickly; the raw
garmin_api_gettool keeps working for anything not yet catalogued.
FAQ
How do I add Garmin to Claude Code?
Run claude mcp add --transport http garmin https://mcp.garmincommunitymcp.com/mcp --header "Authorization: Bearer YOUR_TOKEN", then use /mcp inside Claude Code to confirm the server is connected.
How do I add Garmin to Cursor?
Add a server to ~/.cursor/mcp.json with url https://mcp.garmincommunitymcp.com/mcp and an Authorization header containing your bearer token.
Which transport does Garmin Community MCP use?
Streamable HTTP, stateless, with JSON responses enabled. Any MCP client that supports remote HTTP servers works; SSE-only clients are not supported.
Can I self-host instead?
Yes; several open-source Garmin MCP servers exist and we link to them on hosted vs self-hosting. Garmin Community MCP is for people who'd rather not run a server, handle Garmin MFA or keep tokens fresh.
Garmin as 50 MCP tools, one URL
48-hour free trial. Cancel before it ends and pay nothing.