内容
# Oura Ring MCP 服务器
[](https://dotnet.microsoft.com/download/dotnet/10.0)
[](https://modelcontextprotocol.io/)
[](https://developer.ouraring.com/)
[](https://www.nuget.org/packages/gjlumsden.OuraMcp)
[](LICENSE)
一个 **.NET 10 MCP 服务器**,用于公开 [Oura Ring](https://ouraring.com/) 的健康和健康数据,作为 [Model Context Protocol](https://modelcontextprotocol.io/) 工具,供 AI 助手使用。
> **免责声明:** 这是一个独立开发的开源项目。它与 Ōura Health Oy 无关联、未获得其认可或赞助。"Oura" 和 "Oura Ring" 是 Ōura Health Oy 的商标。该项目使用 [Oura API v2](https://developer.ouraring.com/) 但不由 Oura 维护或支持。有关官方 Oura 支持,请访问 [ouraring.com](https://ouraring.com/)。
## 概述
该服务器连接到 **Oura API v2** 并将戒指数据(睡眠、活动、准备就绪、心率等)作为 MCP 工具通过 **STDIO 传输**公开。身份验证在 **首次启动时自动进行**:服务器在首次启动时打开浏览器进行 Oura 授权,令牌本地持久化以便静默重用和刷新。还提供显式的 `oura-mcp login` 命令,用于无头或预先设置的场景。
## 入门指南
### 先决条件
- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0)
- 在 <https://developer.ouraring.com/> 注册的 Oura API 应用程序(重定向 URI:`http://localhost:8742/callback/`)
### 1. 安装
```powershell
dotnet tool install -g gjlumsden.OuraMcp
```
### 无需安装选项
或者在不安装的情况下运行(需要 .NET 10):
```powershell
dnx -y gjlumsden.OuraMcp
```
### 2. 配置您的 MCP 客户端
将服务器添加到您的 MCP 客户端配置中。客户端通过 STDIO 启动服务器进程,并将您的 Oura 凭证作为环境变量注入。**服务器启动时,它将自动打开浏览器以授权 Oura** - 不需要单独的登录步骤。然后,令牌保存在 `~/.oura-mcp/tokens.json` 中,并在后续启动时重用/刷新。
**VS Code(GitHub Copilot)** - 添加到 `.vscode/mcp.json` 或用户设置:
```json
{
"mcpServers": {
"oura": {
"command": "oura-mcp",
"env": {
"OURA_CLIENT_ID": "<your-client-id>",
"OURA_CLIENT_SECRET": "<your-client-secret>"
}
}
}
}
```
**Claude Desktop** - 添加到 `claude_desktop_config.json`:
```json
{
"mcpServers": {
"oura": {
"command": "oura-mcp",
"env": {
"OURA_CLIENT_ID": "<your-client-id>",
"OURA_CLIENT_SECRET": "<your-client-secret>"
}
}
}
}
```
<details>
<summary><strong>使用无安装(dnx)选项?</strong></summary>
用以下内容替换服务器条目:
```json
{
"mcpServers": {
"oura": {
"command": "dnx",
"args": ["-y", "gjlumsden.OuraMcp"],
"env": {
"OURA_CLIENT_ID": "<your-client-id>",
"OURA_CLIENT_SECRET": "<your-client-secret>"
}
}
}
}
```
</details>
<details>
<summary><strong>是否更喜欢预先登录(无头/CI)?</strong></summary>
您可以在将服务器连接到 MCP 客户端之前,通过运行 `login` 子命令显式验证:
```powershell
$env:OURA_CLIENT_ID = "<your-client-id>"
$env:OURA_CLIENT_SECRET = "<your-client-secret>"
oura-mcp login # 或:dnx -y gjlumsden.OuraMcp -- login
```
令牌保存在 `~/.oura-mcp/tokens.json` 中;后续服务器启动将跳过浏览器提示。您还可以传递 `--no-login` 给 `oura-mcp` 以抑制启动时的自动登录提示(如果令牌是单独配置的)。
</details>
### 3. 开始使用
配置完成后,您的 MCP 客户端将自动发现 Oura 工具。尝试以下提示:
- *"昨晚我睡得怎么样?*"
- *"显示我过去一周的准备就绪分数*"
- *"我的静息心率趋势这个月怎么样?*"
- *"比较我过去 2 周的深度睡眠和 REM 睡眠*"
- *"我的 VO2 最大值和心血管年龄是多少?*"
- *"我这周有多紧张?*"
- *"显示我的 SpO2 趋势 - 有什么问题吗?*"
- *"我这周什么时候锻炼了,消耗了多少卡路里?*"
## 与其他 MCP 工具结合使用
真正的强大功能是将 Oura 数据与其他 MCP 服务器结合使用。例如,与 [WorkIQ](https://github.com/microsoft/work-iq-mcp)(Microsoft 365 Copilot):
- *"查看我上周的会议并与我的压力水平相关联*"
- *"哪些天我会议最多?它如何影响我的睡眠?*"
- *"我星期五压力很大 - 那天我的日程中有哪些会议?*"
- *"比较我在会议繁忙的日子和专注日子的准备度评分*"
与 [Azure MCP 服务器](https://github.com/Azure/azure-mcp):
- *"我本周值班 - 显示我的睡眠质量和准备度,以便我知道自己是否适合响应事件*"
与 GitHub MCP:
- *"显示我的提交活动和每日活动评分 - 我在精力充沛的日子里编码更多吗?*"
任何 MCP 兼容工具都可以组合使用 - AI 助手会自动连接数据源。
## 可用工具
| 工具 | 描述 |
|------|-------------|
| `get_personal_info` | 从 Oura Ring 帐户检索个人信息。 |
| `get_ring_configuration` | 从 Oura Ring 检索戒指配置详细信息。 |
| `get_daily_sleep` | 从 Oura Ring 检索每日睡眠评分和摘要。 |
| `get_sleep_periods` | 从 Oura Ring 检索详细的睡眠周期数据。 |
| `get_sleep_time` | 从 Oura Ring 检索推荐的睡眠时间窗口。 |
| `get_daily_activity` | 从 Oura Ring 检索每日活动评分和步数。 |
| `get_workouts` | 从 Oura Ring 检索锻炼数据。 |
| `get_sessions` | 从 Oura Ring 检索会话数据,例如冥想和呼吸练习。 |
| `get_daily_readiness` | 从 Oura Ring 检索每日准备就绪评分。 |
| `get_daily_stress` | 从 Oura Ring 检索每日压力数据。 |
| `get_daily_resilience` | 从 Oura Ring 检索每日恢复力数据。 |
| `get_rest_mode_periods` | 从 Oura Ring 检索休息模式周期数据。 |
| `get_heart_rate` | 从 Oura Ring 检索心率数据。 |
| `get_daily_spo2` | 从 Oura Ring 检索每日 SpO2 血氧数据。 |
| `get_vo2_max` | 从 Oura Ring 检索 VO2 最大估计值。 |
| `get_cardiovascular_age` | 从 Oura Ring 检索心血管年龄估计值。 |
| `get_tags` | 从 Oura Ring 检索标签。 |
| `get_enhanced_tags` | 从 Oura Ring 检索增强标签。 |
大多数日期范围工具接受可选的 `startDate` 和 `endDate` 参数(格式:`YYYY-MM-DD`)。
> **注意:** HRV(心率变异性)数据嵌入在 `get_sleep_periods` 响应中 - 在 Oura API v2 中没有单独的 HRV 端点。
## 身份验证流程
该服务器使用 **`az login` 样式的 OAuth 身份验证** 模式,类似于 [Azure MCP 服务器](https://github.com/Azure/azure-mcp),集成到主要的 MCP 体验中:
1. **自动首次启动:** 当服务器启动且没有令牌时,它会在正常启动过程中打开浏览器到 Oura OAuth 同意屏幕 - 不需要单独的命令。传递 `--no-login` 以抑制此行为,如果您单独配置令牌。
2. **显式登录(可选):** 您可以仍然运行 `oura-mcp login`(或 `dnx -y gjlumsden.OuraMcp -- login` 用于无安装选项,或 `dotnet run --project src/OuraMcp -- login` 从源代码)以预先身份验证(例如,无头设置,CI)。
3. **令牌交换:** 授权后,本地回调服务器在 `http://localhost:8742/callback/` 接收授权代码并交换访问/刷新令牌。
4. **持久存储:** 令牌保存在 `~/.oura-mcp/tokens.json` 中(Unix 上文件权限仅限所有者)。
5. **自动刷新:** 在后续启动时,服务器加载保存的令牌并在过期时自动刷新。
OAuth 凭证 (`OURA_CLIENT_ID`, `OURA_CLIENT_SECRET`) 从环境变量中读取 - 永远不会存储在源代码中。
### 无头/CI:`OURA_MCP_DISABLE_BROWSER`
对于完全无头的环境(CI 代理,没有显示的容器),您可以设置 `OURA_MCP_DISABLE_BROWSER` 环境变量。当设置时:
- 服务器跳过启动系统浏览器并跳过绑定本地 OAuth 回调侦听器在 `http://localhost:8742/callback/`。
- 交互式登录流程在此模式下无法完成,因此服务器 **快速失败** 并出现清晰的错误,而不是挂起等待回调。
将 `OURA_MCP_DISABLE_BROWSER` 与 `--no-login` 结合使用,并单独配置令牌(例如,将另一个机器上生成的 `tokens.json` 复制到令牌目录中)。要运行交互式 `oura-mcp login` 流程,请保持 `OURA_MCP_DISABLE_BROWSER` 未设置。
## 开发
要贡献或从源代码运行:
```bash
git clone https://github.com/gjlumsden/oura-mcp.git
cd oura-mcp
dotnet build
dotnet test
```
```powershell
# 设置 OAuth 凭证
$env:OURA_CLIENT_ID = "<your-client-id>"
$env:OURA_CLIENT_SECRET = "<your-client-secret>"
# 在本地运行 MCP 服务器(STDIO)- 首次启动时自动打开浏览器
dotnet run --project src/OuraMcp
# 或预先显式身份验证(可选;适用于无头场景)
dotnet run --project src/OuraMcp -- login
```
## 缓存
服务器包含 **内存缓存** 以减少会话内冗余的 Oura API 调用。当 AI 助手使用相同参数调用相同的工具时,返回缓存数据而不是再次命中 API。
缓存 **仅限内存** - 它在服务器进程重启时自动清除。不同的日期范围独立缓存。
| TTL | 端点 | 原因 |
|-----|-----------|-----------|
| **60 分钟** | 个人信息,戒指配置 | 很少更改 |
| **15 分钟** | 睡眠,准备就绪,睡眠周期,睡眠时间 | 可以更改(例如,午睡)但不经常更改 |
| **10 分钟** | 活动,应激,恢复力,锻炼,会话,SpO2,VO2 最大,心血管年龄,标签,休息模式 | 日历锚定数据在记录后稳定 |
| **1 分钟** | 心率 | 高频流数据 |
## 弹性
所有 Oura API 请求都受到 **标准弹性管道** 的保护,由 [Polly](https://github.com/App-vNext/Polly) 通过 `Microsoft.Extensions.Http.Resilience` 提供:
| 策略 | 配置 | 目的 |
|----------|---------------|---------|
| **重试** | 3 次尝试,指数退避 + 抖动 | 处理 429(速率限制),500+,408 和网络错误 |
| **断路器** | 在 10% 故障率时打开,5 秒中断 | 防止敲打失败的 API |
| **尝试超时** | 每个请求 10 秒 | 限制个别请求持续时间 |
| **总超时** | 包括重试在内的 30 秒 | 限制端到端请求持续时间 |
弹性处理程序尊重速率限制响应中的 `Retry-After` 头。身份验证错误(401)和权限错误(403)由客户端单独处理,不会重试。
## 技术栈
- **.NET 10** / C#,带有可为空的引用类型
- **ModelContextProtocol** NuGet 包(MCP C# SDK)- STDIO 传输
- **System.Text.Json** 用于序列化
- **IHttpClientFactory** 用于 HTTP 客户端生命周期管理
- **IMemoryCache** 用于内存响应缓存,带有分层 TTL
- **Microsoft.Extensions.Http.Resilience** (Polly)用于重试,断路器和超时策略
## 许可证
MIT