Local Garmin warehouse that syncs data to SQLite and provides offline trends, correlations, baselines, and anomaly detection.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We ran the install command below but it didn't respond within our test window β this can mean a slow first-time install rather than a real problem.
uvx garmin-local-mcpNo response to initialize.
This is an experimental automated check and can have false negatives β missing environment variables, a slow cold install, etc. It doesnβt necessarily mean somethingβs wrong. Last checked 4d ago.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Garmin Local MCP.
Local-first Garmin data warehouse with an analysis-grade MCP server. Sync once, analyze forever, even when the API is down.

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:
| 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+ |
If you don't own a Garmin, or just want to see what the tools return before handing over credentials, seed a synthetic store:
That 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 |
|---|---|
correlate(hrv, resting_hr) | about β0.5, a genuine inverse relationship |
correlate(training_load, resting_hr, scan_lags=True) | ~0 at lag 0, +0.45 at lag 1 β the effect is next-day |
anomalies() | the illness window, flagged across resting HR, HRV, skin temperature, SpO2 and sleep score at once |
gaps() | 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.
Requires Python 3.12+.
Or run it without installing, via uv:
1. Log in once (MFA supported; tokens persist locally, so future runs never ask for a password):
2. 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.
3. Register the MCP server with your client (see Client setup for Claude Desktop, Cursor, and other clients):
4. Ask questions. Examples of what Claude can now answer from your local warehouse in one or two tool calls:
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 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):
Cursor (~/.cursor/mcp.json, or .cursor/mcp.json in a project):
Any other stdio client / no local install (requires uv):
Note: login and the initial backfill sync are CLI steps (see
Quickstart); the MCP server itself never prompts for
credentials.
| Tool | What it does |
|---|---|
auth_status | Check whether stored Garmin Connect tokens exist (use before sync, or after an auth error). |
sync | Fetch up to 60 days from Garmin Connect into the local store (default: last 30 days ending yesterday; big backfills belong in the CLI). |
sync_status | Local data coverage per table, last sync time, and pending sync errors. |
get_day | One merged view of a single day: wellness, sleep, HRV, training status, performance scores, activities, and data-quality flags. |
query_metrics | Columnar time series for one or more metrics between two dates, with daily/weekly/monthly aggregation and optional stats. |
correlate | Pearson/Spearman correlation between two metrics, with day-lag support and an optional scan over lags -7..+7. |
baselines | Personal mean +/- sd band per metric over a trailing window (default 28 days), to judge what is normal for this user. |
anomalies | Outlier days (z-score deviations) and sustained streaks (5+ consecutive days on one side of the mean). |
list_activities | Recent activities newest-first as a compact table, filterable by type, date range, and minimum distance. |
get_activity | Full stored summary row for one activity (summary fields only, no GPS or sample streams). |
gaps | Missing days per table plus unresolved sync errors, to find holes worth re-syncing before drawing conclusions. |
import_fit | 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.
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.
Everything lives in one directory you own (default ~/.garmin-mcp, override
with the GARMIN_MCP_DATA_DIR environment variable or --data-dir):
Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/anup-shesh-garmin-local-mcp)<a href="https://allmcps.com/mcp/anup-shesh-garmin-local-mcp"><img src="https://allmcps.com/api/badge/anup-shesh-garmin-local-mcp?style=directory" alt="Garmin Local MCP on AllMCPs" /></a>