Garmin健康数据服务器

为健身、健康和教练应用优化的Garmin Connect数据访问语义服务器。

  • by MAnders333
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 MAnders333/garmin-mcp-server

使用说明

Garmin MCP服务器

用于Garmin Connect数据访问的语义MCP服务器,针对健身、健康和教练应用程序进行了优化。

概述

Garmin MCP服务器提供智能工具,将Garmin Connect数据组合成个人教练代理和健身应用程序的有用抽象。使用FastMCP框架构建,并利用python garminconnect库。

主要特点

  • 语义辅导工具:将多个API调用组合为与指导相关的抽象
  • 12专用工具:每日概览、恢复状态、活动分析、训练区、健身概况、训练总结、训练准备情况、日期范围活动、健康趋势和训练计划
  • 代理优化:专为LLM代理消费而设计,具有一致的响应格式
  • 生产就绪:具有streamable_http传输的FastMCP框架
  • OAuth身份验证:使用MFA支持进行安全令牌管理

🚀 快速开始

🐳 Docker(推荐)

在2分钟内开始:

git clone https://github.com/MAnders333/garmin-mcp-server.git
cd garmin-mcp-server

# Automated setup with validation
./scripts/docker-dev-setup.sh

# Or manual setup:
cp .env.example .env
# Edit .env with your Garmin credentials
docker-compose up -d

有关Docker的全面说明,请参阅 Docker快速入门指南.

选项1:Docker(完整细节)

Docker Compose快速入门:

git clone https://github.com/MAnders333/garmin-mcp-server.git
cd garmin-mcp-server

# Copy and configure environment
cp .env.example .env
# Edit .env with your Garmin credentials (GARMIN_EMAIL and GARMIN_PASSWORD)

# Start server with Docker Compose
docker-compose up -d

# View logs
docker-compose logs -f

直接使用Docker:

# Build the image
docker build -t garmin-mcp-server .

# Run with environment file
docker run -d \
  --name garmin-mcp-server \
  --env-file .env \
  -p 8000:8000 \
  -v garmin-tokens:/app/.garmin \
  garmin-mcp-server

选项2:本地Python安装

  1. 克隆和设置

    git clone https://github.com/MAnders333/garmin-mcp-server.git
    cd garmin-mcp-server
    
    # Quick setup (recommended)
    make quick-start
    source .venv/bin/activate  # Linux/macOS
    
    # Or manual setup:
    # uv venv --python 3.11
    # source .venv/bin/activate
    # uv pip install -e ".[dev]"
    
  2. 配置

    # Copy the example configuration
    cp .env.example .env
    
    # Edit .env with your Garmin Connect credentials
    # Required:
    #   GARMIN_EMAIL=your.email@example.com
    #   GARMIN_PASSWORD=your_secure_password
    # Optional:
    #   GARMIN_TOKENS_PATH=~/.garminconnect
    #   MCP_HOST=127.0.0.1
    #   MCP_PORT=8000
    
  3. 运行服务器

    # Start the MCP server (streamable_http transport on port 8000)
    python scripts/start_server.py
    
    # Or using the server module directly
    python src/garmin_mcp/server.py
    

首次运行身份验证

首次运行时,您将使用Garmin Connect进行身份验证(需要MFA):

Starting Garmin MCP Server on 127.0.0.1:8000
Enter MFA code: 123456
✅ Successfully authenticated and saved tokens to ~/.garminconnect

对于Docker用户: OAuth令牌会自动保存在 garmin-tokens Docker卷,所以你只需要验证一次。

有关详细的身份验证设置和故障排除,请参阅 docs/authentication.md.

可用工具

核心辅导工具

  • get_daily_summary -完成每日健康、活动和身体成分总结
  • get_recovery_status -睡眠、心率变异性、身体电池和压力分析
  • get_activities -最近的训练与教练相关指标
  • get_activity_details -通过拆分和区域进行深入的性能分析

健身和训练工具

  • get_training_zones -基于乳酸阈值和最大摄氧量的训练区
  • get_fitness_profile -最大摄氧量、训练状态和比赛预测
  • get_training_summary -长期趋势和目标进展
  • get_training_readiness -训练决策的综合准备度得分(0-100)

活动和健康工具

  • get_activities_by_date -特定日期范围内的锻炼
  • list_wellness_metrics -发现可用的健康趋势指标
  • get_wellness_trend -随着时间的推移,每日健康指标值(HRV、睡眠、压力等)
  • get_training_plan -积极的训练计划和即将进行的计划锻炼

建筑

极简复杂设计

遵循以下原则 “最小可行复杂性”,此服务器使用干净的模块化架构:

  • 直接集成:用途 garminconnect 直接使用库,无需不必要的包装
  • 服务器级身份验证:OAuth令牌管理集成到主服务器模块中
  • 简单依赖关系:只有基本库(FastMCP、garminconnect、pydantic)
  • 清除数据流:身份验证→ API调用→ 具有一致错误处理的响应格式

语义工具设计

此服务器提供语义工具,这些工具:

  • 合并多个API调用 指导相关数据结构
  • 筛选数据 只返回与辅导相关的指标
  • 针对代理进行优化 具有一致的响应格式和优雅的降级
  • 使用指导术语 而不是技术API字段名称

工具响应示例

{
  "date": "2025-10-11",
  "activity_summary": {
    "data": {
      "steps": 8542,
      "distance_meters": 6200,
      "calories_burned": 2145,
      "active_minutes": 67
    },
    "api_method": "get_user_summary",
    "status": "success"
  },
  "sleep_data": {
    "data": {
      "sleep_score": 82,
      "total_sleep_hours": 7.5,
      "deep_sleep_minutes": 89
    },
    "api_method": "get_sleep_data",
    "status": "success"
  },
  "body_battery": {
    "data": [
      {"timestamp": "2025-10-11T06:00:00", "level": 85},
      {"timestamp": "2025-10-11T12:00:00", "level": 67}
    ],
    "api_method": "get_body_battery",
    "status": "success"
  }
}

Docker部署

Docker Compose(推荐)

运行Garmin MCP服务器的最简单方法是使用Docker Compose:

# 1. Copy environment template
cp .env.example .env

# 2. Edit .env with your credentials
GARMIN_EMAIL=your.email@example.com
GARMIN_PASSWORD=your_secure_password

# 3. Start the server
docker-compose up -d

# 4. Check logs
docker-compose logs -f garmin-mcp-server

# 5. Health check
curl http://localhost:8000/health

Docker服务

这 docker-compose.yml 提供两项服务:

生产服务 (默认):

docker-compose up -d
  • 优化生产构建
  • 最小攻击面
  • 持久OAuth令牌存储
  • 健康监测

开发服务 (可选):

docker-compose --profile dev up -d garmin-mcp-dev
  • 使用卷装载重新加载热代码
  • 已启用调试日志记录
  • 默认情况下在端口8001上运行

手动Docker命令

构建并运行:

# Build image
docker build -t garmin-mcp-server .

# Run container
docker run -d \
  --name garmin-mcp-server \
  --env-file .env \
  -p 8000:8000 \
  -v garmin-tokens:/app/.garmin \
  garmin-mcp-server

集装箱管理:

# View logs
docker logs -f garmin-mcp-server

# Stop and remove
docker stop garmin-mcp-server
docker rm garmin-mcp-server

# Clean up volumes (removes OAuth tokens)
docker volume rm garmin-tokens

Docker环境变量

所有环境变量来自 .env.example Docker支持:

# Required
GARMIN_EMAIL=your.email@example.com
GARMIN_PASSWORD=your_password

# Optional Docker-specific settings
MCP_HOST=0.0.0.0                     # Docker internal host (don't change)
MCP_PORT=8000                        # Internal container port
GARMIN_TOKENS_PATH=/app/.garmin      # Token storage path in container

# Optional general settings
GARMIN_IS_CN=false                   # China region support
LOG_LEVEL=INFO                       # Logging level
RATE_LIMIT_PER_MINUTE=60            # API rate limiting
CACHE_TIMEOUT_SECONDS=300           # Cache duration

Docker安全特性

  • 非root用户:容器运行方式为 garmin 用户(非root)
  • 最小基础图像:使用Python精简映像和最少的包
  • 令牌持久性:存储在安全Docker卷中的OAuth令牌
  • 健康监测:内置健康检查端点
  • 网络隔离:在专用Docker网络中运行

Docker故障排除

容器无法启动:

# Check logs for errors
docker-compose logs garmin-mcp-server

# Verify environment variables
docker-compose config

身份验证问题:

# Remove token volume to force re-authentication
docker-compose down
docker volume rm garmin-mcp-server_garmin-tokens
docker-compose up -d

端口冲突:

# Change port in .env file
echo "MCP_PORT=8001" >> .env
docker-compose down && docker-compose up -d

健康检查失败:

# Check if server is responding
docker exec garmin-mcp-server curl -f http://localhost:8000/health

# Check container health status
docker inspect garmin-mcp-server --format='{{.State.Health.Status}}'

配置

环境变量

# Required
GARMIN_EMAIL=your.email@example.com
GARMIN_PASSWORD=your_password

# Optional
GARMIN_TOKENS_PATH=~/.garminconnect  # OAuth token storage (local) / /app/.garmin (Docker)
MCP_HOST=127.0.0.1                   # Server bind address (0.0.0.0 for Docker)
MCP_PORT=8000                        # Server port
GARMIN_IS_CN=false                   # China region support
LOG_LEVEL=INFO                       # Logging level
RATE_LIMIT_PER_MINUTE=60            # API rate limiting
CACHE_TIMEOUT_SECONDS=300           # Cache timeout

安全

  • 本地存储的OAuth令牌(1年生存期)
  • 没有永久存储Garmin数据
  • 使用环境变量进行安全的凭据处理
  • MFA支持增强账户安全
  • Docker容器以非root用户身份运行

发展

项目结构

src/garmin_mcp/
├── __init__.py         # Package initialization
├── server.py           # Main MCP server with 8 tools and authentication
├── models.py           # Pydantic response models for structured responses
└── utils.py            # Utility functions for data processing and error handling

# Docker files
├── Dockerfile          # Multi-stage Docker build
├── docker-compose.yml  # Docker Compose configuration
├── .dockerignore       # Docker build exclusions
├── .env.docker         # Docker-optimized environment template
└── scripts/
    ├── docker-dev-setup.sh    # Automated Docker setup
    └── validate-docker.sh     # Docker validation script

添加新工具

  1. 在中定义工具 server.py:

    @mcp.tool()
    def my_coaching_tool(param: str) -> Dict[str, Any]:
        """Tool description for agents"""
        # Use handle_api_call for consistent error handling
        result = handle_api_call(
            lambda: _garmin_client.get_some_data(param),
            "get_some_data",
            "No data available for this request"
        )
        return result
    
  2. 工具已自动注册 当装饰时 @mcp.tool()

  3. 更新工具文档 在 docs/tools-reference.md

测试

# Setup development environment (if not done already)
make quick-start
source .venv/bin/activate

# Run all tests with coverage
make test

# Or run specific test categories
make test-unit      # Unit tests only
make test-cov       # Tests with detailed coverage
make ci             # Full CI pipeline

有关全面的测试说明,请参阅 docs/testing.md.

设计理念

此服务器需要 教练优先法 数据展示:

  • 语义抽象:工具不是公开原始的API端点,而是将相关数据点组合到与指导相关的结构中
  • 智能过滤:响应仅包括可操作的指标,减少LLM代理的噪音
  • 高级指标:包括训练区、最大摄氧量、心率变异性、乳酸阈值和其他绩效指标
  • 优雅降级:当某些指标不可用时,工具会返回部分数据
  • 教练见解在适当的情况下,工具提供情境建议

用例

私人教练代理

# Get daily coaching overview
overview = await call_tool("get_daily_summary")
# Returns: structured response with status indicators for each API call

# Analyze recent workout
analysis = await call_tool("get_activity_details", {"activity_id": "12345"})
# Returns: activity details, splits data, HR zones with status indicators

# Check training readiness
recovery = await call_tool("get_recovery_status")
# Returns: sleep analysis, HRV, body battery, resting HR with status indicators

# Check if ready to train hard today
readiness = await call_tool("get_training_readiness")
# Returns: composite 0-100 score with training recommendation

# View upcoming training plan
plan = await call_tool("get_training_plan")
# Returns: active plan overview and next 7 days of scheduled workouts

健身仪表板

# Get comprehensive fitness assessment
fitness = await call_tool("get_fitness_profile")
# Returns: fitness metrics, training status, race predictions with status indicators

# Track progress over time
progress = await client.call_tool("get_training_summary", {
    "start_date": "2025-09-11",
    "end_date": "2025-10-11"
})
# Returns: progress data, goals, personal records with status indicators

# Check wellness trends
sleep_trend = await client.call_tool("get_wellness_trend", {
    "metric": "sleep_score",
    "start_date": "2025-09-11",
    "end_date": "2025-10-11"
})
# Returns: daily metric values with trend analysis

贡献

  1. 分叉存储库
  2. 创建要素分支
  3. 通过测试进行更改
  4. 提交拉取请求

指南

  • 遵循语义工具设计原则
  • 包括全面的错误处理
  • 在有价值的地方添加辅导见解
  • 保持响应格式的一致性
  • 使用真实的Garmin数据进行测试

许可证

MIT许可证-请参阅 许可证 文件以获取详细信息。

故障排除

常见问题

认证失败

本地安装:

# Clear existing tokens and retry
rm -rf ~/.garminconnect
python scripts/start_server.py

Docker:

# Remove token volume to force re-authentication
docker-compose down
docker volume rm garmin-mcp-server_garmin-tokens
docker-compose up -d

需要MFA代码

  • 检查电子邮件/短信以获取Garmin Connect MFA代码
  • 代码很快过期-出现提示时立即输入
  • 如果身份验证仍然失败,请在中验证凭据 .env
  • 对于Docker:使用 docker-compose logs -f 在首次身份验证期间

无可用数据

  • 某些指标需要特定的Garmin设备(车身电池、HRV等)
  • 最近的活动可能不会在同步后立即显示
  • 历史数据访问取决于您的Garmin Connect帐户历史记录

服务器无法启动

本地安装:

# Check if port 8000 is already in use
lsof -i :8000

# Or specify different port in .env
echo "MCP_PORT=8001" >> .env

Docker:

# Check if port is in use
docker ps | grep 8000

# Change port in .env and restart
echo "MCP_PORT=8001" >> .env
docker-compose down && docker-compose up -d

Docker特定问题

容器健康检查失败

# Check container logs
docker-compose logs garmin-mcp-server

# Manual health check
docker exec garmin-mcp-server curl -f http://localhost:8000/health

# Restart unhealthy container
docker-compose restart garmin-mcp-server

容器无法启动

# Check Docker configuration
docker-compose config

# View detailed error logs
docker-compose up --no-daemonize

# Check Docker daemon is running
docker info

环境变量问题

# Validate environment file
docker-compose config

# Check variables are loaded correctly
docker-compose run --rm garmin-mcp-server env | grep GARMIN

工具返回无数据状态

  • 验证Garmin Connect帐户是否有活动数据
  • 某些工具要求在指定日期范围内进行最近的活动
  • 检查工具响应-它们包括每个API调用的状态指示器
  • 当数据不可用时,工具返回状态“no_data”而不是失败

文档

支持

致谢