garmin-local-mcp
The garmin-local-mcp server provides a local-first data warehouse for Garmin health data, enabling offline sync, storage, and analysis with 12 curated tools.
Authentication & Sync: Check stored tokens (
auth_status), sync up to 60 days from Garmin Connect (sync), and view data coverage and errors (sync_status).Daily & Time-Series Querying: Get a merged daily snapshot (
get_day) and columnar time series with aggregation/stats (query_metrics).Advanced Analysis: Correlate metrics with lag scanning (
correlate), calculate personal baselines (baselines), and detect outlier days & sustained streaks (anomalies).Activities: List recent activities with filters (
list_activities) and retrieve full summaries for a specific activity (get_activity).Data Completeness: Identify missing days and unresolved sync errors (
gaps).Offline Import: Import manually exported wellness FIT bundles without authentication (
import_fit).Demo Mode: Seed a synthetic data store via CLI to explore features without a Garmin account.
Syncs Garmin Connect health data (wellness, sleep, HRV, activities, etc.) into a local SQLite warehouse and provides analysis tools for querying metrics, correlations, baselines, anomalies, and data gaps, with offline resilience and a zero-auth FIT import fallback.
Click on "Install 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-local-mcpcorrelate my sleep and training load for the last month"
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-local-mcp
Local-first Garmin data warehouse with an analysis-grade MCP server. Sync once, analyze forever, even when the API is down.

Why another Garmin MCP?
Every existing Garmin MCP server follows the same design: a thin live wrapper around Garmin's rate-limited, unofficial API. Each question your AI assistant asks becomes one or more live API calls that return huge raw JSON blobs (a single raw sleep response runs around 230 KB). Multi-month questions like "how does my sleep correlate with training load?" are impractical, and when Garmin changes its auth (as it did in March 2026, breaking the whole ecosystem), those servers go completely dark, even for data they already fetched yesterday.
This project inverts the architecture:
Sync once, analyze forever. Incremental sync into a local warehouse: immutable raw JSON snapshots plus a SQLite database, in a directory you own.
Server-side analysis, compact responses. Trends, correlations, personal baselines, and anomaly detection are computed locally and returned as small columnar tables in a single tool call. Typical responses are under 2 KB, so nothing floods the model's context.
Offline resilience. An API breakage pauses new syncs only. Every query over already-synced history keeps working.
A zero-auth fallback. A standalone decoder for Garmin's undocumented wellness FIT messages (sleep score, HRV, skin temperature, sleep stages, naps) ingests manually exported bundles with no login at all. No other Garmin MCP ships this.
Curated tools. 12 composable tools, not 110.
garmin-local-mcp | Typical API-wrapper Garmin MCPs | |
Local data store you own | Yes (raw JSON + SQLite) | No |
Works offline after an API breakage | Yes (analysis over synced history) | No |
Server-side analysis (trends, correlations, baselines, anomalies) | Yes | No (raw JSON pass-through) |
Response size discipline | Compact columnar tables, typically < 2 KB | Raw payloads, up to hundreds of KB |
Zero-auth ingest path | Yes (FIT bundle import) | No |
Tool count | 12 curated | Often 20 to 110+ |
Related MCP server: Garmin MCP
Try it without a Garmin account
If you don't own a Garmin, or just want to see what the tools return before handing over credentials, seed a synthetic store:
pip install garmin-local-mcp
garmin-local-mcp --data-dir ~/.garmin-mcp-demo demo
garmin-local-mcp --data-dir ~/.garmin-mcp-demo serveThat generates 180 days across every table, then serves them over MCP. No login, no network, no account.
The data is generated rather than recorded, but it is not random. A latent recovery factor drives HRV up while resting heart rate goes down, training load raises the next day's resting heart rate, a six-day illness window sits in the middle of the range, and a few sleep nights are deliberately missing. So the analysis tools have something real to find:
Ask | Returns |
| about −0.5, a genuine inverse relationship |
| ~0 at lag 0, +0.45 at lag 1 — the effect is next-day |
| the illness window, flagged across resting HR, HRV, skin temperature, SpO2 and sleep score at once |
| the missing sleep nights |
sync_status reports demo_store: true on these stores, so an assistant can
never present generated numbers as real measurements. The generator is
deterministic — --seed reproduces a store exactly, and --days changes the
range. demo refuses to overwrite a database it did not generate.
Quickstart
Requires Python 3.12+.
pip install garmin-local-mcpOr run it without installing, via uv:
uvx garmin-local-mcp --help1. Log in once (MFA supported; tokens persist locally, so future runs never ask for a password):
garmin-local-mcp login2. Backfill your history. The sync is resumable, safe to interrupt, and throttled to be polite to Garmin's servers. A year of history is roughly 1,800 requests; for long backfills, start it and let it run (overnight works well). If it gets rate limited or interrupted, re-run the same command and it resumes where it left off.
garmin-local-mcp sync --from 2026-01-013. Register the MCP server with your client (see Client setup for Claude Desktop, Cursor, and other clients):
claude mcp add --scope user garmin -- garmin-local-mcp serve4. Ask questions. Examples of what Claude can now answer from your local warehouse in one or two tool calls:
"How does my sleep score correlate with next-day resting HR?"
"What were my anomalous HRV days this quarter?"
"Show weekly training load vs sleep for the last 3 months."
Client setup
The server speaks stdio, so any MCP client works. pip install garmin-local-mcp
first (or use the uvx variants below, which need nothing installed beyond
uv).
Claude Code
claude mcp add --scope user garmin -- garmin-local-mcp serveClaude Desktop, one-click: download garmin-local-mcp-x.y.z.mcpb from the
latest release,
then in Claude Desktop open Settings > Extensions > Advanced settings, click
"Install Extension…", and select the file. Requires
uv on your PATH;
the extension installs and runs the server from PyPI via uvx, so no manual
Python setup is needed. If the install dialog warns about a missing
Python >=3.12, you can ignore it: uv provisions its own interpreter.
Claude Desktop, manual (Settings, then Developer, then Edit Config; add to
claude_desktop_config.json):
{
"mcpServers": {
"garmin": {
"command": "garmin-local-mcp",
"args": ["serve"]
}
}
}Cursor (~/.cursor/mcp.json, or .cursor/mcp.json in a project):
{
"mcpServers": {
"garmin": {
"command": "garmin-local-mcp",
"args": ["serve"]
}
}
}Any other stdio client / no local install (requires uv):
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": ["garmin-local-mcp", "serve"]
}
}
}Note: login and the initial backfill sync are CLI steps (see
Quickstart); the MCP server itself never prompts for
credentials.
The 12 tools
Tool | What it does |
| Check whether stored Garmin Connect tokens exist (use before sync, or after an auth error). |
| Fetch up to 60 days from Garmin Connect into the local store (default: last 30 days ending yesterday; big backfills belong in the CLI). |
| Local data coverage per table, last sync time, and pending sync errors. |
| One merged view of a single day: wellness, sleep, HRV, training status, performance scores, activities, and data-quality flags. |
| Columnar time series for one or more metrics between two dates, with daily/weekly/monthly aggregation and optional stats. |
| Pearson/Spearman correlation between two metrics, with day-lag support and an optional scan over lags -7..+7. |
| Personal mean +/- sd band per metric over a trailing window (default 28 days), to judge what is normal for this user. |
| Outlier days (z-score deviations) and sustained streaks (5+ consecutive days on one side of the mean). |
| Recent activities newest-first as a compact table, filterable by type, date range, and minimum distance. |
| Full stored summary row for one activity (summary fields only, no GPS or sample streams). |
| Missing days per table plus unresolved sync errors, to find holes worth re-syncing before drawing conclusions. |
| Zero-auth offline ingest of a manually exported Garmin wellness FIT bundle. |
Only sync and import_fit write anything, and only inside the data
directory. The server never prompts: auth problems come back as structured
errors with a hint pointing at the login CLI.
Available metric names include resting_hr, sleep_score, hrv, steps,
stress_avg, body_battery_high, skin_temp_dev_c, vo2max, fitness_age,
achievable_fitness_age, training_load, endurance_score, hill_score,
readiness_score, race_5k_s, and about 35 more; any tool given an unknown
name returns the full list.
Performance scores
Garmin's periodic fitness scores land in their own performance table:
endurance score, hill score (with its endurance and strength sub-scores),
training readiness (score, level, recovery time) and race predictions for 5k,
10k, half and full marathon (all in seconds).
These update on Garmin's own cadence rather than daily, so performance is
deliberately excluded from gaps — a day without a new endurance score is
normal, not a hole. Race predictions and hill score only move after qualifying
running activity, so long stretches of nulls are expected for anyone whose
training is mostly hiking, cycling or strength work.
Data layout and ownership
Everything lives in one directory you own (default ~/.garmin-mcp, override
with the GARMIN_MCP_DATA_DIR environment variable or --data-dir):
~/.garmin-mcp/
├── config.toml # optional settings
├── tokens/ # Garmin Connect session tokens
├── raw/daily/YYYY/YYYY-MM-DD/<endpoint>.json # immutable raw API snapshots
├── raw/activities/<activity_id>.json # one snapshot per activity
└── garmin.db # SQLite warehouseThe raw JSON snapshots are the source of truth and are never overwritten. The
SQLite database is a derived, rebuildable index: garmin-local-mcp reparse
rebuilds it from the raw snapshots entirely offline, which is the universal
escape hatch for schema evolution and parser fixes. Your data never leaves
your machine.
Data quality note
Garmin watches report a provisional on-device resting heart rate that can diverge sharply from Garmin Connect's finalized value on nights with sparse sampling. A real observed case: the watch reported 69 bpm on-device while Garmin Connect later finalized the same night at 56 bpm.
This project handles that in two ways:
The API sync stores Garmin Connect's finalized value.
The FIT importer cross-checks the provisional on-device value against the overnight heart-rate floor. A resting HR sitting more than 10 bpm above the lowest overnight sample is a rate the watch never actually observed; it gets flagged (
rhr_far_above_hr_floor) and withheld, leaving the field for the API to backfill rather than storing a misleading number.
Sparse sleep-stage logging is flagged the same way
(sparse_sleep_stage_logging), and flags surface in get_day so the analysis
layer knows which numbers to trust.
Offline / fallback runbook
If Garmin breaks the unofficial API again (it has before):
Everything analytical keeps working. All query, correlation, baseline, anomaly, and gap tools run on your already-synced local history. Only new syncs pause.
Keep ingesting without auth. Download a daily FIT bundle from the Garmin Connect website and import it locally (exact steps below).
garmin-local-mcp import-fit <folder>decodes the bundle with zero authentication and fills the gap days. FIT-sourced rows never overwrite API-sourced rows (unless you pass--force).Resume when the community catches up. Watch the python-garminconnect project for a fix, upgrade, and run
garmin-local-mcp syncagain. Thanks to resumable sync state, it picks up exactly where it stopped.
Downloading a wellness bundle, step by step
Sign in at connect.garmin.com in any browser.
Go directly to https://connect.garmin.com/app/settings/accountInformation (or click your avatar in the top-right corner, then Settings, then Account Information in the left sidebar).
Scroll to the bottom of the page, to the section titled Export Wellness Data ("Download your wellness FIT files from a specific day. This includes data such as steps, sleep, stress, HRV and more.").
Pick a date in the Date field and click Export. Your browser downloads a small zip for that one day, containing roughly 12 to 15 binary
.fitfiles (*_WELLNESS.fit,*_SLEEP_DATA.fit,*_HRV_STATUS.fit,*_SKIN_TEMP.fit,*_METRICS.fit, and similar).Unzip it into a folder and run:
garmin-local-mcp import-fit "path/to/unzipped/folder"Repeat for each missing day (one bundle per date). The
gapstool orgarmin-local-mcp statustells you which days need filling.
Two things worth knowing:
Overnight sleep belongs to the wake date. To get last night's sleep, export yesterday's date if you slept into this morning, i.e. the date you woke up on.
This per-day export is instant and separate from Garmin's full account export (the "Data Management" link on the same page), which is a bulk archive that can take days to arrive by email and is not what
import-fitexpects.
Configuration
Optional config.toml in the data directory:
Key | Default | Meaning |
| system timezone | IANA name (e.g. |
|
|
|
|
| Delay between API requests during sync |
|
| Default trailing window for the |
Environment variables:
Variable | Meaning |
| Override the data directory (default |
| Override the token store location (default |
| Optional, for non-interactive re-login; when set, |
Development
python -m venv .venv
.venv/bin/pip install -e .[dev] # Windows: .venv\Scripts\pip install -e .[dev]
pytest
ruff check .The test suite runs fully offline against sanitized JSON fixtures and small FIT samples; CI never touches the live API.
Disclaimer
This project is not affiliated with, endorsed by, or supported by Garmin Ltd. It uses the community python-garminconnect library with your own credentials to access your own data. Garmin's APIs are unofficial and can change or break at any time; when that happens, your synced history remains fully usable and the FIT import path keeps working.
All data stays on your machine. Nothing phones home: no telemetry, no third-party services, no cloud. Treat your data directory like the personal health record it is, and never commit it to a repository.
License
MIT
Available Tools
12 toolsanomaliesA
Outlier days (>= z standard deviations from the range mean) and sustained streaks (5+ consecutive days on one side of it).
Default: last 30 days of the core wellness metrics.
| Name | Required | Description | Default |
|---|---|---|---|
| z | No | ||
| end | No | ||
| start | No | ||
| metrics | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses behavioral traits: defines outlier and streak thresholds, defaults to last 30 days and core metrics. However, does not describe output format or whether it modifies data. Without annotations, this is relatively transparent but incomplete.
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, front-loaded sentences with no redundancy. Every word adds value, defining behavior and default scope efficiently.
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 moderate complexity with 4 parameters and no output schema, the description covers anomaly types and defaults but omits return format, pagination, or error conditions. Sufficient for basic understanding 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 0%, so description must compensate. It explains z (threshold), start/end (implied by time range), metrics (core vs customized). But does not explicitly describe each parameter's usage or constraints, leaving some ambiguity.
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 detects outlier days and sustained streaks, defining specific criteria (z standard deviations and 5+ consecutive days). Distinguishes itself from siblings like baselines or get_activity by focusing on anomaly detection.
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 default usage with 'last 30 days of core wellness metrics' but provides no explicit guidance on when to use this tool versus alternatives (e.g., query_metrics, correlate). No when-not or alternative recommendations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
auth_statusA
Check whether stored Garmin Connect tokens exist.
Use before sync, or when a sync failed with an auth error.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description implies a read-only check. Could be improved by explicitly stating no side effects, but otherwise clear.
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 concise sentences with front-loaded purpose, no unnecessary words.
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 tool with no parameters and no output schema, the description fully covers its function and recommended usage scenarios.
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, so baseline applies. Description adds value by explaining the purpose of the tool, making it useful beyond 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?
Description clearly states it checks existence of Garmin Connect tokens, distinguishing it from sibling tools like sync and sync_status.
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?
Explicitly advises use before sync or after an auth error, providing clear context for when to invoke this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
baselinesA
Personal mean +/- sd band per metric over a trailing window (default 28 days; default metrics: resting_hr, hrv, sleep_score, skin_temp_dev_c, stress_avg, steps).
Use to judge whether today's value is normal for this user.
| Name | Required | Description | Default |
|---|---|---|---|
| metrics | No | ||
| window_days | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full weight. It explains the computation (mean and sd) and default window/metrics, but omits details like return format, data freshness, or edge cases (e.g., insufficient data).
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 concise: two sentences that front-load the core concept and purpose, with no redundant words.
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?
Although the tool is simple, the description lacks details on output format (e.g., structure of the band) and does not cover potential errors or data requirements. Without annotations or output schema, more completeness would be beneficial.
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 0% with no parameter descriptions. The description compensates by listing default values for both parameters and specifying the default metrics list, adding significant meaning 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?
The description clearly states it computes mean +/- sd band per metric over a trailing window and is used to judge if today's value is normal for the user. It specifies default window and metrics, making the purpose unambiguous and distinct from siblings like 'anomalies'.
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 explicitly says to use it for judging normality and references default parameters. However, it does not mention when not to use this tool or alternatives like 'query_metrics' or 'anomalies'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
correlateA
Pearson/Spearman correlation between two metrics (default: last 30 days).
Positive lag_days pairs metric_a on day D with metric_b on D+lag; scan_lags=True searches lags -7..+7 for the strongest relationship.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| start | No | ||
| lag_days | No | ||
| metric_a | Yes | ||
| metric_b | Yes | ||
| scan_lags | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses default time range and parameter behaviors (lag_days, scan_lags). However, it does not explain how start/end parameters interact with the default, nor the effect of missing data or the exact output format.
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 concise sentences: first gives purpose and default, second explains key parameters. No wasted words, front-loaded with essential info.
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?
Covers core parameters but omits start/end, no output description, and no guidance on correlation method selection. With 6 parameters and no output schema, more detail is needed for full completeness.
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?
Adds meaning for metric_a, metric_b, lag_days, and scan_lags (e.g., lag explanation, scan range). But start and end parameters are not described, and schema coverage is 0%, so description must do more.
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 it computes Pearson/Spearman correlation between two metrics with a default 30-day window. It distinguishes from sibling tools like 'anomalies' or 'baselines' by focusing on correlation analysis.
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 guidance on when to use this tool versus siblings. Does not provide context on when correlation is appropriate or what prerequisites exist.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gapsB
Missing days per table plus unresolved sync errors (default: first synced date through yesterday).
Use to find holes worth re-syncing before drawing conclusions.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| start | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must cover behavior. It mentions default date range and that it finds missing days and sync errors, but lacks detail on return format, side effects, or limits.
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 concise sentences: first defines purpose, second provides usage guidance. No wasted words.
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?
Despite conciseness, the description lacks critical details (e.g., return format, how missing days are listed) and offers no compensation for missing schema and output schema.
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 0% and the description provides no information about the two parameters (start, end), leaving them completely unexplained.
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 it returns missing days per table and unresolved sync errors, which is specific and distinguishes from sibling tools like sync_status or get_day.
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 gives usage guidance ('Use to find holes worth re-syncing before drawing conclusions'), but does not explicitly state when not to use or list alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_activityA
Full stored summary row for one activity by id (from list_activities).
Summary fields only - no GPS or sample streams.
| Name | Required | Description | Default |
|---|---|---|---|
| activity_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It discloses that only summary fields are returned, not GPS or sample streams, which is useful behavioral information. However, it does not cover other traits like idempotency or rate limits.
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 extremely concise with two short sentences, front-loading key information (what it does and what it excludes). No filler words, making it efficient for an AI agent.
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 has one parameter, no output schema, and no annotations, the description provides basic purpose and a behavioral caveat (no GPS/samples), but lacks details on the return structure or any other context needed for complete understanding.
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?
The description does not add meaning beyond the schema for the single parameter activity_id. It only mentions 'by id', and with 0% schema description coverage, more detail (e.g., how to obtain the ID, expected range) would be beneficial.
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 a full stored summary row for one activity by ID, and distinguishes itself from siblings like list_activities by specifying 'by id' and noting it excludes GPS/sample streams. It is specific and informative.
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 the activity ID comes from list_activities, giving usage context, but does not explicitly state when to use this tool versus alternatives or when not to use it. More explicit guidance on prerequisites or exclusions would improve clarity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_dayA
One merged view of a single day (YYYY-MM-DD): wellness, sleep, HRV, training status, activities, and data-quality flags.
Use for 'how was ' questions.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes data content but does not disclose behavioral traits (e.g., read-only nature, permissions, side effects). With no annotations, more detail would be beneficial.
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 sentences, no wasted words, front-loaded with purpose and followed by usage guidance.
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?
Covers main purpose and data categories, but lacks details on output format or date range constraints. Sufficient for a simple 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?
The description specifies the date format YYYY-MM-DD, which the schema lacks, adding value. Could be more explicit about required format.
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 provides a merged view of a single day with wellness, sleep, HRV, activities, and data-quality flags, distinguishing it from siblings like get_activity and list_activities.
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?
Provides explicit usage context ('Use for 'how was <date>' questions') but does not mention alternatives or when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
import_fitA
Import one manually exported Garmin wellness FIT bundle (folder of .fit files) - zero-auth offline ingest.
Existing API-sourced rows are never overwritten.
| Name | Required | Description | Default |
|---|---|---|---|
| folder | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries full behavioral burden. It discloses that existing API-sourced rows are never overwritten, which is a key safety trait. However, it does not mention error handling, validation, or what happens on success.
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 sentences, front-loaded with the primary action, and each sentence adds value. No redundancy or fluff.
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 one parameter, no output schema, and no annotations, the description covers core purpose and a key behavior. However, it lacks details on error handling, file size limits, and confirmation of success. It's functional but not exhaustive.
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 0%, so description must compensate. It adds meaning by specifying the folder contains .fit files and is a Garmin FIT bundle. However, it does not clarify path format or requirements, but for a single parameter this is adequate.
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 verb 'Import' and the resource 'manually exported Garmin wellness FIT bundle (folder of .fit files)'. It distinguishes from siblings like 'sync' by specifying manual export and zero-auth offline ingest.
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 when to use: when you have a manually exported Garmin FIT bundle. It doesn't explicitly exclude alternatives, but the context of manual ingest and zero-auth sets it apart from sibling tools like 'sync' and 'sync_status'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_activitiesA
List recent activities newest-first as a compact table, filterable by type (e.g. 'running'), date range, and minimum distance.
truncated=true means more rows exist beyond the limit.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| type | No | ||
| limit | No | ||
| start | No | ||
| min_distance_m | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description provides behavioral context: ordering (newest-first) and truncation signal ('truncated=true'). This adds value beyond the input schema, though it omits details like authentication or rate limits.
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 sentences, front-loaded with main action, no filler. Every sentence adds value: the first states purpose and filters, the second explains the truncated flag.
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 tool with 5 parameters and no output schema, description covers core behavior and filtering but lacks return format details (e.g., columns in the compact table). Still, it provides sufficient context for an AI agent to understand the tool's role.
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 0%, so description must explain parameters. It mentions filterable by type (with example 'running'), date range (implied start/end), and minimum distance, but does not explain the 'limit' parameter (default 20) nor date format. Partial coverage.
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?
Description clearly states 'List recent activities newest-first as a compact table', specifying the verb, resource, order, and format. This distinguishes it from siblings like get_activity (single activity) or query_metrics (metrics).
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 listing activities with filters but does not explicitly state when not to use it or mention alternatives. No guidance on when to use get_activity for a single activity or query_metrics for aggregated metrics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_metricsA
Columnar time series for one or more metrics (e.g. resting_hr, sleep_score, steps) between two dates.
Prefer weekly/monthly aggregate for ranges over ~60 days; stats=True adds mean/min/max/sd per metric.
| Name | Required | Description | Default |
|---|---|---|---|
| end | Yes | ||
| start | Yes | ||
| stats | No | ||
| metrics | Yes | ||
| aggregate | No | daily |
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 discloses that stats adds summary statistics and hints at aggregation behavior, but lacks details on output format, pagination, or performance implications.
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 sentences, front-loaded with the core function, and each sentence adds value. No fluff.
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?
Without an output schema, the description partially explains returns ('columnar time series' and stats details). It could be more explicit about the structure, but given the tool's simplicity and sibling differentiation, it is reasonably 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 0%, so the description adds meaning by explaining metrics (with examples), the role of start/end, the aggregate hint, and the stats flag. It does not cover all parameters fully, but provides significant context.
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 it is for retrieving columnar time series for specified metrics between dates, with examples. This differentiates it from siblings like get_activity or get_day, which are more specific.
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?
Provides a usage guideline: prefer weekly/monthly aggregate for ranges over ~60 days. However, it does not explicitly state when not to use or mention alternatives, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
syncB
Fetch up to 60 days from Garmin Connect into the local store.
Default: last 30 days ending yesterday. Use for catch-ups; multi-month backfills belong in the CLI.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ||
| start | No | ||
| endpoints | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry behavioral disclosure. It reveals the tool fetches data (presumably writes to local store), sets a 60-day limit, and defaults to last 30 days. However, it does not disclose write behavior (overwrite/merge), authentication requirements, or rate limits, leaving 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 sentences, no fluff. Action verb upfront, default behavior stated, and usage guidance included. Every sentence adds distinct 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?
The description lacks explanation of return format, error handling, and parameter details (especially 'endpoints'). For a tool with 3 undocumented parameters and no output schema, this is incomplete.
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 0%, so the description must explain parameters. It only implies start/end via default behavior, and 'endpoints' is mentioned but not described. This is insufficient for the 3 parameters.
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 fetches up to 60 days from Garmin Connect into the local store, with a default of last 30 days. It distinguishes from multi-month backfills via CLI, but sibling tools like list_activities or get_activity are not explicitly differentiated.
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 explicitly guides use for catch-ups and advises against multi-month backfills by directing to the CLI. This provides clear when and when-not context, though alternatives among sibling tools are not named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_statusA
Show local data coverage per table, last sync time, and pending sync errors.
Use to see what date ranges are queryable.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
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 describes the tool as read-only, showing status information. However, it does not disclose whether authentication is needed, or if the data is purely local or requires network access. The description is adequate but lacks detail on potential side effects or dependencies.
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 sentences with no wasted words. It front-loads the key purpose and provides a concrete usage hint. Every sentence 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?
Given zero parameters and no output schema, the description covers the essential information: what is shown (coverage, time, errors) and when to use it. It could be more complete by specifying what tables are included or whether the output includes error details, but it is sufficient for basic understanding.
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, and schema coverage is 100% (trivially). The description does not need to add parameter info, and it appropriately focuses on the tool's behavior. Baseline 4 is justified.
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 shows local data coverage, last sync time, and pending sync errors. It also provides a usage hint about queryable date ranges. This distinguishes it from sibling tools like 'sync' (triggers sync) and 'gaps' (shows missing data), but could be more explicit about the tables covered.
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 explicitly says 'Use to see what date ranges are queryable,' which provides a specific use case. While it doesn't list when not to use it, the context of sibling tools (e.g., sync for triggering, get_activity for specific data) makes the usage relatively clear.
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. Dates show when Glama detected each change.
12 tool updates
v1.0.0- First observed
anomalies - First observed
auth_status - First observed
baselines - First observed
correlate - First observed
gaps - First observed
get_activity - First observed
get_day - First observed
import_fit - First observed
list_activities - First observed
query_metrics - First observed
sync - First observed
sync_status
TDQS
Each tool has a clear, distinct purpose: anomalies, baselines, and correlate perform different analyses; gaps, sync, and sync_status handle data coverage and syncing; get_activity, get_day, list_activities, and query_metrics retrieve data in different granularities; import_fit and auth_status are specialized. No two tools overlap in functionality.
Most tools follow a verb_noun pattern (get_activity, list_activities, import_fit, sync_status) or are clear nouns (anomalies, baselines, gaps). The mix of noun and verb_noun is minor and still readable. All use consistent snake_case.
12 tools is well-scoped for a local Garmin data server. The set covers authentication, syncing, data retrieval, and analysis without being bloated. Each tool earns its place for the domain.
The tool surface covers core CRUD-like operations (sync, list, get, query) plus analysis (anomalies, baselines, correlate) and import. Missing update/delete operations, but these are less critical for a read-only local store. Slight gap in data management (e.g., clearing data) but overall comprehensive.
Maintenance
Related MCP Connectors
Multi-tenant hosted MCP server for Oura Ring — 21 read-only tools, OAuth per user.
MCP server for Withings health data — sleep, activity, heart, and body metrics.
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
Remote MCP server for training, nutrition, wellness, and performance data with OAuth 2.0.
Related MCP Servers
- AlicenseAqualityAmaintenanceFitness AI - MCP server providing AI-powered tools and automation by MEOK AI Labs515MIT
- AlicenseBqualityAmaintenanceLocal-first MCP server that connects AI agents to your Garmin sleep, HRV, Body Battery, stress, training readiness and activities, keeping tokens on your machine.4271911MIT
- FlicenseBqualityCmaintenanceA personal remote MCP server for fitness data that provides read-only tools to query Garmin Connect activities and Hevy workouts, enabling users to list, retrieve, and analyze exercise records through natural language.13-
- FlicenseNot gradedqualityBmaintenanceA multi-platform fitness MCP server that syncs data from Garmin, Strava, Google Fit, and Suunto into a local DuckDB database and provides analytics tools via MCP.1-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/anup-shesh/garmin-local-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server