DeepSeek Harness 插件

garmin-connect-plugin-for-dsh

A DeepSeek Harness plugin that exposes Garmin Connect fitness and health data as AI-callable tools(英文原文)

跳到安装方式

来源信息

GitHub 仓库
Likenttt/garmin-connect-plugin-for-dsh
最近更新
2026年8月21日
分类
工具与能力
GitHub stars
10
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/Likenttt/garmin-connect-plugin-for-dsh
插件名:garmin-connect-plugin-for-dsh
作者:Likenttt

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh-CN.md来源说明 · 只读预览
README 语言

dsh-plugin-garmin-connect

> DeepSeek Harness 的 Garmin Connect 插件 — 让 AI 代理直接读取你的运动和健康数据。

![npm version](https://www.npmjs.com/package/dsh-plugin-garmin-connect) ![npm downloads](https://www.npmjs.com/package/dsh-plugin-garmin-connect) ![CI](https://github.com/Likenttt/garmin-connect-plugin-for-dsh/actions/workflows/ci.yml) ![测试报告](TEST_REPORT.zh-CN.md) ![Node.js](https://nodejs.org) ![License: MIT](LICENSE)

English | 中文 | [测试报告](TEST_REPORT.zh-CN.md) | [更新日志](CHANGELOG.md)

> [!WARNING] > 0.1.5 状态: Garmin 两步验证尚未完成,不属于本次发布支持的能力。下文浏览器 > 认证命令仅供本地开发调试,请勿依赖它进行生产访问或 session 恢复。

---

我的更多应用

---

这个插件做什么?

安装本插件后,DeepSeek Harness 的 AI 代理可以通过自然语言自动调用 Garmin Connect 数据。你只需要说一句话,比如:

  • "我昨晚睡得怎么样?"
  • "帮我看一下最近 5 次跑步的配速变化。"
  • "我今天走了多少步?"

代理会自动选择合适的工具调用 Garmin API,并将结果格式化后反馈给你。

注册的工具

插件共注册 10 个工具。其中 8 个只返回 Garmin 数据; download_garmin_activity_fit 会在 MCP/dsh 所在主机写入一个本地文件, create_garmin_workout 会修改用户的 Garmin 训练库。

工具名用途参数示例
get_garmin_activities获取近期运动记录,可选择精简或完整详情{"limit": 5, "detail": "compact"}
get_garmin_sleep获取指定日期或日期范围的睡眠评分、时长与阶段分布{"startDate": "2023-10-01", "endDate": "2023-10-02"}
get_garmin_steps获取指定日期或日期范围的步数;仅当 Garmin 上游提供时才包含目标与步行距离{"startDate": "2023-10-01"}
get_garmin_heart_rate查询指定日期或日期范围的静息、最高与最低心率{"startDate": "2023-10-01", "endDate": "2023-10-02"}
get_garmin_weight查询指定日期或日期范围的身体成分(体重、BMI、体脂率、骨骼肌等){"startDate": "2023-10-01"}
get_garmin_workouts查询 Garmin 训练库中的可复用训练模板(不是日历排期){"limit": 10, "offset": 0}
get_garmin_profile获取经过字段白名单过滤的个人资料摘要{} 或省略
get_running_skill_advice讲解 8 种课型与 4 套训练理念,或先完成必问信息再提供个性化建议{"mode": "explain", "query": "丹尼尔斯", "language": "zh-CN"}
download_garmin_activity_fit下载活动的原始归档,并把其中唯一的 FIT 文件安全提取到所配置父目录下的账号目录{"activityId": 123456789}
create_garmin_workout预览结构化训练;仅在显式确认后创建{"name": "门槛巡航3×8分钟", "steps": [...]}

创建训练采用两次调用流程。首次调用只返回预览和一次性 confirmationId;用户确认未更改的预览后,再使用相同训练定义、 confirmed: true 及该 confirmationId 调用。确认 ID 10 分钟后失效,且不可复用。

个性化跑步训练问询

get_running_skill_advice 明确区分“知识讲解”和“个性化规划”:

  • mode: "explain" 只讲解课型或训练理念,不生成针对某位跑者的日程。
  • 任何针对个人的建议或计划都必须使用 mode: "personalized"。下列六组信息

必须全部回答;如果缺失,工具只返回需要追问的问题,不读取 Garmin 活动,也不得 先猜测训练量、强度或生成逐日/逐周计划。

问询字段助手必须询问的内容
goal目标距离/赛事、未来的 ISO YYYY-MM-DD 日期,以及完赛目标或理想/最低可接受成绩
currentPerformance + performanceBasis过去两年内代表性比赛/计时测试的距离、成绩、不晚于今天的日期、努力程度与条件,或明确填写 no_recent_benchmark
trainingBackground跑龄、最近 4–8 周跑量/时长、频率、最长跑、质量课和中断情况
availability每周可训练天数和时长、固定休息/长跑日、场地限制、力量训练时间,以及是否具备双练条件
healthConstraints + hasWarningSymptoms当前/过去一年伤病、疼痛、相关疾病/用药、睡眠和恢复,并明确回答是否存在健康警示症状
trainingPreference + 偏好细节steadyhard_easymixed,并填写 maxQualitySessionsPerWeek(0–7)与 intensityGuidancePreferencepaceheart_raterpemixed

如果 hasWarningSymptomstrue(例如当前胸部不适、轻微活动异常气短、 晕厥/眩晕或异常心悸),工具会直接返回安全停止结果,不返回课型素材,也不读取 Garmin 活动;它只建议先取得医疗专业人员许可,不自行诊断。如果 performanceBasisno_recent_benchmark,则只建议先建立轻松跑基础或完成 低风险基准测试,不能凭空给出精确门槛/间歇配速。

精简的训练理念层包括:

  • 汉森法:高频、较均匀的周跑量,强调配速纪律和累积疲劳;不能脱离整套

训练量单独照抄“16 英里长跑”。

  • 丹尼尔斯法:用近期真实成绩估计当前 VDOT,再组合 E/M/T/I/R 强度;

不能用目标成绩反推训练配速。

  • 挪威阈值法:可借鉴受控、非力竭的阈值训练和难易日分离;默认不安排

双阈值,也不照搬精英跑量或固定乳酸值。

  • 极化训练:大部分训练真正轻松,少量训练明确艰苦;80/20 是方向,

不是必须精确凑出的比例。

近期 Garmin 跑步数据只能补充上述问询,不能代替用户回答。方法来源、证据边界和 适用限制见训练方法研究说明。 每条训练理念和课型卡还会把相应内容标成 system_principle(体系理念)、 research_evidence(研究证据)或 application_inference(应用推断),避免把 方法定义误写成优越性证据。

---

快速开始

1. 安装本插件 — 从 npm registry(推荐)

npx --legacy-peer-deps=false @deepseek-ai/dsh plugin --profile web add dsh-plugin-garmin-connect

这一条命令会同时安装依赖并激活插件层,首次运行会自动初始化 web profile。你只需要 pnpm 在你的 PATH 中:

npm install -g pnpm

> --legacy-peer-deps=false 让 npm 正常解析 peer 依赖。如果你的 npm 配置了 legacy-peer-deps=true(会跳过 peer 包),dsh 会因缺少 @deepseek-ai/cordis-plugin-group 而报 ERR_MODULE_NOT_FOUND;没有该配置的机器上,这个参数是无害的默认行为。

不启动即可验证插件层是否已组合进配置:

npx --legacy-peer-deps=false @deepseek-ai/dsh --profile web --dump-config | grep -A 2 garmin-connect

其他安装方式:

# 本地源码调试
cd garmin-connect-plugin-for-dsh && npm install
npx --legacy-peer-deps=false @deepseek-ai/dsh plugin --profile web add .

# GitHub 源码安装
npx --legacy-peer-deps=false @deepseek-ai/dsh plugin --profile web add github:<owner>/<repo>

2. 安装 Harness CLI(如果还没有)

npx --legacy-peer-deps=false @deepseek-ai/dsh web

默认在 http://127.0.0.1:3080 打开 Web 界面。如果通过 npx 启动,下面的命令同样加上 npx --legacy-peer-deps=false @deepseek-ai/dsh 前缀;如果已全局安装 dsh,则可以去掉 npx @deepseek-ai/ 前缀。

3. 配置凭据

插件自身不会持久化凭据。请使用环境变量(或启动器提供的密钥存储),并确保 .env 不进入版本控制。

# 仅源码目录:复制随仓库提供的模板
cp .env.example .env

# 编辑 .env,填入你的 Garmin 账号信息

如果使用 registry 安装,请直接在运行 dsh 的目录(工作区根目录)新建 .env, 再按下表填写变量;包内模板不会出现在当前工作目录。插件启动时会自动加载该文件。

| 环境变量 | 必填 | 说明 | |---|---|---| | GARMIN_USERNAME | ✅ | Garmin 账号邮箱 | | GARMIN_PASSWORD | ✅* | 旧版直接登录密码;不要用于下方的 MFA 交互式初始化 | | GARMIN_SESSION_TOKEN | ✅* | 内联预认证令牌(仍支持,但 session 文件更安全) | | GARMIN_SESSION_TOKEN_FILE | ✅* | 本地认证命令生成的 owner-only DI v2(或兼容的旧 OAuth)session 文件路径 | | GARMIN_REGION | ❌ | global(默认,国际版)或 cn(佳明中国) | | GARMIN_FIT_DOWNLOAD_DIR | 仅 FIT | 用户为 FIT 导出显式选择的主机父目录;无默认值,生成的账号目录会包含 GARMIN_REGION | | GARMIN_CACHE_TTL | ❌ | 缓存有效期,单位秒(默认 300) | | GARMIN_REQUEST_TIMEOUT_MS | ❌ | Garmin 请求超时,单位毫秒(默认 15000) | | GARMIN_LOG_LEVEL | ❌ | 日志级别:debug \| info \| warn \| error | | GARMIN_ACTIVITY_DETAIL | ❌ | compact(默认)或 full(扩展运动数据,可能包含精确路线/位置;凭据及账号/社交标识会被过滤) |

> \* GARMIN_PASSWORDGARMIN_SESSION_TOKENGARMIN_SESSION_TOKEN_FILE > 三选一即可。受保护的 session 文件比内联 token 更安全,尤其适合隔离多个进程; > 这不代表未完成的 MFA 初始化已经得到支持。如果同时配置,内联 token > 优先于文件;有效 session 优先于密码登录。 > > ⚠️ 如果密码包含 # 等特殊符号,请用双引号包裹,否则 # 后的内容会被当作注释截断: > `` > GARMIN_PASSWORD="my#secret!pass" > ` > > GARMIN_SESSION_TOKENGARMIN_SESSION_TOKEN_FILE` 的内容都和密码一样敏感。 > Token 导出不会作为 AI 可调用工具提供,也绝不要把 Token 粘贴进 AI 对话。

#### 两步验证——未完成的开发预览

下方浏览器初始化流程仅保留用于开发和诊断,不是 0.1.5 支持的认证路径。若要参与 测试,请在可信的本地终端中亲自运行,并显式选择账号所属区域:

# Garmin 国际区
npm run auth:setup -- --browser --account personal --region global

# 佳明中国区
npm run auth:setup -- --browser --account personal --region cn

auth:setup 只是源码仓库中的 npm script 别名。安装包对外稳定的系统命令名是 garmin-connect-auth,因此 Codex、Claude Code(CC)及其他本地客户端都可以引导用户 使用同一个认证入口:

garmin-connect-auth --help
garmin-connect-auth login --browser --account personal --region global
garmin-connect-auth login --browser --account personal --region cn

直接运行裸命令的前提是 npm 可执行文件已进入 PATH,通常需要全局安装; dsh 的嵌套依赖或普通本地依赖不会自动暴露这个系统命令。可以全局安装已发布版本, 也可以直接通过 npx 运行:

npm install -g dsh-plugin-garmin-connect@0.1.5
npx -y --package dsh-plugin-garmin-connect@0.1.5 \
  garmin-connect-auth login --browser --account personal --region global

源码 checkout 仍可使用 npm install -g .npm run auth:setup -- --browser ...。无论使用哪种入口,命令都会打开隔离、可见的系统 Google Chrome。邮箱、密码、MFA 验证码和 CAPTCHA 只能在 Garmin 页面中输入;CLI 不会读取这些表单值,也不接受通过命令行参数、环境变量、MCP 工具参数或模型输入传入。

浏览器关闭后,CLI 会交换短期 service ticket,并探测与区域绑定的 Garmin DI profile 接口。随后本地终端会并列显示经过安全化处理的 Garmin profile label、请求的账号别名和 配置的 username。只有确认它们属于目标账号时才键入完全一致的 yes;其他任何输入都 会取消写入。确认成功后才会写入 owner-only 的 DI v2 session 并输出路径。Codex、 Claude Code、模型及其他代理不得读取或复制 session 内容或凭据。

为兼容旧用法,省略 --browser 的终端认证流程仍然保留;它在本地终端中隐藏密码/MFA 输入,但不能可靠处理 CAPTCHA 等仅浏览器挑战,也不是受支持的两步验证方案。

如需诊断同一套浏览器/DI 链路,但不希望生成凭据,当前源码还保留一个明确“不落盘” 的实验命令:

# 必须显式选择账号所属区域。
npm run auth:canary -- --region global
npm run auth:canary -- --region cn

该 canary 会打开隔离、可见的系统 Google Chrome 窗口。邮箱、密码、MFA 或 CAPTCHA 只在 Garmin 页面中输入,CLI 不读取这些表单值。程序只捕获一张短期 service ticket, 随后立即关闭临时浏览器,再执行一次严格绑定区域的 DI token 交换并验证 profile API; 不会保存 Cookie、Token、截图、trace、视频、HAR 或 session 文件。因此 canary 通过 也只提供局部诊断证据;0.1.5 尚未提供受支持的浏览器 MFA session 创建流程。

Canary 需要系统 Google Chrome,以及普通依赖安装时提供的可选 playwright-core 驱动。 如果安装依赖时使用了 --omit=optional,canary 将不可用,但普通登录、dsh 和 MCP 运行不受影响。

未完成的初始化命令被设计为只在浏览器登录和显式 profile 确认成功后保存 DI v2 session 并输出文件路径;POSIX 上 session 文件权限为仅文件所有者可读写的 0600;Windows 上使用当前用户配置 目录,但尚未显式校验 Windows ACL。它不会保存密码或 MFA 验证码。运行时使用该路径 并删除 GARMIN_PASSWORD

GARMIN_USERNAME=your-email@example.com
GARMIN_REGION=cn
GARMIN_SESSION_TOKEN_FILE=/absolute/path/to/personal.session.json
GARMIN_FIT_DOWNLOAD_DIR=/absolute/path/to/garmin-fit-parent

DI v2 文件会通过不可逆摘要绑定规范化 username、region,以及刚探测到的 Garmin profile(包括 profileIdHash);绑定信息不会重复保存明文邮箱。运行时会在发布刷新后的 凭据前拒绝 username、region 或 profile 不匹配的文件。access token 会在到期前提前刷新, 轮换后的 refresh token 会先安全写回再投入使用;认证失败时只允许幂等 GET 最多重放一次, 训练创建等写请求绝不会自动重放。

为保持向后兼容,只有 oauth1oauth2 两个字段的旧 session 文件仍可读取。旧文件 没有可校验的 profile 绑定;预期替代方案是带错账号保护且经过验证的 DI v2 session, 但目前不能把未完成的浏览器命令当作受支持的生成方式。在 POSIX 系统中,旧文件本身 仍须通过当前 owner-only 文件权限检查(通常为 0600)。

POSIX 上默认账号目录会以 owner-only 权限创建。如需自定义 session 文件,可添加 --output /absolute/private/path/personal.session.json。在 POSIX 系统中,已经存在的父目录 不能授予 group/other 任何权限(通常为 0700);不存在的父目录会以 owner-only 权限 创建。遇到不安全父目录时命令会拒绝写入,不会擅自放宽或修改其权限。

MFA 初始化依赖 Garmin 私有 SSO/DI 流程,目前尚未完成。2026-08-21 的真实中国区 登录已产生短期 service ticket,DI exchange 与 profile probe 也分别得到验证;但当前 浏览器拦截可能让 Garmin 跳转页停在 ERR_BLOCKED_BY_CLIENT,完整的“捕获 → 交换 → 确认后写入 session → 重启 dsh/MCP → 刷新”链路尚未重新完成端到端验证,国际区浏览器 链路也未验证。因此这些命令仍只是开发预览,不属于 0.1.5 的受支持功能。

#### 多账号:每个账号使用独立进程

当前支持的运行时模型是“每账号每进程隔离”:每个 dsh、Codex、Claude Code 或其他 MCP 进程分别设置自己的 GARMIN_USERNAMEGARMIN_REGIONGARMIN_SESSION_TOKEN_FILE,并使用独立初始化的 session。对于 MFA 账号,目前不能 依赖尚未完成的浏览器流程来生成这些 session。

不要把一个 session 文件复制给其他进程,也不要让并发进程共享同一文件。Garmin 的 refresh token 可能轮换,否则并发写入可能互相覆盖或使凭据失效。例如分别使用 personal-dshpersonal-codexpersonal-claude 别名,并为每个进程使用独立初始化 的 session。不要通过符号链接或大小写不同的路径别名,让另一个运行时指向同一个物理 文件。

多个进程可以共享同一个 GARMIN_FIT_DOWNLOAD_DIR 父目录,插件会按各自配置的区域和邮箱 自动建立独立账号子目录,因此同一邮箱的 cnglobal 账号也不会冲突。例如把两个服务器命名为 garmin-personalgarmin-family,调用时明确选择目标服务器。

这是进程隔离,不是单进程账号选择器,也不是多租户授权系统。不要把同一个 MCP 进程共享给互不信任的用户;当前尚未实现按用户访问控制。在同一对话中切换账号和 自动跨账号同步仍属于路线图能力。

#### 下载 FIT

download_garmin_activity_fit 只接受 activity ID,模型不能指定任意输出路径。工具先把 Garmin 原始活动 ZIP 下载到私有临时位置,执行大小限制,并要求归档中恰好存在一个有效 FIT 文件。假设用户配置的父目录是 <base>,最终路径为

<base>/GARMIN_FIT_<cn|global>_<规范化邮箱>/<activityId>.fit,且不会覆盖已有文件。

cnglobal 来自 GARMIN_REGION<规范化邮箱> 会经过安全规范化:普通邮箱保持可读, 路径分隔符、控制字符等不安全文件名字符会先被处理,再创建账号目录。用户根据自己配置的父目录和此规则定位文件。工具只 返回 activityIdfileNamesizeBytessha256,不会返回父目录、账号子目录、 邮箱或完整路径;ZIP/FIT 二进制内容也不会进入模型上下文。

父目录没有默认值,必须由用户通过 GARMIN_FIT_DOWNLOAD_DIR 显式选择。它只在调用此 工具时必需;未设置时工具会在写入任何文件前失败,其他 Garmin 工具仍可正常使用。 多个账号进程可以安全共享同一个父目录,因为“区域+规范化邮箱”子目录会自动隔离, 即使中国区与国际区使用同一邮箱也不会冲突。 已有的 GARMIN_FIT_<邮箱> 目录不会自动迁移;新下载使用带区域前缀的目录,旧文件保留在原位。

Garmin 的“原始文件”并不保证一定是 FIT。如果归档中没有唯一有效的 FIT 条目,工具会 安全失败,不会把其他格式伪装成 .fit

4. 启动

npx --legacy-peer-deps=false @deepseek-ai/dsh web

打开 http://127.0.0.1:3080。当 设置 → 插件 → 插件列表 中显示 plugin-garmin-connect已挂载、已启用 时,说明插件已成功加载。然后直接对话:*"我昨晚睡得怎么样?"* 或 "帮我看一下最近 5 次跑步。"

5. 集成测试(可选,仅限源码目录)

集成测试脚本仅用于开发,不包含在 npm 包中。在已安装开发依赖的源码目录里配置好 .env 后,可以运行它验证 API 连通性:

npm run test:integration

脚本只检查读取接口;任一检查失败都会以非零状态退出。它不会创建、更新或删除 训练及其他 Garmin 数据。

默认会隐藏账号标识,并只输出数量/状态,不显示活动或健康数值。只有在明确希望把 规范化详情输出到本地终端时,才设置 GARMIN_INTEGRATION_VERBOSE=true

<details> <summary>📋 点击展开完整示例输出</summary>

🔌 Garmin Connect Integration Test
   Domain : garmin.com
   User   : configured (identifier hidden)
   Date   : 2026-08-18
   Scope  : read-only (workout creation/update/deletion is not tested)

── 1. Authentication ──
  ✅ Password login successful

── 2. Activities ──
  ✅ Got 3 activities

── 3. Sleep ──
  ✅ Sleep data loaded

── 4. Steps ──
  ✅ Step data loaded

── 5. Heart Rate ──
  ✅ Heart-rate data loaded

── 6. Weight / Body Composition ──
  ✅ Body-composition data loaded

── 7. Workout Library ──
  ✅ Got 5 workout templates

── 8. User Profile ──
  ✅ Profile loaded

🏁 Integration test complete: 8 passed, 0 failed.
   Write operations were intentionally not tested.

</details>

---

🔐 安全设计

> 凭据只在本地用于直接登录 Garmin Connect,且绝不会由 AI 工具返回。

凭据解析优先级

1. 插件配置值(profile patch / --patch 中为该插件行指定的 config)
   ↓ 回退
2. 环境变量(.env 文件 / Shell 环境)
   ↓ 回退
3. Schema 中定义的默认值

安全措施一览

措施状态
支持环境变量及标记为 secret 的配置
.env 已加入 .gitignore,不会被提交到 Git
账号标识与凭据字段均标记为 role('secret')
浏览器 MFA 初始化⚠️ 未完成的开发预览;0.1.5 不提供正式支持
DI v2 session 绑定 username、region 与 profileIdHash;旧两字段 session 保持兼容
每进程独立初始化的 session 文件支持进程隔离多账号
access token 提前刷新;幂等 GET 最多重放一次,写请求不重放
工具返回值中不包含任何原始凭据
FIT 二进制及本地/账号路径留在主机,模型只收到活动 ID、文件名、大小与 hash
内存缓存减少 API 调用次数,防止触发 Garmin 限流

Session Token

仍然支持 Session Token 登录,但 Token 本身就是凭据,不能出现在代理输出或轨迹日志中。 因此,本插件不会把认证、MFA 提交或 Token 导出暴露为 AI 可调用工具。如果已经拥有 经过验证的 owner-only DI v2 或兼容旧 session 文件,dsh/MCP 可以通过 GARMIN_SESSION_TOKEN_FILE 读取它,运行时不再需要账号密码。DI 文件会绑定规范化 username、region 和 profileIdHash;为兼容旧版本,无绑定的 oauth1/oauth2 两字段 文件仍可读取。使用上方浏览器命令创建新的 MFA session 仍未完成。Garmin refresh token 可能轮换,因此 dsh、Codex、Claude Code 或其他进程之间不得并发共享或复制同一文件。

---

在其他 AI 编程助手中使用(MCP 协议)

本插件同时提供了一个独立的 MCP (Model Context Protocol) 服务器,让你可以在 OpenAI Codex、Claude Code、Claude Desktop、Cursor、Windsurf、WorkBuddy、ZCode 等任何支持 MCP 的客户端中使用相同的 Garmin 工具 — 无需安装 DeepSeek Harness

> 当前可用性: npm 0.1.5 及之后版本已包含独立 MCP 入口;本地源码方式仍适合开发。

先构建本地服务器:

git clone https://github.com/Likenttt/garmin-connect-plugin-for-dsh.git
cd garmin-connect-plugin-for-dsh
npm install
npm run build

请把示例中的 /absolute/path/to/garmin-connect-plugin-for-dsh 替换为本地源码目录的 真实绝对路径。

下面只说明如何把已经验证过的 session 文件接入 MCP 客户端,并不表示未完成的浏览器 MFA 初始化已经成为 0.1.5 的受支持流程。让客户端进程获得非密码的账号/区域信息、 session 文件路径与 FIT 父目录,并把下面的占位路径替换为本机绝对路径:

export GARMIN_USERNAME='你的佳明邮箱'
export GARMIN_REGION='cn'
export GARMIN_SESSION_TOKEN_FILE='/absolute/path/to/personal.session.json'
export GARMIN_FIT_DOWNLOAD_DIR='/absolute/path/to/garmin-fit-parent'

不要在这些环境变量中放密码或 MFA 验证码。MCP 服务器不会提示 MFA,只能读取已有的有效 session。session 文件和 FIT 父目录都需要保护,因为活动文件可能包含精确位置与 健康数据。每个同时运行的客户端进程都需要单独初始化的 session 文件;Codex、 Claude Code、dsh 或其他客户端之间不得复制或并发共享同一文件。

OpenAI Codex(桌面端、CLI 与 IDE 扩展)

同一主机上的 Codex 客户端共用 ~/.codex/config.toml。推荐只在配置中声明需要转发的 环境变量名,不把凭据值复制到 TOML。确保 Codex 进程能够读取上面的变量后,把以下 内容加入 ~/.codex/config.toml

[mcp_servers.garmin-connect]
command = "node"
args = ["/absolute/path/to/garmin-connect-plugin-for-dsh/lib/mcp.js"]
env_vars = ["GARMIN_USERNAME", "GARMIN_REGION", "GARMIN_SESSION_TOKEN_FILE", "GARMIN_FIT_DOWNLOAD_DIR"]

# 只读工具可正常运行;写本地文件或 Garmin 数据前由 Codex 请求批准。
default_tools_approval_mode = "writes"

此配置只读取单独分配给该 Codex 进程的 DI v2 session;Codex 不会接收或询问密码/MFA 验证码。不要复用已经分配给 dsh、Claude Code 或其他运行中进程的 session。第二个账号 请新增 [mcp_servers.garmin-family] 等服务器表,并提供另一个独立初始化的 session 文件。它可以复用同一个 FIT 父目录,输出会自动 进入该账号的“区域+规范化邮箱”子目录。

Codex 进程必须继承上面导出的变量。如果桌面端不是从该终端启动,请在 Settings → MCP servers 中添加服务器并提供环境变量,或通过你日常使用的密钥注入 环境启动它。设置界面中填写的值属于本地凭据,请保护生成的配置文件。

如果只希望当前可信项目使用,可把同一配置写入项目内的 .codex/config.toml。 修改后重启 Codex 客户端,并检查已保存的配置:

codex mcp list
codex mcp get garmin-connect

在 Codex CLI 内输入 /mcp,确认服务器已经连接并查看工具。设置界面及 codex mcp add 的更多用法见 Codex 官方 MCP 文档

Claude Code

Garmin 通常属于个人服务,因此推荐使用 user scope。下面的 bash/zsh 示例不会把 session 内容写入 ~/.claude.json,只配置 owner-only 文件路径:

claude mcp add-json --scope user garmin-connect \
  '{"type":"stdio","command":"node","args":["/absolute/path/to/garmin-connect-plugin-for-dsh/lib/mcp.js"],"env":{"GARMIN_USERNAME":"${GARMIN_USERNAME}","GARMIN_REGION":"${GARMIN_REGION:-global}","GARMIN_SESSION_TOKEN_FILE":"${GARMIN_SESSION_TOKEN_FILE}","GARMIN_FIT_DOWNLOAD_DIR":"${GARMIN_FIT_DOWNLOAD_DIR}"}}'

该服务器只读取单独分配给此 Claude Code 进程的 DI v2 session;Claude Code 不会接收 或询问密码/MFA 验证码。每增加一个进程或账号,都以不同名称注册服务器并提供另一个 独立初始化的 session 文件;不要复制其他进程的 session。 这些服务器可以复用同一个 FIT 父目录。

如果只希望当前项目使用,把 --scope user 改为 --scope local。以后每次启动 Claude Code 时都要保证这些路径变量可用,然后检查连接:

claude mcp get garmin-connect
claude mcp list

在 Claude Code 内输入 /mcp 可以查看连接状态和工具。作用域与 .mcp.json 的更多 说明见 Claude Code 官方 MCP 文档。 不要把个人 Garmin 凭据提交到项目级配置。

在 Codex 或 Claude Code 中实际使用

garmin-connect 显示已连接后,直接用自然语言提问即可,客户端会自动选择 MCP 工具。如果工具选择不明确,可以明确说“使用 garmin-connect MCP 服务器”。例如:

  • “使用 garmin-connect 查看我最近五次跑步。”
  • “对比我最近七天的睡眠和静息心率。”
  • “把 activity 123456789 的 FIT 下载到我配置的 Garmin FIT 父目录下。”
  • “预览一个门槛跑训练,把步骤展示给我;在我确认前不要创建。”

创建训练仍然执行强制的两次调用确认流程:第一次只返回预览;只有用户批准并带上返回的 一次性 confirmationId 后,第二次调用才会创建。

Claude Desktop

编辑 ~/Library/Application Support/Claude/claude_desktop_config.json(macOS)或 %APPDATA%\Claude\claude_desktop_config.json(Windows):

{
  "mcpServers": {
    "garmin-connect": {
      "command": "node",
      "args": ["/absolute/path/to/garmin-connect-plugin-for-dsh/lib/mcp.js"],
      "env": {
        "GARMIN_USERNAME": "你的佳明邮箱",
        "GARMIN_REGION": "cn",
        "GARMIN_SESSION_TOKEN_FILE": "/absolute/path/to/personal.session.json",
        "GARMIN_FIT_DOWNLOAD_DIR": "/absolute/path/to/garmin-fit-parent"
      }
    }
  }
}

重启 Claude Desktop 后,你会看到 🔌 图标表示工具已加载。试试说:*"帮我看下最近 5 次跑步记录"* 或 *"帮我预览一个门槛跑训练"*。

Cursor

把上方相同的 mcpServers.garmin-connect 对象写入工作区 .cursor/mcp.json,并使用 lib/mcp.js 的绝对路径。

Windsurf

打开 Windsurf Settings → Cascade → MCP Servers,或编辑 ~/.codeium/windsurf/mcp_config.json,加入上方相同的 mcpServers.garmin-connect 对象。

WorkBuddy

WorkBuddy 桌面端支持用户级和项目级的本地 MCP。Garmin 属于个人健康数据,推荐使用 用户级 ~/.workbuddy/mcp.json。打开 插件 → MCP 服务器 → 配置 MCP,或直接编辑 该文件,加入:

{
  "mcpServers": {
    "garmin-connect": {
      "command": "/absolute/path/to/node",
      "args": ["/absolute/path/to/garmin-connect-plugin-for-dsh/lib/mcp.js"],
      "env": {
        "GARMIN_USERNAME": "你的佳明邮箱",
        "GARMIN_REGION": "cn",
        "GARMIN_SESSION_TOKEN_FILE": "/absolute/path/to/personal.session.json",
        "GARMIN_FIT_DOWNLOAD_DIR": "/absolute/path/to/garmin-fit-parent"
      }
    }
  }
}

macOS/Linux 用 command -v node、Windows 用 where node 查找 Node.js 的绝对 路径;GUI 应用不一定继承 nvm 的 shell 路径。Windows JSON 路径请使用 C:/.../node.exe