garmin-local-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GARMINTOKENS | No | Override the token store location (default <data_dir>/tokens) | |
| GARMIN_EMAIL | No | Optional, for non-interactive re-login; when set, login skips the prompts (MFA may still prompt if your account requires it) | |
| GARMIN_PASSWORD | No | Optional, for non-interactive re-login; when set, login skips the prompts (MFA may still prompt if your account requires it) | |
| GARMIN_MCP_DATA_DIR | No | Override the data directory (default ~/.garmin-mcp) |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| auth_statusA | Check whether stored Garmin Connect tokens exist. Use before sync, or when a sync failed with an auth error. |
| 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. |
| sync_statusA | Show local data coverage per table, last sync time, and pending sync errors. Use to see what date ranges are queryable. |
| 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. |
| 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. |
| 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 and
returns it with a Bonferroni-adjusted p-value; if that is >= 0.05, |
| 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. |
| anomaliesA | 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. |
| circadianA | Estimate when this user's body clock wants them to wake up, and test that estimate against their own Garmin history. Read-only: analyses synced sleep times locally and changes nothing. Use for "am I a morning person?", "what time should I wake up?" or "what bedtime fits me?". For whether a single night or metric was normal, use baselines or get_day; for a relationship between two metrics, correlate. Returns three separate estimates, each with an 80% interval: chronotype (MCTQ MSFsc, mid-sleep on free days corrected for catch-up sleep), sleep need, and an inferred wake window with bedtime. Also: stability across reasonable settings, and evidence from a rolling holdout on whether waking near the window went with higher Garmin scores beyond sleep duration and regularity (consistent / supportive / suggestive / unsupported; these describe consistency on unseen nights, not statistical significance), plus a plain-language interpretation and notes. Needs 28+ nights with sleep times; evidence needs 180+ days of history. Takes well under a second. |
| 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. |
| get_activityA | Full stored summary row for one activity by id (from list_activities). Summary fields only - no GPS or sample streams. |
| 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. |
| 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. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 13 tools
Each tool has a clearly distinct purpose, with explicit cross-references in descriptions guiding correct selection (e.g., circadian points to baselines/get_day for normalcy and correlate for relationships). No two tools overlap enough to cause misselection; even closely related tools like sync_status and gaps are differentiated by their focus (coverage/errors vs missing days/holes).
All names use snake_case, which is consistent, but the structural convention varies: some are bare nouns (circadian, baselines, anomalies, gaps), some are verb_noun (get_day, get_activity, query_metrics, list_activities), and others are status or action verbs (auth_status, sync, correlate). This mixed pattern is readable but lacks a predictable verb_noun scheme throughout.
13 tools is well within the ideal 3-15 range and each tool earns its place, covering distinct facets of local Garmin data handling: ingestion, status, retrieval, and analysis. The set is neither bloated nor thin for the domain.
The surface covers the essential lifecycle: sync/auth, coverage checks, day-level and activity-level retrieval, time-series queries, and multiple analysis tools (correlation, baselines, anomalies, circadian). Minor gaps exist, such as no explicit tool to discover available metric names for query_metrics, and activity detail is limited to summary rows (no streams), but these are workable limitations rather than dead ends.