关于 oura-mcp
oura-mcp 通过六种只读工具向 MCP 客户端提供 Oura v2 健康数据。它会处理分页和日期范围差异,并报告无效字段,避免静默返回不完整结果。
主要功能
- 01查询全部 19 个 Oura 数据集合
- 02返回结果前获取所有分页
- 03统一处理包含首尾日期的范围
- 04报告被忽略或不支持的查询选项
- 05比较时段并关联指标变化
适用场景
- 01查看睡眠和每日准备度记录
- 02获取日期范围内完整的心率数据
- 03检查两个时段的变化是否超出正常波动
MCP 相关
向 MCP 客户端提供六种只读工具,用于浏览 Oura 数据集合、查询健康记录、检查服务状态,以及比较或关联指标。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx mcp-ouraOURA_SANDBOXSet to 1 to use Oura's official synthetic data with no credentials. The recommended way to try the server before authenticating.OURA_CLIENT_IDclient_id of your Oura application, for OAuth2. Register one at https://cloud.ouraring.com/oauth/applications with the redirect http://localhost:9876/callback/ (the trailing slash is required).OURA_CLIENT_SECRET密钥client_secret of your Oura application. Only needed when running `oura-mcp --authorize` and when refreshing the token.OURA_CREDENTIALS密钥Where the OAuth2 credentials file lives. Defaults to ~/.config/oura-mcp/credentials.json, mode 600.OURA_PAT密钥Oura Personal Access Token. Only if you already had one: Oura stopped issuing them in December 2025.OURA_PAT_FILEPath to a file holding the personal token. Preferable to OURA_PAT: an MCP server is registered in a JSON that gets backed up and shared when asking for help; a separate file rotates without touching the config.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
6收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
oura-mcp
English | 简体中文 | 한국어 | Español
将 Oura v2 API 封装为 MCP 服务。涵盖全部 19 个集合,提供 6 个工具,除 MCP SDK 外没有其他依赖。
本地一天的心率数据有 1,231 条样本,分布在 2 页中
不跟随 Oura 的 next_token 的客户端会返回 其中 1,000 条——占 81%,看起来完整,却没有任何提示说明数据不全。 该数据于 2026 年 8 月 9 日对照真实 API 测得,来自一人、一只戒指、24 小时的数据。
**适用于任何 Oura MCP 服务(包括本服务)的测试标准:**它是否将
next_token——或 cursor、limit——作为工具参数?如果是,分页就成了模型的工作;如果模型忘记再次请求,就会基于不完整的数据给出自信的回答。本服务会在返回结果前完成所有分页,并告知所需页数。
这是 Oura 在不作提示的情况下返回不完整数据的 四 种情形之一。以下列出了全部四种情形的测量结果,并在此一一修正。
安装
从最新版本下载 oura-mcp.mcpb,
然后双击即可。Claude Desktop 会处理剩下的事情——无需终端、Python 或 Node。
开箱即用的情况下,它使用 Oura 官方样例数据运行,并且每条样例响应都会明确说明,因此不会被误认为是你自己的睡眠数据。
更喜欢使用命令行?uvx --from mcp-oura oura-mcp。
完全不想在机器上安装 Python?
docker run -i --rm -e OURA_SANDBOX=1 ghcr.io/proscar87/oura-mcp
-i 不是可选项:MCP 服务通过 stdin 和 stdout 通信,而不是通过端口通信。没有它,容器就没有 stdin,无法收到握手请求,客户端会报告服务未出现。
在浏览器中使用 claude.ai 或 ChatGPT?它们通过 URL 连接,因此服务必须部署在公网上:在你自己的 Cloudflare 账户中将其部署为 Worker——免费,大约需要 10 分钟,且仅供你使用。请参阅 远程服务:claude.ai 和 ChatGPT。
问题,实测结果
Oura 无法提供你所请求的数据时,并不会返回错误,而是返回其他内容,并将其包装成看似正确的响应。以下是我们于 2026 年 8 月 9 日对照真实 API 测量发现的四种情形:
1. 跳过分页,得到的数据就不完整
{ "data": [ ... ], "next_token": "eyJ0eXAiOi..." }
如果返回了 next_token,而你没有继续请求,就只会收到第一页,没有任何提示告诉你数据不全。本地一天的 heartrate 数据——一人、一只戒指、24 小时——共有 1,231 条样本,分布在 2 页中。不进行分页的客户端会得到 1,231 条中的 1,000 条:占 81%,看起来完整。一个月的数据约有 37,000 条。
2. 请求单日数据却返回零条记录
end_date 在不同集合中的行为并不一致:
| 不包含请求的最后一天 | 包含请求的最后一天 |
|---|---|
daily_activity、sleep、workout | daily_sleep、daily_readiness、daily_stress、daily_spo2、daily_resilience、daily_cardiovascular_age、sleep_time |
此外,workout 按 UTC 日期筛选,而报告中的 day 使用本地时间:在 -06:00 时区,请求 7 月 16 日至 18 日的数据,却返回了 15 日和 16 日的记录——早于请求的开始日期。
这里的日期范围始终包含两端。我们会在范围两侧各多请求两天,然后再筛选数据;无论特定集合的行为如何,这种做法都正确,而且 Oura 修改行为后仍然适用。
3. latest=true 在不适用的地方会被忽略
只有 heartrate 和 ring_battery_level 会遵循它。在其他 17 个集合中,Oura 不会报错:它会返回整个集合。你只请求最新记录,结果却拿到 10 条,还以为只有 1 条。此处会在发出请求前拒绝该参数。
4. 不存在的字段会被静默忽略
fields=does_not_exist 会返回完整记录——字段筛选根本没有生效;而 fields=score,does_not_exist 会应用有效字段,悄悄丢掉无效字段。此处从未出现过的字段会列在 ignored_fields 下。
**情况总是一样:**你要的是一回事,得到的却是另一回事,而且没有任何提示。这就是为什么这个包宁可大声提醒,也不愿悄悄少提供数据。
安装
无需凭据即可试用
pip install mcp-oura
OURA_SANDBOX=1 oura-mcp --check
这个沙盒是官方的——它包含在 Oura 的 OpenAPI 规范中,有 34 个镜像路由——并且无需身份验证即可提供合成数据。19 个集合中有 18 个可以使用:personal_info 不行,这也合情合理,因为它会返回电子邮件、年龄、体重和身高。
正确的顺序是:先观察服务运行并了解数据结构,再去获取凭据。
使用你自己的数据
**Oura 已于 2025 年 12 月停止发放 Personal Access Token。**现有令牌仍可使用,但无法创建新令牌。因此有两种途径:
**a) OAuth2——目前可用的方式。**在
cloud.ouraring.com/oauth/applications
注册应用,重定向地址填写 http://localhost:9876/callback/——末尾的斜杠是必需的,否则门户会以 invalid_redirect_uri 拒绝。
如果你是在
developer.ouraring.com上注册的,你的应用属于 Oura 的新门户,其令牌端点也不同。旧版端点会在每次刷新时拒绝这些应用——因此注册只会成功一次;等第一个访问令牌过期后,就会一直失败,而且没有任何说明。此服务会先尝试旧版端点,失败后自动切换到新版端点;无论哪种情况,都无需配置。
export OURA_CLIENT_ID="…"
export OURA_CLIENT_SECRET="…"
oura-mcp --authorize # opens the browser, waits for the callback
oura-mcp --authorize --manual # headless machines: you paste the URL back
令牌会以 600 权限模式存储在 ~/.config/oura-mcp/credenciales.json 中——如果你恰好安装了 keyring,也可以存入系统密钥链;但它不是此包的依赖项——并且会自动刷新。oura-mcp --forget 会将其删除。
b) 个人令牌,适用于你已经拥有令牌的情况。
export OURA_PAT="your-token"
oura-mcp --check
--check 用于自检:它会报告你正在使用哪种凭据、授予了哪些作用域,以及访问令牌还剩多长时间,但不会返回令牌或任何健康数据。它会报告令牌的长度,而不是令牌本身。错误消息会被复制并粘贴到聊天和问题反馈中;它们不该包含任何其他内容。
将其连接到 Claude Code
安装此包后(pip install mcp-oura):
claude mcp add -s user oura --env OURA_SANDBOX=1 -- oura-mcp
运行 oura-mcp --authorize 后,即可移除 OURA_SANDBOX。
如果你使用 uv,无需永久安装任何内容:
claude mcp add -s user oura --env OURA_SANDBOX=1 -- uvx --from mcp-oura oura-mcp
必须使用 --from,因为发行包名称是 mcp-oura,而可执行文件名称是 oura-mcp。(这需要 uv;如果没有它,上面的命令会因“找不到命令”而失败,此时应使用 pip install。)
作为 Claude Code 插件:
claude plugin marketplace add proscar87/oura-mcp
claude plugin install oura@oura-mcp
连接到 Claude Desktop
一键安装: 从
发布页面下载 oura-mcp.mcpb 并双击。
Claude Desktop 会安装它——无需终端、JSON 或 Python。它默认启用示例数据,因此即使你还没有任何凭据,也能正常运行。
想使用自己的数据时,只需向它提出请求:它会通过 Claude 打开 Oura 的授权页面,等待回调,然后重试你的请求。无需终端。这之所以可行,是因为 MCP 专门为此提供了一种模式——URL 引导,而由客户端负责打开页面。
Oura 仍然要求每个应用都必须注册,因此你需要从
cloud.ouraring.com/oauth/applications
获取一次 client ID 和 secret。这是 Oura 的规定,不是此服务的规定。oura-mcp --authorize 仍供终端用户以及无法显示 URL 的客户端使用。
**或者手动配置,**编辑 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"oura": {
"command": "/full/path/to/oura-mcp",
"env": { "OURA_SANDBOX": "1" }
}
}
}
which oura-mcp 会给出完整路径。Claude Desktop 不会继承终端的 PATH,因此在这里仅填写程序名会静默失败——这是配置 MCP 服务时最常见的错误之一。
远程连接:claude.ai 和 ChatGPT
实验性功能。 已在 Cloudflare 的真实运行环境中使用 Oura 示例数据完成端到端测试,也已使用 Oura 的模拟版本测试其登录流程,但尚未在真实部署、真实 Oura 账户或 claude.ai 和 ChatGPT 上完成连接测试。如果你尝试了,欢迎提交 issue 说明结果。
claude.ai 从 Anthropic 的云端访问连接器,ChatGPT 则从 OpenAI 的云端访问,而不是从你的电脑访问,因此你电脑上的服务对它们都不可见。
ts/worker 是同一服务的 Cloudflare Worker 版本,由你部署在自己的账户中,且仅供你自己的 Oura 账户使用。没有人运行共享实例,因此你的令牌和数据不会经过任何其他人。
它增加了本地服务不需要的三项功能:自己的同意页面,用于显示哪个应用正在请求访问,以及结果将发送到哪里;在 Oura 登录后检查账户是否为你配置的账户——其他人都会被拒绝,如果未配置所有者,则任何人都无法访问;以及一个统一的位置,用于续期 Oura 只能使用一次的刷新令牌,并且一次处理一个请求。
逐步部署说明,以及具体哪些内容已验证、哪些尚未验证,请参阅: ts/worker/README.md。
工具
oura_collections | 全部 19 个集合、每个集合包含的内容及其接受的参数 |
oura_query | 完整查询某个集合,覆盖指定范围并翻页至末尾 |
oura_today | 昨晚的睡眠和今天的准备度,以及此前的几天 |
oura_compare | 判断两个时段的差异是否超过该指标自身的波动范围 |
oura_relate | 判断两个指标的日间变化是否存在超出偶然程度的联动 |
oura_check | 不泄露任何信息的自检 |
六个,而不是十九个。 如果每个集合都对应一个工具,模型在了解各集合内容前,就得先从 19 个相似的名称中作出选择。在这里,集合是一个参数,需要时再查询目录。
这六个工具都声明为只读,但这并非一句空话:整个软件包中没有任何 POST、PUT 或 DELETE,并且有一项测试会读取源代码,确保这一点始终成立。
oura_today 是唯一一个为了方便而非正确性而存在的工具:“我睡得怎么样?”需要今天的两条记录以及足够的历史数据来判断它们是否反常;原本这需要进行四次往返,也有四次可能提前停止。它不做任何计算——没有平均值、没有差值,也不会说“你的 HRV 上升了 12%”。它返回原始数据,比较则在可以引用方法的地方进行。根据九年的真实数据,连续测量值之间的变化有四分之三落在该指标自身的正常波动范围内,因此,脱离这一背景给出百分比,只会凭空制造信号,而非如实报告信号。它唯一的参数是 days,取值范围为 1 至 30,默认值为 7。
示例
以下示例均于 2026 年 10 月 8 日使用 Oura 的示例数据(OURA_SANDBOX=1)运行。响应内容有所删节;每条沙盒响应还会包含 synthetic,说明这些数字并非来自你的数据。
1. “它能正常工作吗?” → oura_check
{"mode": "sandbox", "data": "synthetic, from Oura, not yours", "oura_responds": true,
"unavailable_in_sandbox": ["personal_info"],
"next_step": "drop OURA_SANDBOX and set your own credential to see your data"}
2. “我昨晚睡得怎么样,今天的准备度如何?” → oura_today
原始返回昨晚的 daily_sleep、今天的 daily_readiness,以及此前 7 天的数据。响应中会明确说明:"computed": "raw records only: this call computed no average, no delta and no trend."
3. “你能在我的 Oura 数据中看到什么?” → oura_collections
全部 19 个集合,以及每个集合包含的内容和数据形态:
"daily_sleep": {"shape": "date_range", "carries": "sleep score and its contributors"}, …
4. “给我看看最近三晚的睡眠评分” →
oura_query(collection="daily_sleep", start=…, end=…)
{"collection": "daily_sleep", "n": 3, "pages": 1,
"data": [{"day": "2026-10-05", "score": 80, "contributors": {…}}, …],
"discarded_out_of_range": "3 record(s) from the ±2-day safety margin were trimmed. This is normal and nothing you asked for is missing: …"}
pages 统计的是一直翻到末尾的页数。范围两侧各额外包含的两天,是为了让每个集合中的日期范围都保持首尾包含;响应会说明这些日期已被裁剪,而不会对此含糊其辞。
5. “我最近两周的睡眠有改善吗?” →
oura_compare(metric="daily_sleep.score", a_start=…, a_end=…, b_start=…, b_end=…)
{"period_a": {"n": 14, "mean": 76.5}, "period_b": {"n": 14, "mean": 76.5},
"difference": 0.0, "noise_band": 2.823, "verdict": "within_noise",
"reading": "The difference (0) is inside what this metric does on its own over periods this long (±2.823). It is not evidence of a change — and with these days, a real change smaller than 2.823 would be missed more often than seen."}
6. “我的步数会影响次晚的睡眠吗?” →
oura_relate(x="daily_activity.steps", y="daily_sleep.score", start=…, end=…, lag=1)
{"lag": 1, "pairs": 118, "verdict": "cannot_tell",
"reading": "These days give 4.852 effective pairs of day-to-day changes, and at least 20 are needed. …"}
Oura 的示例数据重复一个短周期模式,因此在 118 天的数据中,有效配对少于五组。真实数据通常需要约三个月。
oura_compare:唯一的计算及其方法
“我停止饮酒后,HRV 有所上升吗?”这是人们真正会提出的问题,而直接给出两个平均值会得出错误答案:每日指标会自行波动,而且一个好夜晚往往会接着一个好夜晚,因此教科书式的比较约三分之一的时间会把普通噪声判作变化(实测:在这些指标通常具有的自相关程度下为 34–38%)。
oura_compare 接受一个 metric——collection.field,例如
daily_readiness.score、sleep.average_hrv 或 daily_activity.steps——以及两个时间段:a_start/a_end 和 b_start/b_end。它会给出两个均值、差值,以及该指标在这么长的时间段内自行波动的范围;此范围根据你之前 120 天的数据测量,并针对日与日之间的依赖性进行校正。随后给出以下三种结论之一:
outside_noise— 差值超出波动范围。数值水平不同;但这并不说明原因,也不代表这种差异会持续。within_noise— 差值没有超出范围。这并不表示“没有变化”:对于这些天的数据,若真实变化小于该范围,漏掉它的概率会高于发现它的概率,响应会说明这一点。cannot_tell— 某个时间段内少于 7 天有有效值,或用于测量波动范围的历史数据少于 60 天,或指标从未波动——Oura 的示例数据就属于这种情况。不会臆测波动范围。
此方法是通过模拟选定的,而非预先决定的:使用根据你的历史数据估算的波动范围和 t 临界值,在所有测试过的自相关程度下,噪声被判作变化的概率最高约为二十分之一,测试套件也确保了这一点。当天数据尚在累积,因此不纳入计算。sleep 使用每天时长最长的主要睡眠,响应会说明这一规则。提出多次比较并保留其中超过阈值的一次,会因偶然而找到一个超过阈值的结果——响应也会说明这一点。
当被问及某项指标是否呈趋势时,服务会告诉模型比较时间窗口的前半段和后半段。针对该方法进行模拟的专门斜率检验,发现的趋势只多出少数几个点,而且仅适用于 60–90 天的时间窗口(tools/trend_study.md),因此没有趋势工具。
oura_relate:相关性,以及排除可能造成误导的情况
“高强度训练日会让次日早晨的 readiness 降低吗?”将两列数据进行相关性分析,会因两种常见情况得出错误答案:两项指标都在周末上升时,即使彼此毫无关系也会呈现相关性;两项指标都在数月间缓慢变化时也是如此。在不相关的模拟指标上进行测量时,若指标共享每周节律,简单相关性有 41–93% 的概率将它们判为相关;若共享趋势,则有 58% 的概率。
oura_relate 接受两个指标 x 和 y、一个范围 start/end,以及以天为单位的 lag(0–7)。它会从每项指标中扣除各自每个星期几的常见水平,只比较连续两天之间的日间变化,根据自相关校正配对数量,并返回相关性、95% 区间以及同样的三种结论。所有模拟的无相关情形——每周节律、随机游走、共享趋势、30% 的日期缺失——误报率都保持在约 5%(实测最高为 5.2%)。
- 滞后由你选择,且只能选一次。 Oura 会将一晚的睡眠和次日早晨的 readiness 记在醒来的日期下,因此某日的活动与之后的睡眠对应时,
lag=1。first_pair会显示哪一天与哪一天配对,从而让错误的对齐方式一目了然。尝试多个滞后值就相当于进行多次检验;而且由于该方法处理的是变化,一个滞后值下的真实相关性也会以相反方向出现在相邻滞后值下——响应会同时说明这两点。 - 大约需要三个月的数据。 有效配对少于 20 组时,结果为
cannot_tell;日期存在缺口时,则需要更长的时间范围。 - 它衡量的是共同变化,而非因果关系或变化方向。 其他因素可能同时影响两者,响应每次都会说明这一点。
oura_query 参数
collection | 19 个集合之一。oura_collections 列出了它们 |
day | 单日。是 start=end=day 的简写 |
start、end | 日期范围,包含起止两天 |
fields | 仅返回这些字段。Oura 会在其端进行裁剪,因此返回的数据更少 |
latest | 最新记录。仅适用于 heartrate 和 ring_battery_level |
format | json 或 csv。节省幅度因集合而异:heartrate 为 55%,daily_sleep 为 10% |
如果响应数据不完整,以下字段会说明原因:
truncated 会通过 continue_from 指明已到达的最后一天;Oura
重复令牌时会返回 pagination_cycle;此外还有 ignored_fields、
discarded_out_of_range、uneven_columns、查询结果为空时的 empty,
以及返回的数据量大到值得注意时的 large_response。
还有四个字段会说明一些你原本无从得知的情况:
synthetic— 这是 Oura 的样例数据,不是你的数据。扩展以样例模式发布,因此每个响应都会带上这个字段,避免模型把虚构数字说成你的睡眠数据。rate_limited— Oura 返回了 429,但重试成功。数据是完整的;警告针对的是下一次查询。Oura 不会在成功响应中发送速率限制标头,因此遭到拒绝是唯一能表明你已接近上限的信号。fields_split—fields以"day,score"而不是["day","score"]的形式传入,因此被拆分了。Oura 的字段名称都不含逗号,所以拆分没有歧义;但悄悄重新解释你的输入,正是这个包一直想避免的问题。cached— 答案来自本次会话的内存,而不是 Oura。仅当日期范围在今天之前结束时才会出现,因为已经结束的一天不会再增加记录;今天的数据绝不会缓存,因为戒指会随时同步。空答案也绝不会缓存——我们无法区分“没有数据”和“戒指尚未同步”,如果把后者冻结下来,就会把暂时的空缺变成永久空缺。数据只存在内存中,并随进程结束而消失:绝不会将健康数据写入磁盘。
最后一点源于实际测量:30 天的 daily_activity 有 252,000 个字符,其中 87% 都是单个字段 met,即每分钟一条的 MET 序列。用 fields 请求三列,返回的同样 30 天数据只有 5,000 个字符——减少 99%。服务不会自行裁剪数据——那会导致返回不完整——但会指出哪些数据量大,以及如何减少返回量。
(参数名称保持稳定,并在此处记录;模型读取的工具说明也包含相同信息。参数名称在 0.2.0 及之前的版本中使用西班牙语;0.3.0 改为英文,并在 CHANGELOG 中记为一项破坏性变更。)
此服务不做什么
除 oura_compare 和 oura_relate 外,它不做分析。 不分析趋势、不检测异常、不提供建议——而这些恰恰是其他服务提供价值的地方。
原因是:在这里计算出的平均值传给模型时,只是一个数字,没有附带计算方法。基于九年的真实数据,每两次连续测量之间的变化,有四分之三落在该指标本身的正常波动范围内。如果服务只告诉你“你的 HRV 上升了 12%”,却不说明该指标自身的波动幅度,那不是在提供信息,而是在制造信号。
oura_compare 和 oura_relate 的存在,就是为了正面回应这一问题:它们会连同数字一起给出范围。趋势分析目前还没有一种能经受同样模拟检验的方法——对自相关的日数据计算斜率,是最容易制造信号的做法——所以这里不提供趋势分析。
其他内容都以原始数据形式提供。分析应当放在可以引用计算方法的地方——例如 cotejo,它对血液生物标志物正是这样处理的。
19 个集合
每日摘要 — daily_sleep、daily_readiness、daily_activity、
daily_stress、daily_spo2、daily_resilience、daily_cardiovascular_age、
vO2_max
分数背后的详细信息 — sleep(阶段、HRV、温度、入睡潜伏期)、
sleep_time、workout、session、rest_mode_period、tag、enhanced_tag
高分辨率数据 — heartrate、ring_battery_level
无日期范围 — personal_info、ring_configuration
日期范围集合使用 YYYY-MM-DD。heartrate 和 ring_battery_level
使用带时间的 ISO 8601 格式。
其他 Oura MCP 服务
截至 2026 年 8 月,这类服务已有多个,准确说明它们之间的差异很重要。benngermin/oura-mcp
支持正确分页,并提供可恢复的游标。
daveremy/oura-mcp 在我们修复的同一周也发布了
end_date 修复。
davidmosiah/oura-mcp 提供了最完整的 MCP 接口。分页已不再能区分各家服务。
据我们所能核实,真正能体现差异的是:它们都没有说明 workout 的 UTC 时差问题,也没有说明在 Oura 忽略 latest 时拒绝该参数的行为,或对从未生效的字段发出警告。它们也都没有把“不进行分析”作为明确立场。
隐私政策
本节之所以存在,是因为 Claude 连接器目录要求提供隐私政策。内容很简短,因为可说明的事项不多:服务在你的计算机上运行,只与一个服务 Oura API 通信。
收集的信息。 我们不收集任何信息。你请求的健康数据从 Oura API 传送到你的 MCP 客户端,不会经过我们的任何服务,因为我们没有这样的服务。
存储的内容及其位置。 仅有你的凭据,而且只存储在你的计算机上:
| OAuth2 令牌 | ~/.config/oura-mcp/credenciales.json,权限模式为 600 — 如果你安装了 keyring,则存储在系统密钥链中 |
| 个人令牌 | 由你决定存放位置:OURA_PAT,或 OURA_PAT_FILE 指向的文件 |
不会将任何健康数据写入磁盘;缓存正是围绕这一限制设计的,而不是事后才提出这种说法。已结束日期的数据仅保存在内存中,且只在进程运行期间保留;--forget 会清除这些数据。服务退出后,你的睡眠数据不会留下任何痕迹。
**如果你部署远程 Worker,**情况相同,但有一点不同:它运行在你的 Cloudflare 账户中,而不是你的计算机上,因此你的 Oura 令牌会存放在那里 — 在 Durable Object 中;应用的令牌则经过哈希处理后存入 KV,并对其携带的内容进行加密。健康数据仍然绝不会被存储:每次收到请求时才会获取,并且只保存在 Worker 的内存中。只有你能操作它。详情:ts/worker/README.md。
共享对象。 没有任何对象。唯一的出站连接是连接到 api.ouraring.com,并使用你的令牌获取你所请求的内容。Oura 对你数据的使用受其隐私政策约束,而非本政策。
保留期限。 凭据会一直保留,直到你将其删除:运行
oura-mcp --forget,或移除相应文件。健康数据完全不会保留 — 它只存在于响应中,仅此而已。
诊断不会泄露任何信息。 oura_check 会报告令牌长度,但绝不会报告令牌本身;会报告个人资料的字段名称,但绝不会报告字段值。令牌被封装在一种类型中,即使在堆栈跟踪中也不会打印出来。
联系方式。 仓库问题。
关于语言的说明
该代码库使用英语:代码、注释、测试以及内部文档(AGENTS.md、ROADMAP.md、CHANGELOG.md)均为英文。
在 0.2.0 及之前的版本中,它使用西班牙语编写。0.3.0 中重命名了工具参数,这是一次破坏性更改,并已在 CHANGELOG 中记录;随后,正文也改成了英文。仍然使用西班牙语的内容都是存储键,不能重命名,否则会导致有人已保存的凭据失效;对此有一个测试,其名称明确说明了这一点。
许可证
MIT。
mcp-name: io.github.proscar87/oura-mcp
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。