Garmin Connect MCP server

Garmin Connect MCP server

Enables AI assistants to design strength training workouts, push them to Garmin Connect and your watch, and read back completed sessions and exercise history.

Category
访问服务器

README

Garmin Connect MCP server

An MCP server for strength training on Garmin Connect. Design a session in conversation with an AI assistant, push it to your watch, and read back what you actually lifted.

Unofficial. Not affiliated with, endorsed by, or supported by Garmin. Garmin and Garmin Connect are trademarks of Garmin Ltd. This project talks to Garmin's private workout-service endpoints through the reverse-engineered python-garminconnect client, so Garmin can change or break it without notice. Use at your own risk, and check your own obligations under Garmin's terms of service.

Everything runs locally. Your credentials stay on your machine and only ever go to Garmin.

Why this exists

Garmin Connect will not import workout .FIT files — FIT import only works for completed activities, not planned workouts. Your options are the Connect web UI by hand, or the same private endpoint the web app itself calls. This takes the second route and puts an MCP interface on it, so a workout can come out of a conversation instead of twenty minutes of clicking.

Tools

Tool Does
search_exercises Search Garmin's ~1500-movement catalogue
list_workouts Saved workouts and their IDs
get_workout Read one workout's structure back
create_workout Build and upload, with round-trip verification
update_workout Replace contents in place, keeping the ID
delete_workout Delete one workout by ID
schedule_workout Put a workout on the calendar for a date
list_programs / get_program Multi-day templates in programs/
sync_program Create-or-update every workout in a program
get_recent_sessions Completed sessions with set counts and volume
get_exercise_history One movement over time: load, reps, volume, e1RM
export_history Bulk CSV/JSON dump into exports/
get_device_sync_status Devices and last sync, to confirm a push landed

delete_workout is the only destructive tool.

Setup

Requires Python 3.12 or newer (garminconnect 0.3.x needs it).

git clone https://github.com/YOUR-USERNAME/garmin-mcp.git
cd garmin-mcp
./setup.sh

setup.sh creates .venv/ in the project directory, installs dependencies, and copies .env.example to .env. Nothing is installed system-wide. If your newest Python has no wheels for a dependency yet, override it:

PYTHON=python3.13 ./setup.sh

Fill in .env with your Garmin login, then authenticate once:

./.venv/bin/python garmin_login.py

This step is interactive on purpose. Garmin may ask for an MFA code, and the MCP server has no terminal to ask on — it would simply hang. The login caches tokens to ~/.garminconnect, and the server reuses them silently from then on. Re-run it only if the server reports the session expired.

Verify the build without touching the network:

./.venv/bin/python garmin_mcp.py --self-test

Connect it to a client

Claude Desktop

Add to claude_desktop_config.json — on macOS at ~/Library/Application Support/Claude/, on Windows at %APPDATA%\Claude\:

{
  "mcpServers": {
    "garmin": {
      "command": "/absolute/path/to/garmin-mcp/.venv/bin/python",
      "args": ["/absolute/path/to/garmin-mcp/garmin_mcp.py"]
    }
  }
}

Use absolute paths and the venv's interpreter rather than a bare python — the app does not inherit your shell's PATH. Restart the app afterwards.

Anything else

It is a standard stdio MCP server, so any client works. To debug outside one:

npx @modelcontextprotocol/inspector ./.venv/bin/python garmin_mcp.py

Programs

A program is a JSON file in programs/ describing a multi-day template. sync_program pushes every workout in it, matching on name — existing workouts are updated in place, new ones created. See programs/example.json for a commented template.

{
  "name": "Example Upper/Lower",
  "workouts": [
    {
      "name": "[EX] Upper A",
      "warmup": "Two or three ramp-up sets.",
      "blocks": [
        {
          "repeat": 4,
          "steps": [
            { "exercise": "Barbell Bench Press", "reps": 5, "weight_kg": 60,
              "note": "4x5-7. Add 2.5kg once you hit 7 on every set." },
            { "rest_seconds": 180 }
          ]
        }
      ]
    }
  ]
}

A block is a repeat group that runs repeat times. A step is either an exercise (exercise + reps, optionally weight_kg and note) or a rest (rest_seconds). A superset is one block holding both exercises with a short rest between and a long rest at the end. Omit weight_kg for bodyweight work. Omit warmup for the default warm-up step, or set it to "" for none.

programs/*.json is gitignored apart from the example, so your own training never lands in a commit.

Things that will bite you

Garmin silently blanks unrecognised exercise names. The upload returns 200, and the exercise shows up nameless on the watch mid-session. This is why search_exercises exists and why every name is resolved against the catalogue before upload. Display names are hyphenated in ways nobody types — "Rope Press-down", "Close-grip Chin-up" — so the search normalises punctuation and understands shorthand like "db", "bb", "ohp", "rdl", "skullcrusher".

The two halves of the API disagree on weight units. The workout-service takes weightValue in kilograms, despite weightUnit carrying "factor": 1000.0. Activity payloads — what you lifted — report grams. Both are handled; don't "fix" either.

Round-trip verification cannot catch a unit error. It compares what Garmin stored against what was sent, and Garmin faithfully stores whatever you send. When grams were being sent, the check passed and Connect displayed "75,000 kg". Eyeball your first upload in Connect.

Update, don't delete-and-recreate. Keeping the workout ID means the watch treats the change as an edit. Recreating makes it drop the old workouts and pull down new ones, which is where stale duplicates come from.

429 and 401 look the same. Garmin rate limits logins per IP, aggressively. When the first login transport is throttled, garminconnect's fallback reports a misleading 401. If you saw 429 just before, it is throttling — wait 30–60 minutes, and don't retry in a loop, which extends the block. To rule out a genuinely wrong password: garmin_login.py --check-env.

Layout

garmin_mcp.py       the server — tool definitions
garmin_core.py      auth, payload building, verification, set parsing
garmin_login.py     one-time interactive login (MFA lives here)
programs/           multi-day templates as JSON
setup.sh            creates .venv and installs dependencies

Licence

MIT — see LICENSE.

Built on python-garminconnect (MIT) and the MCP Python SDK (MIT).

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选