Oura Ring MCP Server
This read-only Oura Ring MCP server lets an MCP client (Claude, Cursor, VS Code, etc.) query your Oura readiness, sleep, HRV, activity, stress and heart-rate data without any ability to change it.
Single-day answer:
get_daily_overviewreturns one date's readiness, sleep, naps, activity, stress, resilience, SpO2, cardiovascular age, VO2 max, bedtime guidance, workouts, sessions and tags;get_profilereturns age, height, weight, sex, ring hardware and battery.Multi-day trends:
get_trendsgives a day-by-day table with averages, min/max, readiness zones and workouts per day over 1-90 days.Per-data-type ranges:
list_daily_readiness,list_daily_sleep,list_sleep_periods,list_daily_activity,list_workouts,list_sessions,list_daily_health,list_tagsandlist_rest_mode_periodscover ranges (typically 7 days, up to 400) withstart/end,daysand pagination.Deep dives:
get_sleep_periodreturns one night's hypnogram plus HR/HRV curves;get_heart_ratereturns the heart-rate time series aggregated to 5min/15min/hour/day (or raw samples) with per-source stats.Filtering and detail: most list tools support
raw: truefor Oura's original objects, andlist_workoutsaccepts anactivitysubstring;get_heart_rateacceptssourceandlatest.Graceful degradation: unshared data types come back under
unavailablerather than failing; a sandbox mode serves Oura's public sample data.
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 Ring MCP ServerHow did I sleep last night, and why is my readiness only 64?"
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 Ring MCP Server (read-only)
Ask Claude, Cursor, VS Code or any MCP client about your Oura Ring readiness, sleep, HRV, activity, stress and heart rate, without giving it any way to change your data.
"How did I sleep last night, and why is my readiness only 64?" "Compare my HRV and lowest heart rate over the last 30 days." "Show me last night's sleep stages and heart-rate curve." "Does my readiness drop after days I tagged alcohol?"
(Run the one-time auth step before or after installing.)
Why this server
Read-only, enforced. Oura's API has no write endpoints for your data, and this client goes further: it can only send
GET, refuses any URL outside/v2/usercollection/, never touches the webhook API, and every tool carriesreadOnlyHint: true. Tests fail the build otherwise.Answers whole questions in one call.
get_daily_overviewreturns a day's readiness, sleep, naps, activity, stress, resilience, SpO2, workouts and tags together.get_trendsreturns a day table plus averages and readiness zones over up to 90 days.Model-friendly output. Compact JSON with hours, minutes, km and local times instead of seconds and meters; hypnograms as stage segments; heart rate aggregated into buckets. Pass
raw: truefor Oura's original objects.Degrades gracefully. If you untick a data type on Oura's consent page, combined tools list it under
unavailableinstead of failing.Your tokens stay on your machine. Your own Oura API application, OAuth with PKCE, a
0600token file, and safe handling of Oura's single-use refresh tokens. No third-party servers, no telemetry.Try it without an account.
OURA_SANDBOX=1serves Oura's public sample data.
Related MCP server: oura-mcp-cloudflare-workers
Quick start
You need Node.js 20.11+ and an Oura account. (Oura retired personal access tokens in December 2025, so OAuth is the only way in.)
1. Create an Oura API application (2 minutes)
Open cloud.ouraring.com/oauth/applications and create a new application.
Set the Redirect URI to
http://localhost:8787/callback.Copy the Client ID and Client Secret.
Applications work for up to 10 users without Oura's approval, which is plenty for personal use.
2. Connect your Oura account
npx -y @royreznik/oura-ring-mcp authPaste your Client ID and Client Secret when asked (the secret isn't echoed). Your browser opens Oura's consent page; leave every data type ticked and approve. Tokens are saved to ~/.config/oura-ring-mcp/tokens.json and refreshed automatically from then on.
(For scripts, set OURA_CLIENT_ID and OURA_CLIENT_SECRET instead of answering the prompts.)
3. Add it to your MCP client
As a plugin (adds the server plus an /oura:auth skill that walks you through connecting):
/plugin marketplace add royreznik/oura-ring-mcp
/plugin install oura@oura-ring-mcpOr just the MCP server:
claude mcp add oura --scope user -- npx -y @royreznik/oura-ring-mcpAdd to the client's MCP config (Claude Desktop: Settings → Developer → Edit Config; Cursor: ~/.cursor/mcp.json; Windsurf: ~/.codeium/windsurf/mcp_config.json):
{
"mcpServers": {
"oura": {
"command": "npx",
"args": ["-y", "@royreznik/oura-ring-mcp"]
}
}
}For Claude Desktop you can also install the .mcpb bundle from the latest release.
.vscode/mcp.json (or your user mcp.json):
{
"servers": {
"oura": { "type": "stdio", "command": "npx", "args": ["-y", "@royreznik/oura-ring-mcp"] }
}
}~/.codex/config.toml:
[mcp_servers.oura]
command = "npx"
args = ["-y", "@royreznik/oura-ring-mcp"]Run auth on the host first, then mount the token directory:
docker build -t oura-ring-mcp https://github.com/royreznik/oura-ring-mcp.git
docker run -i --rm -v ~/.config/oura-ring-mcp:/home/node/.config/oura-ring-mcp oura-ring-mcpThen ask: "Give me my Oura overview for today."
Try it without an account
claude mcp add oura-sandbox --env OURA_SANDBOX=1 -- npx -y @royreznik/oura-ring-mcpSandbox mode serves Oura's public sample data. No auth step, no personal data.
Tools
Tool | What it returns |
| One day: readiness, sleep score and main sleep, naps, activity, stress, resilience, SpO2, cardiovascular age, VO2 max, bedtime guidance, workouts, sessions, tags (defaults to the latest scored day) |
| Day-by-day table plus avg/min/max for readiness, sleep and activity scores, sleep stages, HRV, lowest HR, temperature, steps, calories and stress, over 1-90 days |
| Age, height, weight, sex, email; ring model, size, color, firmware; battery level |
| Readiness scores, contributors, temperature deviation |
| Sleep scores and contributors |
| Nights and naps: stages, latency, efficiency, HR, HRV, breathing; one night's hypnogram and HR/HRV curves |
| Activity score, steps, calories, activity minutes, sedentary time |
| Activity, intensity, duration, calories, distance (filterable by activity) |
| Meditation/breathing/relaxation sessions with mood, HR and HRV |
| Stress, resilience, SpO2 and breathing disturbance, cardiovascular age, VO2 max, bedtime window, joined by day |
| Tags and notes from the Oura app (alcohol, caffeine, sickness, custom...) |
| Rest Mode periods and their symptom tags |
| Heart-rate time series aggregated to 5min/15min/hour/day (or raw), with per-source stats; up to 30 days per call |
List tools accept start / end (YYYY-MM-DD, inclusive), a days shortcut and next_token. See the tool reference for details.
Configuration
Variable | Default | Purpose |
| from token file | Your app's client ID ( |
| from token file | Your app's client secret ( |
|
| Must exactly match a redirect URI registered on your app |
|
| Where credentials are stored. Must be absolute ( |
| unset |
|
oura-ring-mcp Start the MCP server on stdio (what your MCP client runs)
oura-ring-mcp auth Connect your Oura account (opens your browser)
oura-ring-mcp status Check the stored connection
oura-ring-mcp logout Delete the locally stored tokens
oura-ring-mcp --version"Today" is computed in your computer's timezone, which should match the timezone your Oura app uses.
Privacy and security
oura-ring-mcp talks only to
api.ouraring.com(plus your browser visitingcloud.ouraring.comduringauth). No telemetry, no intermediary server.Tokens and your client secret live in one file only your user can read (
0600). They are never logged or returned by tools.Your MCP client sends tool results to its language model. Health data you ask about is shared with that model provider under its terms.
To disconnect, run
oura-ring-mcp logout. To revoke access completely, delete the application at cloud.ouraring.com/oauth/applications or revoke it in your Oura account.
Details: PRIVACY.md, SECURITY.md.
How authentication works
OAuth 2 authorization-code flow with PKCE (S256) and a random
state, captured by a loopback-only callback server.Oura refresh tokens are single-use. oura-ring-mcp refreshes shortly before expiry (and on a 401), one refresh at a time, under a lock file so several clients on one machine (e.g. Claude Desktop and Claude Code) never refresh at once, and writes new tokens atomically. If a write fails, the new tokens stay in memory so a full disk can't log you out.
Rate limits (429, honouring
Retry-After), server errors, timeouts (30s) and network errors are retried with backoff. Cancelling a request in your client stops its Oura calls.
Troubleshooting
Symptom | Fix |
Oura shows a redirect URI error | The app's redirect URI must match |
| Register another URI on your app (e.g. |
| Run |
| Run |
A data type appears under | It was unticked on Oura's consent page, or needs an active Oura membership. Run |
| Update the Oura app on your phone and open it so it syncs. |
Today's data is missing | Oura only has data after the ring syncs through the Oura app. Open the app, then ask again. |
npx -y @royreznik/oura-ring-mcp statusDevelopment
npm install
npm test # unit, MCP integration, end-to-end and packaging tests (no network)
npm run smoke:sandbox # every tool against Oura's live sandbox API
npm run smoke:live # every tool against your account (after auth); prints only counts
npm run inspect # MCP InspectorSee CONTRIBUTING.md. The one hard rule: oura-ring-mcp stays read-only.
Credits and legal
Architecture, auth and test approach are adapted from whoop-mcp by Oryan Omer (MIT).
MIT © Roy Reznik. Unofficial project, not affiliated with or endorsed by Oura Health Oy. "Oura" is a trademark of Oura Health Oy. Nothing here is medical advice.
Available Tools
14 toolsget_daily_overviewDaily overviewARead-onlyIdempotent
Get everything Oura recorded for one day in a single call: readiness (score, contributors, temperature deviation), sleep score and the night's main sleep (stages, HRV, lowest heart rate, efficiency), naps, activity (score, steps, calories), stress, resilience, SpO2, cardiovascular age, VO2 max, bedtime guidance, workouts, sessions and tags. Start here for 'today', 'last night' or any single date; use get_trends for multi-day questions and the list_* tools for one data type over a range. Omit date for the latest day with a sleep or readiness score. Data types the user didn't grant are listed under unavailable instead of failing the call.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Day to show (YYYY-MM-DD); a night's sleep belongs to the day you woke up. Defaults to the latest day. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=true, and destructiveHint=false, so the description does not need to restate safety. It adds meaningful behavioral context beyond annotations: missing permissions cause the affected data types to appear under `unavailable` rather than failing the call, and it lists the returned categories for a tool with no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary action and scope, then efficiently layers in usage routing, default behavior, and fallback behavior. The long data-type list is information-dense but earns its place by telling the agent exactly what a 'daily overview' returns.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description carries the burden of explaining return contents and does so by enumerating the included data categories. It also covers selection guidance, default behavior, and partial-availability handling, leaving no significant gap for an agent deciding to call this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents the single `date` parameter, including its default. The description adds a small refinement beyond the schema: 'Omit date for the latest day with a sleep or readiness score,' which clarifies what 'latest day' means in practice.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Get everything Oura recorded for one day in a single call.' It enumerates the data types covered and explicitly distinguishes itself from get_trends (multi-day) and list_* tools (one data type over a range), so an agent can select it confidently against siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: 'Start here for today, last night or any single date,' and names alternatives for other cases ('use get_trends for multi-day questions and the list_* tools for one data type over a range'). It also clarifies the default when date is omitted, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_heart_rateGet heart rateARead-onlyIdempotent
Get the heart-rate time series between two times, aggregated into buckets aligned to local time (5min, 15min, hour or day) with avg/min/max bpm and the dominant source, plus overall and per-source stats (awake, rest, sleep, workout, session, live). Use it for heart rate at particular times, during a workout or across a day; for overnight averages, lowest heart rate and HRV prefer list_sleep_periods. Defaults to the last 24 hours at hourly resolution; ranges are limited to 30 days per call. resolution 'raw' returns individual samples (the first 2000); latest: true returns only the most recent sample and ignores the other arguments. truncated: true means the range held more samples than one call fetches, so narrow it.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | End: a date (includes that whole day) or ISO 8601 date-time. Defaults to now. | |
| start | No | Start: a date (YYYY-MM-DD, local midnight) or ISO 8601 date-time. Defaults to 24 hours ago. | |
| latest | No | Return only the most recent sample; other arguments are ignored. | |
| source | No | Only include samples recorded in this context. | |
| resolution | No | Bucket size. "raw" returns individual samples (truncated after 2000). | hour |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a safe, idempotent read, but the description adds genuinely new behavior: a 30-day range cap per call, raw resolution truncating at 2000 samples, latest:true overriding all other arguments, and the meaning of a truncated:true response. These are operational constraints not present in the annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose before the usage routing and edge cases. It is a single dense paragraph with heavy parenthetical enumeration of sources and stats; every clause carries information, though it could be broken into sentences for easier scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-value burden and does so: it names the returned fields (avg/min/max bpm, dominant source, overall and per-source stats) and the truncated flag. Combined with defaults, limits, and the sibling routing, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: it clarifies that latest:true causes other arguments to be ignored, that raw returns individual samples capped at 2000, and that buckets are aligned to local time. The interaction between latest and the other params is not derivable from the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (get the heart-rate time series) and immediately qualifies the shape of the result: bucketed aggregation with avg/min/max bpm, dominant source, and per-source stats. It also explicitly distinguishes itself from list_sleep_periods for overnight/HRV use cases, so an agent can differentiate it from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete when-to-use cases (at particular times, during a workout, across a day) and an explicit when-not with a named alternative (overnight averages, lowest HR, HRV → prefer list_sleep_periods). It also states defaults (last 24h at hourly) and the 30-day per-call range limit, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_profileGet Oura profileARead-onlyIdempotent
Get the user's Oura profile and ring hardware: age, height, weight, biological sex and email; each ring's model, size, color, firmware and setup date; and the latest battery level with its timestamp. Use it for questions about the person or the device, or to put scores in context (e.g. age next to VO2 max or cardiovascular age). Takes no arguments. A part Oura won't share (scope not granted) comes back as an error field while the rest still returns.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/idempotent/non-destructive, so safety is covered. The description adds genuinely non-obvious behavior: that missing scopes yield an error field for that part while the rest of the payload still returns, which directly affects how an agent should parse a partial response. It also confirms the tool takes no arguments.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The most important fact – what this tool returns – is front-loaded in the first sentence, followed by usage, argument count, and partial-failure behavior. All four sentences carry information the agent needs; none is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the full burden of describing the return payload, and it does so field by field, including the error-field-on-missing-scope case. Combined with annotations covering the safety profile, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, which is the baseline-4 case. The description explicitly states 'Takes no arguments', consistent with the empty schema, so nothing further is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (get) and resource (Oura profile + ring hardware), then enumerates the concrete fields returned: age, height, weight, sex, email, ring model/size/color/firmware/setup date, battery level. This is enough for an agent to distinguish it from siblings like get_daily_overview or get_trends without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage contexts ('questions about the person or the device', 'put scores in context, e.g. age next to VO2 max or cardiovascular age'), which is stronger than implied usage. However it never explicitly names an alternative tool or states when not to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sleep_periodGet sleep periodARead-onlyIdempotent
Get one sleep period in full detail by its sleep_id: the same summary as list_sleep_periods plus a hypnogram (deep/light/REM/awake segments at 5-minute resolution, in local time), heart-rate and HRV curves through the night (downsampled to at most 120 points, with avg/min/max), and the readiness contributors it produced. Use it to explain one specific night; get the id from list_sleep_periods or get_daily_overview first. An unknown id returns a 404 error; raw: true returns Oura's original object.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| sleep_id | Yes | Sleep period id (from list_sleep_periods or get_daily_overview). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), but the description adds real behavioral context beyond them: the 404 on unknown ids, the 5-minute hypnogram resolution in local time, the downsampling cap of 120 points for HR/HRV, and the effect of raw:true.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and payload, then usage, then edge cases. Every sentence carries information (return content, id source, error behavior, raw flag) with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully compensates by enumerating what comes back and at what granularity. Combined with the error and raw behaviors, an agent has everything needed to call and interpret this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are already documented. The description restates the raw flag's behavior ('raw: true returns Oura's original object') and the id's provenance, adding negligible meaning beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get one sleep period in full detail by its sleep_id') and immediately distinguishes itself from list_sleep_periods by describing the extra payload (hypnogram, HR/HRV curves, readiness contributors). An agent can tell this apart from its siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it ('Use it to explain one specific night') and where the required id comes from ('get the id from list_sleep_periods or get_daily_overview first'). The alternative list tool is named, so routing is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trendsTrendsARead-onlyIdempotent
Summarize the last N days (default 14, up to 90, including today) as a day-by-day table plus avg/min/max for readiness, sleep and activity scores, sleep hours and stages, HRV, lowest heart rate, temperature deviation, steps, active calories and stress, with readiness-zone counts and workouts per day. Use it for week or month comparisons and 'how am I trending' questions; use get_daily_overview for a single day and the list_* tools for full detail on one data type. Days without data are omitted; today is flagged in_progress and its partial activity is left out of the averages.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many days to look back, including today (1-90). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds real behavioral context beyond them: days without data are omitted, today is flagged in_progress, and today's partial activity is excluded from averages. It stops short of describing granularity/pagination behavior, but for a read-only aggregate this is strong disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the output shape then the routing guidance, then the edge-case behavior. The long metric enumeration is justified because no output schema exists to convey the return columns; every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly takes on the burden of describing the returned table and per-metric aggregates, and it also covers the two behaviors an agent could otherwise get wrong (missing days, in-progress today excluded from averages). An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single optional parameter is fully documented in the schema (default 14, range 1-90, inclusive of today). The description restates those same facts (default 14, up to 90, including today) without adding syntax or edge-case meaning beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ("Summarize") plus resource ("last N days") and an explicit enumeration of what the summary contains (readiness, sleep, activity, HRV, steps, stress, workouts per day). It is clearly distinguishable from siblings like get_daily_overview and the list_* tools without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the use cases ("week or month comparisons", "how am I trending" questions) and routes to alternatives with a condition: get_daily_overview for a single day, list_* tools for full detail on one data type. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_daily_activityList daily activityARead-onlyIdempotent
List daily activity: activity score (0-100) and contributors, steps, active, total and target calories, walking-equivalent distance in km, minutes of high/medium/low activity, sedentary, resting and non-wear hours, and inactivity alerts. Use it for movement, step and calorie questions over a range; individual workouts are in list_workouts. An Oura activity day runs 4 a.m. to 4 a.m., so today's row is partial. Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records, next_token }, oldest first. Days without data are absent, and today's data appears only after the ring syncs. If next_token is not null, call again with it for the rest. raw: true returns Oura's original objects.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive), and the description adds substantial context beyond them: the 4 a.m.–4 a.m. Oura day boundary, partial today rows, missing days for no-data, sync latency before today's data appears, oldest-first ordering, and pagination via next_token. This is unusually rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and scope, and every sentence carries information the agent needs. The opening field enumeration is long, but with no output schema it earns its place by telling the agent what data comes back.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even without an output schema, the description specifies the return shape ({ records, next_token }), ordering, pagination continuation, and the raw flag. Combined with the range semantics, an agent has everything needed to call and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: end is inclusive, days is capped at 400 and ignored when start is set, and next_token should be re-passed for the rest. It stops short of adding syntax beyond the schema's YYYY-MM-DD format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List daily activity') and enumerates exactly what each record contains (activity score and contributors, steps, calories, distance, activity minutes, sedentary/resting/non-wear hours, alerts). It also distinguishes itself from list_workouts, so an agent can tell it apart from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes usage: 'Use it for movement, step and calorie questions over a range; individual workouts are in list_workouts.' It also gives the default range (last 7 days) and the selection rule between start/end and days, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_daily_healthList daily health metricsARead-onlyIdempotent
List per-day health metrics joined by date: stress (day summary, minutes of high stress and high recovery), resilience level and contributors, average SpO2 and breathing disturbance index, cardiovascular age, VO2 max, and bedtime guidance (Oura's optimal bedtime window). Use it for stress, resilience, breathing and cardio-fitness trends; readiness, sleep and activity scores have their own list_* tools. Each field appears only on days Oura computed it (VO2 max and cardiovascular age update occasionally). Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records } oldest first, plus unavailable listing any data type the user didn't grant.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/idempotent, but the description adds materially new behavior: fields appear only on days Oura computed them (VO2 max and cardiovascular age are sporadic), the default window is 7 days, and the response includes an `unavailable` list for data types the user didn't grant. That permission-gap disclosure is exactly the kind of context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the resource and field list, then usage routing, then range rules and return shape. It is dense and somewhat long, but nearly every clause carries operational information that the schema does not.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description documents the return shape ({ records } oldest first plus `unavailable`), data sparsity behavior, and full range semantics. An agent has everything needed to call and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds real meaning: the range is inclusive, the default is the last 7 days, days caps at 400, and days is ignored when start is set. The inclusive semantic is not stated in the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource (list per-day health metrics) and enumerates the exact fields returned: stress, resilience, SpO2, breathing disturbance, cardiovascular age, VO2 max, bedtime guidance. It explicitly distinguishes itself from siblings by noting readiness, sleep and activity scores live in their own list_* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States intended use ('for stress, resilience, breathing and cardio-fitness trends') and routes the agent away from this tool for readiness/sleep/activity via named sibling tools. Both when-to-use and when-not-to-use are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_daily_readinessList daily readinessARead-onlyIdempotent
List daily readiness scores (0-100, with Oura's zone: optimal 85+, good 70-84, pay_attention below 70) and their contributors: HRV balance, resting heart rate, recovery index, body temperature, sleep balance, previous night, previous-day activity, activity balance and sleep regularity, plus temperature deviation from baseline in °C. Use it to see how readiness and its drivers changed over a range; for a single day use get_daily_overview, and for readiness next to sleep and activity use get_trends. Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records, next_token }, oldest first. Days without data are absent, and today's data appears only after the ring syncs. If next_token is not null, call again with it for the rest. raw: true returns Oura's original objects.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safe read-only, idempotent, non-destructive profile, and the description adds substantial extra behavior: default 7-day window, 400-day cap, days ignored when start is set, inclusive bounds, oldest-first ordering, absent days for missing data, today only after ring sync, and next_token pagination. raw:true semantics (Oura originals vs friendly units) are also disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and drivers before usage guidance, then range, return shape, and caveats. Dense but essentially waste-free; the contributor enumeration is long, though each item is a real field name an agent may need.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the return shape ({ records, next_token }), ordering, pagination contract, and the raw-vs-summary switch. Combined with full schema coverage and read-only annotations, an agent has everything needed to call and page this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, but the description adds meaning beyond the schema: start/end are inclusive, days is capped at 400 and silently ignored when start is set, and next_token is the continuation handle from a prior call. It does not restate the parameter formats, so it stays above rather than at baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (daily readiness scores) and immediately defines the payload: score scale, Oura zones, the nine contributors, and temperature deviation. It explicitly distinguishes itself from get_daily_overview (single day) and get_trends (readiness next to sleep/activity), so an agent can route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use plus two named alternatives with the conditions that select them: single day -> get_daily_overview, combined sleep/activity view -> get_trends. Range defaults and overrides are also stated, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_daily_sleepList daily sleep scoresARead-onlyIdempotent
List daily sleep scores (0-100, with Oura's zone) and the contributors behind them: total sleep, efficiency, restfulness, REM, deep sleep, latency and timing. Use it for 'how well did I sleep' over a range; for hours, stages, HRV and heart rate use list_sleep_periods, and for one night's hypnogram use get_sleep_period. Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records, next_token }, oldest first. Days without data are absent, and today's data appears only after the ring syncs. If next_token is not null, call again with it for the rest. raw: true returns Oura's original objects.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, non-destructive), and the description adds substantial context beyond them: default 7-day range, inclusive date semantics, days capped at 400 and ignored when start is set, oldest-first ordering, absent days, sync delay for today, and pagination via next_token. This is well beyond what annotations and schema alone convey, though a few operational details (unit of the score contributors, rate limits) remain unstated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense but well-ordered passage: purpose first, then sibling routing, then range semantics, then return/pagination behavior, then the raw flag. Every sentence carries load and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the return shape ({records, next_token}), ordering, pagination loop, and edge cases (missing days, unsynced today). It is complete enough for an agent to call and page through results correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3, and the description exceeds it by clarifying the interplay between parameters (days is 'ignored when start is set', start/end are inclusive YYYY-MM-DD, raw returns Oura's original objects rather than friendly units). It reinforces and contextualizes the schema rather than merely restating it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List daily sleep scores') and immediately distinguishes itself from siblings by naming list_sleep_periods and get_sleep_period with their respective scopes (hours/stages/HRV vs one night's hypnogram). An agent can route correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the use case ('how well did I sleep' over a range) and then names the two alternative tools with the exact conditions that select each one. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_rest_mode_periodsList rest mode periodsARead-onlyIdempotent
List Rest Mode periods, which the user turns on when sick, injured or recovering, with start and end day (an ongoing period has no end) and the symptom tags logged during each. Use it to explain dips in readiness or activity, or to check whether the user was unwell on given days. Covers the last 90 days by default; set start and end (inclusive, YYYY-MM-DD) or days. A period that overlaps the range is included. Returns { records, next_token }; raw: true returns Oura's original objects.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| days | No | The last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/non-destructive, and the description still adds non-obvious behavior: a 90-day default window, inclusive start/end semantics, the rule that any period overlapping the range is included, and the return shape ({ records, next_token }) plus what raw:true does. That is real added behavioral context rather than restating the safety profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with no filler; the entity definition, usage rationale, range rules and return contract each earn their place. Front-loaded well, though the middle sentence packs a lot into one clause chain.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still conveys the return shape, pagination token, default window and range-inclusion rule, and gives concrete diagnostic use cases. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds range semantics the schema does not state: start/end are inclusive and overlapping periods are still returned. That extra meaning justifies a notch above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb+resource and defines the domain entity in-line ('periods the user turns on when sick, injured or recovering'), including the shape of a period (start/end day, ongoing = no end, symptom tags). This clearly separates it from siblings like list_tags or list_daily_readiness.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete when-to-use cases: 'explain dips in readiness or activity' and 'check whether the user was unwell on given days', plus the default 90-day window and how to override it. It never names an alternative sibling or a when-not condition, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sessionsList sessionsARead-onlyIdempotent
List mindfulness sessions recorded in the Oura app (meditation, breathing, relaxation, nap, rest, body status) with mood, start and end time, duration, and heart-rate and HRV stats (avg/min/max). Use it for questions about guided practice and how it affected heart rate or HRV; sleep is in list_sleep_periods and exercise in list_workouts. Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records, next_token }, oldest first. Days without data are absent, and today's data appears only after the ring syncs. If next_token is not null, call again with it for the rest. raw: true returns Oura's original objects.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, non-destructive), and the description goes well beyond them: default 7-day window, days capped at 400 and ignored when start is set, days without data are absent, today's data only appears after ring sync, oldest-first ordering, and pagination via next_token. This is rich operational context that materially affects invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: the core purpose leads, then routing, then range semantics, then return/pagination behavior. Every sentence carries information an agent needs, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description specifies the return shape ({ records, next_token }), ordering, and how to continue pagination. Combined with annotations covering the safety profile, nothing needed to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters. The description largely restates schema content (raw, days-ignored-when-start-set) but adds that start/end are inclusive, which is marginally useful. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (list mindfulness sessions in the Oura app) and enumerates the exact session subtypes and returned fields. It explicitly distinguishes itself from list_sleep_periods and list_workouts, so an agent can route correctly without opening another schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the concrete use case (questions about guided practice and its effect on heart rate or HRV) and explicitly routes sleep and exercise to the sibling tools. The when-to-use and when-not-to-use conditions are both present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sleep_periodsList sleep periodsARead-onlyIdempotent
List individual sleep periods (nights and, by default, naps) with bedtime, hours in bed and asleep, deep/REM/light/awake hours, latency, efficiency, average and lowest heart rate, average HRV, breathing rate and the readiness score each produced. Use it for sleep duration, stages and overnight HRV or heart rate across days; use list_daily_sleep for scores only, and pass a sleep_id to get_sleep_period for the full hypnogram. Periods the user rejected or deleted are left out, and each period belongs to the day the user woke up. Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records, next_token }, oldest first. Days without data are absent, and today's data appears only after the ring syncs. If next_token is not null, call again with it for the rest. raw: true returns Oura's original objects.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). | |
| next_token | No | Pass the next_token from a previous call to get the following records. | |
| include_naps | No | Set false to return only long (main) sleeps. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description goes well beyond them: rejected or deleted periods are excluded, each period is attributed to the wake-up day, days without data are absent, and today's data only appears after the ring syncs. It also documents pagination termination (call again if next_token is not null) and the raw:true escape hatch.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded: purpose first, then routing to siblings, then behavioral/range/pagination details. Every sentence carries distinct information (exclusions, wake-up-day semantics, defaults, sync caveat, raw mode) with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by specifying the return shape ({ records, next_token }, oldest first) and pagination behavior. Combined with the range defaults, exclusion rules and sync caveat, an agent has everything needed to call this correctly on the first try.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents start, end, days, next_token, raw and include_naps. The description restates the same facts (inclusive YYYY-MM-DD, days up to 400 ignored when start is set) rather than adding new parameter-level meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (list individual sleep periods) and immediately enumerates the fields returned (bedtime, hours in bed/asleep, stage hours, latency, efficiency, HR, HRV, breathing rate, readiness). It explicitly differentiates itself from list_daily_sleep (scores only) and get_sleep_period (full hypnogram), so an agent can route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('sleep duration, stages and overnight HRV or heart rate across days') and names two alternatives with the exact condition that selects each ('list_daily_sleep for scores only', 'pass a sleep_id to get_sleep_period for the full hypnogram'). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tagsList tagsARead-onlyIdempotent
List the tags and notes the user logged in the Oura app (e.g. alcohol, caffeine, late meal, sickness, travel, custom tags) with their time, end time if any, and comments, merging classic and enhanced tags into one list sorted by time. Use it to explain unusual readiness or sleep, then cross-check the tagged days with get_daily_overview or get_trends. Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records } oldest first, plus unavailable listing any data type the user didn't grant.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description goes further: it discloses the merge of classic and enhanced tags, the time-based sort order, the default range, the start/days precedence rule, and the `unavailable` field for ungranted data types. Since no output schema exists, this disclosure of return shape and permission gaps is genuinely valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A dense single paragraph but well front-loaded: purpose and examples first, then usage guidance, then range rules, then return shape. Every clause carries information, though the range/return details could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description steps in to describe the return value ({ records } oldest first, plus `unavailable`), and it fully explains scoping and the permission caveat. An agent has everything needed to call and interpret this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all three parameters (start, end, days) are already documented with formats and constraints. The description largely restates this (inclusive YYYY-MM-DD, days up to 400, ignored when start is set, 7-day default) rather than adding new semantics, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Uses a specific verb (List) and resource (tags and notes the user logged), enumerates concrete examples (alcohol, caffeine, late meal, sickness, travel, custom tags), and describes how classic and enhanced tags are merged. It is immediately distinguishable from every sibling, none of which deal with tags.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states the diagnostic purpose ('Use it to explain unusual readiness or sleep') and names the follow-up tools (get_daily_overview, get_trends) for cross-checking. This is a clear when-to-use with alternatives, not just implied context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_workoutsList workoutsARead-onlyIdempotent
List workouts, auto-detected by the ring or added manually, with activity type, label, intensity (easy/moderate/hard), source, start and end time, duration in minutes, calories and distance in km. Use it for training questions such as 'how many runs this month'; narrow it with activity, a case-insensitive substring like 'run' or 'swim'. For whole-day movement use list_daily_activity, and for heart rate during a workout call get_heart_rate with its start and end and source 'workout'. Range: the last 7 days by default; set start and end (inclusive, YYYY-MM-DD) or days (up to 400, ignored when start is set). Returns { records, next_token }, oldest first. Days without data are absent, and today's data appears only after the ring syncs. If next_token is not null, call again with it for the rest. raw: true returns Oura's original objects.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Last day to include (YYYY-MM-DD). Defaults to today. | |
| raw | No | Return Oura's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: the last N days up to end. Ignored when start is set. | |
| start | No | First day to include (YYYY-MM-DD). | |
| activity | No | Only return workouts whose activity contains this text (case-insensitive), e.g. "running". | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish a safe, idempotent read, and the description adds substantial context beyond them: default 7-day window, inclusive date range semantics, days ignored when start is set, pagination via next_token, oldest-first ordering, the sync-lag caveat that today's data appears only after the ring syncs, and that days without data are simply absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then usage, then parameters, then return/pagination behavior — a sensible information hierarchy. It is dense and mostly earns its length, but several clauses (date format, day limits, raw semantics) repeat what the schema already states, costing some tightness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a list tool with no output schema, it covers everything an agent needs: result shape ({ records, next_token }), ordering, pagination loop, default range, sync-lag and missing-day caveats, and the raw escape hatch. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters, and the description largely restates them (activity substring, days vs start, raw). It adds only marginal meaning, chiefly that start/end are inclusive and that the range defaults to the last 7 days, so the baseline 3 is appropriate rather than a higher score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb and resource (list workouts), plus scope detail: auto-detected vs manual, and the fields returned (activity type, label, intensity, source, times, duration, calories, distance). It explicitly distinguishes itself from list_daily_activity and get_heart_rate, so an agent can route without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete use case ('how many runs this month'), instructions for narrowing (activity with case-insensitive substring like 'run' or 'swim'), and names two alternatives with the exact condition that selects each — list_daily_activity for whole-day movement and get_heart_rate for in-workout heart rate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.0.0- Changed
get_profile1 field changed- added
Input schema / $schemaAdded value: +"http://json-schema.org/draft-07/schema#"
14 tool updates
v0.1.0- First observed
get_daily_overview - First observed
get_heart_rate - First observed
get_profile - First observed
get_sleep_period - First observed
get_trends - First observed
list_daily_activity - First observed
list_daily_health - First observed
list_daily_readiness - First observed
list_daily_sleep - First observed
list_rest_mode_periods - First observed
list_sessions - First observed
list_sleep_periods - First observed
list_tags - First observed
list_workouts
TDQS
Scored across 14 tools
Tools mostly target distinct resources, and the descriptions actively route the agent (get_daily_overview for one day, get_trends for multi-day, list_* for one data type over a range). There is real overlap between get_daily_overview and the various list_* tools, and between list_daily_sleep and list_sleep_periods, but the descriptions explicitly delineate them, so misselection is unlikely.
A clean, predictable verb_noun pattern holds throughout: get_profile, get_daily_overview, get_sleep_period, get_heart_rate, get_trends and list_daily_readiness, list_daily_sleep, list_sessions, list_sleep_periods, list_daily_activity, list_workouts, list_daily_health, list_tags, list_rest_mode_periods. The get_/list_ distinction usefully encodes single-vs-collection semantics.
14 tools is well within the ideal band for a rich health-data domain, and each tool earns its place by covering a distinct Oura data type or aggregation level. No redundant or filler tools.
The surface covers profile/hardware, single-day overview, trends, readiness, sleep scores, individual sleep periods with hypnogram, activity, workouts, health metrics, tags, rest mode, and a raw heart-rate time series. Since the Oura API is read-only, the absence of write operations is appropriate, leaving no obvious gaps.
Maintenance
Related MCP Connectors
Multi-tenant hosted MCP server for Oura Ring — 21 read-only tools, OAuth per user.
Read sleep, readiness, activity, stress, heart rate and workouts from the Oura Ring.
Read wearables and lab health data — sleep, activity, workouts, timeseries, lab tests and orders.
Connect your Oura Ring account securely in minutes. Enable authorized access to your sleep, activi…
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables users to query Polar health data (activity, sleep, recovery, training sessions, heart rate) through MCP with secure authentication, redacted personal info, and bounded responses.-
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to query Oura Ring health data, including sleep, readiness, HRV, activity, and SpO2, through OAuth2-authenticated tools running on Cloudflare Workers.32 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to access Oura Ring health data such as sleep, readiness, activity, workouts, HRV, and event-centered recovery timelines using OAuth2 authentication.MIT
- AlicenseAqualityCmaintenanceProvides read-only access to Oura Ring data, including sleep, readiness, activity, heart rate, stress, workouts, and more, through MCP clients like Claude Desktop and Claude Code.22MIT