关于 garmin-mcp
面向运动员和教练的非官方 MCP 服务,用于查看 Garmin Connect 的训练、活动、健康和睡眠数据。它在本机计算带有引用依据的训练负荷与准备度指标,以 SQLite 缓存数据,并可将经确认的结构化训练加入 Garmin 日历和手表。
主要功能
- 0120 项训练与健康查询工具
- 02本机计算并引用负荷和准备度依据
- 03按需下载并使用 SQLite 缓存
- 04创建训练并安排到日历
- 05活动、睡眠、健康和设备数据
适用场景
- 01回顾训练负荷和每周活动
- 02根据个人基线查看晨间准备度
- 03规划并安排结构化训练
- 04查看睡眠、HRV 和健康趋势
MCP 相关
该服务向 MCP 客户端提供 Garmin Connect 数据、分析工具、资源和提示词,支持 stdio 与 streamable HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
20收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| to | string | 否 | 结束日期;默认值:今天 |
| from | string | 否 | 开始日期;默认值:`to` 前 7 天 |
| force | boolean | 否 | 重新下载已存储的日期 |
| scope | enum | 否 | all | activities | health(每日摘要、睡眠、HRV、体重)| training(状态、准备度、VO2max)| reference(个人资料、装备、设备、活动类型、训练项目、from..to 范围内的日历月份,也包括未来月份)all | activities | health | training | reference |
详细介绍
Garmin MCP
询问 AI 助手,了解你的训练实际进展如何。 Garmin MCP 是一款非官方的开源 MCP 服务,可访问你的 Garmin Connect 数据:训练负荷、训练状态和晨间准备度均在你的设备上根据已发表的运动科学文献中的方法计算,并附有引用;提供 20 个围绕运动员常见问题设计的工具,而非 Garmin API 的镜像;采用本地 SQLite 缓存,只下载回答问题所需的数据;还能创建结构化训练计划,从答案直接添加到 Garmin 日历并同步到手表。它还可以读取活动、健康、睡眠、训练状态、身体成分、装备、设备和训练计划库。
兼容 Claude Code、Claude Desktop、Codex、Antigravity CLI、opencode 以及任何其他 MCP 客户端(stdio 或 streamable HTTP)。
文档:endurancetools.github.io/garmin-mcp(各客户端的入门指南、提问示例、配置和故障排除)。贡献与开发:DEVELOPMENT.md。
非官方项目。Garmin 和 Garmin Connect 是 Garmin Ltd. 或其子公司的商标;本项目与 Garmin 无关联,也未获 Garmin 认可。训练分析(get_load、get_readiness)仅提供训练信息,不构成医疗建议。
为什么选择 Garmin MCP
- 答案可供核验。 根据功率、配速、心率或单次训练 RPE 计算训练负荷(TSS),并计算体能、疲劳和训练状态(CTL/ATL/TSB)、ACWR、强度分布和晨间准备度。晨间准备度基于你自己的 HRV、静息心率、睡眠和训练负荷,并与个人基线比较;计算采用已发表的运动科学文献中的方法,并附有引用。每个答案都会返回所用的数值和规则,你也可以修改这些规则。方法与证据
- 专为实际问题设计的工具,而非 API 镜像。 提供 20 个围绕“回顾一下我的这一周”或“我今天可以进行高强度训练吗?”等问题设计的工具,一次调用即可回答一个问题。整个工具列表占用的模型上下文约为 7,800 个 token;在 42 个工具选择场景中,首次工具调用有 42 次选对了工具。精心设计的工具
- 本地运行,保护隐私。 你会在 Garmin 官方页面登录,因此工具不会接触到你的密码。下载的数据会保存在电脑上的本地数据库中,查询结果可在毫秒内返回;下载速度经过控制,以避免给 Garmin 造成过多负担;工具答案只会发送给你连接的 AI 客户端。数据存储位置
- 从答案到手表。 询问“周四进行 6×400 m 训练,每组间休息 90 s”:你会先看到训练步骤和预计时长,只有在你同意后才会保存,随后训练计划会添加到 Garmin 日历并同步到手表。训练计划与日历
入门
要求:Node.js 22 或更高版本、Garmin Connect 账户,以及用于登录窗口的 Chrome、Edge、Brave 或 Chromium(也可使用终端备用方式)。
1. 登录一次。 这会在浏览器中打开 Garmin 自己的登录页面。你的密码不会经过此工具;只会存储 Garmin 签发的令牌,位置为 ~/.garmin-mcp。
npx -y garmin-mcp-cli login
2. 将服务添加到客户端。
| 客户端 | 配置 |
|---|---|
| Claude Code | claude mcp add garmin -- npx -y garmin-mcp-server |
| Claude Desktop | 从 GitHub 发布页安装 garmin-mcp-<version>.mcpb,或添加到 claude_desktop_config.json:{"mcpServers":{"garmin":{"command":"npx","args":["-y","garmin-mcp-server"]}}} |
| Codex | ~/.codex/config.toml:[mcp_servers.garmin] command = "npx" args = ["-y", "garmin-mcp-server"] |
| Antigravity CLI | agy mcp add garmin npx -y garmin-mcp-server |
| opencode | opencode.json:{"mcp":{"garmin":{"type":"local","command":["npx","-y","garmin-mcp-server"],"enabled":true}}} |
| 任何其他客户端 | 命令 npx,参数 -y garmin-mcp-server,传输方式为 stdio |
3. 提问。 只有问题需要数据时才会下载。例如:
- “我这周睡得怎么样?”或“我的 HRV 整个夏天的趋势如何?”
- “评估一下我的训练周”或“总结一下我从 2026-08-04 到 2026-09-28 的训练周期”
- “我累了吗?我现在的状态如何?”
- “我的下一场比赛是什么时候?”或“这周有什么计划?”
- “为我安排周四的 6×400 m 训练,每组间休息 90 s”(你会先看到训练步骤,只有在你同意后才会保存)
- “将活动 21001 重命名为 Parkrun PB”
可选:预先加载一段日期范围,这样首次提问就能立即得到答复。
npx -y garmin-mcp-cli sync --scope all --from 2026-07-01 --to 2026-09-30
数据获取方式
登录和启动服务都不会下载任何内容。如果问题涉及本地数据库中没有的日期,工具会准确下载相应范围,等待最多 20 s 后作答;尚未完成的下载会在后台继续进行,并在答复中说明(meta.source 为 partial)。所有下载的数据都会保留在本地数据库中:已存储的日期不会再次下载,除非你传入 --force,因此重复提问无需额外成本。
为避免给 Garmin 造成负担,较长日期范围会按 7 天分块,从最新日期开始下载;每个实际下载了内容的数据块之后会随机暂停 1-11 s,每天最多发送 600 个请求。遇到 429 响应或 Cloudflare 验证时,所有下载都会暂停 6 h。同步中断后会从中断处继续。
设置 GARMIN_AUTO_FETCH=false 后,除非运行 garmin sync 或 garmin_sync 工具,否则不会下载任何内容;读取工具会在 meta.sync_hint 中返回缺失范围,然后由模型先向你确认。
在真实账户完成 90 天同步后进行测量(约 1 小时内发送 433 个请求):答复从本地数据库获取,耗时为 1-110 ms。
工具
| 工具 | 用途 |
|---|---|
get_activities | 密集活动列表,支持游标分页;type 接受 Garmin 类型键(garmin://activity-types 中的所有键) |
get_activity | 单项活动:summary、splits、hr_zones、power_zones、weather、exercise_sets(力量训练组),或 full(所有部分及原始数据流,按 50 KB 分页) |
update_activity | 名称、类型、描述、RPE、感受 |
download_activity_file | 将 FIT(解压后)、GPX、TCX、KML、CSV 下载到下载目录(GARMIN_FIT_DOWNLOAD_DIR) |
query_health | 步数(含每日距离)、静息心率(含每日心率最小值/最大值)、HRV(含状态和基线)、睡眠、压力、身体电量、呼吸、SpO2、强度分钟数、卡路里(消耗量,以及关联饮食日志时的摄入量)、楼层数;按天或周查询,并提供 7/28 天趋势 |
get_sleep | 查询一晚的睡眠及各阶段,或查询一段时间范围内的睡眠及平均值 |
get_training_status | VO2max、训练准备度、恢复时间、Garmin 状态、负荷和负荷重点、garmin_load_model(根据 Garmin 训练负荷计算的 CTL/ATL/TSB,可选每日序列);比赛预测、耐力/爬坡分数、体能年龄、个人纪录、适应情况 |
get_body_composition | 以 kg 为单位的称重记录及趋势 |
get_period_summary | 周、月或任意 from..to 范围(最长 366 天):各运动项目的训练量、心率区间、休息日、时间最长/强度最高的活动、期末的 garmin_load_model、健康和能量平均值 |
list_workouts、get_workout | 任意日期范围内的训练库、已安排的训练、日历中的比赛和活动(默认:未来 60 天),以及易读的训练步骤 |
create_workout、schedule_workouts | 根据预设(跑步间歇、跑走结合、轻松 Z2、力量循环)或输入的定义(可嵌套重复、心率/配速/功率目标)创建训练;create_workout 设置 dry_run: true 时会显示训练步骤和预计时长,但不会保存;schedule_workouts 会将训练添加到日历,也可以将其移除 |
get_gear、get_devices | 显示里程的装备,以及显示上次同步时间和设置的设备 |
garmin_sync | 显式下载指定范围的数据(全部/活动/健康/训练/参考数据),并显示进度通知 |
get_load | 自有负荷模型(根据功率、配速、心率或 RPE 计算每项活动的 TSS,并采用各日期有效的阈值):CTL/ATL/TSB、ACWR 7:28、单调度和压力、带可覆盖阈值的标记、按运动项目划分的 ISO 周、3 区强度分布;可选每日序列、每项活动的 TSS/IF/负荷来源/EF、月度 EF 趋势 |
get_readiness | 根据 HRV、静息心率、睡眠时长和负荷给出晨间 GO / MODIFY / REST 建议;显示 Garmin 的 Training Readiness、身体电量、压力和睡眠分数,但不纳入计算;支持可覆盖的 rules,并显示每项信号的数值、参考值和评级 |
get_thresholds、set_threshold | 按日期查询阈值历史(各运动项目的 LTHR、LT1、HRmax、FTP、VO2max 等;自动记录 Garmin 个人资料更改)、根据 Garmin 个人资料查询各运动项目的心率和功率区间,以及仅在本地记录测试结果 |
仅当设置 GARMIN_ENABLE_DESTRUCTIVE=true 时,才可使用 delete_activity、delete_workout、delete_weigh_in,以及覆盖已保存的训练(使用 workout_id 的 create_workout)。
资源:garmin://profile、garmin://gear、garmin://devices、garmin://activity-types、garmin://sync-status,以及支持 ID 补全的模板 garmin://activity/{id} 和 garmin://workout/{id}。提示词:weekly_review、plan_next_week。
每个响应都采用 { data, meta: { source: cache|live|partial|local, fetched_at, coverage?, sync_hint? } } 格式,以 JSON 文本和符合工具 outputSchema 的 structuredContent 形式返回;失败时返回 { error: { code, message, hint } }。
分析工具的公式、默认值和限制:docs/analytics.md。Garmin Connect 涵盖哪些数据,以及仍缺少哪些数据:docs/coverage.md。
CLI
garmin-mcp-cli 与服务端共享核心功能,方便进行设置和检查:
garmin login [--strategy auto|browser|curl|fetch] [--email] [--token-path]
garmin import-tokens <file> # garmin_tokens.json from python-garminconnect 0.3.x
garmin status [--json]
garmin sync [--scope ...] [--from --to] [--force] [--pause <s>] # default: last 7 days
garmin activities [--from --to --type --limit --json]
garmin health <metric> [--from --to --week --json]
garmin load [--from --to] [--source auto|hrtss|garmin_load] [--flags <file.json>] [--series] [--activities] [--efficiency] [--by-sport] [--json]
garmin readiness [date] [--rules <file.json>] [--json] # GO / MODIFY / REST for the morning
garmin thresholds [--date --param --history --json] # LTHR, LT1, HRmax ... in effect, per sport
garmin thresholds add <date> <param> <value> [--source test|manual] [--note]
garmin thresholds export [--out <file.csv>] # date,param,value,source,note
garmin thresholds import <file.csv>
garmin import-activities <file.csv...> # Garmin Connect "Activities" CSV exports
garmin doctor # TLS strategy, hosts, permissions, tokens, SQLite driver
garmin serve [--transport stdio|streamable-http] [--port]
garmin logout
load、readiness 和 thresholds 输出与 get_load、get_readiness 和 get_thresholds 工具相同的结果:默认输出 Markdown 表格,使用 --json 时则输出工具的 { data, meta } 封装。它们仅读取本地数据库,不会下载数据;缺失日期会以注释形式返回,并附上用于补全数据的 garmin sync 命令。import-activities 会从 Garmin Connect CSV 导出文件(英文或波兰语表头)中,为同步活动未覆盖的日期添加活动;thresholds export/import 则会在 CSV 文件中保存或导入阈值历史记录。
使用 npx -y garmin-mcp-cli <command> 运行,或全局安装(npm i -g garmin-mcp-cli)。
登录
garmin login 会在已安装的 Chrome、Edge、Brave 或 Chromium 中打开 Garmin 的真实登录页面(使用临时配置文件,之后会删除)。你可以在其中登录,包括在 Garmin 要求时完成 MFA 或 CAPTCHA;该工具只会捕获 Garmin 随后重定向过来的一次性票据,并将其兑换为令牌。Cloudflare 会将其识别为真实浏览器。如果找不到浏览器,请设置 GARMIN_BROWSER_PATH。
如果没有浏览器(无头服务器、Docker),或使用 --strategy curl|fetch,它会在终端中要求输入电子邮件、密码和 MFA,并调用 Garmin 的移动端登录 API:先尝试 curl-impersonate(可选的 cuimp 软件包,首次使用时会下载其二进制文件),然后使用普通 fetch。如果这种方式也被阻止,请使用 Python 登录并导入令牌;garmin doctor 会打印准确的命令:
uvx --with "garminconnect>=0.3" python <path>/python-login.py ~/.garmin-mcp/garmin_tokens.json
garmin import-tokens ~/.garmin-mcp/garmin_tokens.json
令牌和数据库存放在权限为 0700 的目录中,文件权限为 0600;权限设置过于宽松时,服务端会拒绝启动。
远程服务和 Docker
Streamable HTTP:GARMIN_MCP_TRANSPORT=streamable-http GARMIN_MCP_HTTP_TOKEN=<secret> npx -y garmin-mcp-server 会通过 POST /mcp 提供服务,并使用 Authorization: Bearer <secret>。未设置令牌时,只会绑定到 127.0.0.1。若请求的 Host 或 Origin 不是 localhost、127.0.0.1 或 [::1],则会返回 403(DNS 重绑定防护);使用公共主机名时,请通过 GARMIN_HTTP_ALLOWED_HOSTS=mcp.example.com 将其添加。
服务端支持 MCP 2026-07-28(server/discover,列表结果缓存一小时)以及通过常规 initialize 握手进行的 2025 版修订,在 stdio 和 HTTP 上均可使用,因此旧版 MCP SDK 的客户端无需改动即可连接。
Docker:docker build -t garmin-mcp . && docker run -i -v garmin-data:/data garmin-mcp(使用 docker run -it -v garmin-data:/data garmin-mcp login 登录)。
配置
优先级:CLI 标志 > 环境变量 > <data dir>/config.json > 默认值。始终会展开 ~、$HOME 和 ${HOME}。
| 变量 | 默认值 | |
|---|---|---|
GARMIN_DATA_DIR | ~/.garmin-mcp | 令牌、数据库、config.json |
GARMIN_TOKENS_FILE | $GARMIN_DATA_DIR/tokens.json | |
GARMIN_EMAIL、GARMIN_PASSWORD | 仅首次登录时使用 | |
GARMIN_REGION | global | cn 会切换全部三个主机 |
GARMIN_SSO_STRATEGY | auto | auto(已安装浏览器时使用浏览器,否则使用终端)、browser、curl、fetch、import |
GARMIN_BROWSER_PATH | 自动检测 | 用于登录窗口的 Chrome/Edge/Brave/Chromium |
GARMIN_ENABLED_TOOLS、GARMIN_DISABLED_TOOLS | 以逗号分隔的允许/拒绝列表 | |
GARMIN_ENABLE_DESTRUCTIVE | false | 删除工具和覆盖训练计划 |
GARMIN_AUTO_FETCH | true | 读取工具会自行下载缺失数据;false:仅执行显式同步 |
GARMIN_FIT_DOWNLOAD_DIR | $GARMIN_DATA_DIR/downloads | |
GARMIN_MCP_TRANSPORT、GARMIN_MCP_PORT、GARMIN_MCP_HOST、GARMIN_MCP_HTTP_TOKEN | stdio、8000、127.0.0.1、 | |
GARMIN_HTTP_ALLOWED_HOSTS | 以逗号分隔的主机名(不含端口,IPv6 地址需加方括号);除 localhost、127.0.0.1、[::1] 外,只有列表中的主机名可用于 Host/Origin;其他请求将收到 403 | |
GARMIN_LOG_LEVEL | info | 在 stderr 上输出 pino JSON |
GARMIN_TIMEZONE | 系统时区 | 用于“今天”的 IANA 时区 |
GARMIN_CONCURRENCY | 4 | 并行 connectapi 请求数 |
GARMIN_MIN_REQUEST_INTERVAL_MS | 250 | 请求开始间隔(±25% 随机抖动) |
GARMIN_SYNC_CHUNK_DAYS / GARMIN_SYNC_PAUSE_S / GARMIN_SYNC_MAX_REQUESTS_PER_DAY | 7 / 1-11 / 600 | 同步节奏;暂停时间以秒为单位,可以是随机范围或固定值 |
GARMIN_DI_CLIENT_IDS、GARMIN_APP_VERSION、GARMIN_APP_USER_AGENT | 内置 | 用于 Garmin 更改移动应用标识时 |
更多信息
- DEVELOPMENT.md:monorepo 布局、测试、工具列表预算、评估、发布。
- docs/coverage.md:Garmin Connect 的所有读取和写入操作,以及对应的工具。
- CHANGELOG.md。
- 许可证:MIT。作者:Marcin Milewicz(LinkedIn)。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。