Skip to main content
Glama

佳明中国区训练数据 → 本地 SQLite → AI 直接分析

把佳明手表的数据变成 AI 能读的数据库,然后在 WorkBuddy / Claude 里用人话提问:「最近四周负荷是不是加太快了」「昨晚睡得怎么样」。

中国区账号(connect.garmin.cn)可以直接用,不需要换区、不需要跨区桥接工具。

手表 ──蓝牙──> 手机 Garmin Connect ──> connect.garmin.cn
                                          │  garminconnect + is_cn=True
                                          ▼
                              sync.py 增量同步(按需触发)
                                          ▼
                                  data/garmin.db (SQLite)
                                          ▼
                              mcp_server.py(本地 MCP 服务,9 个工具)
                                          ▼
                              WorkBuddy / Claude Desktop 对话

数据全程只在本机。密码只在首次登录用一次,之后走 token,不上传任何第三方。


一、这件事为什么值得做

佳明官方的数据出口有三个问题:

渠道

问题

Garmin Connect 网页

图表浅,只能看单次,做不了趋势对比和自定义统计

官方 Health / Training API

需要公司身份申请商业审批,个人基本拿不到

第三方平台(Strava / Runalyze / Intervals.icu)

中国区账号拿不到授权,绑上也读不到数据

而中国区账号的唯一官方客户端 connect.garmin.cn 又是封闭的。所以路子只剩一条:在本机模拟网页登录,把数据拉下来自己存。

好消息是 garminconnect 这个库支持中国区,只差一个参数。


Related MCP server: GarminSynapse

二、和其它方案比

方案

中国区可用

历史数据

能否被 AI 读

成本

官方全量导出 FIT

✅

全部

❌ 要自己解析

免费

GarminDB

✅

全部

部分

免费

托管 MCP(AthleteData / stats.training)

❌ 需国际区

30 天

✅

$9-10/月

本项目

✅

全部

✅

免费

本项目 ≈ garminconnect + SQLite + 一个 MCP 服务,一共约 1400 行 Python。


三、快速开始

1. 环境

python -m venv .venv
.venv/bin/pip install -r requirements.txt      # Windows: .venv\Scripts\pip.exe

2. 登录(唯一需要手动的一步)

# Windows
.venv\Scripts\python.exe sync.py --login
# macOS / Linux
.venv/bin/python sync.py --login

输入佳明中国区账号(邮箱或手机号)和密码,开了双重验证会要求输验证码。

成功后 token 存在 data/tokens/,之后再也不会问你要密码。

密码只在这一次登录里使用,不落盘。如果脚本在非交互环境跑(比如被 AI 调用),会直接读 GARMIN_EMAIL / GARMIN_PASSWORD 环境变量。

3. 拉历史

.venv\Scripts\python.exe sync.py --full

活动默认一路往回翻到最早一条;健康数据每天要 5 个请求,默认只拉 30 天(想补更早的用 --health-days 90)。

4. 接到 AI

MCP 服务配置写进 ~/.workbuddy/mcp.json(Claude Desktop 是 claude_desktop_config.json):

{
  "mcpServers": {
    "garmin-cn": {
      "command": "/绝对路径/到本项目/.venv/bin/python",
      "args": ["/绝对路径/到本项目/mcp_server.py"],
      "env": { "PYTHONUTF8": "1" }
    }
  }
}

Windows 下把 command 换成 D:/你的路径/.venv/Scripts/python.exe,路径用正斜杠可以省掉转义。

写完必须完全重启客户端(不是关窗口,是从托盘退出)。本地 MCP 不会出现在「连接器市场」里,它在设置页的 MCP Servers 区块,需要手动信任一次。


四、四个文件在干什么

store.py — 数据落地

四张表,全部保留原始 JSON,方便以后解析新字段而不用重新拉数据:

表

内容

activities

活动列表:距离、时长、配速、心率、爬升、训练效应、VO2max

splits

单次活动的分段明细(按需拉取,只拉看过的)

daily

每日健康:静息心率、HRV、睡眠分期、Body Battery、准备度、负荷

meta

键值对,主要存 last_sync

conn = sqlite3.connect(DB_PATH)
conn.execute("PRAGMA journal_mode=WAL")   # 关键:同步写入时读不阻塞

sync.py — 增量同步

三条原则:

  1. token 优先。有 token 就直接用,绝不再问密码

  2. 只补缺的。先查库里已有的日期,只拉缺口

  3. 慢一点。每次请求间隔 0.8 秒,遇 429 指数退避

client = Garmin(email, password, is_cn=True)   # ← 中国区唯一的开关
client.login(str(TOKENS))                      # 有 token 走这条

mcp_server.py — 把库暴露成工具

9 个工具,AI 按需调用:

工具

作用

db_info

库状态:多少条、数据到哪天、上次同步

sync_now

立刻增量同步

list_activities

最近 N 次训练清单,可按运动类型筛

activity_detail

单次训练分段明细(首次调用才去拉)

daily_health

静息心率 / HRV / 睡眠 / Body Battery / 负荷

training_summary

主入口:按周汇总 + 负荷比 + 配速心率漂移

sleep_report

多日睡眠:明细、睡眠债、作息规律性、红旗

morning_briefing

早起汇报:昨晚恢复 + 今日建议

query_sql

只读 SQL,自定义统计

设计上最有用的一个决定:查询类工具在开始前会自动检查 last_sync——

  • 距上次同步 < 6 小时 → 直接读本地,秒回

  • 超过 6 小时 → 先增量同步一次再回答

  • 同步失败 → 不报错,用旧数据回答 + 开头加一句提示

所以不需要任何定时任务。你什么时候问,它就什么时候保证数据是新的。

briefing.py — 口语化的恢复汇报

早上想看「昨晚睡得怎么样」,最没用的做法是把一堆字段推给你。这个文件把数字翻译成人话:

昨晚 7 小时 30 分,比你这周的平均(6.8 小时)好一点。够数了。
00:39 躺下、08:12 起,这个入睡时间算你近期偏早的。
夜间 HRV 152,比你 28 天的基线(132)高了一截,恢复是往上走的。
今天准备度 91,是最近少见的高位。昨天没怎么动,别浪费。

每个维度分 4-6 档(睡眠 5 档、准备度 4 档、HRV 6 档),所以连着看一周每天说的话不一样,不是填空模板。


五、踩过的坑(这部分最有价值)

1. 中国区只差一个参数

Garmin(email, password, is_cn=True)

设了 is_cn=True,登录域名就切到 connect.garmin.cn;否则一律打到国际站,中国区账号必然失败。

也可以用环境变量 GARMIN_IS_CN=1。

2. token 优先于密码,顺序反了就会卡住

第一版写成这样:

email = os.getenv("GARMIN_EMAIL") or input("账号: ")      # ← 先问密码
password = os.getenv("GARMIN_PASSWORD") or getpass()
has_token = tokens_exist()                                # ← 才看 token

结果明明已经登录过,脚本还是停下来等输入,在非交互环境直接挂死。

正确顺序:先看有没有 token,有就直接 login(token_dir),失败了才回退到账号密码。

3. MCP Python SDK 2.x 换了 API

网上绝大多数教程写的是:

from mcp.server.fastmcp import FastMCP     # 2.x 里已不存在
mcp = FastMCP("garmin-cn")

2.x 里改成了:

from mcp.server.mcpserver import MCPServer
mcp = MCPServer("garmin-cn")

装之前先 pip show mcp 看版本,否则会对着不存在的模块调试半天。

4. 日志绝对不能打 stdout

MCP 走 stdio 上的 JSON-RPC,任何一行 print() 都会污染协议,客户端表现为「服务连接失败」但看不到任何报错。

print(line, file=sys.stderr, flush=True)   # 所有日志都走 stderr

5. Windows 下中文乱码

MCP 服务的 env 里加 PYTHONUTF8=1(或 PYTHONIOENCODING=utf-8),否则返回的中文全是问号。

6. SQLite 并发锁

同步正在写的时候 AI 来读,会直接 database is locked。开 WAL 就好:

PRAGMA journal_mode=WAL;

实测写入事务未提交时读照样成功。

7. 限流是真的

佳明对频繁登录很敏感。登录成功一次就要把 token 落盘,所有后续同步复用 token。请求之间留 0.8 秒,遇 429 指数退避。

别把同步设成几分钟一次,这个接口扛不住。

8. 健康数据 = 一天 5 个请求

活动列表一次能翻很多条,但每日健康是拼出来的(睡眠、HRV、准备度、Body Battery、训练状态各一个请求)。补 90 天 ≈ 450 次请求,大概 5-8 分钟,中间容易撞限流。所以默认只拉 30 天,按需往前补。

9. 睡眠时间戳是 UTC,不是本地时间

sleepStartTimestampLocal 这个名字极具误导性——它给你的是 UTC 毫秒。直接 fromtimestamp() 会差 8 小时,算出来的「入睡时间」完全是错的。

t = dt.datetime.fromtimestamp(ms / 1000, dt.timezone.utc)   # 必须指定 UTC

10. 国行字段比想象中全

网上说法是国行缺训练准备度、HRV 状态这些。实测(Forerunner 265 + 中国区)17 个字段几乎全满,训练准备度、急性/慢性负荷、HRV 状态都在。VO2max 只在部分活动中产生,属于正常。

所以别预设「国行数据不全」,先拉一遍看实际填充率再决定分析口径。

11. MCP 配置写完要完全重启

不是关窗口。Windows 上点 × 只是缩到托盘,配置根本没重读。要从托盘图标右键退出,再打开。


六、数据安全

  • 密码只在首次登录时用一次,不写进任何文件

  • token 存在 data/tokens/,.gitignore 已排除

  • 数据库 data/garmin.db 含全部原始 JSON,同样已排除

  • 所有请求直连 connect.garmin.cn,不经过任何中转服务器

.gitignore 的核心几条:

data/
.env
.venv/
__pycache__/

注意:data/ 目录里同时有 token 和你的全部训练记录,分享 garmin.db 前记得先清空。


七、能问什么

信任 MCP 之后直接说人话,AI 会自己调工具取数:

看看我最近四周,负荷是不是加太快了
昨晚睡得怎么样
这周三的间歇跑,配速有没有掉
我 HRV 连着一周在降,是不是该减量
下个月有半马,基于我现在数据给个三周安排
我这一年哪几个月跑量掉得最厉害

比通用建议准的地方在于:它看的是你的真实数据,不是你描述的数据。


八、局限

  1. 库会失效。garminconnect 靠模拟网页登录,佳明一改版就可能断。社区通常几天内修好,pip install -U garminconnect 升级即可。数据在本地,不会丢。

  2. 强度分布是估算的。库里存的是活动平均心率,不是逐秒心率区间。要精确的 Z1-Z5 占比,得额外拉每次活动的 hr_in_timezones。

  3. 更早的历史需要官方导出兜底。部分接口只回补最近 30 天。


License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Downloads all your Garmin health and fitness data into a local SQLite database and exposes 45 MCP tools for AI analysis, enabling assistants to query sleep, training load, HRV, and more.
    48
    146 PyPI
    166
    AGPL 3.0
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to retrieve and analyze Garmin Connect health data, including daily summaries, sleep, HRV, workouts, and raw FIT files, while also supporting SQL queries on the underlying database.
    10
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables read-only access to Garmin Connect China account data, including activities, splits, sleep summaries, and available training metrics, so users can analyze running volume, laps, recent training, and race preparation through natural language.
    1
    -