Skip to main content
Glama

oura-mcp

A Model Context Protocol server that exposes the full Oura Ring v2 API to LLM agents — including period-level sleep data, time-series HR/HRV, hypnogram rendering, SpO2, and derived analytics tools.

Why this exists

Existing community Oura MCP servers return only daily contributor scores — opaque 0–100 numbers from Oura's algorithm (deep_sleep: 11, efficiency: 88). They omit the underlying period data: actual minutes of deep/REM/light sleep, sleep stage timeline, restless periods, breathing rate, SpO2, time-series heart rate and HRV.

For any non-trivial analysis — correlation studies, intervention tracking, hypnogram visualisation, percentile comparisons — the contributor scores are useless. oura-mcp fixes that gap.

Feature

Existing MCPs

oura-mcp

Daily sleep score

Actual deep/REM/light minutes

Hypnogram (sleep stage timeline)

Time-series HRV / heart rate

SpO2, breathing rate, restless periods

Date-range queries

partial

✓ all tools

Percentile & trend analytics

Local cache (reproducible analyses)

Compact mode (token-efficient)


Related MCP server: Oura MCP

Token safety

Your Oura PAT grants full read access to your biometric history. Treat it like an API key.

If a token is accidentally committed: revoke it immediately at cloud.ouraring.com, then use git filter-repo to purge it from history (a simple delete-and-recommit leaves it in the log forever). See SECURITY.md.


Quickstart

1. Install

pip install oura-ring-mcp
# or with uv:
uv pip install oura-ring-mcp

Or for a developer install from source:

git clone https://github.com/jhamblin/oura-ring-mcp.git
cd oura-ring-mcp
pip install -e .
# or: uv pip install -e .

2. Set your PAT

# Option A — environment variable (recommended for Claude Desktop)
export OURA_PAT="your-token-here"

# Option B — config file
mkdir -p ~/.oura-mcp
echo '{"pat": "your-token-here"}' > ~/.oura-mcp/config.json

3. Register with Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "oura": {
      "command": "oura-ring-mcp",
      "env": {
        "OURA_PAT": "your-token-here"
      }
    }
  }
}

Restart Claude Desktop. Ask it to call oura_personal_info to verify connectivity.

4. (Optional) Enable local cache

export OURA_MCP_CACHE_DIR=~/.oura-mcp/raw

With the cache enabled, past dates are served from disk — analyses are reproducible and don't burn API calls on repeat queries.


Tool reference

Direct API tools

Tool

Oura endpoint

Notes

oura_personal_info

/personal_info

Profile (sex, age, height, weight). Connectivity check.

oura_sleep

/sleep

Primary tool. Period-level data: deep/REM/light minutes, hypnogram, HRV, HR, SpO2, restless periods. Overnight buffer applied automatically.

oura_daily_sleep

/daily_sleep

Daily sleep score + contributors.

oura_daily_readiness

/daily_readiness

Readiness score + contributors + temperature deviation.

oura_daily_activity

/daily_activity

Steps, calories, MET minutes, activity score.

oura_daily_spo2

/daily_spo2

Average SpO2 + breathing disturbance index. Gen 3 / data-dependent.

oura_daily_stress

/daily_stress

Stress/recovery duration breakdown. Gen 3+.

oura_daily_resilience

/daily_resilience

Resilience level + contributors. Gen 3+.

oura_daily_cardiovascular_age

/daily_cardiovascular_age

Estimated vascular age. Gen 3+.

oura_daily_sleep_time

/sleep_time

Recommended bedtime window + status.

oura_workouts

/workout

Workout sessions (manual + auto-detected).

oura_sessions

/session

Meditation / breathwork sessions.

oura_tags

/enhanced_tag/tag

User tags. Auto-selects enhanced_tag; falls back on 404.

oura_heart_rate

/heartrate

Time-series HR. Takes ISO datetimes. Compact by default.

oura_rest_mode_period

/rest_mode_period

Rest mode (sick / recovery) periods.

oura_ring_configuration

/ring_configuration

Hardware / firmware info.

Derived / analytics tools

Tool

Inputs

Returns

oura_render_hypnogram

date

ASCII sleep stage timeline: █=deep ░=light ▒=REM ·=awake (5 min/char)

oura_percentiles

metric, date range, percentiles=[50,75,95]

P50/P75/P95 (configurable) for any sleep session field

oura_rolling_average

metric, date range, window=7

[{date, value, rolling_avg}] per day

oura_summary_table

date range

Compact per-night rows: {date, deep_min, rem_min, light_min, awake_min, efficiency, hrv, rhr, sleep_score, readiness_score, cache_status}

oura_cache_rebuild

date range

Force-refresh cache from API for a date range

Common parameters

All date-keyed tools accept:

  • date: single day YYYY-MM-DD (defaults to today)

  • start_date / end_date: inclusive range (each defaults to today)

  • pat: per-call PAT override (for multi-account use)

date and start_date/end_date are mutually exclusive.


Output modes

Most data-heavy tools support a format parameter:

compact (default)

Strips bulky time-series arrays and replaces them with summaries:

  • heart_rate.items (5-sec samples, 5000+/night) → heart_rate.summary = {min, max, avg, samples}

  • hrv.items (~100 values/night) → hrv.summary = {min, max, avg, samples}

  • sleep_phase_30_sec, movement_30_sec dropped

  • sleep_phase_5_min kept (small; used for hypnogram rendering)

Typical oura_sleep response in compact mode: ~2–3 KB per night.

full

Returns the unmodified Oura API response. Use when you need raw time-series for plotting or custom analysis. Caller is responsible for context budget.


Cache behaviour

Set OURA_MCP_CACHE_DIR to enable the local cache.

  • One JSON file per day: <cache_dir>/<YYYY-MM-DD>.json

  • Cache-first for past dates: if the file exists, the API is not called

  • Today always re-fetched: data is incomplete until ~6 hours after wake

  • cache_status field on every oura_summary_table row: "hit", "miss", or "disabled"

  • oura_cache_rebuild: force-refresh a date range (useful for historical backfills or after Oura revises scores retroactively)

Cache files match the structure of oura_fetch.py's raw/oura/ layout, so existing raw data from that script is compatible.


Implementation notes

Overnight sleep buffer

The Oura /sleep endpoint filters by bedtime_start, not by the logical day field. A sleep starting at 11:30 pm on Apr 12 has day = 2026-04-13 (the wake date). oura_sleep automatically expands the fetch range by ±1 day and filters results in memory by day, so overnight sleeps are never missed. This is regression-tested in tests/test_overnight_filter.py.

Pagination

Oura paginates /sleep, /heartrate, /workout, /session, and others via next_token. All tools that use these endpoints call get_all(), which follows next_token until exhausted.


Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

License

MIT. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    Provides access to Oura Ring health data including sleep, readiness, and resilience metrics through the Oura API, enabling language models to query and analyze personal health information.
    6
    116
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides LLMs with access to Oura Ring health data including sleep metrics, activity tracking, heart rate, readiness scores, and other wellness insights through the Oura API v2.
    MIT