Garmin
taxuspt/garmin_mcp · 482 stars · Python · MIT
MCP server MCP server to access Garmin data
Install
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-authThese 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.
Files
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
fitparsedependency 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.formatacceptsfit(default),gpx,tcx, orcsv.set_fit_download_dir(path)— sets and persists the default download directory (written to the config file).
Where files are saved (precedence):
output_dirargument — one-off override, not persisted.GARMIN_FIT_DOWNLOAD_DIRenvironment variable.- 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). Useget_activity()for summaries instead.
Specialized Workout Formats:
upload_running_workout(),upload_cycling_workout(),upload_swimming_workout()- Sport-specific workout uploads. Useupload_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
- 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
- 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
- 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
- 4Memorymodelcontextprotocol/serversA basic implementation of persistent memory using a local knowledge graph. This lets Claude remember information about the user across chats.85.8k
- 5Sequential Thinkingmodelcontextprotocol/serversAn MCP server implementation that provides a tool for dynamic and reflective problem-solving through a structured thinking process.85.8k
- 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