健康数据聚合服务器

一个用于聚合和分析来自多个来源的健康和健身数据的模型上下文协议(MCP)服务器,支持Whoop和Strava等平台。

  • by Marholoubek
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 Marholoubek/health_mcp

使用说明

健康MCP服务器

一种模型上下文协议(MCP)服务器,用于聚合和分析来自多个来源的健康和健身数据。目前支持 欢呼 和 斯特拉瓦 具有可扩展的适配器架构,可用于未来的集成(Withings、Oura、Garmin等)。

特性

多提供商支持

  • 模块化架构:每个适配器都是可选的,可以独立配置
  • 自动启用:配置凭据时,适配器会自动启用
  • 统一身份验证:在所有提供者之间共享单个OAuth回调服务器

Whoop集成

  • 睡眠分析:跟踪睡眠持续时间、阶段(深度、快速眼动、轻度)、效率和一致性
  • 恢复跟踪:监测恢复评分、心率变异性、静息心率和血氧饱和度
  • 应变监测:查看每日压力、锻炼历史和心率区域
  • 高级见解:获取个性化建议、趋势分析和相关性

Strava集成

  • 活动跟踪:查看跑步、骑行、游泳和所有活动类型的完整统计数据
  • 性能指标:距离、步速、速度、海拔、心率、力量和节奏
  • 培训区:心率和功率区配置以及每项活动的分布
  • 运动员统计:所有时间总计、年初至今和最近的活动摘要
  • 齿轮跟踪:监控自行车、鞋子和其他设备上的距离

可用工具

将军

工具 说明
list_adapters 列出所有可用适配器及其身份验证状态

Whoop工具

认证

工具 说明
whoop_authenticate 启动Whoop的OAuth2登录流程
whoop_check_auth 检查当前身份验证状态

个人资料

工具 说明
get_user_profile 获取用户资料和身体测量值

睡眠

工具 说明
get_sleep_summary 最近的睡眠与表现、阶段和需求
get_sleep_history 随时间变化的睡眠历史与趋势

恢复

工具 说明
get_recovery_score HRV和状态的最新恢复
get_recovery_history 随时间推移的恢复趋势

压力和锻炼

工具 说明
get_strain_today 当前压力和心率
get_strain_history 随时间变化的每日应变模式
get_workout_history 包含HR区域和卡路里的锻炼细节

分析和见解

工具 说明
get_health_overview 综合健康仪表板
analyze_sleep_patterns 睡眠时间、一致性和建议
analyze_recovery_factors 影响恢复的相关性
get_weekly_report 每周与趋势的比较
get_training_readiness 锻炼强度建议

斯特拉瓦工具

认证

工具 说明
strava_authenticate 启动Strava的OAuth2登录流程
strava_check_auth 检查当前Strava身份验证状态

个人资料和统计数据

工具 说明
get_strava_profile 运动员档案,包括历史数据和装备

活动

工具 说明
get_strava_activities 最近与距离、速度、人力资源等相关的活动。
get_strava_activity_detail 包含圈数、分段数和完整统计数据的详细活动
get_strava_weekly_summary 按活动类型划分的每周培训总结

培训区

工具 说明
get_strava_zones 您配置的人力资源和电力培训区
get_strava_activity_zones 特定活动的区域分布

安装

先决条件

  • Python 3.10或更高版本
  • 至少一个供应商(Whoop和/或Strava)的API证书

设置

  1. 克隆仓库

    cd /path/to/health_mcp
    
  2. 创建虚拟环境

    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
  3. 安装依赖项

    pip install -r requirements.txt
    
  4. 配置API凭据

    复制示例配置:

    cp config.example.yaml config.yaml
    

    编辑 config.yaml 使用API凭据(配置一个或两个):

    # Whoop - Get credentials from https://developer.whoop.com/
    whoop:
      client_id: "your_client_id_here"
      client_secret: "your_client_secret_here"
      redirect_uri: "http://localhost:8787/callback"
    
    # Strava - Get credentials from https://www.strava.com/settings/api
    strava:
      client_id: "your_client_id_here"
      client_secret: "your_client_secret_here"
      redirect_uri: "http://localhost:8787/callback"
    

    备选方案:环境变量

    # Whoop
    export HEALTH_MCP_WHOOP_CLIENT_ID="your_client_id"
    export HEALTH_MCP_WHOOP_CLIENT_SECRET="your_client_secret"
    
    # Strava
    export HEALTH_MCP_STRAVA_CLIENT_ID="your_client_id"
    export HEALTH_MCP_STRAVA_CLIENT_SECRET="your_client_secret"
    

正在获取API凭据

欢呼

  1. 首选 Whoop开发者门户
  2. 创建新应用程序
  3. 将重定向URI设置为 http://localhost:8787/callback
  4. 复制您的客户端ID和客户端密码

斯特拉瓦

  1. 首选 Strava API设置
  2. 创建新应用程序(或使用现有应用程序)
  3. 将“授权回调域”设置为 localhost
  4. 复制您的客户端ID和客户端密码

使用Claude Desktop

将以下内容添加到您的Claude Desktop配置文件中:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json 视窗: %APPDATA%\Claude\claude_desktop_config.json

{
    "mcpServers": {
        "health": {
            "command": "/path/to/health_mcp/venv/bin/python",
            "args": ["-m", "src.server"],
            "cwd": "/path/to/health_mcp",
            "env": {
                "HEALTH_MCP_WHOOP_CLIENT_ID": "your_whoop_client_id",
                "HEALTH_MCP_WHOOP_CLIENT_SECRET": "your_whoop_client_secret",
                "HEALTH_MCP_STRAVA_CLIENT_ID": "your_strava_client_id",
                "HEALTH_MCP_STRAVA_CLIENT_SECRET": "your_strava_client_secret"
            }
        }
    }
}

使用游标

将以下内容添加到光标MCP设置中:

{
  "mcpServers": {
    "health": {
      "command": "/path/to/health_mcp/venv/bin/python",
      "args": ["-m", "src.server"],
      "cwd": "/path/to/health_mcp"
    }
  }
}

首次身份验证

设置MCP服务器后,向您配置的每个提供程序进行身份验证:

欢呼

  1. 询问AI:“使用我的Whoop帐户进行身份验证”
  2. 将打开一个浏览器窗口进行OAuth授权
  3. 登录并授权应用程序
  4. 令牌会自动保存

斯特拉瓦

  1. 询问AI:“使用我的Strava帐户进行身份验证”
  2. 将打开Strava OAuth的浏览器窗口
  3. 授权请求的权限
  4. 令牌会自动保存

您可以通过询问“列出我的健康适配器”来检查哪些适配器可用并经过身份验证

示例问题

Whoop特定

  • “我昨晚睡得怎么样?”
  • “我今天的康复分数是多少?”
  • “显示我过去一个月的睡眠趋势”
  • “我今天准备好进行高强度的锻炼了吗?”
  • “哪些因素影响了我的康复?”

Strava专用

  • “显示我最近的Strava活动”
  • “我每周的训练总结是什么?”
  • “显示我上次跑步的详细信息”
  • “我的训练区是什么?”
  • “今年我骑了多少自行车?”

组合分析(当两者连接时)

  • “将我在Whoop的锻炼压力与我在Strava的活动进行比较”
  • “显示我的整体健康状况”
  • “我的训练负荷在所有来源中表现如何?”

项目结构

health_mcp/
├── src/
│   ├── __init__.py
│   ├── server.py              # Main MCP server with dynamic adapter loading
│   ├── config.py              # Configuration management
│   ├── auth/
│   │   ├── __init__.py
│   │   ├── oauth_server.py    # Shared OAuth callback server
│   │   └── token_store.py     # Token persistence
│   ├── adapters/
│   │   ├── __init__.py
│   │   ├── base.py            # Abstract adapter interface
│   │   ├── whoop.py           # Whoop API adapter
│   │   └── strava.py          # Strava API adapter
│   └── tools/
│       ├── __init__.py
│       ├── sleep.py           # Whoop sleep tools
│       ├── recovery.py        # Whoop recovery tools
│       ├── strain.py          # Whoop strain & workout tools
│       ├── profile.py         # Whoop profile tools
│       ├── insights.py        # Whoop analysis tools
│       └── strava.py          # Strava-specific tools
├── config.example.yaml
├── requirements.txt
└── README.md

适配器架构

服务器使用模块化适配器模式:

  • 可选适配器:每个适配器都是可选的,可以独立启用
  • 自动发现:当凭据存在时,适配器会自动启用
  • 显式控制:使用 enabled: true/false 在配置中覆盖自动检测
  • 统一接口:所有适配器都实现了一个通用的基类以保持一致性
  • 提供商特定工具:每个适配器都可以为特定于提供商的功能提供独特的工具

配置选项

# Each adapter section supports:
provider_name:
  client_id: "..."
  client_secret: "..."
  redirect_uri: "http://localhost:8787/callback"
  enabled: true  # Optional: explicitly enable/disable (auto-detected by default)

使用新适配器进行扩展

要添加新的健康数据提供程序,请执行以下操作:

  1. 在中创建新适配器 src/adapters/ 实施 HealthAdapter 基类
  2. 在中添加配置属性 src/config.py
  3. 在中创建特定于提供商的工具 src/tools/
  4. 在中注册适配器和工具 src/server.py

适配器骨架示例:

from .base import HealthAdapter, SleepRecord, RecoveryRecord, WorkoutRecord

class NewProviderAdapter(HealthAdapter):
    provider_name = "new_provider"

    async def is_authenticated(self) -> bool:
        # Check auth status
        pass

    async def authenticate(self) -> bool:
        # Initiate OAuth flow
        pass

    async def get_workouts(self, start=None, end=None, limit=10) -> list[WorkoutRecord]:
        # Implement workout data fetching
        pass

    # Implement other methods (return empty lists for unsupported features)

令牌存储

OAuth令牌安全地存储在 ~/.health_mcp/tokens.json 具有受限的文件权限(600)。令牌过期时会自动刷新。

故障排除

“未通过身份验证”错误

运行相应的身份验证工具:

  • 哇: whoop_authenticate
  • 斯特拉瓦: strava_authenticate

“缺少配置”错误

确保您的 config.yaml 设置正确或导出环境变量。

OAuth回调失败

  • 确保端口8787可用
  • 检查您的重定向URI是否与提供商的开发人员门户完全匹配
  • 对于Strava,确保授权回调域设置为 localhost

令牌刷新失败

删除 ~/.health_mcp/tokens.json 并重新进行身份验证。

适配器未显示

  • 检查凭据是否配置正确
  • 使用 list_adapters 查看适配器状态的工具
  • 检查服务器日志中的初始化错误

许可证

MIT许可证

贡献

欢迎投稿!请随时提交以下拉取请求:

  • 新的健康数据适配器(Withings、Oura、Garmin、Apple health等)
  • 其他分析工具
  • 错误修复与改进