mcpField
G
Garmin Connect

Garmin Connect

本地服务
github.com健康医疗11 周前更新

关于 Garmin Connect

这是一个面向个人 Garmin Connect 账户的非官方 MCP 服务,也提供 Python 库、命令行和本地 HTTP API。它可读取健康与运动数据,并创建或修改训练、运动记录和体重数据。

主要功能

  1. 01读取活动、分组训练组和泳池趟数
  2. 02查询每日健康数据与长期趋势
  3. 03创建训练并安排日程
  4. 04记录或修正训练和体重数据
  5. 05离线搜索 Garmin 动作目录

适用场景

  1. 01查看一周睡眠及每日健康指标
  2. 02分析跑步、骑行或游泳配速
  3. 03安排带目标的训练计划
  4. 04记录力量训练组数和身体成分

MCP 相关

MCP 工具可通过 stdio 或 HTTP 提供给 MCP 客户端;工具与本地 HTTP API 路由共用。服务使用 Garmin Connect 的私有端点,登录凭据令牌保存在本地。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"happyc0der-garmin-connect-api": {
"command": "uvx",
"args": [
"garmin-connect-api"
],
"env": {
"GARMINTOKENS": "<GARMINTOKENS>"
}
}
}
}
启动命令uvx garmin-connect-api
需要配置的环境变量
GARMINTOKENS密钥Directory holding the tokens `garmin login` writes. Defaults to ~/.garmin-api/default.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypigarmin-connect-api0.3.1

工具

38

收录的工具列表 · 更新于 1 周前

此工具无需参数。

详细介绍

garmin-connect-api

通过 MCP 客户端(例如 Claude)、Python 或本地 HTTP API 读取和写入 Garmin Connect:包括带有逐组力量训练详情的活动、每日健康数据、计划训练、已完成的力量训练课程,以及包含完整身体成分数据的称重记录。

非官方。 本项目与 Garmin 无关联,也未获其认可。它通过 python-garminconnect 使用与 Garmin Connect 网站相同的私有端点,因为 Garmin 不为个人用户提供公开 API。这些端点可能会在不另行通知的情况下发生变化,且使用这些端点不受 Garmin 服务条款认可。本项目仅供你访问自己的账号和数据。

状态

v0.3。可读取带有逐组力量训练详情的活动、分段和泳池游泳长度、每日健康数据、最长两年的趋势数据以及带名称的个人纪录;可写入力量训练、跑步、骑行和游泳训练、已完成的力量训练课程、组次更正,以及带身体成分数据的称重记录。共 38 个工具,均已通过真实账号验证。错误报告和功能请求请提交至 GitHub Issues。

快速开始

你需要安装 uv 和 Python 3.12 或更高版本。

1. 登录一次,在终端中运行:

uvx --from garmin-connect-api garmin login

这是唯一需要输入密码的地方。程序会询问你的 Garmin 邮箱、密码和任何多重验证代码,然后将令牌存储在 ~/.garmin-api/default 中,仅你的用户可读取。 之后不会再要求输入密码;如果没有令牌,每个工具都会提示你运行此命令。

2. 将服务添加到你的 MCP 客户端。

Claude Code:

claude mcp add --scope user --transport stdio garmin -- uvx garmin-connect-api@latest

Claude Desktop:编辑 claude_desktop_config.json(macOS 上位于 ~/Library/Application Support/Claude/,Windows 上位于 %APPDATA%\Claude\):

{
  "mcpServers": {
    "garmin": {
      "command": "uvx",
      "args": ["garmin-connect-api@latest"]
    }
  }
}

@latest 会让 uvx 在每次启动服务时检查是否有新版本。不加它时,uvx 会一直运行首次下载的版本。

3. 提出问题。“我这周睡得怎么样?”、“我昨天游泳时的配速保持得如何?”、“从夏天以来我的静息心率有什么变化?”、“显示我最近一次力量训练的组次,并把第 3 至第 5 组改成哑铃划船”、“安排一次周四的游泳训练:先轻松游 200 码,然后做 8 组 100 码自由泳,每组间休息 20 秒,使用 25 码泳池”。

功能

38 个工具均带有注释,让客户端知道哪些工具只读取数据(24 个)、哪些会新增内容(8 个),哪些会删除或覆盖内容(6 个),并可在运行前询问确认。每个参数都有说明,细致到训练步骤的配速目标。

读取写入
按类型和日期筛选的活动创建力量训练、安排训练计划,并推送到手表
每组力量训练详情:动作、次数、重量创建跑步、骑行或泳池游泳训练,并设置目标
跑步和骑行的分段;泳池游泳的每 100 米配速记录已完成的力量训练,包含每一组
一次查看某一天的数据:步数、心率、压力、身体电量、睡眠、HRV、准备度更正某次训练的组数数据:动作、次数、重量
最长两年的趋势:12 项指标,可按日、周或月查看记录体重,或完整的身体成分数据
带名称和单位的个人纪录重命名活动或更改其描述
每次体重记录及身体成分数据删除活动、训练或体重记录
计划训练和日历
Garmin 的 1,527 项动作目录,可离线使用

有四个工具是专为模型编写的,而非对端点的镜像:garmin_status 无需调用 Garmin 即可检查登录状态,find_exercise 可查找 Garmin 对某项力量训练动作的命名,recent_strength_sessions 和 week_summary 则可通过一次调用回答常见问题。

记录已完成的训练是 Garmin 自家的开发者计划从未提供过的写入操作。系统会将训练编码为包含组消息的 FIT 活动文件并上传,因此它会以力量训练活动的形式出现在 Garmin Connect 中,并逐项列出训练动作。

身体成分数据来自智能秤(脂肪、水分、骨骼肌、骨量、BMI、基础代谢率、内脏脂肪),会写入 FIT 体重秤文件,方式与 Garmin 自家的 Index 体重秤相同。普通体重记录只包含体重。

输出示例

回答简洁明了,并以人们易于阅读的方式汇总。以下示例使用的是模拟数据,格式与 Garmin 返回的数据相同。

“我昨天游泳时配速保持得怎么样?”会调用 get_activity_laps:

{
  "sport": "lap_swimming",
  "pool_length": 25.0,
  "pool_unit": "m",
  "summary": {
    "lengths": 80,
    "distance": 2000.0,
    "average_pace": "1:52/100m",
    "first_half_pace": "1:50/100m",
    "second_half_pace": "1:54/100m",
    "by_stroke": {"FREESTYLE": 1800.0, "BACKSTROKE": 200.0},
    "fastest_segment": {"lengths": "5-8", "pace": "1:44/100m"},
    "slowest_segment": {"lengths": "77-80", "pace": "2:01/100m"}
  }
}

“从夏天以来,我的静息心率有什么变化?”会调用 get_trend,将较长时间范围的数据按周汇总:

{
  "metric": "resting_hr",
  "unit": "bpm",
  "aggregation": "week",
  "summary": {
    "days_with_data": 88,
    "average": 54.2,
    "min": 49.0,
    "max": 61.0,
    "first_period_average": 57.3,
    "last_period_average": 51.6,
    "change": -5.7
  }
}

写入数据前须知

  • 你记录的活动可能会自动分享。 如果你的 Garmin 账户已连接 Strava 或其他应用,上传训练后也可能会发布到这些应用;从 Garmin 删除训练并不会将其从其他应用中删除。
  • 请认真对待速率限制。 Garmin 的登录入口前设有 Cloudflare 和账户级速率限制,连续登录失败可能导致账户被锁定一天或更久。此处不会重试登录;遇到速率限制时,所有调用路径都会停止,不会重试。如果遇到这种情况,请等待。
  • 动作名称必须使用 Garmin 自己的命名方式,例如 BENCH_PRESS / BARBELL_BENCH_PRESS。除原始 workout DTO 外,所有写入操作都会先对照动作目录检查名称,并提示相近选项。因此,拼写错误会返回有用的错误信息,而不是 Garmin 简单的 400 错误。在搜索中也可以使用常见健身房名称:“rdl”“ohp”“pull ups”“bench presses”。
  • 如需更正已记录训练,请编辑其组数数据。 修改某组后重新记录训练会创建第二条活动;再次记录完全相同的训练则会被报告为重复项。
  • 训练和身体成分数据必须提供时区偏移量,否则早上 7 点的读数可能会错开数小时。缺少时区偏移量时,系统会拒绝这些数据。

命令行

garmin doctor                          # setup check, no network
garmin activities --type strength_training --limit 5
garmin sets <activity-id>              # per-set detail
garmin day 2026-10-18                  # one day of health data
garmin exercises "lat pulldown"        # search the catalogue, offline
garmin workout create workout.json     # plan a strength workout
garmin log-session session.json        # log a completed one
garmin encode-session session.json     # build its FIT file without uploading
garmin decode-fit activity.zip         # read sets out of a Garmin export
garmin serve                           # the HTTP API on 127.0.0.1:8765

使用 uvx --from garmin-connect-api garmin ... 运行,或使用 uv tool install garmin-connect-api 安装。示例规格文件: session.json, workout.json。

也可以在 Garmin Connect 网站上手动导入编码后的训练文件,这样就无需以你的名义登录任何服务。

Python 库

from datetime import datetime, timedelta, timezone
from garmin_api.services import activities, health, uploads
from garmin_api.models.workouts import (
    StrengthSessionSpec, StrengthSessionExercise, StrengthSessionSet,
)

for activity in activities.list_activities(limit=5, activity_type="strength_training"):
    sets = activities.get_sets(activity.activity_id)
    print(activity.name, sets.total_volume_kg, "kg")

print(health.day("2026-10-18").steps)

uploads.log_strength_session(StrengthSessionSpec(
    name="Push A",
    start_time=datetime(2026, 10, 18, 7, 0, tzinfo=timezone(timedelta(hours=-4))),
    exercises=[StrengthSessionExercise(
        category="BENCH_PRESS",
        exercise_name="BARBELL_BENCH_PRESS",
        sets=[StrengthSessionSet(reps=10, weight_kg=60.0, rest_s=120)],
    )],
))

响应采用 pydantic 模型,并修正了 Garmin 数据中的不一致之处:使用千克而非克、时间点带时区,并统一使用 snake_case。未映射的数据仍可在 raw 中找到 Garmin 的原始负载。

HTTP API

garmin serve 会在 127.0.0.1:8765 上运行相同的 API,并在 /docs 提供交互式文档。MCP 工具由这些路由生成,因此两者不会出现偏差。由于它可以写入你的账户,该服务会拒绝来自浏览器中打开的网页的写入请求,并要求请求使用除 localhost 以外的主机名,以防止 DNS 重绑定。绑定到 localhost 以外的地址需要设置 GARMIN_API_KEY,客户端使用的主机名必须列在 GARMIN_API_HOSTS 中。garmin mcp --http 会在同样的防护机制下通过 HTTP 提供 MCP 工具。

配置

变量用途
GARMINTOKENS令牌的存储位置。默认为 ~/.garmin-api/default。
GARMIN_API_KEY将 HTTP 服务绑定到 localhost 以外的地址时必需。
GARMIN_API_HOSTSHTTP 和 MCP 服务要响应的额外主机名,以逗号分隔。使用 localhost 以外的任何名称时必需。

Docker

Dockerfile 会从代码检出目录构建 MCP 服务。令牌存储在容器内的 /tokens;将现有目录挂载到该位置,并以你自己的用户身份运行,这样刷新的令牌仍归你所有。也可以在容器内登录:

mkdir -p ~/.garmin-api/default
docker build -t garmin-connect-api .
docker run -it --rm --user "$(id -u):$(id -g)" -v ~/.garmin-api/default:/tokens garmin-connect-api garmin login
docker run -i --rm --user "$(id -u):$(id -g)" -v ~/.garmin-api/default:/tokens garmin-connect-api

开发

git clone https://github.com/happyc0der/garmin-connect-api
cd garmin-connect-api
uv sync
uv run pytest

480 个离线测试无需网络或账户即可运行,支持 Linux、macOS 和 Windows。测试涵盖与真实 Garmin 响应格式相匹配的模型、FIT 编解码器的往返转换、与 FIT 配置文件匹配的全部 1,527 个目录练习、HTTP 路由,以及每个 MCP 工具的输出与其自身公布的架构是否一致(严格的客户端会强制检查该架构)。

针对真实账户的测试需显式选择运行;其中会创建数据的测试还需要第二次显式选择:

GARMIN_LIVE=1 uv run pytest tests/live                      # read only
GARMIN_LIVE=1 GARMIN_LIVE_WRITE=1 uv run pytest tests/live  # creates, then deletes

为什么采用非官方途径

Garmin 官方 Connect Developer Program 面向企业,没有上传已完成活动的端点,并且自 2026 年起不再接受新申请。封装该计划的聚合服务每月收费数百美元,而且仅支持只读或仅限计划的操作。因此,本项目会谨慎使用 Garmin 自家网站所用的端点:不轮询,也不会在触发速率限制时重试。

引用

如果你在研究中使用本项目,请使用 CITATION.cff 中的元数据引用;GitHub 的“引用此仓库”按钮可以生成相应格式。

许可

MIT。Garmin 和 Garmin Connect 是 Garmin Ltd. 的商标,在此仅用于说明本项目适用的对象。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。