关于 TrainBud
TrainBud 是开源 MCP 服务,可让用户通过 AI 客户端查询 Garmin Connect 训练数据。它结合本地历史记录与个人基线,提供运动、睡眠、恢复和趋势工具,并配有仪表板和手表小组件。
主要功能
- 01查询 Garmin Connect 健身数据
- 02本地 SQLite 历史记录与缓存
- 03依据个人 28 天基线生成发现
- 04仪表板、语音界面和手表小组件
- 05运动、睡眠与恢复查询工具
适用场景
- 01通过 AI 客户端询问近期运动和睡眠
- 02将当前指标与个人基线比较
- 03查看训练趋势和每周摘要
- 04在 Garmin 手表上查看恢复与睡眠信息
MCP 相关
通过 stdio MCP 向 Claude Desktop、Cursor 等客户端提供健身数据工具;`trainbud serve` 还可提供远程 HTTP MCP。工具涵盖活动、睡眠、心率、恢复、身体成分、趋势和个人背景信息。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y trainbudGARMIN_EMAILThe email address for your Connect account. Stored only in your local .env; `npx trainbud setup` writes it for you.GARMIN_PASSWORD密钥Your Connect password. Stored only in your local .env. Accounts with MFA enabled are not supported, because the unofficial library this drives cannot complete that flow.ANTHROPIC_API_KEY密钥Optional, and only for the watch app's Ask card and daily insight. The MCP tools themselves need no model key: every finding is computed in code, and the model only phrases it.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
TrainBud
与您的训练数据对话。
TrainBud 是一个开源 MCP 服务,可将您的 Garmin Connect 健身数据连接到 Claude、Cursor 和其他 AI 助手。用日常语言询问锻炼、睡眠、心率、恢复和身体成分数据——数据保留在您的设备上,私密安全。
**免责声明:**TrainBud 是非官方社区项目,与 Garmin Ltd. 无关联,也未获得其认可或赞助。Garmin Connect 是 Garmin Ltd. 的商标。
试用
连接到您的 MCP 客户端后,可以询问:
- “我今天做了什么?”
- “我这周的睡眠情况怎么样?”
- “我恢复得够好吗,明天可以进行高强度训练吗?”
- “我的静息心率呈下降趋势吗?”
更多想法请参阅 examples/prompts.md。
为什么选择 TrainBud
- 私密——凭据保存在本地
.env文件中;数据缓存在您的设备上 - 本地优先——使用 SQLite 缓存,会话令牌保存在
.trainbud/中 - 随处可用——支持 Windows、macOS、Linux(Node.js 22.12+)
- 兼容任意 MCP 客户端——Claude Desktop、Cursor 及其他兼容 stdio 的客户端
- 智能获取——批量调用 API,并在会话过期时自动重新验证
快速开始
npx trainbud setup
设置向导将引导您完成凭据配置、身份验证,以及连接 Cursor 或 Claude Desktop,无需编辑 MCP 配置。然后重启 MCP 客户端,并询问它 您今天做了什么。
如需让 trainbud 位于 PATH 中,而不必每次都输入 npx:
npm install -g trainbud
trainbud setup
需要 Node 22.12+。完整指南:QUICKSTART.md
从源码开始(适用于贡献者,或运行尚未发布的提交)
git clone https://github.com/Zsadigzade/trainbud.git
cd trainbud
npm install
npm run build
npm link # puts `trainbud` on your PATH; undo with `npm unlink -g trainbud`
trainbud setup
如果不使用 npm link,本 README 中的每个 trainbud <command> 都应替换为
在仓库根目录运行的 node dist/index.js <command>。如果 dist/ 尚不存在,
请先运行 npm run build。
Claude Code 插件(推荐)
作为 Claude Code 插件安装——一步即可安装技能和 MCP 服务:
/plugin marketplace add Zsadigzade/trainbud
/plugin install trainbud@trainbud
设置凭据,然后重启 Claude Code:
export GARMIN_EMAIL="[email protected]"
export GARMIN_PASSWORD="yourpassword"
| 命令 | 功能 |
|---|---|
/trainbud:trainbud-setup | 首次设置和诊断 |
/trainbud:trainbud | 询问锻炼、睡眠、恢复、HR、压力、VO2 max 相关问题 |
插件文件位于 plugin/。请参阅 plugin/README.md。
Claude Code 技能(仓库内)
本仓库还在 .claude/skills/ 中提供项目技能,供开发时使用,无需安装插件:
| 命令 | 功能 |
|---|---|
/trainbud-setup | 安装、验证身份、配置 MCP、运行实时检查 |
/trainbud | 询问锻炼、睡眠、恢复、HR、压力、VO2 max 相关问题 |
在 Claude Code 中打开仓库(在此目录中运行 claude)——技能会自动加载。
如需在每个项目中使用技能而不安装插件,请将它们复制到 ~/.claude/skills/。
设置完成后,重启 MCP 客户端,并尝试使用 “我今天做了什么?” 调用 /trainbud。
仪表盘
trainbud serve 会在 /dashboard 提供仪表盘。它优先适配手机,因为配对流程是:你站在手表旁边,手里拿着手机来批准代码。
它会显示今天相较于你自身基线的突出情况、本周相较于上周的情况,以及静息心率和睡眠相较于你自身 30 天中位数的曲线——所有数据都从本地历史记录中读取,因此页面会立即呈现,即使你的 Connect 会话已过期也能正常使用。曲线中断表示当天没有测量数据,而不是数值为零。
你也可以在这里告诉 TrainBud 它正在与谁对话:
| 设置 | 影响内容 |
|---|---|
| 姓名、单位、主要运动、每周目标 | 所有渲染结果,以及告知 AI 的关于你的信息 |
| 阈值 | 绿色变为琥珀色、琥珀色变为红色的界限——手表上也会应用 |
| 手表卡片 | 手腕上显示哪些卡片以及显示顺序,下次同步时即时生效 |
| AI 模型、语气、回答长度 | Ask 卡片和每日洞察的表达方式 |
| 你自己的 Ask 问题 | 最多五个,每个 32 个字符。它们会排在手表 Ask 菜单的前面;其余位置则根据触发的内容自动生成 |
| 每月支出上限 | 可选。超过上限时拒绝 Ask 请求,而不是继续超额支出 |
| 隐私 | 默认开启的本地功能计数器,并提供删除按钮 |
用量。 TrainBud 使用你自己的 AI 提供商密钥,因此每个问题和每日洞察的费用都由你承担。仪表盘会显示每次调用的 token 数和费用、本月至今的用量,以及 30 天图表。如果此版本中的某个模型没有公开价格记录,其费用会标记为未知,而不是零——若将调用费用记为零,支出上限就永远不会触发。
此页面上的任何内容都不会离开你的设备。没有可供发送数据的端点。
Garmin 手表小组件(Connect IQ)
通过 ciq/ 中的 Connect IQ 小组件,在 Garmin 手表上查看恢复、睡眠、活动、压力和 VO2 max。
需要: trainbud serve 正在运行 + HTTPS 隧道(与 Web AI 使用相同的设置)。
- 启动服务和隧道:
trainbud serve cloudflared tunnel --url http://127.0.0.1:3847 - 构建并侧载小组件——参见 ciq/README.md
- 在 Garmin Connect Mobile → Connect IQ → TrainBud 设置中,设置:
- 服务器 URL — 你的隧道 URL(例如
https://abc.trycloudflare.com)
- 服务器 URL — 你的隧道 URL(例如
- 在手表上打开小组件——它会显示配对代码。在仪表盘中批准该代码(
/dashboard?token=YOUR_API_KEY)以完成设置。仪表盘会将该 token 换成会话 Cookie,并将其从 URL 中移除,因此之后可以安全地截取地址栏。
概览会显示恢复和睡眠,或用几个字符展示最突出的发现(“RHR +4 bpm”),数据来自最近一次缓存的摘要,因此无需等待网络即可渲染;缓存超过两小时后,它会注明这一点。打开小组件并点按或滑动,即可轮播你在仪表盘中启用的卡片。手表会调用 GET /api/watch——这是精简的 JSON 摘要,而非完整的 MCP 协议。
在 Today 卡片上,按 START(或点按)可打开一条发现,查看触发它的规则——“过去 3 天每天都至少高于你 28 天中位数 48 bpm 的 3 bpm 和 2 个标准差”——然后可以将其静音三天(POST /api/mute)。Sleep 卡片会说明昨晚相较于你平常睡眠的变化(“深度睡眠 40m(1h24m)”)。在小组件只有 64 KB 的 Forerunner 55 上,这两项功能会被编译排除,以便其余内容仍能装下。
检测器规则
每条发现都会由一条你可以查看和调整的规则触发。仪表盘的 检测器规则 部分包含各项阈值——静息心率的天数、bpm 和标准差,睡眠债务小时数,HRV 降幅,训练负荷比,以及“多个信号同时出现”(静息心率升高、HRV 降低且睡眠压力同时升高)——并设有限制,确保不会出现每天都有发现或一天都没有发现的情况。每个界面都会显示触发某条发现的规则,以及当时生效的数值。
语音(/voice)
按住手机上的按钮,大声提出问题,然后听取朗读的回答。
访问一次 https://YOUR-HOST/voice?token=YOUR_API_KEY;它会用密钥换取 Cookie,
并重定向到干净的 URL。
- Android / Chrome — 语音识别在浏览器中进行。免费,无需密钥。
- iPhone / Safari — 录制音频,并通过 Groq 在服务器端转录
(
whisper-large-v3-turbo,每小时音频约需 $0.04)。在控制面板中添加密钥。 - 两者皆可 — 回答会以语音播报;Read me my day / Read today's insight 完全免费:它们根据已有数据通过代码生成,而非由模型生成。
这不是手表功能,也不可能成为手表功能:Connect IQ 不向小组件开放麦克风或扬声器。它也不是免提功能——移动浏览器会在标签页进入后台时暂停麦克风,因此手机必须保持唤醒,且页面显示在前台。
完整说明:docs/VOICE.md
持续运行(/voice 和手表,无需守在终端旁)
在终端中运行 trainbud serve 会一直持续到终端关闭。若要让服务和隧道在重启后自动恢复:
.\scripts\install-always-on.ps1 -Hostname trainbud.example.com
这会注册一个服务定时任务和一个监控程序,每五分钟检查两部分是否正常——因为隧道能响应不代表服务能响应:没有后端的隧道会在 HTTP 200 响应下显示自己的错误页面,因此链接看似正常,手表却报告 HTTP -400。指南中还提供了 systemd、launchd 和 Docker Compose 配置示例。
完整说明,包括 Cloudflare 命名隧道:docs/ALWAYS-ON.md
连接到 Claude Desktop
编辑 claude_desktop_config.json:
Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"trainbud": {
"command": "node",
"args": ["C:/path/to/trainbud/dist/index.js", "start"],
"env": {
"GARMIN_EMAIL": "[email protected]",
"GARMIN_PASSWORD": "yourpassword"
}
}
}
}
将 trainbud 添加到 PATH(npm install -g trainbud,或在克隆目录中运行 npm link),
然后让客户端调用命令,而不是指定路径:
{
"mcpServers": {
"trainbud": {
"command": "trainbud",
"args": ["start"]
}
}
}
重启 MCP 客户端,然后就可以开始提问了。
工具
| 工具 | 可回答的问题 |
|---|---|
get_latest_activity | 最近一次训练——距离、配速、HR、海拔 |
get_activities_range | 两个日期之间的活动 |
get_sleep_data | 睡眠时长、阶段、评分、醒来次数,以及昨晚哪些部分与平时不同 |
get_heart_rate_trends | 一段时间内的静息、最高和平均 HR |
get_recovery_status | 根据 HRV、睡眠、压力和静息 HR 计算的恢复评分 |
get_body_composition | 体重、体脂和肌肉量趋势 |
get_stress_levels | 每日压力平均值和趋势 |
get_vo2_max_trends | 随时间变化的 VO2 max 体能趋势 |
get_training_insights | 每周综合摘要(活动、睡眠、恢复、压力) |
get_findings | 与你自己的 28 天基线相比,哪些方面值得关注,以及触发每项发现的规则 |
get_week_review | 本周与上周的对比、训练负荷预测、睡眠债务和下一场比赛 |
compare_workouts | 将一次训练与自己之前同类型、同距离的训练进行比较 |
remember_context | 记录目标、比赛及日期、伤病或备注 |
get_user_context | 任意日期关于你的记录内容 |
log_subjective | 训练实际感受如何——RPE、酸痛、心情 |
CLI
trainbud setup # Interactive first-time setup (recommended)
trainbud serve # Remote HTTP MCP for web AI (claude.ai, ChatGPT)
trainbud check # Live diagnostics against all tools
trainbud doctor # What the watch would see: public URL, AI key, history depth
trainbud backfill # Pull Garmin history into the local store (resumable)
trainbud findings # What stands out against your own baselines, and the rule each fired on
trainbud rederive # Rebuild sleep measurements (deep, REM, awakenings) from the local archive — no Garmin requests
trainbud start # Start the MCP server (stdio)
trainbud auth # Force re-authentication
trainbud cache clear # Clear cached data
trainbud devices # List paired watches
trainbud devices revoke <id> # Take one watch's access away
trainbud rotate status # Which secrets are set, and whether their two homes agree
trainbud rotate api-key # Replace TRAINBUD_API_KEY, and say what that invalidates
trainbud rotate ai-key # Replace the AI key in BOTH .env and app.db
trainbud status # Show session and cache status
trainbud --version # Print version
rotate ai-key 会有意同时写入两个存储位置。AI 密钥既保存在 .env 中,也保存在
app.db 中;实际读取的是数据库中的副本,只手动编辑文件会导致轮换后的密钥无法生效。
以上每条命令都可以通过 npx trainbud <command> 运行,无需安装。
故障排除:trainbud: command not found
可以使用 npx trainbud <command>,也可以通过
npm install -g trainbud 全局安装。如果是在克隆目录中运行?请在仓库根目录运行一次 npm link,
或直接通过 node dist/index.js doctor 调用已构建的入口文件
(需先运行 npm run build)。
配置
| 变量 | 默认值 | 描述 |
|---|---|---|
GARMIN_EMAIL | — | Garmin Connect 邮箱 |
GARMIN_PASSWORD | — | Garmin Connect 密码 |
TRAINBUD_SESSION_PATH | .trainbud/session.json | 会话令牌存储路径 |
TRAINBUD_LOG_PATH | .trainbud/mcp.log | 日志文件路径 |
TRAINBUD_CACHE_PATH | .trainbud/cache.db | SQLite 缓存数据库 |
CACHE_TTL_ACTIVITIES | 1800 | 活动缓存 TTL(秒) |
CACHE_TTL_SLEEP | 7200 | 睡眠缓存 TTL(秒) |
CACHE_TTL_STATS | 3600 | 统计数据缓存 TTL(秒) |
TRAINBUD_API_KEY | 自动生成 | HTTP MCP(trainbud serve)的 Bearer 令牌 |
TRAINBUD_HOST | 127.0.0.1 | HTTP 服务的绑定主机 |
TRAINBUD_PORT | 3847 | HTTP 服务的绑定端口 |
安全与隐私
- 凭据仅保存在本地
.env文件中,不会发送给第三方 .trainbud/session.json中的会话令牌与密码同样敏感- 工具错误在传递给 AI 客户端前会经过净化处理
- 使用非官方的
garmin-connectnpm 包(而非 Garmin 的企业级 OAuth API) - 底层库不支持 MFA——请关闭 MFA 或使用应用专用密码
- 服务默认绑定到
127.0.0.1。只有在将隧道指向该地址时,才能从互联网访问;除/health外的所有路由都需要 API 密钥 - 仪表盘仅在
/dashboard?token=…接收一次密钥,随后将其换成HttpOnly会话 Cookie,并重定向到干净的 URL——因此密钥不会留在地址栏、历史记录或屏幕截图中 - 已配对的手表持有作用域限定于该手表的令牌,该令牌在配对时生成,并以 SHA-256 哈希形式存储在服务端。
trainbud devices会列出这些令牌,trainbud devices revoke <id>可撤销其中一个,而不会登出仪表盘、/mcp或其他手表。在 0.5.2 之前配对的手表持有的是 API 密钥本身;请重新配对,将其替换为作用域令牌 - 每个响应都包含
Content-Security-Policy、X-Content-Type-Options、X-Frame-Options和Referrer-Policy,包括 401 响应。只有实际通过 TLS 到达的请求才会收到 HSTS,因此环回仪表盘仍可访问
TrainBud 不是什么
- 不是托管服务。 没有 TrainBud 账户,也没有 TrainBud 服务端。你在自己的设备上运行它,并使用自己的 Garmin 凭据
- 不是 Garmin 官方集成。 它通过非官方库调用 Connect Web API。Garmin 可以随时更改该 API,且不会另行通知
- 不兼容 MFA。 如果你的 Connect 账户启用了 MFA,此工具将无法登录
- 并非免费使用。 AI 功能使用你自己的 Anthropic 密钥,费用由你承担。仪表盘会统计每次调用,并可在达到你设定的上限后拒绝请求
故障排查
| 问题 | 解决方法 |
|---|---|
| 身份验证失败 | 检查 .env 中的凭据,然后运行 trainbud auth |
| 账户已启用 MFA | 关闭 MFA 或使用应用专用密码 |
| 数据过时 | 运行 trainbud cache clear |
| 请求频率受限 | 等待 60 秒;有可用缓存时会使用缓存响应 |
| 手表显示“Not a TrainBud server”或错误 -400 | 你的公共 URL 返回的不是 TrainBud 的 JSON——通常是隧道已断开。运行 trainbud doctor;它会准确说明收到了什么响应 |
| 手表显示“Watch not authorised” | 手表配对后 API 密钥发生了变化。请从仪表盘重新配对 |
| 手表显示“AI not set up” | AI 功能需要你自备密钥。请在仪表盘中粘贴 Anthropic 密钥 |
| 没有睡眠/HR 数据 | 确保 Garmin 设备已同步到 Garmin Connect |
| 服务无法启动 | 检查 .env 中是否已设置 GARMIN_EMAIL 和 GARMIN_PASSWORD |
Docker
每次推送时都会在 CI 中构建并测试已发布的镜像,因此它不是一个悄然失效的承诺:
docker pull ghcr.io/zsadigzade/trainbud:latest
也可以从此仓库自行构建:
docker build -t trainbud .
最重要的一点:在 /app/.trainbud 挂载一个卷。
SQLite 历史记录、缓存的会话和日志都保存在那里。没有挂载卷,每次容器重启都会丢失已下载的历史记录,并从头重新进行身份验证。
作为桌面客户端的 MCP 服务
默认入口点通过 stdio 使用 MCP,因此客户端会运行该容器:
{
"mcpServers": {
"trainbud": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "GARMIN_EMAIL", "-e", "GARMIN_PASSWORD",
"-v", "trainbud-data:/app/.trainbud",
"trainbud"
]
}
}
}
必须使用 -i——否则容器没有 stdin,客户端会看到服务连接后立即静默。两个不带值的 -e 标志会从你自己的环境中传递变量,因此凭据不会出现在配置文件中。
作为 HTTP 服务,供 watch 应用或 Web 客户端使用
docker run --rm -p 3847:3847 \
-e GARMIN_EMAIL -e GARMIN_PASSWORD \
-e TRAINBUD_API_KEY \
-e TRAINBUD_HOST=0.0.0.0 \
-v trainbud-data:/app/.trainbud \
--entrypoint node trainbud dist/index.js serve
容器内需要设置 TRAINBUD_HOST=0.0.0.0:服务默认绑定到 127.0.0.1,这在笔记本电脑上是合适的默认设置,但无法从容器外部访问。
填充历史记录
trainbud setup 是交互式命令,需要终端,因此在 Docker 中请直接执行一次性回填:
docker run --rm -e GARMIN_EMAIL -e GARMIN_PASSWORD \
-v trainbud-data:/app/.trainbud \
--entrypoint node trainbud dist/index.js backfill
同样的方式也适用于 doctor、check 和 devices。
开发
npm install
npm run build
npm test # the whole suite, via the Node test runner
npm run lint
npm run dev # Start with auto-reload
使用 nvm/fnm 和 .nvmrc 配置 Node 22。npm run test:coverage 会通过 Node 自带的测试运行器报告覆盖率,npm run test:watch 会在发生更改时重新运行测试。
有关架构和设计说明(Obsidian 知识库,位于此仓库之外),请参阅 CONTRIBUTING.md 和 docs/VAULT.md。
路线图
- VO2 max 趋势
- 压力水平
- 训练洞察
- 训练对比
- Docker 镜像 — 已发布至
ghcr.io/zsadigzade/trainbud
许可证
MIT — 请参阅 LICENSE。
Garmin Connect 是 Garmin Ltd. 的商标。本项目与 Garmin Ltd. 无关。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。