Model or dataset
Taxuspt/garmin_mcp avatar
Taxuspt/garmin_mcp

Garmin MCP Server: Installation, tool filtering, and first use

MCP server to access Garmin data

1,406 stars441 forksPythonMIT

At a glance

What is it?
Taxuspt/garmin_mcp exposes Garmin Connect activity, health, training, workout, gear, and course data to MCP clients through python-garminconnect. It suits users who want an LLM interface over Garmin data, but its broad tool surface, account credentials, and mutable operations require deliberate configuration.
Who is it for?
Adopt garmin_mcp if your work depends on asking an MCP client to inspect or update a Garmin account and you are comfortable managing credentials, persisted OAuth tokens, and a large tool catalog. Do not adopt it for full activity GPS traces, sport-specific workout uploads, bulk deletion, or workloads that cannot tolerate mutable Garmin operations.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Garmin MCP's account-level integration and intended users

Taxuspt/garmin_mcp solves a specific integration problem: it places Garmin Connect data behind Model Context Protocol tools that clients such as Claude can call. The intended user is not simply an athlete looking at Garmin's own application. The likely user is an engineer, analyst, or MCP client operator who wants conversational or agent-driven access to activities, body composition, sleep, heart rate, training status, workouts, gear, courses, and related records.

The scope extends beyond activity summaries. The README groups the implementation into activity management, health and wellness, training and performance, workouts, devices, gear, weight, challenges, nutrition, women's health, profiles, courses, activity analysis, and file downloads. It states that the server implements more than 110 tools covering about 90 percent of python-garminconnect version 0.3.2. That breadth makes the project useful as a shared account interface, but it also gives an MCP client a substantial catalog of callable operations rather than a narrow read-only API.

This is an account-level integration built on Garmin Connect. The Docker configuration accepts GARMIN_EMAIL and GARMIN_PASSWORD and mounts a volume at /root/.garminconnect for OAuth tokens. Credential and session storage therefore belong in the adoption decision. The server is aimed at users who control an MCP client and understand that the client can receive personal fitness and health information from the connected Garmin account.

python-garminconnect, MCP tools, and Garmin data flow

The repository uses a library-backed adapter design. The pyproject.toml file depends on garminconnect version 0.3.2, MCP versions from 1.28.1 up to but excluding 2.0, and fitparse. Login, resumed login, connectapi, and download internals are handled by python-garminconnect rather than exposed as independent MCP tools. The server package registers Garmin operations as MCP tools and returns their data to a compatible client.

Most tools follow a direct request and response path. A client invokes a named operation such as retrieving recent activities or getting gear, the server maps that operation to python-garminconnect, and the resulting Garmin data is returned as tool output. Some tools add aggregation or calculation. The README identifies weekly health summaries, CTL, ATL and TSB trends, HRV trends, VO2 max trends, respiration trends, Power Duration Curve analysis, climb detection with VAM, cardiac drift, W/kg calculations, and detailed workout inspection as examples.

Other flows persist state or alter remote data. The set_fit_download_dir tool writes the default output directory to the server configuration. The set_activity_exercise_sets tool replaces every existing set on a recorded strength activity. Course tools can upload or delete courses. The delete_activity tool has a two-call confirmation gate: the first call previews the deletion, while a second call with confirm=true performs it. Tool execution is therefore not uniformly read-only, even when the client initially intends to inspect data.

Activity analysis follows a hardware-dependent path. FIT parsing requires compatible cycling hardware such as a Garmin Rally, Favero Assioma, PowerTap P1, or electronic shifting from Shimano Di2 or SRAM eTap. The README says fitparse is installed automatically, but usable input data still depends on the Garmin activity and attached equipment.

Python package installation and Docker deployment for garmin_mcp

The repository defines a Python 3.10 or later package named garmin-mcp and declares console entry points named garmin-mcp and garmin-mcp-auth. The Dockerfile contains the editable installation command used by its container build. It installs the package and its dependencies into the current environment:

bash
uv pip install -e .

The Dockerfile then sets garmin-mcp as the container entry point. The README does not document a complete host installation tutorial or the exact interactive steps required to finish Garmin authentication, so it should not be treated as one. It does show the Python package configuration and a Docker Compose service.

For the container route, the Compose file expects GARMIN_EMAIL and GARMIN_PASSWORD to be supplied as environment values. This configuration passes the credentials into the service and preserves the token directory in a named volume:

yaml
environment:
  - GARMIN_EMAIL=${GARMIN_EMAIL}
  - GARMIN_PASSWORD=${GARMIN_PASSWORD}
volumes:
  - garmin-tokens:/root/.garminconnect

The same service uses stdin_open: true and tty: true for interactive MFA input. That detail matters during a first run because authentication may require interaction rather than only an unattended API request. The Python package also exposes garmin-mcp-auth, but the README does not state its argument syntax, so authentication flags cannot be inferred.

First garmin_mcp use through an MCP client

After installing the package in the same manner used by the repository's Dockerfile, the declared server entry point is garmin-mcp. The package metadata maps that executable to garmin_mcp:main, while the container uses the same executable as its entry point. The README does not specify command-line arguments or transport flags, so a first-use sequence should begin by connecting the server through the chosen MCP client rather than inventing client configuration.

The first useful operation should be a read request such as listing recent activities. This checks that the MCP connection, Garmin account session, and basic read path are available without modifying account data. Before calling a write tool, confirm whether get_gear, get_activity, or get_activity_exercise_sets returns the expected account and object. For strength activities, the README requires reading existing sets before calling set_activity_exercise_sets because that operation replaces the full set collection.

File downloads require one additional setup step. The download directory has a documented precedence order: the output_dir argument overrides GARMIN_FIT_DOWNLOAD_DIR, which overrides the persisted directory set through set_fit_download_dir. If none is configured, download_activity_file returns status: "needs_setup". The documented response should be treated as a setup requirement, not a completed download.

The environment variable GARMIN_FIT_DOWNLOAD_DIR can provide an explicit destination, while set_fit_download_dir persists a directory in the server configuration. Do not assume that the first activity download will create a final directory automatically. The documented result before configuration is specifically needs_setup.

Reducing the Garmin MCP catalog with GARMIN_ENABLED_TOOLS

Context use is a project-specific concern because garmin_mcp registers more than 110 tools by default. The README provides two environment variables for changing that surface. GARMIN_ENABLED_TOOLS is a comma-separated allowlist. If it is set, only named tools are registered. GARMIN_DISABLED_TOOLS is a comma-separated denylist, and it is ignored whenever an allowlist is present.

Filtering is case-insensitive. Names that do not match a registered tool are ignored with a warning on stderr. That behavior gives operators a signal for misspelled tool names, although it does not make configuration automatically safe. An allowlist is the more restrictive choice because it prevents unlisted tools from being registered. A denylist requires enumerating what should be absent while leaving the rest of the catalog available.

The README uses sleep, stress, and recent activities as an example scenario, but its configuration example is truncated before it shows the complete allowlist value. A complete executable snippet cannot be reconstructed without inventing tool names. The mechanism itself is clear: define GARMIN_ENABLED_TOOLS with the exact registered names that the intended client requires, then inspect stderr during startup for unmatched names.

Filtering also affects an MCP client's ability to change Garmin data. Exposing only summary and retrieval tools can reduce both context use and accidental write paths. This is not a formal permission model, however. Any registered mutation, download, upload, or deletion tool remains callable if the client invokes it.

Garmin MCP write boundaries and destructive operations

The server includes editing tools, but several behaviors are destructive or irreversible. The set_activity_exercise_sets tool writes structured sets onto a recorded strength activity and replaces every existing set, including watch-detected sets. The keep_timing option preserves recorded timing while replacing exercise, repetition, and weight values in order. Garmin rejects unknown exercise keys and leaves the activity unchanged, so callers must use valid Garmin keys from Exercises.json.

Deletion has stricter gating but no rollback. The delete_activity tool must first be called to preview the operation, then called again with confirm=true. The README states that deletions are logged to stderr and that there is no undo. By contrast, delete_blood_pressure is intentionally omitted. The project also omits get_activity_details because that endpoint can return large GPS tracks and chart payloads of roughly 50 KB to 500 KB.

Course deletion is also present. The tool list includes course listing, detail retrieval, GPX upload and download, and deletion. These operations mean an MCP client should not receive unrestricted account access merely because its main goal is data retrieval. Configure the narrowest practical tool allowlist and keep confirmation behavior visible in the client workflow.

The repository identifies the project as licensed under MIT. That license permits use, modification, distribution, and sublicensing subject to its conditions, including preservation of its copyright and permission notice. Account use remains subject to Garmin's service terms and the permissions associated with the supplied credentials.

Maintenance signals, dependency constraints, and direct-library alternative

The repository is not archived, and its last push was on 2026-10-15. Its listed release is Garmin MCP DXT 0.1.0, dated 2026-05-08. These facts show the available release and recent repository activity, but they do not establish how quickly future Garmin changes will require code changes. Upgrade work also includes revalidating Garmin operations, exercise keys, authentication behavior, and client compatibility affected by MCP package changes.

The dependency ceiling is especially relevant. The pyproject.toml file states that MCP 2.x renamed mcp.server.fastmcp to mcp.server.mcpserver, and that the project is capped below version 2 until the server is ported to that API. The package also pins python-dotenv, garminconnect, and requests, while fitparse and test dependencies have lower bounds. A deployment therefore inherits both Garmin library compatibility and the repository's MCP 1.x constraint.

A direct python-garminconnect script is a real alternative for an engineer who wants Garmin data without an MCP layer. It can call the library in an ordinary Python process, keep the operation list small, and avoid giving an LLM account-level tools. The difference is the interface and trust boundary. A direct script requires the engineer to implement retrieval, authentication, persistence, and error handling. garmin_mcp supplies a broad callable catalog and MCP client integration, but adds a large context surface and exposes more mutation paths. For a narrow report, the direct script may be simpler. For an MCP-driven workflow, the server supplies the protocol layer.

Editorial conclusion

Adopt garmin_mcp if your work depends on asking an MCP client to inspect or update a Garmin account and you are comfortable managing credentials, persisted OAuth tokens, and a large tool catalog. Do not adopt it for full activity GPS traces, sport-specific workout uploads, bulk deletion, or workloads that cannot tolerate mutable Garmin operations. Before connecting account data, verify the enabled tool list, protect the OAuth token volume, configure an explicit FIT download directory, and review every write or deletion tool that the client can invoke.

Frequently asked questions

What does Taxuspt/garmin_mcp do?

It is a Python MCP server that connects to Garmin Connect and exposes fitness, health, training, activity, workout, gear, course, and related data to Claude and other MCP-compatible clients.

How do I install garmin_mcp?

The package requires Python 3.10 or later. The Dockerfile installs the repository with `uv pip install -e .`, while pyproject.toml defines the `garmin-mcp` and `garmin-mcp-auth` entry points.

How can I limit the Garmin MCP tools exposed to a client?

Set GARMIN_ENABLED_TOOLS to a comma-separated allowlist. Without that variable, GARMIN_DISABLED_TOOLS can define a denylist, although it is ignored whenever the allowlist is set.

Why does download_activity_file return status: "needs_setup"?

That status occurs when no download directory is configured. The server checks output_dir, then GARMIN_FIT_DOWNLOAD_DIR, then the directory persisted through set_fit_download_dir.

Can garmin_mcp recover a deleted activity?

No. delete_activity requires a preview call followed by confirm=true, and the README states that deletion has no undo.

Which Garmin MCP activity analysis features need compatible hardware?

The README says FIT analysis requires a compatible power meter or supported electronic shifting. It names Garmin Rally, Favero Assioma, PowerTap P1, Shimano Di2, and SRAM eTap examples.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. Taxuspt/garmin_mcp on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/taxuspt-garmin-mcp.svg)](https://hysenlabs.com/projects/taxuspt-garmin-mcp)

Was this useful?