Read sleep, readiness, activity, stress, heart rate and workouts from the Oura Ring.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Register a webhook so Oura notifies your callback URL when data changes. Oura verifies the URL before activating it, and the subscription EXPIRES — renew it with oura_renew_webhook_subscription. Oura: POST /v2/webhook/subscription.
Which collection to watch, e.g. daily_sleep or workout.
Which change to be notified about.
The HTTPS URL Oura should call.
A secret Oura echoes back so you can verify the callback.
The server marks this tool as destructive. Running it may delete or overwrite data on the server or in any account you connected with your headers.
Register a webhook so Oura notifies your callback URL when data changes. Oura verifies the URL before activating it, and the subscription EXPIRES — renew it with oura_renew_webhook_subscription. Oura: POST /v2/webhook/subscription.
| Argument | Type | Description |
|---|---|---|
| data_type* | string | Which collection to watch, e.g. daily_sleep or workout. |
| event_type* | string | Which change to be notified about. |
| callback_url* | string | The HTTPS URL Oura should call. |
| verification_token* | string | A secret Oura echoes back so you can verify the callback. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"callback_url",
"verification_token",
"event_type",
"data_type"
],
"properties": {
"data_type": {
"type": "string",
"description": "Which collection to watch, e.g. daily_sleep or workout."
},
"event_type": {
"enum": [
"create",
"update",
"delete"
],
"type": "string",
"description": "Which change to be notified about."
},
"callback_url": {
"type": "string",
"description": "The HTTPS URL Oura should call."
},
"verification_token": {
"type": "string",
"description": "A secret Oura echoes back so you can verify the callback."
}
}
}Remove a webhook subscription. Notifications stop immediately. Oura: DELETE /v2/webhook/subscription/{id}.
| Argument | Type | Description |
|---|---|---|
| subscription_id* | string | The subscription to delete. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"subscription_id"
],
"properties": {
"subscription_id": {
"type": "string",
"description": "The subscription to delete."
}
}
}Fetch a single document by id from one collection. Ids come from oura_list_documents. Oura: GET /v2/usercollection/{collection}/{document_id}.
| Argument | Type | Description |
|---|---|---|
| sandbox | boolean | Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring. |
| collection* | string | Which collection the document belongs to. |
| document_id* | string | The document's id. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"collection",
"document_id"
],
"properties": {
"sandbox": {
"type": "boolean",
"description": "Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring."
},
"collection": {
"enum": [
"daily_activity",
"daily_cardiovascular_age",
"daily_readiness",
"daily_resilience",
"daily_sleep",
"daily_spo2",
"daily_stress",
"enhanced_tag",
"rest_mode_period",
"ring_configuration",
"session",
"sleep",
"sleep_time",
"tag",
"vO2_max",
"workout"
],
"type": "string",
"description": "Which collection the document belongs to."
},
"document_id": {
"type": "string",
"description": "The document's id."
}
}
}Fetch individual heart-rate samples over a DATETIME range. This collection is sampled continuously, so it uses start_datetime/end_datetime rather than dates, and can return a great many points — narrow the window or pass latest. Oura: GET /v2/usercollection/heartrate.
| Argument | Type | Description |
|---|---|---|
| latest | boolean | Return only the most recent sample. |
| sandbox | boolean | Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring. |
| next_token | string | Cursor from the previous page's next_token. Omit for the first page. |
| end_datetime | string | ISO-8601 end. |
| start_datetime | string | ISO-8601 start, e.g. 2026-08-01T00:00:00Z. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"latest": {
"type": "boolean",
"description": "Return only the most recent sample."
},
"sandbox": {
"type": "boolean",
"description": "Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring."
},
"next_token": {
"type": "string",
"description": "Cursor from the previous page's next_token. Omit for the first page."
},
"end_datetime": {
"type": "string",
"description": "ISO-8601 end."
},
"start_datetime": {
"type": "string",
"description": "ISO-8601 start, e.g. 2026-08-01T00:00:00Z."
}
}
}Fetch the wearer's profile — age, weight, height, biological sex and email. Oura: GET /v2/usercollection/personal_info.
| Argument | Type | Description |
|---|---|---|
| sandbox | boolean | Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"sandbox": {
"type": "boolean",
"description": "Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring."
}
}
}Fetch ring battery readings over a DATETIME range, or just the latest. Oura: GET /v2/usercollection/ring_battery_level.
| Argument | Type | Description |
|---|---|---|
| latest | boolean | Return only the most recent reading. |
| sandbox | boolean | Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring. |
| next_token | string | Cursor from the previous page's next_token. Omit for the first page. |
| end_datetime | string | ISO-8601 end. |
| start_datetime | string | ISO-8601 start. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"latest": {
"type": "boolean",
"description": "Return only the most recent reading."
},
"sandbox": {
"type": "boolean",
"description": "Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring."
},
"next_token": {
"type": "string",
"description": "Cursor from the previous page's next_token. Omit for the first page."
},
"end_datetime": {
"type": "string",
"description": "ISO-8601 end."
},
"start_datetime": {
"type": "string",
"description": "ISO-8601 start."
}
}
}Fetch a single webhook subscription with its callback URL, event type and expiry. Oura: GET /v2/webhook/subscription/{id}.
| Argument | Type | Description |
|---|---|---|
| subscription_id* | string | The subscription's id. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"subscription_id"
],
"properties": {
"subscription_id": {
"type": "string",
"description": "The subscription's id."
}
}
}List documents from one Oura collection over a date range. This is the main read: pick `collection` for what you want — daily_sleep and sleep for sleep, daily_readiness for recovery, daily_activity for movement, daily_stress and daily_resilience for load, workout and session for exercise, daily_spo2, daily_cardiovascular_age and vO2_max for cardiovascular measures, tag and enhanced_tag for the wearer's own annotations, rest_mode_period and ring_configuration for device state. Oura: GET /v2/usercollection/{collection}.
| Argument | Type | Description |
|---|---|---|
| sandbox | boolean | Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring. |
| end_date | string | End of the range, YYYY-MM-DD. |
| collection* | string | Which document collection to read. |
| next_token | string | Cursor from the previous page's next_token. Omit for the first page. |
| start_date | string | Start of the range, YYYY-MM-DD. Defaults to a recent window. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"collection"
],
"properties": {
"sandbox": {
"type": "boolean",
"description": "Read Oura's synthetic sandbox data instead of the wearer's real data. Use this to learn a response shape without a ring."
},
"end_date": {
"type": "string",
"description": "End of the range, YYYY-MM-DD."
},
"collection": {
"enum": [
"daily_activity",
"daily_cardiovascular_age",
"daily_readiness",
"daily_resilience",
"daily_sleep",
"daily_spo2",
"daily_stress",
"enhanced_tag",
"rest_mode_period",
"ring_configuration",
"session",
"sleep",
"sleep_time",
"tag",
"vO2_max",
"workout"
],
"type": "string",
"description": "Which document collection to read."
},
"next_token": {
"type": "string",
"description": "Cursor from the previous page's next_token. Omit for the first page."
},
"start_date": {
"type": "string",
"description": "Start of the range, YYYY-MM-DD. Defaults to a recent window."
}
}
}List the webhook subscriptions registered for the application. Oura: GET /v2/webhook/subscription.
No arguments.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {}
}Extend a webhook subscription's expiry. Oura subscriptions lapse if not renewed, so this is the tool that keeps a live integration alive. Oura: PUT /v2/webhook/subscription/renew/{id}.
| Argument | Type | Description |
|---|---|---|
| subscription_id* | string | The subscription to renew. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"subscription_id"
],
"properties": {
"subscription_id": {
"type": "string",
"description": "The subscription to renew."
}
}
}