mcpField
O
Oura Ring

Oura Ring

本地服务
github.com健康医疗08 周前更新

关于 Oura Ring

这款 MCP 服务让 AI 客户端以结构化摘要访问 Oura Ring 健康数据,提供每日统计与趋势,而非默认返回原始 API 数据。支持本地和托管部署。

主要功能

  1. 01睡眠、准备度与活动摘要
  2. 02HRV、心率和 SpO₂ 数据
  3. 03每日统计与趋势报告
  4. 04本地 stdio 和远程 HTTP 传输
  5. 05时区感知日期与 SQLite 缓存

适用场景

  1. 01查看指定时段的睡眠与准备度
  2. 02检查心率和压力变化
  3. 03比较活动与健康趋势
  4. 04在本地或网页客户端查看 Oura 摘要

MCP 相关

向 MCP 客户端提供 Oura 数据工具,以及 `oura://today`、`oura://yesterday` 和 `oura://week` 资源。支持本地 stdio 和远程 Streamable HTTP。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"antvsl-oura": {
"command": "uvx",
"args": [
"my-oura-mcp"
],
"env": {
"OURA_CLIENT_ID": "<OURA_CLIENT_ID>",
"OURA_CLIENT_SECRET": "<OURA_CLIENT_SECRET>",
"OURA_REDIRECT_URI": "<OURA_REDIRECT_URI>",
"OURA_API_MODE": "<OURA_API_MODE>",
"OURA_TZ": "<OURA_TZ>",
"OURA_TOKEN_STORE": "<OURA_TOKEN_STORE>",
"OURA_PUBLIC_URL": "<OURA_PUBLIC_URL>",
"OURA_OAUTH_ALLOWED_REDIRECT_ORIGINS": "<OURA_OAUTH_ALLOWED_REDIRECT_ORIGINS>",
"OURA_MCP_TOKEN": "<OURA_MCP_TOKEN>"
}
}
}
}
启动命令uvx my-oura-mcp
需要配置的环境变量
OURA_CLIENT_IDClient ID of your Oura application from developer.ouraring.com
OURA_CLIENT_SECRET密钥Client secret of your Oura application
OURA_REDIRECT_URIOAuth redirect URI; must match the Oura application byte for byte
OURA_API_MODEsandbox for Oura's synthetic data (no auth needed), production for your own
OURA_TZIANA timezone deciding what counts as today. Set it explicitly on servers, whose clocks run in UTC
OURA_TOKEN_STORE密钥Where the OAuth flow stores tokens. Written by the server, not set by hand
OURA_PUBLIC_URLPublic https address, without a trailing slash. Enables OAuth 2.1 for Claude.ai and ChatGPT; leave empty for local or Bearer-token clients
OURA_OAUTH_ALLOWED_REDIRECT_ORIGINS密钥Comma-separated trusted OAuth redirect origins; defaults to Claude.ai and ChatGPT
OURA_MCP_TOKEN密钥Shared secret guarding the HTTP endpoint. Required whenever the server binds to anything other than loopback; without it the server refuses to start

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimy-oura-mcp0.4.2
ocidocker.io/iican/oura-mcp:0.4.2

工具

11

收录的工具列表 · 更新于 2 周前

参数类型必填说明
rawboolean否
end_dateany否
days_backany否
start_dateany否

详细介绍

my-oura-mcp

CI License: MIT Python 3.12+

让 Claude、ChatGPT 和 Codex 访问你的 Oura Ring 数据:睡眠、 准备度、HRV、静息心率、活动、SpO₂、压力。

问一句“我上周睡得怎么样”,你的 MCP 客户端就会调用合适的工具并 返回摘要,而不是一大段 JSON:

{
  "metric": "sleep_detail",
  "period": { "start": "2026-07-23", "end": "2026-07-29", "days": 7 },
  "stats": {
    "total_h":    { "mean": 7.1, "min": 5.9, "max": 8.4 },
    "deep_h":     { "mean": 1.3, "min": 0.9, "max": 1.8 },
    "avg_hrv":    { "mean": 42,  "min": 31,  "max": 55, "trend_per_week": 1.8 },
    "efficiency": { "mean": 88,  "min": 82,  "max": 93 }
  }
}

刚接触 MCP? Model Context Protocol 让 AI 客户端访问外部数据。 安装此服务并连接一次,然后用自然语言询问睡眠情况。 无需编写代码。

在 Claude Code 和 Codex 中可本地使用;部署到自己的服务后,也可在 claude.ai 和 ChatGPT 中远程使用。

Читать по-русски: README.ru.md

为什么还要做一个

  • 默认精简。 工具返回每天的数据值和趋势统计,而非原始 API 负载。只需设置 raw=True,即可获取原始响应。 一个月的心率数据可缩减 10 倍以上。
  • 一套代码,两种传输方式。 本地使用 stdio,远程使用 streamable-http。只需切换一个标志,无需重写。
  • 时区处理准确。 Oura 的某些端点会按内部 UTC 时间戳筛选数据,却返回本地 day 字段;心率时间戳则以 UTC 返回。这两种情况都会悄悄丢失或错置 UTC 以外的数据。本服务已处理这些问题——请参阅时区处理。
  • 应对不稳定的网络。 支持 next_token 分页,通过指数退避重试断开的连接,并将 HTTP 状态码转换为说明修复方法的消息。
  • 授权前先试用。 Oura 沙盒无需任何凭据即可使用。

快速开始

需要 uv。此步骤无需 Oura 令牌。

git clone https://github.com/AntVsl/oura_mcp && cd oura_mcp
cp .env.example .env
uv sync

检查数据是否正常流动(访问 Oura 沙盒,无需授权):

uv run python -m my_oura_mcp.smoke

在本地连接——服务会打印已填入绝对路径的命令,且不会自行写入任何内容:

uv run my-oura-mcp install

然后向客户端询问 Oura 摘要。get_status 工具会报告服务所处的模式。

工具

工具返回内容默认范围
get_daily_summary睡眠、准备度和活动评分7 天
get_sleep睡眠阶段、效率、HRV、静息 HR、呼吸、体温7 天
get_sleep_score仅每日睡眠评分——比 get_sleep 更轻量7 天
get_readiness准备度评分、HRV 平衡、体温偏差7 天
get_activity活动评分、步数、卡路里7 天
get_heartrate按分钟记录的心率汇总为每日统计3 天
get_spo2睡眠期间的血氧、呼吸紊乱指数7 天
get_stress负荷时间和恢复时间7 天
get_heart_health心血管年龄、VO₂max30 天
get_tags你在 Oura 应用中输入的标签30 天
get_status服务模式和授权状态—

每个数据工具都可使用 days_back,或指定 start_date/end_date 日期范围(YYYY-MM-DD),还可通过 raw 获取 Oura 未经处理的响应。

使用你自己的数据

沙盒会返回合成数据。要使用你自己的数据,需要一个 Oura 应用和一次性授权——无需通过审核,新建的应用即可立即使用。

操作
1在 developer.ouraring.com 注册应用
2将 OURA_CLIENT_ID 和 OURA_CLIENT_SECRET 填入 .env
3运行 uv run my-oura-mcp auth——打开浏览器,并以 600 模式存储令牌
4在 .env 中设置 OURA_API_MODE=production

注册时:重定向 URI 必须是 http://localhost:8765/callback,逐字节匹配。权限范围为 daily、heartrate、tag、spo2、stress、heart_health。其他内容可任意填写。

之后令牌会自动刷新。使用 my-oura-mcp auth --status 检查,使用 auth --logout 删除令牌。

个人访问令牌已无法使用:Oura 于 2025 年 12 月停止发放此类令牌。

刷新令牌只能使用一次。 每次刷新都会使旧令牌失效,因此两个实例共享一个令牌存储时会互相导致令牌失效。如果出现提示令牌只能使用一次的 400 错误,请重新运行 auth,并确保只运行一个实例。

配置

所有配置都放在 .env 中(参见 .env.example)。机密信息绝不会提交到 git。

变量用途
OURA_CLIENT_ID / OURA_CLIENT_SECRETOura 应用凭据
OURA_REDIRECT_URI必须与应用中的设置完全一致
OURA_API_MODEsandbox(合成数据)或 production
OURA_TZ决定“今天”含义的时区。在服务器上必须显式设置
OURA_MCP_TOKEN用于保护 HTTP 端点的共享密钥;也是授权页面的密码
OURA_PUBLIC_URL公共 https 地址。设置后,即可为 Claude.ai 和 ChatGPT 启用 OAuth
OURA_OAUTH_ALLOWED_REDIRECT_ORIGINS以逗号分隔的 OAuth 客户端来源;默认包括 Claude.ai 和 ChatGPT
OURA_TOKEN_STOREOAuth 流程写入令牌的位置。无需手动设置
OURA_CACHE_DBSQLite 缓存文件。设为空值可禁用缓存

运行

同一份代码,支持两种传输方式:在本机与客户端一起运行时使用 stdio;在服务器上运行时使用 HTTP,让网页客户端和手机都能访问。

本地运行
客户端命令
Claude Codeclaude mcp add --scope user oura -- uv --directory PATH run my-oura-mcp
Codexcodex mcp add oura -- uv --directory PATH run my-oura-mcp

运行 uv run my-oura-mcp install 会打印这些命令,并自动填入绝对路径。--scope user 使服务可从任意目录访问;不加此参数时,只能从运行命令的目录访问。使用 claude mcp list / codex mcp list 验证。

不会向外部暴露任何内容,也不会使用网络。若要调试传输本身,可运行 uv run my-oura-mcp --transport http --port 8000——在环回地址上运行无需密钥。

在服务器上

这样一来,任何设备都能访问服务器,包括 Claude.ai 和 ChatGPT。docs/DEPLOY.md(俄语)中提供了分步说明:如何放行流量、如何迁移 Oura 授权,以及如何连接网页客户端。

客户端连接方式
Claude.ai、ChatGPTOAuth。无需输入客户端 ID 或密钥——客户端会自行注册,授权页面会要求提供 OURA_MCP_TOKEN
Claude Codeclaude mcp add --scope user --transport http oura URL --header "Authorization: Bearer TOKEN"
Codexcodex mcp add oura --url URL --bearer-token-env-var OURA_MCP_TOKEN

OURA_PUBLIC_URL 会启用 OAuth:服务器将成为自己的授权服务器,并支持动态客户端注册,但仅限 https://claude.ai 和 https://chatgpt.com。其他客户端需要将其确切来源添加到 OURA_OAUTH_ALLOWED_REDIRECT_ORIGINS;在要求提供密钥之前,授权页面会显示客户端名称及其返回来源。

有两种暴露服务器的方式,选择并非无关紧要。Caddy 更简单,但其证书会进入证书透明度日志——这是一份公开日志,会暴露该地址托管了服务。Cloudflare Tunnel 则完全无需开放入站端口。如果同一台主机上运行着 VPN,就只能使用隧道。

如何选择
stdio,本地HTTP,服务器上
在此机器上使用 Claude Code 和 Codex是是
其他设备否是
Claude.ai、ChatGPT、手机否是,通过 OAuth
需要域名和主机否是
数据会离开此机器否是,传到你的服务器

确保恰好只有一个运行中的实例:Oura 的刷新令牌只能使用一次,两个共享令牌存储的服务器会相互取消授权。

时区处理

Oura 的日期语义导致了三个独立的问题,它们都会悄无声息地丢失数据,而不是报错。如果你要自行基于此 API 构建应用,值得了解:

  • sleep 和 daily_activity 按内部 UTC 时间戳筛选,而不是按 Oura 返回的 day 字段筛选。在 UTC+3 时,午夜后开始的一晚会落在前一个 UTC 日期:查询 28..28 会返回空结果,尽管 day=28 的记录明明存在。服务器会扩大时间范围,然后再按 day 筛选。已通过遍历所有端点验证;其他六个端点表现正常。
  • heartrate 返回 UTC 时间戳。 按该字符串的前十个字符分组,会将本地日期拆成两天,把本地时间 00:00–03:00 的数据推到前一天——而这恰好是你关心的静息心率。分组使用 OURA_TZ。
  • Oura 每天会返回多条睡眠记录——包括夜间睡眠和午睡。随便选一条,可能会让 12 分钟的午睡取代一整晚睡眠。标记为 long_sleep 的记录优先,否则选择时长最长的记录;午睡会单独报告为 naps_h,因此其 HRV 不会与夜间睡眠的 HRV 求平均。

安全

  • .env、令牌存储和缓存均已列入 .gitignore。提交前请检查:git status --porcelain。
  • 令牌存储和 SQLite 缓存文件仅授予所有者权限(600)。
  • HTTP 端点使用 OURA_MCP_TOKEN 进行保护,并通过恒定时间比较进行验证。访问控制模型刻意保持简单:一个密钥、一个所有者,不区分用户。
  • 如果在非环回地址上启动且未提供密钥,服务器会拒绝启动,而不会悄悄将健康数据暴露到开放互联网。试试看: uv run my-oura-mcp --transport http --host 0.0.0.0。
  • /healthz 特意保持开放——反向代理需要访问它,而且它只会返回 ok。
  • Caddy 会从日志中移除 Authorization 标头。

缓存

较早日期的数据会存入 SQLite。最近两个已完成日期的数据会在每次请求时重新检查,因为延迟同步可能会更新这些数据;更早的历史数据则直接从缓存读取,不会发起网络调用。

uv run my-oura-mcp cache --status   # what is cached
uv run my-oura-mcp cache --clear    # forget it

有三点值得注意。今天的数据从不缓存——Oura 仍在写入数据。空数据日也不会缓存:空数据日可能意味着“没有佩戴戒指”,也可能意味着“尚未同步”;第二种情况会在几小时内自行解决,而缓存的空数据则会一直保留。模式也是键的一部分,因此沙盒数据不会出现在生产环境中。

每分钟心率数据会绕过缓存:这些行没有 day 字段。

MCP 资源

支持资源的客户端可以读取 oura://today、oura://yesterday 和 oura://week。它们提供与工具相同的睡眠/准备度/活动摘要,无需手动选择参数。

附带使用配方的技能

skills/oura 提供了一个面向 Claude 的技能——不是更多工具,而是基于这些工具构建的工作流:睡眠是否真的在改善、今天是否适合承受负荷、状态不佳时身体发生了什么、日常习惯的改变是否有效。每个工作流都包含一系列调用和一种分析答案的方法,这是任何单个工具都无法实现的。

将其复制到客户端的技能目录即可安装:

cp -r skills/oura ~/.claude/skills/

测试会将配方与代码进行核对:如果某个字段名没有被任何工具返回,uv run pytest 就会报错,而不是悄无声息地让模型无所适从。

将这些仓库技能复制到 Codex 的技能目录后,Codex 也可以加载它们:

mkdir -p ~/.codex/skills
cp -R skills/oura skills/oura-mcp-maintenance ~/.codex/skills/

oura 通过 MCP 服务解读数据。oura-mcp-maintenance 则指导如何安全地修改此仓库及其 Claude/ChatGPT/Codex 集成。

遇到问题时

Claude 提示没有 Oura 工具。 服务未能连接。运行 claude mcp list 查看其状态。常见原因是使用了相对路径,但这里需要完整路径——uv run my-oura-mcp install 会打印正确的命令。

“授权未通过——没有令牌”。 服务处于 production 模式,但尚未登录 Oura。运行 uv run my-oura-mcp auth;运行 uv run my-oura-mcp auth --status 查看令牌状态。

VPS 上的服务返回 401。 OURA_MCP_TOKEN 不匹配。标头值会原样发送,因此 Bearer 一词和空格都属于值的一部分:应为 Bearer abc123,而不是 abc123。

返回的数据对应错误的日期。 未设置 OURA_TZ。服务的系统时钟几乎总是 UTC,因此“今天”会比你当地时间早或晚几个小时,夜间睡眠数据也会落在前一天。请明确设置,例如 OURA_TZ=Europe/Moscow。

“刷新令牌已被拒绝”。 Oura 的刷新令牌只能使用一次;如果第二个实例用掉了它,就会发生这种情况。确保只运行一个实例:VPS 启动后,也将本地 Claude Code 指向它。运行 my-oura-mcp auth 恢复。

对 api.ouraring.com 的请求因 SSL_ERROR_SYSCALL 或超时而失败。 通常问题不在服务端:客户端会采用退避策略重试四次。如果仍然无效,通常可以使用 VPN 解决。

claude.ai 无法连接到你的服务。 检查是否设置了 OURA_PUBLIC_URL,并确认它与连接器 URL 逐字符匹配,包括 https://,且末尾没有斜杠。启动横幅会显示 OAuth 是否已启动。除此之外,请参阅 docs/DEPLOY.md。

你在授权页面上点击“允许”后没有任何反应。 检查服务日志:如果 POST /oauth/consent 返回 303,之后却没有 POST /token,说明浏览器阻止了跳回 claude.ai 的跳转。这是 Content-Security-Policy 过于严格的表现——curl 无法复现,因为它完全不会执行 CSP 检查。

“请求已过期”/request expired。 授权请求存储在进程内存中,因此重启服务会使所有已打开的授权页面失效。问题不在密钥——返回 claude.ai 并重新开始连接即可。

开发

uv run pytest

测试不会访问网络;Oura 的响应由 respx 模拟。 工具测试通过 mcp.call_tool() 运行,而不是直接调用函数——有些 bug 只有在真实协议层才会出现,因为 MCP 客户端会将声明的默认值作为显式参数传递。

对于 Codex 和其他编码 Agent,仓库说明以及任务/审查结构见 AGENTS.md 和 docs/agents。

x86_64 macOS: cryptography 49+ 不为此平台提供 wheel,并会尝试从 Rust 源码构建。pyproject.toml 专门为此固定使用 48.0.0;Linux 和原生 arm64 不受影响。Apple Silicon 用户也可能遇到此问题:如果 Homebrew 安装在 /usr/local 而非 /opt/homebrew,就会触发——使用 file $(which python3) 检查。

网络不稳定: 如果对 api.ouraring.com 的请求因 SSL_ERROR_SYSCALL 失败或超时,问题通常不在服务端。客户端会通过退避机制尝试四次;若仍不行,请尝试使用 VPN。

请参阅 docs/ROADMAP.md,了解计划内容以及有意推迟的事项。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。