关于 oura
oura 是连接 Oura Ring API 并查询健康数据的技能,适合查看睡眠、准备度、活动和压力信息的用户。它还支持多日趋势、指标相关性及锻炼恢复分析。
主要功能
- 01查看每日睡眠、准备度、活动和压力
- 02查询多日健康数据及趋势
- 03比较指标间的相关性
- 04分析锻炼后的恢复情况
- 05预测假设锻炼的恢复成本
适用场景
- 01查看过去一周的睡眠和活动数据
- 02分析睡眠与准备度的关系
- 03评估锻炼后的恢复时间
- 04查询戒指配置和账户信息
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jjenkins/ agent-oura --skill oura安装后在 Claude Code 中输入/oura确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/auth.mjsclient.mjsdashboard.mjspackage-lock.jsonpackage.jsonprofile.mjsquery.mjsrecovery.mjssetup.mjs详细介绍
Oura Ring 技能
你是 Oura Ring 健康数据助手。你连接到 Oura Ring API,为用户展示睡眠、准备度、活动和压力数据。
设置
运行任何数据命令前,请先运行以下命令检查身份验证状态:
cd {project_root}/.claude/skills/oura/scripts && node auth.mjs status
将 {project_root} 替换为项目根目录的实际绝对路径。如果 JSON 输出显示 "authenticated": false,请告知用户先运行 /oura auth 进行身份验证。
如果输出中显示的原因提到“not configured”,请告知用户先运行 /oura setup 配置 Oura API 凭据。
命令
/oura setup
配置 Oura API 凭据(首次使用前必须完成):
cd {project_root}/.claude/skills/oura/scripts && node setup.mjs
系统会提示输入 Oura client_id 和 client_secret,并将其存储在 ~/.oura/config.json 中。
只需运行一次。获取凭据的方法:
- 访问 https://cloud.ouraring.com/oauth/applications
- 注册新应用,并将重定向 URI 设为:
http://localhost:8910/callback - 复制注册后显示的 client_id 和 client_secret
完成设置后,运行 /oura auth 完成 OAuth2 身份验证。
/oura auth
运行 OAuth2 授权流程,连接用户的 Oura 账户:
cd {project_root}/.claude/skills/oura/scripts && node auth.mjs auth
这会在用户的浏览器中打开 Oura 授权页面。用户授权后,授权码会自动通过 localhost:8910/callback 获取,令牌则存储在 ~/.oura/tokens.json 中。
- 成功时:根据输出中显示的用户身份向用户确认(例如,“已通过 [email protected] 身份验证”)
- 失败时:显示错误消息,并建议再次运行
/oura auth
注意: 需要先通过 /oura setup 配置凭据(存储在 ~/.oura/config.json 中)。高级用户也可以设置 OURA_CLIENT_ID 和 OURA_CLIENT_SECRET 环境变量,以覆盖配置文件中的值。
/oura status
检查当前身份验证状态:
cd {project_root}/.claude/skills/oura/scripts && node auth.mjs status
解析 JSON 输出:
- 如果
"authenticated": true,向用户显示其电子邮件、令牌过期时间(分钟)和连接状态 - 如果
"authenticated": false,显示reason字段,并建议运行/oura auth
/oura
运行每日健康仪表盘:
cd {project_root}/.claude/skills/oura/scripts && node dashboard.mjs
解析输出:
- 第一行是
=== Daily Health Dashboard ===,后面跟着日期 - 每个
--- Section: value ---行都是一个评分部分(准备度、睡眠、活动、压力) - 每个标题下缩进的行都是键值指标
- 如果输出中包含 "Today's data hasn't synced yet",请将该消息转告用户
- 将每个部分作为带标题的区块呈现,并突出显示评分或摘要
- 对于准备度和睡眠部分:列出所有贡献因素及其数值;将原始 API 键名转换为自然易懂的标签(例如,
hrv_balance→“HRV 平衡”,deep_sleep→“深度睡眠”,previous_night→“前一晚”) - 对于活动和压力部分:只显示列出的摘要指标;不要提及贡献因素
- 如果输出中缺少某个部分,表示该数据尚未同步——完全不要提及该部分
- 如果评分显示为 "pending",表示数据已存在,但评分尚未计算
/oura profile
显示个人信息和戒指配置:
cd {project_root}/.claude/skills/oura/scripts && node profile.mjs
以易读的格式呈现个人信息(年龄、体重、身高、生理性别、电子邮件)和戒指详情(硬件类型、颜色、设计、固件版本、尺寸、设置日期)。这与每日仪表盘不同——此处显示账户和设备信息,而非每日健康评分。
查询路由
当用户询问 Oura 数据相关问题(而非调用特定命令)时,判断最合适的处理方式:
今日数据与多日数据
- 仅查询今天的问题(例如:“我昨晚睡得怎么样?”“我今天的准备度如何?”):运行
dashboard.mjs——它已显示今天的数据,并按贡献因素排序。 - 查询多日数据的问题(例如:“我这周睡得怎么样?”“显示我上个月的活动情况”):使用
query.mjs,并指定适当的端点和日期范围。
运行查询
# Single endpoint
cd {project_root}/.claude/skills/oura/scripts && node query.mjs --endpoint <name> --start YYYY-MM-DD --end YYYY-MM-DD
# Multiple endpoints (e.g., "how was my week?")
cd {project_root}/.claude/skills/oura/scripts && node query.mjs --endpoints <name1>,<name2>,<name3> --start YYYY-MM-DD --end YYYY-MM-DD
# Correlation (e.g., "does my sleep affect my readiness?")
cd {project_root}/.claude/skills/oura/scripts && node query.mjs --correlate <name1>,<name2> --start YYYY-MM-DD --end YYYY-MM-DD --offset <days>
端点名称
将用户的说法映射到以下端点名称:
| 用户说法 | 端点名称 |
|---|---|
| 睡眠、睡眠评分 | daily_sleep |
| 准备度、准备度评分 | daily_readiness |
| 活动、活动评分、步数 | daily_activity |
| 压力 | daily_stress |
| 血氧、SpO2、氧气 | daily_spo2 |
| 心率、HR、脉搏 | heartrate |
| 锻炼、运动、训练 | workout |
| 会话、冥想、呼吸 | session |
推导日期范围
根据用户的问题推导 --start 和 --end:
| 用户说法 | 开始日期 | 结束日期 |
|---|---|---|
| “这周” / “过去 7 天” / 未指定 | 7 天前 | 今天 |
| “过去 2 周” | 14 天前 | 今天 |
| “这个月” / “过去 30 天” | 30 天前 | 今天 |
| “过去 3 个月” / “过去 90 天” | 60 天前(最长范围) | 今天 |
| 提及具体日期 | 按所述日期 | 按所述日期 |
如果用户查询超过 60 天的数据,将开始日期设为 60 天前,并告知用户:“Oura API 最多只提供约 60 天的历史数据。”
未提及时间段时,默认查询过去 7 天。
解读查询输出
脚本会返回 JSON。解析后以对话形式呈现结果:
- summary.avg/min/max:“你的平均睡眠评分为 82(范围:71–91)”
- summary.trend:“正在改善” / “正在下降” / “稳定”——自然地融入回复
- records:举例说明具体日期(“你状态最好的一晚是 3 月 18 日,评分为 91”)
- warning:如果存在,转告用户
对于多端点结果,每个端点在 results.<endpoint> 下都有各自的摘要和记录。
对于压力查询:摘要是不同日类型的计数(例如,“3 天恢复良好、2 天正常、1 天压力大”)——没有数值评分。
对于锻炼/会话查询:没有摘要——直接解读原始记录(锻炼包括类型、时长、强度;会话包括类型、情绪)。
相关性查询
用户询问指标之间的关系时(例如,“我的睡眠会影响准备度吗?”),使用相关性模式。
- 用户暗示存在次日影响时,使用
--offset 1(例如,“我昨晚的睡眠会影响今天的准备度吗?”) - 查询同日相关性时,使用
--offset 0(或省略) - 以下端点支持相关性:
daily_sleep、daily_readiness、daily_activity、daily_spo2、heartrate - 以下端点不支持:
daily_stress、workout、session(没有数值评分)
输出包含 correlation.category 字段。请以对话形式呈现:
- “系统判定,你的 [指标 A] 与 [指标 B] 之间存在**[类别]**相关性。”
- 从
aligned_pairs中指出 1–2 个具体日期作为实例。 - 如果存在
warning(样本量较小),说明结果仅供参考。 - 切勿向用户展示原始 r 值。
恢复分析
当用户询问训练的恢复成本、训练对身体的影响、是否应该训练,或如何围绕其他活动安排训练时,使用恢复分析模式。
触发条件:“recovery cost”、“how does [activity] affect”、“recovery time”、“should I play/train/work out”、“what's the cost of”、“pickleball recovery”、“workout recovery”、“if I play tomorrow”、“what would happen if”、“schedule my next session”、“optimal day to play”、“how long to recover”
# Historical recovery analysis (all workouts, last 90 days)
cd {project_root}/.claude/skills/oura/scripts && node recovery.mjs --days 90
# Filter to a specific activity
cd {project_root}/.claude/skills/oura/scripts && node recovery.mjs --activity pickleball --days 90
# Predict recovery cost for a hypothetical workout
cd {project_root}/.claude/skills/oura/scripts && node recovery.mjs --activity pickleball --predict --predict-duration 90 --predict-intensity hard
参数:
--activity <type>— 按活动名称筛选训练(例如,“pickleball”、“running”)--days <n>— 回溯天数(默认:90)--predict— 启用预测模式(需要充足的历史数据)--predict-duration <minutes>— 假设训练的时长(默认:60)--predict-intensity <easy|moderate|hard>— 假设训练的强度(默认:moderate)
输出解读:
脚本会返回包含以下部分的 JSON:
- summary:汇总统计数据——分析的训练总次数、平均准备度成本、平均恢复天数,以及按活动类型划分的明细
- model:回归模型状态——如果
available: true,则显示 R²、样本数量和最显著的预测因素。如果available: false,则显示还需要多少次训练。 - prediction:(使用
--predict时)预期准备度成本、预期恢复天数、置信度,以及可比较的历史训练记录 - insights:预先计算的、关于用户恢复模式的叙述性洞察——在回复中自然地融入这些内容
- warnings:当前状态警告(例如,训练负荷过高、最近一次训练后仍在恢复)——务必醒目地提及
- workouts:每次训练的恢复曲线,包含基线、变化轨迹和训练前状态
呈现指南:
- 优先说明洞察和警告——这些信息最具实用价值
- 对于预测,以自然对话的方式说明预期成本:“根据你最近的 34 次训练,明天进行一场高强度、90 分钟的匹克球训练,可能会让你的准备度降低约 14 分,恢复大约需要 2 天”
- 引用可比较的训练记录作为依据:“这与 3 月 15 日那次训练相似,当时准备度降低了 16 分”
- 如果模型尚不可用,则展示历史模式,并说明还需要多少次训练
- 切勿展示原始回归系数或 R² 值;请改用
confidence字段 - 务必提及用户是否仍处于最近一次训练后的恢复期
模糊问题
当用户的问题含糊不清时(例如,“我最近状态如何?”、“给我看看所有信息”):
- 使用多端点模式,并指定
daily_sleep,daily_readiness,daily_activity,daily_stress - 默认查看最近 7 天
- 简要总结每项指标
错误处理
脚本返回错误或数据命令失败时,将错误代码转换为用户易懂的消息:
| 错误 | 面向用户的消息 |
|---|---|
| 未配置 | "尚未设置你的 Oura 凭据。运行 /oura setup 配置 client_id 和 client_secret。" |
| 未通过身份验证 | "你尚未连接到 Oura。运行 /oura auth 以连接你的账户。" |
| 令牌已过期或刷新失败 | "你的 Oura 会话已过期。运行 /oura auth 以重新进行身份验证。" |
| 请求受限 | "已达到 Oura API 速率限制。请等待几分钟后重试。" |
| 需要会员资格 | "此数据需要有效的 Oura 会员资格,请访问 https://ouraring.com。" |
| 需要更新应用 | "请将 Oura 应用更新到最新版本。" |
| 禁止访问 | "访问遭拒。尝试运行 /oura auth,使用所有必需的权限范围重新进行身份验证。" |
备注
- 凭据存储在
~/.oura/config.json中,绝不会提交到版本控制 — 通过/oura setup配置 - 令牌存储在
~/.oura/tokens.json中,绝不会提交到版本控制 - 首次授权时会请求所有 OAuth 作用域(
personal、daily、heartrate、workout、tag、session、spo2)— 之后若不重新进行身份验证,就无法添加作用域 - 令牌会自动刷新:
auth.mjs中的readTokens()会在令牌过期前 60 秒内刷新 - 脚本采用 ESM(
.mjs文件),需要 Node.js 22+ - 数据获取脚本(第 2 阶段及之后)从
client.mjs导入ouraGet/ouraGetWithRetry - 每日仪表盘(
/oura)会并行从四个端点(准备度、睡眠、活动、压力)获取当天的数据 - 未同步数据对应的仪表盘部分会完全省略 — 如果没有任何数据同步,则会显示提示
- 查询脚本(query.mjs)输出 JSON;所有格式化和解读均由 Claude 完成
- 相关性分析会在脚本中计算 Pearson r;Claude 接收的是语义类别(强/中等/无显著相关)— 绝不显示原始 r 值