oura-mcp-local
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@oura-mcp-local How did I sleep last night? Include readiness and HRV."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
oura-mcp-local
A small, read-only MCP server for the Oura API v2. It returns pre-shaped physiology — nights, chronotype, temperature shifts, baseline drift — and leaves interpretation to whatever is calling it.
OAuth2 authorization-code flow with PKCE and a state check; local callback on a
*.localhostname (both loopback addresses).Client secret and tokens live in
~/.oura-mcp-local/with0600permissions. Tokens are never printed.api.ouraring.comandcloud.ouraring.comare the only hosts in the code.Scopes requested:
daily heartrate tag spo2 stress(stress is its own scope on the app form and gatesdaily_stress). Nopersonal, noemail, no workouts.Single dependency:
@modelcontextprotocol/sdk(pluszod, which it needs).Date ranges capped at 366 days; HR curves at 31 days.
Tools
Tool | Answers |
| Is it connected, which scopes, when does the token expire. No health data. |
| The night before a timed event: bedtime, wake, duration, lowest HR and when, hours awake at the event, hours since HR trough, sleep vs 30-day median, readiness, temperature deviation. |
| Median/IQR bedtime, wake, midpoint; weekday vs weekend; regularity; midpoint shift vs ~03:30 reference; day-by-day phase series. |
| Per-night summaries; optional 5-min HR curve. |
| Sustained nightly-temperature shift detector: shift day, elevated-phase mean, amplitude, duration, extension flag. Raw series and parameters returned. |
| Compact daily table: readiness, sleep score, activity, steps, stress, SpO2, lowest HR, HRV, temperature. |
| User-entered tags. |
| Recent nights vs baseline for lowest HR, avg HR, HRV, respiratory rate, temperature; deltas, z-scores, flags. |
| CSVs (sleep, daily, temperature, tags) into a directory under your home folder. |
Related MCP server: Oura MCP
Setup
Register an application at https://cloud.ouraring.com/oauth/applications. Redirect URI:
https://oura.localhost:3000/callback. Why that name: Oura's form requires https and rejects IP literals, and its identity server's firewall then blocks any redirect containinghttps://localhost("Request blocked"). A subdomain of.localhostpasses the firewall and resolves to loopback on macOS, systemd-resolved Linux and modern browsers without a hosts entry. Any*.localhostname works; the server always binds loopback only.Build and configure:
git clone https://github.com/ktortti/oura-mcp.git && cd oura-mcp npm ci && npm run build node dist/index.js init # asks for client ID and secret (secret hidden); writes ~/.oura-mcp-local/config.json node dist/index.js auth # opens the Oura consent page; tokens saved to ~/.oura-mcp-local/tokens.json # Oura requires an https redirect. The callback runs on a self-signed cert for the redirect hostname (generated once with # openssl into ~/.oura-mcp-local/). If the browser warns, choose Advanced → Proceed. If it refuses outright, # copy the full URL from the address bar (it contains code=...) and paste it into the terminal. node dist/index.js statusRegister with Claude Code (no secrets in the MCP config):
claude mcp add --scope user oura -- node "$(pwd)/dist/index.js" serveRestart the app;
claude mcp listshould showoura.First query:
oura_event_contextfor a recent date and a clock time. Check the bedtime, wake and lowest-HR time against the Oura app for the same night.
Archive (full-fidelity, local)
node dist/index.js archive ~/oura-data 2026-01-01 2026-12-31Pulls every collection the token can read (sleep, daily sleep/readiness/activity/stress/SpO2/resilience, sleep_time, rest_mode_period, enhanced_tag) plus the daytime 5-minute heart-rate series, and writes raw/<endpoint>.json untouched alongside flattened CSVs: nights.csv, sleep_hr_curves.csv and sleep_hrv_curves.csv (one row per 5-minute sample per night), heartrate.csv, and one CSV per daily endpoint. The MCP tools remain the query layer; the archive is for keeping your own copy and for analysis outside a model's context.
Notes
Oura refresh tokens are single-use. Several server processes (one per Claude Code session, say) can share the token file: refresh happens under a lock file (stale after 2 min and only if the owning process is gone), and a process re-reads the file before spending its own refresh token, so a sibling's refresh is adopted rather than raced.
Access tokens are refreshed automatically a minute before expiry and on a 401. Requests retry up to three times on 429 (honouring
Retry-After), 5xx and network errors, with at most four in flight at once. Pagination is capped at 50 pages and rejects a repeated token.oura_exportonly writes under your home directory: lexical check, realpath of the existing ancestor before anything is created, realpath again after, andO_NOFOLLOWon each file open. This is best-effort containment for local use — it defeats mistakes and pre-existing symlinks, not a hostile process on the same machine racing the checks.Responses are validated against minimal zod schemas per endpoint; an unexpected shape fails with the endpoint and field named rather than producing misleading numbers.
To revoke: delete
~/.oura-mcp-local/tokens.jsonand remove the app's access at cloud.ouraring.com.Set
OURA_MCP_HOMEto relocate the config directory (tests and sandboxes).npm testcovers the analysis functions (synthetic data), the API client (scriptedfetch: pagination guards, validation, retries, refresh and cross-process refresh), export path containment (including symlink escape) and the lock file.npm run lintandnpm run typecheckare what CI runs.
Available Tools
9 toolsoura_baseline_driftA
Baseline drift: nightly lowest HR, average HR, HRV, respiratory rate and temperature deviation over the last window nights vs the preceding baseline, with deltas, z-scores and flags. Interpretation is left to the caller.
Inputs: days, window.
oura_chronotypeB
Computed chronotype from main sleep periods: median/IQR bedtime, wake and midpoint; weekday vs weekend; regularity (SD of midpoint); midpoint shift vs a ~03:30 population reference; day-by-day phase series (useful across travel).
Inputs: days.
oura_dailyC
Compact daily table: readiness score, sleep score, activity score and steps, stress summary, SpO2 average, nightly lowest HR, average HRV, temperature deviation.
Inputs: end (required), start (required).
oura_event_contextA
Sleep and physiology context for a timed event on a given day (a test, a flight, a race): the preceding night (bedtime, wake, duration, lowest HR and when), hours awake at the event, hours since the nightly HR trough, sleep vs 30-day median, readiness and temperature deviation.
Inputs: date (required), time (required).
oura_exportB
Write CSVs (sleep, daily, temperature, tags) for a date range into a directory under your home folder. Local disk only.
Inputs: dir (required), end (required), start (required).
oura_sleep_periodsB
Per-night summaries (main sleep and naps): bedtime, wake, midpoint, hours, efficiency, latency, lowest HR and its time, average HR/HRV/respiratory rate, temperature deviation. Optional 5-min HR curve (limits range to 31 days).
Inputs: end (required), start (required), main_sleep_only, include_hr_curve.
oura_statusA
Connection status: token expiry, granted scopes, whether the local config and token files exist and are private. Returns no health data and no absolute paths.
Inputs: no named parameters.
oura_tagsD
User-entered tags (e.g. alcohol, travel, illness, custom) with day, times and comments.
Inputs: end (required), start (required).
oura_temperature_shiftsB
Nightly temperature deviation with a sustained-shift detector: baseline mean, shift day, elevated-phase mean, amplitude, duration, and a flag when the current elevation has outlasted the expected duration. Heuristic; parameters exposed and the raw series returned so the decision is auditable.
Inputs: end (required), start (required), threshold, confirm_days, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Most tools have clearly distinct purposes (status, event context, chronotype, sleep periods, temperature shifts, daily summary, tags, drift, export). Some metric overlap exists between sleep_periods, daily, and baseline_drift (HRV, lowest HR, temperature deviation), but descriptions clarify the analytical intent.
All tools share the consistent 'oura_' prefix and snake_case style. Most are descriptive nouns (oura_sleep_periods, oura_temperature_shifts), but 'oura_export' breaks the noun pattern with a verb, and 'oura_daily' is an adjective, creating minor inconsistency.
Nine tools is a well-scoped set for a health-data server covering status, sleep, readiness, temperature trends, tags, and export. Each tool earns its place without feeling bloated or thin.
The core Oura data surface is covered: sleep summaries, daily scores, temperature, tags, drift analysis, and CSV export. Minor gaps exist (no detailed sleep stages, no workout/activity session breakdown), but agents can accomplish most wellness workflows.
Maintenance
Related MCP Connectors
Read sleep, readiness, activity, stress, heart rate and workouts from the Oura Ring.
Read-only Apple Health data synced from your iPhone: sleep, heart rate, HRV, workouts and trends.
Read wearables and lab health data — sleep, activity, workouts, timeseries, lab tests and orders.
Multi-tenant hosted MCP server for Oura Ring — 21 read-only tools, OAuth per user.
Related MCP Servers
- AlicenseBqualityDmaintenanceProvides 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.6116MIT
- AlicenseBqualityBmaintenanceLocal-first MCP server that connects AI agents to your Oura Ring readiness, sleep, activity, and HRV data. Tokens never leave your machine.27439 npm6MIT
- AlicenseNot gradedqualityCmaintenanceProvides read-only access to Oura Ring health and activity data, including sleep, readiness, activity, stress, SpO2, resilience, workouts, sessions, and heart rate via the Oura API v2.18 PyPIMIT
- AlicenseNot gradedqualityCmaintenanceGives Claude and other MCP clients read-only access to Oura Ring data through the Oura API v2, exposing sleep sessions, readiness, activity, stress, heart rate, workouts and long-range trends as queryable tools. It runs locally, evens out the API's quirks, and keeps credentials on the user's machine.MIT