garmin-mcp
Analyze your own Garmin Connect data locally and read-only inside Claude Desktop via 13 tools.
Connection/account:
whoamichecks login and returns your profile;get_user_profilereturns units, preferences, activity level.Daily wellness (
get_daily_health): summary, sleep, stress, heart rate, HRV, SpO2, respiration, hydration, steps, floors, intensity minutes, Body Battery (and events), stats/body.Training (
get_training): readiness, morning readiness, status, VO2max, fitness age.Fitness/performance (
get_fitness): race predictions, cycling FTP, lactate threshold, personal records, endurance score, hill score, resting heart rate, weekly intensity minutes.Body composition (
get_weight): weight, BMI, body-fat % over a range; optionally raw weigh-ins.Steps (
get_steps_history): daily or weekly totals over a range.Activities:
list_activities(recent or by date range/type, limit 1–50) andget_activity(summary, splits, weather, GPS/HR/power details, HR zones, exercise sets).Devices (
get_devices): paired Garmin devices with model, firmware, last sync.Goals (
get_goals): active, future, or past goals.Workouts:
get_workouts(saved workouts) andget_scheduled_workouts(calendar by year/month).Constraints: fully local stdio, read-only, passwordless at runtime, no telemetry.
Provides read-only access to a user's Garmin Connect data, including activities, sleep, HRV, Body Battery, stress, heart rate, SpO2, respiration, hydration, steps, floors, intensity minutes, weight/body composition, training readiness, VO2 max, fitness age, race predictions, personal records, devices, goals, workouts, and scheduled workouts.
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."
Updating
git pull
npm install # dependencies may have changed
npm run build # build/ is not part of the repoThen restart Claude Desktop. It runs the server as a child process, and a running instance keeps the code it loaded at startup — so an update only takes effect after a restart.
Your login survives an update: ~/.garmin-mcp/tokens.json is untouched and the
path in claude_desktop_config.json stays the same. Only re-run npm run login
if a tool actually reports 🔒 Not logged in.
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.
Development
npm run build # tsc -> build/
npm test # unit tests for the pure helpers (no network, no credentials)
npm run smoke # milestone test against Garmin's Cloudflare (needs network)
npm run login # one-time interactive login (needs your credentials)
npm start # run the built server directly (normally Claude Desktop does this)CI (.github/workflows/ci.yml) runs npm ci, npm run build and npm test on
Node 22. build doubles as the type-check. smoke and login are deliberately
excluded — they need live Garmin access and real credentials, and would be flaky.
npm test covers the pure helpers only (trimLongArrays, decodeJwtExp,
toSearchParams) and never imports the MCP SDK, so a green test run says nothing
about tool registration. After changing tools or upgrading dependencies, probe the
server over stdio. No Garmin credentials are needed — registration and argument
validation both happen before any authentication:
npm run build
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| node build/mcp/server.jsExpect an initialize reply plus a tools/list reply containing all 13 tools with
their input schemas. To also confirm that argument validation still bites, add one
more line to the printf above — it should come back as -32602, not as a login
error:
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_activity","arguments":{"activityId":"not-a-number"}}}' \Dependencies are updated by Dependabot (.github/dependabot.yml, weekly). The npm
updates arrive as one grouped PR that can include major versions, so read its
package.json diff before merging, and run the stdio probe above rather than
trusting a green build alone.
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.Calls hang right after an update — the previous server process may have left its
cycletlsGo helper behind. Check withpgrep -fl cycletlsand clear it withpkill -f cycletls; the next call starts a fresh one.
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
13 toolsget_activityB
Data for a single activity by activityId. Pick via include: summary, splits, weather, details (GPS/HR/power streams), hr_zones, exercise_sets.
| Name | Required | Description | Default |
|---|---|---|---|
| include | No | Which parts to return. Default: [summary]. | |
| activityId | Yes | The numeric activityId (from list_activities). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It implies a read operation but does not state that it is read-only, what happens if the activityId is invalid, or any size/pagination behavior for the heavier includes like details. For a data-fetch tool this leaves notable gaps.
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?
Two short sentences with no filler. The resource and selector are front-loaded, and the include options follow immediately, making it easy to scan.
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?
For a two-parameter getter with no output schema, the description covers the purpose and the include enum reasonably well. It still omits usage context (when to call this vs list_activities) and any behavioral caveats, so it is adequate but not fully complete.
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 baseline would be 3, but the description adds meaning by listing the include options and clarifying that 'details' means GPS/HR/power streams, which is not explicit in the enum alone. This is genuine added semantic value over 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?
The description states a specific resource ('a single activity') and identifies the key selector ('by activityId'), so the agent can tell it retrieves one activity record. It does not explicitly contrast with list_activities or the other get_* siblings, but the singular scope is clear enough.
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?
No when-to-use guidance or alternatives are given. The schema note '(from list_activities)' hints at provenance, but the description never says when this tool is preferable to list_activities or how to obtain an activityId. Usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_daily_healthC
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?
With no annotations and no output schema, the description carries the full behavioral burden, yet it discloses nothing about authentication, rate limits, data freshness, units, or what a partial or empty response looks like. The only behavioral hint is that multiple metrics can be requested at once, which is already evident from the array schema.
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?
Front-loaded and short, which is good, but the long enumeration of all fourteen metric names duplicates the schema verbatim and consumes most of the description's length without adding information. Structure is fine; content density is low.
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?
For a multi-metric aggregation tool with no annotations and no output schema, the description should at least hint at the return shape, units, or timezone handling. It provides none of that, leaving the agent unable to anticipate what each metric key contains.
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 description coverage is 100%, including the date format/pattern and the metrics enum and defaults, so the schema already fully documents both parameters. The description merely re-lists the enum members rather than adding meaning such as units, granularity, or how metrics interact. Baseline 3 applies.
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?
States a clear verb-resource pairing: returning daily wellness metrics for a given date. An agent can distinguish this from siblings like get_training, get_weight, and get_activity, which cover different data domains. It stops short of explicitly naming what it is not, so a 5 is not warranted.
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?
There is no guidance on when to use this tool versus the many similar-looking siblings (get_fitness, get_activity, get_steps_history), nor any stated prerequisites or exclusions. The only selection advice offered is about picking metric values, which is parameter-level, not tool-level.
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 the burden. It does disclose a genuine behavioral trait: four metrics are date-agnostic (startDate/endDate are ignored for them) while the other four honor the range. It says nothing about permissions, return shape, or whether mixed metric groups are supported in a single call.
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?
Two tight clauses, front-loaded with the resource then the grouping rule. Little waste, though the parenthetical grouping is dense and slightly awkward to parse on first read.
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?
For a 3-parameter read tool with no output schema and no annotations, the description covers metric selection well but leaves open whether date-agnostic and range-based metrics can be requested together, and gives no hint of return structure. Adequate but with visible gaps.
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, but the description adds real meaning beyond the enum listing: it annotates which enum values are latest-only versus date-range-scoped, and clarifies that startDate/endDate only matter for half the metrics. That is information the schema enum does not convey.
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 names the resource (fitness/performance metrics) and the selection mechanism (the `metrics` array), which is more specific than the bare name. It does not differentiate from siblings such as get_training or get_daily_health, which could plausibly overlap with performance data, so it stops short of a 5.
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?
It implies when each metric applies by splitting them into date-agnostic (latest only) and range-based groups, which is a useful selection rule. However, it offers no explicit when-to-use vs when-not-to-use guidance and never mentions alternatives or overlap with get_training/get_daily_health.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_goalsC
Goals filtered by status (active, future, or past).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max goals (1-50). Default: 30. | |
| status | No | Goal status. Default: active. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden but discloses almost nothing: no read-only confirmation beyond the 'get' prefix, no pagination behavior, no default ordering, and no note on what an empty result means. For a zero-annotation tool this is a substantial gap.
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 short sentence with the resource front-loaded and no wasted words. It is efficient, though the terseness borders on under-specification rather than optimal brevity.
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?
For a two-parameter, zero-required-parameter read tool with fully documented schema and no output schema, the description is minimally sufficient. It omits any note on default behavior or return semantics, which keeps it at a bare-adequate level.
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 description coverage is 100%, so both the limit (1-50, default 30) and status enum are fully documented in the schema. The description only restates the status values and adds nothing about the limit or default behavior, so the baseline 3 applies.
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 names the resource (goals) and the filtering dimension (status with enumerated values), so an agent knows this is a goal-retrieval tool. It does not explicitly state a verb like 'list/retrieve' or call out its distinctness from the health/fitness siblings, but the resource is unique enough to be unambiguous.
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?
There is no guidance on when to use this tool versus alternatives, no prerequisites, and no mention of the sibling tools. The status filter is the only implied usage signal, and it is not framed as a decision point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scheduled_workoutsC
Scheduled workouts / calendar for a month (defaults to the current month).
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | Year, e.g. 2026. Default: current year. | |
| month | No | Month 1-12. Default: current month. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the full burden. It discloses the default-month behavior but nothing about return format, whether the calendar is sparse or filled, auth needs, or pagination. 'Calendar' hints at structure but is not elaborated.
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 short sentence, front-loaded with the resource and default. Efficient, though the slash phrasing is slightly terse.
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 2-param read whose schema is fully covered, but with no annotations and no output schema, the description leaves the return shape and sibling differentiation to inference.
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 both year and month are fully documented with types, bounds, and defaults. The description only restates the default-month behavior already present in 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?
States a specific verb/resource relationship: retrieving scheduled workouts as a calendar for a month. It's distinguishable from get_workouts (likely completed sessions) by the 'scheduled' qualifier, though it doesn't explicitly name the contrast.
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?
No indication of when to use this vs get_workouts or get_training. The calendar/month framing implies a schedule view, but no exclusions or alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_steps_historyA
Step totals over a date range. granularity 'daily' (Garmin caps the span at 28 days) or 'weekly'. Default: daily, 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. | |
| granularity | No | daily or weekly. Default: daily. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It usefully reveals a Garmin-specific 28-day cap for daily granularity and states default date ranges, but omits return format, pagination, and any auth or rate-limit 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?
Two short sentences, front-loaded with the core purpose and then the key granularity constraint and default. Every sentence carries useful information and there is no filler.
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?
For a simple read tool with three optional parameters, no annotations, and no output schema, the description covers the main behavior, defaults, and a critical timeout-like cap. It could mention the return shape, but it is otherwise complete enough to call correctly.
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 description coverage is 100%, so the baseline would be 3. The description adds one meaningful constraint not present in the schema: daily granularity caps the span at 28 days. The default values it restates are largely redundant with 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?
The description states a clear resource and scope: step totals over a date range, with daily or weekly granularity. It does not explicitly differentiate itself from siblings like get_daily_health or get_training, but the purpose is understandable without further inference.
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?
It explains granularity options and defaults, but gives no guidance on when to use this tool versus sibling tools such as get_daily_health or get_training. There are no prerequisites or when-not-to-use conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trainingC
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?
With no annotations, the description carries the full behavioral burden, yet it says nothing beyond the basic scope. It does not state that this is a non-mutating read, whether authentication or a connected device is required, what happens when no data exists for the date, or how much data is returned per metric.
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?
Two short sentences, front-loaded with the resource and scope before the parameter hint. The only redundancy is restating the metric enum values that the schema already lists.
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?
For a two-parameter, all-optional read tool with full schema coverage, the description is adequate but thin. With no output schema and no annotations, it should say more about the shape of the returned data per metric and the no-data case.
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 description coverage is 100% and both parameters are fully documented in the schema, including defaults and the date pattern, so the baseline of 3 applies. The description's enumeration of metric values duplicates the enum already present in the schema rather than adding new meaning.
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 names a concrete resource ('training metrics') and scopes it to a date, then enumerates the available metric kinds, so an agent knows exactly what comes back. The verb is implicit in the 'get_' name, and it draws no boundary against near-siblings like get_fitness or get_daily_health, which is what keeps it from a 5.
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?
There is no statement of when to reach for this tool versus get_fitness, get_daily_health, or get_activity. 'Pick via `metrics`' is parameter guidance, not usage guidance, and no prerequisites or exclusions are given.
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 disclosure burden. It does reveal useful behavior: the default window (~4 weeks) and the effect of include_raw (individual weigh-ins included). It omits auth/permission requirements and any note on data granularity or pagination limits, so it is only partially transparent.
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?
Three tight sentences: resource and metrics first, then the optional flag, then the default window. Every sentence carries information and nothing is padded.
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?
For a simple read tool with zero required params, full schema coverage and no output schema, the description covers the resource, the returned metrics, the flag behavior and the default range. Only minor gaps remain, such as no mention of the date format or whether ranges are inclusive, both of which the schema largely handles.
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 description coverage is 100%, so all three parameters are already documented in the schema, including the same default values quoted in the description. The description essentially restates the include_raw and default-range semantics, adding no format or constraint detail beyond the structured fields.
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 names a specific resource and enumerates the exact metrics returned (weight, BMI, body-fat %) plus the raw-entry option, so an agent can distinguish it from siblings like get_daily_health or get_activity. It stops short of explicitly naming which sibling to use for other health metrics, so it earns a 4 rather than a 5.
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?
Usage is implied by the resource and the stated default range ('last ~4 weeks'), which tells the agent this is the weight-tracking read. There is no explicit when-to-use versus when-not-to-use guidance or reference to an alternative tool for related body metrics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_workoutsC
Saved workouts on the account.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max workouts (1-100). Default: 50. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden, and it says nothing about read-only behavior, pagination, default page size, or ordering. Only a weak implication that this is a read operation can be inferred from the phrase 'saved workouts'.
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?
It is brief, but the brevity is under-specification rather than conciseness - a single nominal fragment with no verb and no front-loaded actionable information. Nothing is wasted, but almost nothing is delivered either.
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 annotations, no output schema, and a bare noun phrase, the definition is inadequate for an agent to confidently invoke the tool. It should at minimum state that it lists workouts for the authenticated user and describe pagination behavior.
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 description coverage is 100% and the single 'limit' parameter is fully documented in the schema with range and default. The description adds nothing about parameters, so the baseline of 3 applies.
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 fragment 'Saved workouts on the account' identifies the resource and the qualifier 'saved' loosely distinguishes it from the sibling get_scheduled_workouts. However it contains no verb at all, so the agent must infer that this is a retrieval/list operation, leaving the purpose only implied.
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?
There is no when-to-use guidance, no conditions, and no mention of alternatives among the many siblings (get_scheduled_workouts, get_training, list_activities). The agent receives nothing to route on.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_activitiesA
List activities. Without dates: the most recent ones (use limit=1 for the last activity). With startDate/endDate and/or type: activities in that range, optionally filtered by type (e.g. running, cycling, swimming).
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by activity type, e.g. 'running', 'cycling'. | |
| limit | No | Max activities (1-50). Default: 10. | |
| endDate | No | End date (YYYY-MM-DD). Default: today. | |
| 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 the burden. It usefully discloses the default no-date behavior (returns most recent) and the limit=1 shortcut, which is real behavioral value. But it says nothing about auth/permissions, pagination, ordering, or how many results come back by default beyond the schema's stated default.
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?
Two tight sentences with the default-case behavior front-loaded before the ranged/filtered case. No filler, though the parenthetical examples for type are partly redundant with the schema's own examples.
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 and no annotations, this description is nearly sufficient: it covers invocation modes (default vs ranged vs filtered) and the key shortcut. The remaining gap is only return-shape and ordering, which is a modest omission for a list tool.
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 description coverage is 100%, so the baseline is 3. The description adds intent for how parameters combine (dates and/or type filter the range) and a concrete limit=1 use case, which is slightly beyond the schema, but format/default details remain the schema's job.
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?
States a specific verb+resource ('List activities') and immediately scopes behavior by date/type, which distinguishes it from the singular get_activity sibling in practice. However, it never explicitly names get_activity or get_steps_history as alternatives, so sibling differentiation is inferential rather than stated.
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?
Gives clear conditional guidance: omit dates for the most recent activities, use limit=1 for the last activity, pass startDate/endDate and/or type for a ranged/filtered query. Missing is any 'do not use this when...' or pointer to the detail tool get_activity for a single record.
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.
10 tool updates
v1.1.1- Added
get_activity - Changed
get_daily_health1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get_fitness1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Added
get_goals - Added
get_scheduled_workouts - Added
get_steps_history - Changed
get_training1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get_weight1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Added
get_workouts - Added
list_activities
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 13 tools
Most tools target distinct Garmin data domains with metric parameters that clarify scope. However, get_daily_health and get_steps_history overlap on step data, and get_training/get_fitness both cover performance metrics, so a few boundaries could still be confused.
The set is almost entirely consistent snake_case with a get_* verb-noun pattern for 11 of 13 tools. list_activities and whoami are minor deviations, but overall the naming is predictable and readable.
13 tools is well-scoped for a Garmin health/fitness server. Each tool maps to a clear category (health, training, fitness, weight, steps, activities, devices, profile, goals, workouts, scheduling) without excessive fragmentation.
The read-only surface covers the major Garmin data lifecycle: health, training, activities, workouts, goals, devices, profile, and scheduling. Minor gaps exist (no separate sleep endpoint, no write/delete operations), but these are likely API limitations and agents can work around them.
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.-