Oura Ring について
AI クライアントから Oura Ring の健康データを構造化された形で参照できる MCP サーバーです。生の API データではなく、日別統計や傾向を返し、ローカルとホスト環境に対応します。
主な機能
- 01睡眠・準備度・活動の概要
- 02HRV・心拍数・SpO₂ データ
- 03日別統計と傾向のレポート
- 04ローカル stdio とリモート HTTP
- 05タイムゾーン対応の日付と SQLite キャッシュ
活用シーン
- 01指定期間の睡眠と準備度を確認
- 02心拍数やストレスの変化を調べる
- 03活動と健康の傾向を比較
- 04ローカルまたはウェブクライアントで Oura の概要を確認
MCP 対応
MCP クライアントに Oura データ用ツールと `oura://today`、`oura://yesterday`、`oura://week` のリソースを提供します。ローカルの stdio とリモートの Streamable HTTP に対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx my-oura-mcpOURA_CLIENT_IDClient ID of your Oura application from developer.ouraring.comOURA_CLIENT_SECRETシークレットClient secret of your Oura applicationOURA_REDIRECT_URIOAuth redirect URI; must match the Oura application byte for byteOURA_API_MODEsandbox for Oura's synthetic data (no auth needed), production for your ownOURA_TZIANA timezone deciding what counts as today. Set it explicitly on servers, whose clocks run in UTCOURA_TOKEN_STOREシークレットWhere the OAuth flow stores tokens. Written by the server, not set by handOURA_PUBLIC_URLPublic https address, without a trailing slash. Enables OAuth 2.1 for Claude.ai and ChatGPT; leave empty for local or Bearer-token clientsOURA_OAUTH_ALLOWED_REDIRECT_ORIGINSシークレットComma-separated trusted OAuth redirect origins; defaults to Claude.ai and ChatGPTOURA_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 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
11掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| raw | boolean | いいえ | |
| end_date | any | いいえ | |
| days_back | any | いいえ | |
| start_date | any | いいえ |
詳細
my-oura-mcp
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を指定すれば取得できます。心拍数データを1か月分取得する場合、データ量を10分の1以上に削減できます。 - 1つのコードベースで2つのトランスポートに対応。 ローカル利用向けの
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、安静時心拍数、呼吸、体温 | 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₂max | 30日間 |
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 を設定します |
登録時の Redirect URI は http://localhost:8765/callback です。バイト単位で完全に一致させてください。Scopes は daily、heartrate、tag、spo2、stress、heart_health です。それ以外は任意です。
以降、トークンは自動的に更新されます。my-oura-mcp auth --status で確認し、auth --logout で削除できます。
Personal Access Token は現在使えません。Oura は 2025 年 12 月に発行を終了しました。
リフレッシュトークンは一度しか使えません。 更新のたびに古いトークンは無効になるため、同じトークンストアを共有する 2 つのインスタンスは互いに動作を妨げます。症状として、使い捨てに関する記述を含む
400が表示されます。対処するには、authを再実行し、インスタンスを 1 つだけにしてください。
設定
すべての設定は .env にあります(.env.example を参照)。シークレットが git に送られることはありません。
| 変数 | 用途 |
|---|---|
OURA_CLIENT_ID / OURA_CLIENT_SECRET | Oura アプリケーションの認証情報 |
OURA_REDIRECT_URI | アプリケーションの設定と完全に一致させる必要があります |
OURA_API_MODE | sandbox(合成データ)または 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_STORE | OAuth フローがトークンを書き込む場所です。手動で設定しないでください |
OURA_CACHE_DB | SQLite キャッシュファイルです。空の値を指定するとキャッシュが無効になります |
実行方法
コードベースは 1 つで、トランスポートは 2 種類です。このマシン上のクライアントの隣では stdio を、Web クライアントやスマートフォンからアクセスできるサーバーでは HTTP を使用します。
ローカルでの実行
| クライアント | コマンド |
|---|---|
| Claude Code | claude mcp add --scope user oura -- uv --directory PATH run my-oura-mcp |
| Codex | codex 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 の認証情報を移行する方法、Web クライアントを接続する方法を順を追って説明しています。
| クライアント | 接続方法 |
|---|---|
| Claude.ai、ChatGPT | OAuth。入力するクライアント ID やシークレットはありません。クライアントが自身を登録し、同意ページで OURA_MCP_TOKEN の入力を求めます |
| Claude Code | claude mcp add --scope user --transport http oura URL --header "Authorization: Bearer TOKEN" |
| Codex | codex 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 に指定する必要があります。同意ページには、シークレットを求める前にクライアント名と戻り先のオリジンが表示されます。
公開する方法は 2 つありますが、どちらを選ぶかは見た目だけの問題ではありません。Caddy は簡単ですが、証明書が Certificate Transparency に記録されます。これは、そのアドレスでサービスが稼働していることを明らかにする公開ログです。Cloudflare Tunnel ならインバウンドポートを一切開かずに済みます。同じホスト上で VPN を使っている場合は、トンネルを使う必要があります。
どちらを選ぶか
| stdio、ローカル | HTTP、サーバー上 | |
|---|---|---|
| このマシン上の Claude Code と Codex | はい | はい |
| 他のデバイス | いいえ | はい |
| Claude.ai、ChatGPT、スマートフォン | いいえ | はい、OAuth 経由 |
| ドメインとホストが必要 | いいえ | はい |
| データがこのマシンの外に出る | いいえ | はい、自分のサーバーへ |
稼働中のインスタンスは必ず 1 つだけにしてください。Oura のリフレッシュトークンは 1 回しか使えないため、2 つのサーバーが同じトークンストアを共有すると、互いの認証を無効にしてしまいます。
タイムゾーンの処理
Oura の日付の仕様に起因するバグが 3 つありました。いずれもエラーを出さずにデータが失われるものでした。この API を使って開発する場合は、知っておくと役立ちます。
sleepとdaily_activityは、dayフィールドではなく、内部の UTC タイムスタンプで絞り込まれます。 UTC+3 では、午前 0 時を過ぎて始まった夜の記録が前日の UTC 日付に含まれます。そのため、28..28を指定すると何も返されない一方で、day=28のレコードは確かに存在します。サーバーは検索範囲を広げ、後からdayで絞り込みます。すべてのエンドポイントを調べて確認済みです。他の 6 つはこの問題の影響を受けません。heartrateは UTC のタイムスタンプを返します。 この文字列の先頭 10 文字でグループ化すると、現地の 1 日が 2 つに分かれ、現地時間の 00:00~03:00 が前日に押し込まれます。まさに知りたい安静時心拍数がその対象です。グループ化にはOURA_TZを使用します。- Oura は 1 日に複数の睡眠レコードを返します。 夜間の睡眠に加えて、昼寝も含まれます。任意のレコードを選ぶと、12 分の昼寝が一晩分の睡眠に取って代わる可能性があります。
long_sleepとしてタイプされたレコードを優先し、なければ最も長いレコードを選びます。昼寝はnaps_hとして別に報告するため、その HRV が夜間の睡眠の平均に混ざることはありません。
セキュリティ
.env、トークンストア、キャッシュは.gitignoreに含まれています。コミット前にgit status --porcelainで確認してください。- トークンストアと SQLite キャッシュは、所有者のみがアクセスできる(
600)ファイル権限で書き込まれます。 - HTTP エンドポイントは、定数時間比較を使って
OURA_MCP_TOKENで保護されています。アクセスモデルは意図的にシンプルです。1 つのシークレット、1 人の所有者、ユーザーごとの分離なしです。 - サーバーは、シークレットがない状態でループバック以外のアドレス上で起動することを拒否します。 ヘルスデータをインターネットにひそかに公開することはありません。次のコマンドで試せます。
uv run my-oura-mcp --transport http --host 0.0.0.0 /healthzは意図的に公開されています。リバースプロキシに必要であり、ok以外は返しません。- Caddy はログから
Authorizationヘッダーを除去します。
キャッシュ
古い日付のデータは SQLite に保存されます。直近の完了済みの 2 日分は、後からの同期で更新される可能性があるため、リクエストのたびに再確認されます。それより古い履歴は、ネットワークに接続せずキャッシュから返されます。
uv run my-oura-mcp cache --status # what is cached
uv run my-oura-mcp cache --clear # forget it
知っておくとよい点が 3 つあります。今日のデータはキャッシュされません — Oura は現在もデータを書き込んでいます。データが空の日もキャッシュされません。空の日は「リングを装着しなかった」か「まだ同期されていない」のどちらかを意味します。後者は数時間以内に解消されますが、空のデータをキャッシュすると、その状態が永続してしまいます。モードもキーの一部なので、サンドボックスのデータが本番環境に表示されることはありません。
1 分ごとの心拍数データはキャッシュを通しません。このデータの行には day フィールドがありません。
MCP リソース
リソースに対応しているクライアントは、oura://today、oura://yesterday、oura://week を読み取れます。これらは、引数を手動で選択することなく、ツールと同じ睡眠・コンディション・アクティビティの概要を提供します。
レシピ付きスキル
skills/oura には、Claude 向けのスキルが含まれています。ツールを追加するものではなく、ツールを使ったワークフローを提供します。睡眠が実際に改善しているか、今日は負荷をかけてもよいか、調子の悪い日に体に何が起きていたか、生活習慣の変化に効果があったか、といったことを判断できます。それぞれ、呼び出しの手順と回答を考察する方法をまとめたもので、単一のツールでは表現できない内容です。
クライアントのスキルディレクトリにコピーしてインストールします。
cp -r skills/oura ~/.claude/skills/
レシピはテストによってコードと照合されます。ツールが返さないフィールド名があれば、モデルに何も伝えないままになるのではなく、uv run pytest が失敗します。
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 という文字列とその後のスペースも値に含める必要があります。abc123 ではなく、Bearer abc123 を指定してください。
別の日のデータが返ってくる。 OURA_TZ が設定されていません。サーバーの時計はほとんどの場合 UTC のため、「今日」の始まりがあなたのタイムゾーンと数時間ずれ、夜間の睡眠が前日として記録されます。OURA_TZ=Europe/Moscow のように明示的に設定してください。
「リフレッシュトークンが拒否されました」。 Oura のリフレッシュトークンは 1 回しか使えません。2 つ目のインスタンスがトークンを使用したときに発生します。起動するインスタンスは必ず 1 つだけにしてください。VPS を起動したら、ローカルの Claude Code も VPS を参照するように設定してください。my-oura-mcp auth で復旧できます。
api.ouraring.com へのリクエストが SSL_ERROR_SYSCALL またはタイムアウトで失敗する。
通常、サーバー側の問題ではありません。クライアントはバックオフを挟んで 4 回再試行します。それでも解決しない場合は、通常 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() を使用します。実際のプロトコル層では、MCP クライアントが宣言済みのデフォルト値を明示的な引数として渡すため、そこでしか発生しないバグもあります。
Codex やその他のコーディングエージェント向けのリポジトリの指示とタスク/レビュー構成は、AGENTS.md と docs/agents にあります。
x86_64 macOS: cryptography 49 以降はこのプラットフォーム向けのホイールを提供しておらず、Rust ソースからビルドしようとします。pyproject.toml ではこの環境に限り 48.0.0 を指定しており、Linux とネイティブ arm64 には影響しません。Apple Silicon でも、Homebrew が /opt/homebrew ではなく /usr/local にインストールされている場合は、この問題が発生します。file $(which python3) で確認してください。
ネットワークの不安定さ: api.ouraring.com へのリクエストが SSL_ERROR_SYSCALL で失敗したりタイムアウトしたりする場合、通常はサーバー側の問題ではありません。クライアントはバックオフを行いながら 4 回試行します。それでも解決しない場合は、VPN をお試しください。
今後の予定と意図的に延期された項目については、docs/ROADMAP.md をご覧ください。
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。