garmin-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@garmin-mcpWhat's my training readiness today?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Garmin → Claude MCP server
Analyze your own Garmin Connect data — activities, sleep, HRV, Body Battery, training readiness — right inside Claude Desktop.
A fully local, read-only MCP server that lets you analyze your own Garmin Connect data in Claude Desktop. The server runs as a local child process of Claude Desktop and talks to it over stdio.
Guiding principles
100% local — nothing is hosted or exposed to the network (stdio).
Read-only — there is no write endpoint to Garmin.
No third party — the only network contact is Garmin. No telemetry, no external logging.
Passwordless at runtime — the password is never stored; after the one-time login only local tokens are used.
Related MCP server: Garmin Health MCP Server
Requirements
Node.js ≥ 20 (tested with Node 22 LTS), npm.
A Garmin Connect account.
Setup (4 steps)
# 1) Install dependencies
npm install
# 2) Milestone test: does the client get through Garmin's Cloudflare protection?
npm run smoke
# Expectation: "Status 200" and "Challenge: no".
# 3) One-time interactive login (prompts for email, hidden password, MFA if enabled)
npm run login
# Creates ~/.garmin-mcp/tokens.json (mode 0600). The password is NOT stored.
# 4) Compile TypeScript to build/
npm run buildConnecting Claude Desktop
Claude Desktop → Settings → Developer → Edit Config. Add the server with its
absolute path (claude_desktop_config.json):
{
"mcpServers": {
"garmin": {
"command": "node",
"args": ["/absolute/path/to/garmin-mcp/build/mcp/server.js"]
}
}
}Then restart Claude Desktop. Try it in chat, e.g.:
"Am I logged in to Garmin? Use
whoami." "Show me my daily summary and my recent activities."
Available tools
13 read-only tools. Date parameters are YYYY-MM-DD (default = today); ranges
default to the last ~4 weeks. Several tools take a metrics[] / include[] selector,
so one tool covers many data types (this keeps the tool list small for good tool
selection). Long time series in responses are truncated to stay compact.
Tool | Description |
| Connection check + account profile |
| Daily wellness for a date — |
| Training for a date — |
| Fitness/performance — |
| Body weight & composition over a range ( |
| Step totals over a range — |
| One activity by |
| Recent activities, or by date range/type ( |
| Paired Garmin devices |
| User profile & settings (units, preferences) |
| Goals ( |
| Saved workouts ( |
| Scheduled workouts / calendar ( |
How it works
The server registers each Garmin data method as an MCP tool and talks to Claude
Desktop over stdio. Every call goes through a generic connectapi() request to
connectapi.garmin.com with a bearer token, sent via
cycletls so the TLS fingerprint looks
like a real browser (Garmin sits behind Cloudflare).
Authentication happens once (npm run login): a login cascade — mobile iOS JSON
login first, the classic widget/CSRF flow as fallback — yields a CAS service ticket,
which is exchanged in Garmin's DI-OAuth2 flow for an access + refresh token. The
tokens are cached locally and the access token is refreshed automatically on expiry;
your password is never stored.
Security model
The password is never stored — it is only used for the one-time login.
Tokens live at
~/.garmin-mcp/tokens.jsonwith file mode0600(only you can read them).The access token is renewed automatically via the refresh token when it expires.
Read-only: there is no code path that changes anything on Garmin.
No telemetry, no external logging. Diagnostics go to
stderronly (never over the stdio MCP channel).
Architecture (layers)
src/http/impersonate.ts— TLS impersonation viacycletls(JA3 fingerprint) + cookie jar, so Garmin's bot protection lets us through.src/http/smoke.ts— milestone test againstsso/embed.src/garmin/auth.ts— login cascade (mobile iOS JSON login → widget/CSRF fallback) + MFA + DI-OAuth2 ticket exchange + refresh.src/garmin/tokens.ts— local token cache (0600).src/garmin/client.ts— genericconnectapi()+ typed, read-only data methods.src/mcp/server.ts— MCP server, tool registration, stdio transport.src/cli/login.ts— one-time interactive login.
Maintenance & risks (named honestly)
This uses Garmin's unofficial internal API, ported from the open-source Python
package python-garminconnect.
Expected breakage points and how to fix them:
Unofficial API — endpoint paths can change. On errors, compare the paths in
src/garmin/client.tsagainst the currentpython-garminconnectsource.JA3 / User-Agent — on a
403or a "Just a moment …" Cloudflare page, update the JA3/User-Agent pair insrc/http/impersonate.tsto a current Chrome (both together).Client ids — the DI-OAuth2 client ids (
GARMIN_CONNECT_MOBILE_ANDROID_DI_*) rotate; update the list insrc/garmin/auth.tson auth errors.garthis discontinued — the previously common auth librarygarthis no longer maintained; the authoritative reference ispython-garminconnect.Keep the token folder private —
~/.garmin-mcp/holds valid session tokens; don't share it, don't commit it.Terms of service — access via the unofficial API may be in tension with Garmin's terms of service. Intended for private personal use with your own data.
Troubleshooting
403or a "Just a moment …" page — Garmin's Cloudflare is blocking the TLS fingerprint. Update the JA3/User-Agent pair insrc/http/impersonate.tsto a current Chrome (both together), then re-runnpm run smoke.🔒 Not logged in/ session expired — runnpm run loginagain.⏳rate limited (HTTP 429) — Garmin is throttling; wait a bit and retry.First run is slow / cycletls errors —
cycletlsdownloads a small Go helper binary on first use; make sure it can execute and isn't blocked by the OS.
Re-login
If tools report 🔒 Not logged in (token expired/invalid):
npm run loginLicense
MIT © Marcel Fortmann
Disclaimer
This is an unofficial, community project. It is not affiliated with, endorsed by, or sponsored by Garmin. Garmin® and Garmin Connect™ are trademarks of Garmin Ltd. or its subsidiaries.
Available Tools
7 toolsget_daily_healthA
Daily wellness metrics for a date. Pick one or more via metrics: summary, sleep, stress, heart_rate, hrv, spo2, respiration, hydration, steps, floors, intensity_minutes, body_battery, body_battery_events, stats_and_body.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Date in YYYY-MM-DD format. Default: today. | |
| metrics | No | Which daily metrics to return. Default: [summary]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, and description does not mention defaults (date defaults to today, metrics defaults to summary) or any side effects. Basic behavior is clear but lacks depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise, front-loaded with purpose, every word adds value. No unnecessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema; description does not explain response format or default behavior. Adequate for a simple retrieval but could be more complete regarding expected output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. Description adds context around metrics being selectable but does not provide new information beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it returns daily wellness metrics for a date, listing available metric types. Distinguishes from sibling tools (whoami, get_weight, etc.) which cover different domains.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies usage for retrieving daily wellness data but lacks explicit when-to-use or when-not-to-use guidance. No comparison to alternatives provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_devicesA
Garmin devices paired to the account (model, firmware, last sync).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the burden. It indicates a read-only retrieval of device information, but does not disclose any potential limitations, authentication requirements, or response size constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that is clear, direct, and contains no unnecessary words. Every element conveys meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and no output schema, the description adequately covers the tool's purpose and expected return fields. It could be improved by mentioning the scope (all paired devices) and potential limitations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, so schema coverage is 100%. The description adds value by listing the output fields (model, firmware, last sync), which is helpful for the agent. Baseline for 0 parameters is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the tool returns Garmin devices paired to the account, with specific fields (model, firmware, last sync). This distinguishes it from sibling tools like get_weight or get_user_profile which focus on different data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when a list of paired devices is needed, but does not explicitly state when to use this tool versus alternatives or provide any exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fitnessA
Fitness/performance metrics. Pick via metrics: race_predictions, cycling_ftp, lactate_threshold, personal_records (all latest, date-agnostic), and endurance_score, hill_score, resting_heart_rate, weekly_intensity_minutes (over the given date range).
| Name | Required | Description | Default |
|---|---|---|---|
| endDate | No | End date (YYYY-MM-DD). Default: today. | |
| metrics | No | Which metrics to return. Default: [race_predictions, personal_records]. | |
| startDate | No | Start date (YYYY-MM-DD). Default: ~4 weeks ago. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses that some metrics are date-agnostic and others require a date range, which is useful behavioral trait. However, it lacks details on output format, authentication needs, or potential errors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the main purpose and efficiently conveys parameter usage. No redundant words; every phrase adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description omits return format details. However, it covers the essential aspects: available metrics, how dates affect them, and parameter defaults. For a tool with no required parameters, this is nearly complete, though a brief note on output structure would help.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning by grouping metrics into two categories (date-agnostic vs. date-range) and clarifying default values for dates and metrics. This goes beyond the schema's parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool returns 'Fitness/performance metrics' with a specific list of metric names, distinguishing between date-agnostic and date-range metrics. This clearly identifies the resource and scope, differentiating it from sibling tools like get_training or get_daily_health.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how to select metrics via the `metrics` parameter and clarifies which metrics need date parameters. However, it does not explicitly state when to prefer this tool over siblings, nor does it provide when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trainingA
Training metrics for a date. Pick via metrics: readiness, morning_readiness, status, vo2max, fitness_age.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Date in YYYY-MM-DD format. Default: today. | |
| metrics | No | Which training metrics to return. Default: [readiness, status, vo2max]. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose behavioral traits such as read-only nature, required permissions, side effects, or response format. The name implies a retrieval operation, but the description lacks explicit transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description consists of two short, front-loaded sentences with no extraneous information. Every word is necessary and directly contributes to understanding the tool's purpose and parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, no output schema, and no annotations, the description provides adequate context for basic use. However, it lacks details about return values, date handling beyond default, and any behavioral context, leaving some gaps for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema descriptions already detail both parameters. The description adds a concise list of metric options, but this overlaps with the schema's enum values. It provides no new semantic meaning beyond what the schema offers, meeting the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool retrieves 'Training metrics for a date' and lists the specific available metrics via notation. This distinguishes it from sibling tools like get_weight or get_daily_health, which address different health domains.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when training metrics are needed and provides a list of metrics to choose from, but it does not specify when to use this tool over alternatives or indicate any prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_user_profileA
User profile & settings: units, preferences, activity level, etc.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries full burden. It hints at a read operation but does not confirm safety or disclose any prerequisites, error conditions, or side effects. The behavioral traits are inadequately communicated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one sentence, efficiently conveying the purpose without redundancy. It uses a list format with examples for clarity, and every word serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description partially compensates by listing example data categories. However, it could be more explicit about the full return structure. Given the tool's simplicity and sibling diversity, this is nearly adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so baseline is 4. The description adds value by listing the categories of data returned (units, preferences, activity level), which helps the agent understand the output content.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves user profile and settings including units, preferences, and activity level. It is specific and distinguishes itself from sibling tools like whoami (basic identity) and get_weight (specific metric).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for getting profile/settings data but does not explicitly state when to use this tool versus alternatives like get_daily_health or get_training. No exclusion criteria or alternative suggestions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_weightA
Body weight & body composition (weight, BMI, body-fat %) over a date range. Set include_raw for the individual weigh-in entries too. Default range: the last ~4 weeks.
| Name | Required | Description | Default |
|---|---|---|---|
| endDate | No | End date (YYYY-MM-DD). Default: today. | |
| startDate | No | Start date (YYYY-MM-DD). Default: ~4 weeks ago. | |
| include_raw | No | Also include individual weigh-in entries. Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the data returned (weight, BMI, body-fat %), default date range, and the effect of include_raw. It implies a safe read operation without stating it explicitly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no filler. The first sentence front-loads the main purpose, and the second adds the optional parameter. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose and parameters adequately. While there is no output schema, the tool is simple enough (aggregated health data) that the agent can infer the return format. A brief note on output structure would be beneficial but not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three parameters are described in the schema (100% coverage). The description adds value by explaining the default date range and the purpose of include_raw (to include individual entries), going beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves body weight and composition (weight, BMI, body-fat %) over a date range. It specifies the exact data types and the optional parameter for individual entries, making it distinct from sibling tools like get_daily_health.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool (for weight/composition data over a date range) and provides default behavior (~4 weeks). However, it does not explicitly contrast with alternatives like get_daily_health or specify when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoamiA
Check the Garmin connection and return the logged-in account profile (display name, full name).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. Description discloses read-only nature and return fields, but does not mention error behavior, authentication requirements, or what happens if not connected.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single clear sentence with no unnecessary words. Efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequate for a simple parameterless tool. Additional details about error handling could improve, but current description is sufficient for use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist, schema coverage is 100%. Description confirms no input needed, adding minimal value beyond schema but sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it checks Garmin connection and returns account profile (display name, full name). Distinct from sibling tools that focus on specific data (weight, fitness, etc.).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage for verifying connection and basic profile, but does not explicitly guide when to use over get_user_profile (which might overlap). No exclusions provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v1.0.0- First observed
get_daily_health - First observed
get_devices - First observed
get_fitness - First observed
get_training - First observed
get_user_profile - First observed
get_weight - First observed
whoami
TDQS
Scored across 7 tools
Each tool targets a distinct aspect of Garmin data: account info, weight, profile, daily health, training metrics, fitness/performance, and devices. No overlapping purposes.
All tools use consistent snake_case verb_noun pattern (e.g., get_weight, get_user_profile), with 'whoami' as a minor but acceptable variation.
7 tools cover a broad health/fitness domain without being excessive. The count is well-scoped for the server's purpose.
Covers major data categories (profile, weight, daily health, training, fitness, devices). Minor gaps like detailed activity logs are absent, but overall surface is solid for a read-only server.
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.
Connect Claude to your Intervals.icu watch data for fitness, workout review, and plan writing.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Related MCP Servers
- AlicenseBqualityAmaintenanceConnects Claude Desktop to Garmin Connect, enabling natural language queries of fitness activity data, health metrics, sleep analysis, workout management, and device information with 94 available tools.1101MIT
- AlicenseAqualityDmaintenanceEnables Claude Desktop to access and analyze Garmin wearable health data including sleep, HRV, Body Battery, and activity metrics. Users can query their health trends, track recovery, and generate interactive HTML dashboards using natural language.96MIT
- FlicenseNot gradedqualityBmaintenanceConnects Claude Desktop to your Garmin Connect running data stored locally in SQLite, enabling querying, syncing, and AI analysis of fitness activities.1-
- FlicenseNot gradedqualityCmaintenanceConnects Garmin watch data to Claude Desktop, allowing users to ask natural language questions about their health and activity data from Garmin Connect.-