使用说明
Garmin MCP服务器
此模型上下文协议(MCP)服务器连接到Garmin Connect,并通过流式HTTP传输将您的健身和健康数据暴露给OpenWebUI、Claude或任何其他兼容MCP的客户端。
信用:https://github.com/Taxuspt/garmin_mcp
特性
-
78+MCP工具 涵盖:
- 活动管理(列表、获取详细信息、分段、天气、装备)
- 健康与保健指标(步数、心率、睡眠、压力、身体电池)
- 训练和表现数据(最大摄氧量、心率变异性、训练效果、健身年龄)
- 设备管理
- 齿轮跟踪
- 体重管理
- 挑战与徽章
- 锻炼
- 妇女健康数据
- 数据管理(添加身体成分、血压、水合作用)
- 个性化训练和饮食建议
-
可流式HTTP传输 -用于Kubernetes/容器部署的网络可访问MCP服务器
-
令牌持久性 -缓存OAuth令牌以避免重复的MFA提示
-
非交互式MFA -支持基于环境的MFA代码的容器化部署
先决条件
- Python 3.10+(推荐3.12)
- Garmin Connect帐户凭据
- 对于Kubernetes:kubectl访问集群
部署选项
1.独立(地方发展)
安装
# Clone the repository
git clone <repository-url>
cd garmin_mcp
# Install dependencies
uv sync
跑步
使用stdio传输(适用于Claude Desktop等MCP客户端):
export GARMIN_EMAIL="your-email@example.com"
export GARMIN_PASSWORD="your-password"
export GARMIN_MCP_TRANSPORT="stdio"
uv run garmin-mcp
使用流式HTTP传输(用于网络访问):
export GARMIN_EMAIL="your-email@example.com"
export GARMIN_PASSWORD="your-password"
export GARMIN_MCP_TRANSPORT="streamable-http"
export GARMIN_MCP_HOST="0.0.0.0"
export GARMIN_MCP_PORT="8000"
uv run garmin-mcp
服务器将可在以下位置访问 http://localhost:8000/mcp
首次设置(MFA-仅在Garmin Connect上启用时)
如果您在Garmin Connect帐户上启用了MFA,则需要在首次运行时提供2FA代码。您有两个选择:
选项A:互动式(促进当地发展)
- 服务器将在终端中提示输入MFA代码
选项B:非交互式(用于自动化)
export GARMIN_MFA_CODE="123456" # Code from email/SMS
export GARMIN_MFA_WAIT_SECONDS="180" # Optional: wait up to 180s for code to appear
注: 如果您的Garmin Connect帐户未启用MFA,您可以跳过这些环境变量。
成功登录后,OAuth令牌将保存到 ~/.garminconnect 在代币到期之前,未来的运行将不需要MFA。
使用Claude Desktop进行配置
编辑您的Claude Desktop配置:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - 视窗:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"garmin": {
"command": "uv",
"args": ["run", "garmin-mcp"],
"env": {
"GARMIN_EMAIL": "your-email@example.com",
"GARMIN_PASSWORD": "your-password",
"GARMIN_MCP_TRANSPORT": "stdio"
}
}
}
}
注: 如果您在Garmin Connect帐户上启用了MFA,请添加 "GARMIN_MFA_CODE": "123456" 到 env 第一轮比赛的部分。
更改后重新启动Claude Desktop。
2.Docker部署
塑造形象
docker build -t garmin-mcp:latest .
运行容器
基本运行(stdio传输):
docker run --rm -it \
-e GARMIN_EMAIL="your-email@example.com" \
-e GARMIN_PASSWORD="your-password" \
-e GARMIN_MCP_TRANSPORT="stdio" \
-v garmin_tokens:/root/.garminconnect \
garmin-mcp:latest
网络可访问(流式HTTP):
docker run --rm -it \
-e GARMIN_EMAIL="your-email@example.com" \
-e GARMIN_PASSWORD="your-password" \
-e GARMIN_MCP_TRANSPORT="streamable-http" \
-e GARMIN_MCP_HOST="0.0.0.0" \
-e GARMIN_MCP_PORT="8000" \
-e GARMIN_MFA_CODE="123456" \
-e GARMIN_MFA_WAIT_SECONDS="180" \
-p 8000:8000 \
-v garmin_tokens:/root/.garminconnect \
garmin-mcp:latest
注: 仅包括 GARMIN_MFA_CODE 和 GARMIN_MFA_WAIT_SECONDS 如果您在Garmin Connect帐户上启用了MFA。
服务器将可在以下位置访问 http://localhost:8000/mcp
使用Docker Compose:
创建 docker-compose.yml:
version: '3.8'
services:
garmin-mcp:
build: .
image: garmin-mcp:latest
container_name: garmin-mcp
restart: unless-stopped
ports:
- "8000:8000"
environment:
- GARMIN_EMAIL=${GARMIN_EMAIL}
- GARMIN_PASSWORD=${GARMIN_PASSWORD}
- GARMIN_MCP_TRANSPORT=streamable-http
- GARMIN_MCP_HOST=0.0.0.0
- GARMIN_MCP_PORT=8000
# Only include MFA variables if MFA is enabled on your Garmin Connect account
- GARMIN_MFA_CODE=${GARMIN_MFA_CODE}
- GARMIN_MFA_WAIT_SECONDS=180
volumes:
- garmin_tokens:/root/.garminconnect
volumes:
garmin_tokens:
运行方式:
docker-compose up -d
3.Kubernetes部署
先决条件
- 配置了kubectl的Kubernetes集群
- 持久卷支持(用于令牌存储)
第一步:创造秘密
使用您的Garmin凭据创建Kubernetes密钥:
kubectl create namespace mcpo # or your preferred namespace
kubectl create secret generic garmin-secrets \
--from-literal=email='your-email@example.com' \
--from-literal=password='your-password' \
--from-literal=mfa='123456' \
-n mcpo
注: 这 mfa 仅当您的Garmin Connect帐户启用了MFA时,才需要密钥。如果未启用MFA,则省略 --from-literal=mfa 线。这 mfa 密钥仅在第一次运行或令牌过期时需要。您可以在建立令牌后将其删除。
步骤2:创建持久卷索赔
创建 pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: garmin-tokens
namespace: mcpo
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
应用它:
kubectl apply -f pvc.yaml
步骤3:部署应用程序
创建 deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: garmin-mcp
namespace: mcpo
spec:
replicas: 1
selector:
matchLabels:
app: garmin-mcp
template:
metadata:
labels:
app: garmin-mcp
spec:
containers:
- name: garmin-mcp
image: garmin-mcp:latest # Replace with your image registry
imagePullPolicy: Always
ports:
- containerPort: 8000
name: http
env:
- name: GARMIN_EMAIL
valueFrom:
secretKeyRef:
name: garmin-secrets
key: email
- name: GARMIN_PASSWORD
valueFrom:
secretKeyRef:
name: garmin-secrets
key: password
- name: GARMIN_MCP_TRANSPORT
value: "streamable-http"
- name: GARMIN_MCP_HOST
value: "0.0.0.0"
- name: GARMIN_MCP_PORT
value: "8000"
# Only include MFA variables if MFA is enabled on your Garmin Connect account
- name: GARMIN_MFA_CODE
valueFrom:
secretKeyRef:
name: garmin-secrets
key: mfa
- name: GARMIN_MFA_WAIT_SECONDS
value: "180"
volumeMounts:
- name: tokens
mountPath: /root/.garminconnect
readinessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
tcpSocket:
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
volumes:
- name: tokens
persistentVolumeClaim:
claimName: garmin-tokens
应用它:
kubectl apply -f deployment.yaml
步骤4:创建服务
创建 service.yaml:
apiVersion: v1
kind: Service
metadata:
name: garmin-mcp
namespace: mcpo
spec:
selector:
app: garmin-mcp
ports:
- name: http
port: 80
targetPort: 8000
type: ClusterIP
应用它:
kubectl apply -f service.yaml
步骤5:(可选)创建Istio HTTPRoute
如果使用Istio,请创建 httproute.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: garmin-mcp
namespace: mcpo
spec:
parentRefs:
- name: your-gateway
namespace: istio-system
hostnames:
- garmin-mcp.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /mcp
backendRefs:
- name: garmin-mcp
port: 80
应用它:
kubectl apply -f httproute.yaml
环境变量
| 变量 | 描述 | 默认值 | 必填 |
|---|---|---|---|
GARMIN_EMAIL |
Garmin Connect电子邮件地址 | - | 是 |
GARMIN_PASSWORD |
Garmin Connect密码 | - | 是 |
GARMIN_MFA_CODE |
2FA代码(仅当启用MFA时) | - | 否* |
GARMIN_MFA_WAIT_SECONDS |
等待MFA代码的秒数 | 0 |
没有 |
GARMINTOKENS |
令牌存储目录的路径 | ~/.garminconnect |
没有 |
GARMIN_MCP_TRANSPORT |
运输类型: stdio 或 streamable-http |
http |
没有 |
GARMIN_MCP_HOST |
为HTTP传输绑定主机 | 0.0.0.0 |
没有 |
GARMIN_MCP_PORT |
HTTP传输端口 | 8000 |
没有 |
*仅当您的Garmin Connect帐户启用MFA时才需要,并且仅在首次运行或令牌到期时才需要
许可证管理
OAuth令牌会自动保存到 ~/.garminconnect (或指定的路径 GARMINTOKENS)成功登录后。这些令牌在重启过程中持续存在,从而消除了后续运行中对MFA的需求,直到它们过期。
对于Kubernetes: 令牌存储在PersistentVolumeClaim中,因此它们在pod重启和部署过程中会持续存在。
故障排除
登录问题
- 无效凭证:验证您的电子邮件和密码是否正确
- 需要MFA:如果您启用了MFA,请确保
GARMIN_MFA_CODE设置为首次运行 - 令牌已过期:删除令牌目录并重新进行身份验证
网络问题
- 无法连接到服务器:验证服务器是否绑定到
0.0.0.0(不是127.0.0.1) - 连接被拒绝:检查防火墙规则和端口暴露
- 404错误:确保使用正确的传输类型(用于网络访问的流式HTTP)
Kubernetes问题
- 吊舱碰撞循环:检查日志
kubectl logs -n mcpo deployment/garmin-mcp - 服务无法访问:验证服务选择器是否与部署标签匹配
- 令牌持久性:确保PVC安装正确,并有可用的存储空间
查看日志
Docker:
docker logs <container-id>
库贝内特斯:
kubectl logs -n mcpo deployment/garmin-mcp -f
可用工具
该服务器提供78多种MCP工具。看 TOOLS.md 查看按类别组织的完整列表。
查询示例
一旦连接到MCP服务器,您就可以使用自然语言查询您的Garmin健身数据。以下是您可以进行的一些示例查询:
活动查询
-
“显示我最近的活动”
- 使用:
list_activities
- 使用:
-
“9月1日至11月6日期间,我做了哪些跑步活动?”
- 使用:
get_activities_by_dateactivity_type=“正在运行”
- 使用:
-
“获取活动ID 204592654的详细信息”
- 使用:
get_activity
- 使用:
-
“给我看看我最后一次跑步的成绩”
- 使用:
get_activity_splits
- 使用:
-
“我活动204592654期间的天气怎么样?”
- 使用:
get_activity_weather
- 使用:
健康与保健查询
-
“11月6日我走了多少步?”
- 使用:
get_steps_data
- 使用:
-
“显示我11月5日的睡眠数据”
- 使用:
get_sleep_data
- 使用:
-
“11月6日我的心率是多少?”
- 使用:
get_heart_rates
- 使用:
-
“获取11月1日至11月6日的身体电池数据”
- 使用:
get_body_battery
- 使用:
-
“11月5日我的压力水平是多少?”
- 使用:
get_stress_data或get_all_day_stress
- 使用:
-
“显示我11月6日的静息心率”
- 使用:
get_rhr_day
- 使用:
-
“获取11月6日的身体成分数据”
- 使用:
get_body_composition
- 使用:
-
“11月6日我的训练准备情况如何?”
- 使用:
get_training_readiness
- 使用:
-
“显示我11月6日的水分数据”
- 使用:
get_hydration_data
- 使用:
-
“获取我11月6日的SpO2(血氧)数据”
- 使用:
get_spo2_data
- 使用:
-
“11月6日我的呼吸频率是多少?”
- 使用:
get_respiration_data
- 使用:
培训和绩效查询
-
“我11月6日的最大摄氧量和健身年龄是多少?”
- 使用:
get_max_metrics
- 使用:
-
“获取11月6日的心率变异性(HRV)数据”
- 使用:
get_hrv_data
- 使用:
-
“显示我11月6日的健身年龄数据”
- 使用:
get_fitnessage_data
- 使用:
-
“我对204592654活动的训练效果如何?”
- 使用:
get_training_effect
- 使用:
-
“获取9月1日至11月6日的山丘分数”
- 使用:
get_hill_score
- 使用:
-
“显示我在9月1日至11月6日之间的耐力得分”
- 使用:
get_endurance_score
- 使用:
设备和装备查询
-
“列出我的所有Garmin设备”
- 使用:
get_devices
- 使用:
-
“我的主要训练设备是什么?”
- 使用:
get_primary_training_device
- 使用:
-
“显示我用于活动204592654的装备”
- 使用:
get_activity_gear
- 使用:
挑战和目标查询
-
“我的积极目标是什么?”
- 使用:
get_goalsgoal_type=“活动”
- 使用:
-
“显示我的个人记录”
- 使用:
get_personal_record
- 使用:
-
“我获得了什么徽章?”
- 使用:
get_earned_badges
- 使用:
-
“获取我的比赛预测”
- 使用:
get_race_predictions
- 使用:
用户配置文件查询
-
“我的全名是什么?”
- 使用:
get_full_name
- 使用:
-
“我使用什么单位制?”
- 使用:
get_unit_system
- 使用:
-
“显示我的用户配置文件”
- 使用:
get_user_profile
- 使用:
数据管理查询
-
“添加重量测量值:75.5公斤”
- 使用:
add_weigh_in
- 使用:
-
“获取11月1日至11月6日的体重测量值”
- 使用:
get_weigh_ins
- 使用:
-
“添加11月6日的身体成分数据”
- 使用:
add_body_composition
- 使用:
训练和饮食建议
-
“通过训练和饮食建议让我为马拉松做好准备”
- 使用:
get_training_and_diet_recommendations
- 使用:
-
“我想提高我的跑步成绩,给我训练和饮食建议”
- 使用:
get_training_and_diet_recommendations
- 使用:
-
“我想减肥,我该怎么办?”
- 使用:
get_training_and_diet_recommendations
- 使用:
复杂查询
MCP服务器可以处理复杂的多步骤查询:
-
“分析我的训练周:向我展示11月1日至11月6日的活动、睡眠质量和身体电池”
- 联合
get_activities_by_date,get_sleep_data,get_body_battery
- 联合
-
“比较我的跑步表现:获取我最近5次跑步的活动、训练效果和心率区域”
- 联合
list_activities,get_training_effect,get_activity_hr_in_timezones
- 联合
-
“给我一份11月6日的完整健康总结:步数、睡眠、压力、心率和身体电池”
- 联合
get_steps_data,get_sleep_data,get_stress_data,get_heart_rates,get_body_battery
- 联合
单窗格摘要和见解
-
“显示我上周的每周单窗格摘要”
- 使用:
get_period_summaryperiod=“week”,anchor_date=“上周”
- 使用:
-
“获取每月的仪表板摘要,包括活动和准备情况”
- 使用:
get_period_summary周期=“每月”
- 使用:
-
“过去4周我的趋势是什么?”
- 使用:
get_trends具有start_date、end_date、include=[“rhr”、“hrv”、“sleep”、“steps”、“body_battery”]
- 使用:
-
“本周检测到任何恢复危险信号”
- 使用:
detect_anomalies具有启发式阈值(默认值合理)
- 使用:
-
“给我一份今天的准备情况明细”
- 使用:
get_readiness_breakdown
- 使用:
-
“我这个月的数据有多完整?”
- 使用:
get_data_completeness
- 使用:
-
“28°C下60分钟跑步的水合目标,重量75公斤”
- 使用:
get_hydration_guidance重量kg=75,训练分钟=60,温度c=28
- 使用:
-
“本周教练提示”
- 使用:
get_coach_cues周期=“每周”
- 使用:
提示:这些工具接受自然时间框架短语,如
today,yesterday,last week,this week,last month,last 28 days.Ranges会自动锁定到今天,因此周中的请求永远不会到达未来。
访问服务器
当部署了Streamable HTTP传输时,MCP服务器可以在以下位置访问:
- 本地:
http://localhost:8000/mcp - Kubernetes与Istio:
https://garmin-mcp.example.com/mcp - 码头工人:
http://<container-ip>:8000/mcp
配置您的MCP客户端(OpenWebUI、Claude等)以连接到 /mcp 流式HTTP传输的端点。
安全说明
- 从不提交凭据:使用环境变量或Kubernetes Secrets
- 令牌存储:令牌存储在本地/PVC上-确保适当的访问控制
- 网络安全:对于生产,使用TLS/HTTPS(在入口/网关处终止)
- 秘密轮换:定期旋转Garmin密码并相应地更新密码
许可证
看 许可证 文件以获取详细信息。
贡献
欢迎投稿!请打开问题或提交拉取请求。
