ClaudeCodeMod

All shelves / MCP servers

Garmin

taxuspt/garmin_mcp · 482 stars · Python · MIT

MCP server MCP server to access Garmin data

Install

In your shell
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-auth

These repos do not share one command. When an entry shows a command, it was copied as published. Check the repo's README before you run it.

Open the repo

Files

README.md

Garmin MCP Server

This Model Context Protocol (MCP) server connects to Garmin Connect and exposes your fitness and health data to Claude and other MCP-compatible clients.

Garmin's API is accessed via the awesome python-garminconnect library.

Features

  • List recent activities with pagination support
  • Get detailed activity information
  • Edit activities: name, type, description/notes, event type, perceived effort (RPE), and feel
  • Access health metrics (steps, heart rate, sleep, stress, respiration)
  • View body composition data
  • Track training status and readiness
  • Access cycling FTP and lactate threshold metrics
  • Manage gear and equipment, including free-text notes returned by get_gear
  • Access workouts and training plans
  • Inspect detailed workout step structures, including repeat groups and swim pace targets
  • Weekly health aggregates (steps, stress, intensity minutes)
  • Advanced cycling analytics: power zones, FIT file analysis, DI2 electronic shift intelligence
  • Training load trend (CTL/ATL/TSB), HRV trend, VO2 max trend, respiration rate trend
  • Power Duration Curve, climb detection with VAM, cardiac drift (aerobic decoupling), W/kg calculations

Tool Coverage

This MCP server implements 110+ tools covering ~90% of the python-garminconnect library (v0.3.2):

  • ✅ Activity Management (20 tools) - includes write tools for type, description, event type, perceived effort, and feel
  • ✅ Health & Wellness (34 tools) - includes custom lightweight summary tools
  • ✅ Training & Performance (13 tools) - includes CTL/ATL/TSB, HRV, VO2 max, and respiration trends
  • ✅ Workouts (8 tools)
  • ✅ Devices (7 tools)
  • ✅ Gear Management (5 tools)
  • ✅ Weight Tracking (5 tools)
  • ✅ Challenges & Badges (10 tools)
  • ✅ Nutrition (9 tools) - food logs, meals, custom foods, food logging, and multi-day intake summaries
  • ✅ Women's Health (3 tools)
  • ✅ User Profile (3 tools)
  • ✅ High-Level Workout Builders (4 tools) - create and schedule workouts without writing JSON
  • ✅ Courses (5 tools) - list / get details / upload GPX as course / download GPX / delete course
  • ✅ Activity Analysis (2 tools) - FIT file parsing, Power Duration Curve; requires power meter and/or Di2
  • ✅ Activity File Downloads (2 tools) - download activity files in FIT, GPX, TCX, or CSV format

Note: Activity Analysis tools require a compatible power meter (e.g., Garmin Rally, Favero Assioma, PowerTap P1) and/or Shimano Di2 / SRAM eTap electronic shifting. The fitparse dependency is installed automatically.

Gear Notes

Each item in the gear array returned by get_gear includes a notes field containing the free-text Notes value shown in Garmin Connect. Gear without a Notes value returns null; all existing gear fields remain unchanged.

Activity File Downloads

Two tools let you download a raw activity file to disk:

  • download_activity_file(activity_id, format="fit", output_dir=None) — downloads the activity and saves it to the configured directory. format accepts fit (default), gpx, tcx, or csv.
  • set_fit_download_dir(path) — sets and persists the default download directory (written to the config file).

Where files are saved (precedence):

  1. output_dir argument — one-off override, not persisted.
  2. GARMIN_FIT_DOWNLOAD_DIR environment variable.
  3. Persisted config set via set_fit_download_dir.

First-run behavior: if no directory is configured, download_activity_file returns status: "needs_setup". The assistant will ask where you want to save files (suggesting the current directory as default), call set_fit_download_dir to persist your choice, and then retry the download automatically.

Intentionally Skipped Endpoints

Some endpoints are not implemented due to performance or complexity considerations:

High Data Volume:

  • get_activity_details() - Returns large GPS tracks and chart data (50KB-500KB). Use get_activity() for summaries instead.

Specialized Workout Formats:

  • upload_running_workout(), upload_cycling_workout(), upload_swimming_workout() - Sport-specific workout uploads. Use upload_workout() for general workouts.

Maintenance & Destructive Operations:

  • delete_activity(), delete_blood_pressure() - Destructive operations require careful consideration.
  • Internal/Auth methods: login(), resume_login(), connectapi(), download() - Handled automatically by the library.

If you need any of these endpoints, please open an issue.

Tool Filtering

This server registers 110+ tools by default, which can be a lot of context for an LLM to carry in every session. You can expose only the tools you need with two optional environment variables:

Tool names are case-insensitive. With neither variable set, all tools register (unchanged default behaviour). Names that match no tool are ignored with a warning on stderr, which makes typos easy to spot.

Example — expose only sleep, stress, and recent activities:

"env": {
  "GARMIN_ENABLED_TOOLS": "get_sleep_data,get_stress_summary,get_activities"
}

High-level workout tools

These builder tools let an LLM create and schedule workouts without writing raw Garmin JSON.

create_walk_run_workout

Creates a walk/run interval workout with optional heart-rate zone target.

{
  "name": "W3 Mié 2:2",
  "run_seconds": 120,
  "walk_seconds": 120,
  "repeats": 9,
  "warmup_min": 10,
  "cooldown_min": 8,
  "hr_zone": "Z3"
}

Returns: {"status": "success", "workout_id": 1234567890, ...}

create_z2_walk_workout

Creates a steady Z2 walking workout.

{
  "name": "Z2 Walk 45m",
  "duration_min": 45,
  "hr_min": 110,
  "hr_max": 130
}

Returns: {"status": "success", "workout_id": 1234567890, ...}

create_strength_workout

Creates a strength workout from a list of exercises. Each becomes a reps-based step, with the name kept in the step description. The name is also sent as exerciseName, but Garmin only retains that when it matches one of its own exercise keys (e.g. FARMERS_CARRY) — any other value is accepted and then stored empty.

category is optional and passed straight through. Omit it and the key is left out of the payload entirely, which Garmin accepts. Supply it and it must be one of Garmin's exercise categories — anything else, including OTHER and UNASSIGNED, is rejected with 400 - Invalid category. The full list is published at Exercises.json.

{
  "name": "Full Body A",
  "exercises": [
    {"name": "Sentadillas", "sets": 3, "reps": 12, "rest_seconds": 90},
    {"name": "Flexiones",   "sets": 3, "reps": 15, "rest_seconds": 60},
    {"name": "Peso muerto", "sets": 3, "reps": 10, "rest_seconds": 90},
    {"name": "Farmers Carry 40m", "sets": 3, "reps": 1, "rest_seconds": 90, "category": "CARRY"}
  ]
}

Returns: {"status": "success", "workout_id": 1234567890, ...}

schedule_week

Schedules multiple workouts in one call.

{
  "week": [
    {"date": "2026-05-12", "workout_id": 1234567890},
    {"date": "2026-05-14", "workout_id": 1234567891}
  ]
}

Returns: {"status": "complete", "scheduled": [...]}

Full flow example

create_walk_run_workout(name="W3 Mié 2:2", run_seconds=120, walk_seconds=120,
                        repeats=9, warmup_min=10, cooldown_min=8)
  → workout_id = 1560092011

schedule_workout(workout_id=1560092011, date="2026-05-06")
  → OK

After syncing your watch, the workout appears on the Forerunner 965 calendar.

Raw upload_workout end conditions

When building custom workout JSON for upload_workout or upload_workouts, the endCondition.conditionTypeId and endCondition.conditionTypeKey must match Garmin's canonical mapping. Garmin treats the numeric conditionTypeId as the source of truth; if the key and ID conflict, Garmin stores the condition that matches the ID.

For example, this is invalid for a heart-rate end condition because ID 4 is calories, not heart.rate:

{
  "endCondition": {
    "conditionTypeId": 4,
    "conditionTypeKey": "heart.rate"
  },
  "endConditionValue": 145
}

Use ID 6 for heart rate:

{
  "endCondition": {
    "conditionTypeId": 6,
    "conditionTypeKey": "heart.rate"
  },
  "endConditionValue": 145
}

For a zone-based heart-rate end condition, use endConditionZone (1-5) on the same endCondition object and omit endConditionValue. If both are sent,

Facts

Kind
MCP server
Repo
taxuspt/garmin_mcp
Group
Uncategorized
Stars
482
License
MIT
Language
Python
Last push
2026-10-01
Forks
413

More on this shelf

  1. 1Everythingmodelcontextprotocol/serversThis MCP server attempts to exercise all the features of the MCP protocol. It is not intended to be a useful server, but rather a test server for builders of MCP clients. It implements prompts, tools, resources, sampling, and more to showcase MCP capabilities.85.8k
  2. 2Fetchmodelcontextprotocol/serversA Model Context Protocol server that provides web content fetching capabilities. This server enables LLMs to retrieve and process content from web pages, converting HTML to markdown for easier consumption.85.8k
  3. 3Gitmodelcontextprotocol/serversA Model Context Protocol server for Git repository interaction and automation. This server provides tools to read, search, and manipulate Git repositories via Large Language Models.85.8k
  4. 4Memorymodelcontextprotocol/serversA basic implementation of persistent memory using a local knowledge graph. This lets Claude remember information about the user across chats.85.8k
  5. 5Sequential Thinkingmodelcontextprotocol/serversAn MCP server implementation that provides a tool for dynamic and reflective problem-solving through a structured thinking process.85.8k
  6. 6Timemodelcontextprotocol/serversA Model Context Protocol server that provides time and timezone conversion capabilities. This server enables LLMs to get current time information and perform timezone conversions using IANA timezone names, with automatic system timezone detection.85.8k