Skip to main content
Glama

oura-mcp

CI npm License: MIT

A Model Context Protocol server for the Oura Ring API v2. Exposes sleep, activity, readiness, heart rate, and workout data to MCP-compatible clients (Claude Desktop, Claude Code, Cursor, ...) via OAuth.

Quick start

npx @yasuakiomokawa/oura-mcp configure

The wizard collects your Oura Client ID/Secret, walks through browser OAuth, saves tokens to ~/.config/oura-mcp/, and adds an mcpServers.oura entry to any detected MCP client config. Restart the client and the tools below are available.

Re-running configure pre-fills the saved Client ID / port so you only need to press Enter to keep them. Type --force to wipe saved state and start from scratch:

npx @yasuakiomokawa/oura-mcp configure --force

Related MCP server: oura-ring-mcp-server

Prerequisites

  1. Register an Oura developer app at https://cloud.ouraring.com/oauth/applications

  2. Redirect URI must be exactly: http://localhost:54321/callback (or http://localhost:<port>/callback if you customize OURA_CALLBACK_PORT)

  3. Enable the read scopes you need (Email, Personal info, Daily activity, Heart rate, Workout, Tag, Session, SpO2, Ring configuration, Stress, Heart health)

  4. Note the Client ID and Client Secret — you'll enter them in npx @yasuakiomokawa/oura-mcp configure

Installation

Three paths depending on your client:

1. MCP Registry (auto-discovery clients)

Once published to the official MCP Registry, supported clients can install io.github.YasuakiOmokawa/oura-mcp from their UI. The wizard step still has to run once to obtain OAuth tokens.

2. Manual config (Claude Desktop / Claude Code / Cursor)

Run npx @yasuakiomokawa/oura-mcp configure — Step 4 of the wizard auto-detects:

  • Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)

  • Claude Code (user): ~/.claude.json

  • Claude Code (project): ./.mcp.json

  • Cursor (user): ~/.cursor/mcp.json

  • Cursor (project): ./.cursor/mcp.json

Each detected file is backed up to <file>.bak.<ISO-timestamp> before an atomic write.

To configure manually, add to your client config:

{
  "mcpServers": {
    "oura": {
      "command": "npx",
      "args": ["-y", "@yasuakiomokawa/oura-mcp"]
    }
  }
}

3. Skill (optional)

The companion oura-api-skill ships per-endpoint reference and three workflow recipes (weekly review / sleep trend / recovery check). Bundle it as a Claude Code plugin or import into your skills directory.

Tools provided

Tool

Purpose

oura_authenticate

Start OAuth flow in browser; returns the URL. Used after refresh_token expires.

oura_auth_status

Check current token validity and expiry.

oura_clear_auth

Wipe stored tokens.

oura_api_list_paths

List every supported GET endpoint with summaries.

oura_api_get

Generic GET to /v2/.... Auto-paginates via max_pages (1-20) or accepts next_token in params.

oura_api_get returns structuredContent with { status, data, next_token, pages_fetched, has_more }.

Configuration

Two ways. The config file (Option A) is the recommended path — it stores secrets at-rest with 0600 and is self-healing. Environment variables (Option B) are kept for CI / Docker / ephemeral environments where writing a file is impractical, but they leak more easily and are not recommended for daily use.

Run the wizard once and forget about it:

npx @yasuakiomokawa/oura-mcp configure

This writes:

~/.config/oura-mcp/config.json   # 0600, contains clientId / clientSecret / callbackPort
~/.config/oura-mcp/tokens.json   # 0600, contains the OAuth access / refresh tokens

Permissions are re-checked on every load and chmod'd back to 0600 if anything else touched them.

config.json schema:

{
  "schemaVersion": 1,
  "clientId": "...",
  "clientSecret": "...",
  "callbackPort": 54321
}

Option B — environment variables (CI / Docker only)

OURA_CLIENT_ID=...
OURA_CLIENT_SECRET=...        # must be set together with OURA_CLIENT_ID
OURA_CALLBACK_PORT=54321      # optional; safe to set in env regardless of Option A/B

When the server boots and both OURA_CLIENT_ID and OURA_CLIENT_SECRET are set, it uses them and emits a config.env_credentials warning to stderr.

Why not recommended:

  • process.env is readable from /proc/<pid>/environ by any process running as the same user.

  • Environment is inherited by every child process the server spawns.

  • Crash dumps and observability tools that capture process.env will leak the secret.

  • OURA_CLIENT_SECRET=... npx ... typed at the shell ends up in shell history.

OURA_CALLBACK_PORT is not a secret and is fine to pass via env in either mode.

Never use args for secrets

Process arguments are visible to other users via ps / /proc/<pid>/cmdline. Use the env block of your MCP client config:

{
  "mcpServers": {
    "oura": {
      "command": "npx",
      "args": ["-y", "@yasuakiomokawa/oura-mcp"],
      "env": { "OURA_CLIENT_ID": "...", "OURA_CLIENT_SECRET": "..." }
    }
  }
}

Troubleshooting

  • "refresh_token expired" — run oura_authenticate (in chat) or npx @yasuakiomokawa/oura-mcp configure (in terminal).

  • Port 54321 already in use — set OURA_CALLBACK_PORT=<other port> and update the redirect URI in your Oura developer app to match.

  • "Path not found" — verify the path with oura_api_list_paths. Common slips: missing /v2/ prefix, typo in daily_sleep.

  • Setup hangs at "Waiting for authorization" — you haven't approved in the browser yet, or the authorize page was opened in a different browser session than the one with localhost reachability.

  • No log output — set OURA_LOG_LEVEL=debug for verbose stderr logging.

Development

git clone https://github.com/YasuakiOmokawa/oura-mcp.git
cd oura-mcp
npm install
npm test
npm run build

Useful scripts:

  • npm run lint / npm run typecheck — Biome + TypeScript checks

  • npm run test:coverage — Vitest with V8 coverage

  • npm run update:docs — re-fetch the Oura OpenAPI schema and regenerate skills/oura-api-skill/references/

License

MIT

Available Tools

5 tools
oura_api_getOura API GETA
Read-onlyIdempotent

Generic GET to Oura Ring API v2. Use oura_api_list_paths to see endpoints. Pagination via max_pages or pass next_token in params.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath starting with /v2/, e.g. "/v2/usercollection/daily_sleep"
paramsNoQuery params. Daily endpoints: start_date/end_date (YYYY-MM-DD). Time-series: start_datetime/end_datetime (ISO 8601). Pass next_token to continue.
max_pagesNoAuto-follow next_token up to N pages (default 1).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataYesConcatenated data array (or single object) from Oura
statusYesHTTP status of the last fetched page
has_moreYesTrue if more pages exist beyond fetched
next_tokenYesCursor for next page or null
pages_fetchedYesNumber of pages fetched

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, so the description's mention of pagination adds some value. It doesn't disclose error handling or rate limits, but with annotations, the behavioral disclosure is moderate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no wasted words, front-loaded purpose. Highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema and annotations, the description adequately covers the tool's role, including pagination and endpoint discovery. It is complete enough for a generic GET tool, though it could mention auth prerequisites briefly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with descriptions for all parameters. The description reinforces pagination via max_pages or next_token, which is already in schema, adding minimal new semantic meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it's a generic GET to Oura Ring API v2, and references oura_api_list_paths for endpoint discovery, distinguishing it from auth tools. However, it doesn't fully specify which data it retrieves beyond being generic.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It mentions using oura_api_list_paths to see endpoints and pagination options, but lacks explicit when-to-use vs alternatives or exclusions. The usage context is implied but not fully articulated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

oura_api_list_pathsList Oura API endpointsA
Read-onlyIdempotent

List all available Oura API v2 GET endpoints with summaries.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide readOnlyHint=true and idempotentHint=true, fully covering safety and idempotency. Description adds 'with summaries' but no further behavioral traits. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded with key information, no redundant words. Efficient and clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Adequately describes a parameterless tool with no output schema; explains purpose and output format ('summaries'). Slightly vague on summary content, but sufficient for the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters with 100% schema coverage (empty object). Baseline is 4 as per guidelines; description does not need to add parameter info.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description explicitly states 'List all available Oura API v2 GET endpoints with summaries', specifying verb, resource, and scope. Clearly distinguishes from sibling tools like oura_api_get (which retrieves specific endpoint data) and authentication tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context: use to discover available endpoints. No explicit when-not or alternatives listed, but tool purpose is self-explanatory and siblings are distinct, making guidance implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

oura_authenticateAuthenticate with OuraA

Start OAuth authorization flow. Returns a URL to open in browser. Used for re-authentication after refresh_token expires.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate readOnlyHint=false and openWorldHint=true, so the description correctly implies mutation via OAuth flow. It adds that a URL is returned, but does not disclose potential side effects like token invalidation. The description adds moderate context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description consists of two concise, front-loaded sentences with no redundant information. Every sentence earns its place, clearly stating purpose and return value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters and no output schema, the description covers the essential purpose and return value. It could elaborate on the overall OAuth flow (e.g., requiring a callback), but the current content is sufficient for an agent to use the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters (100% coverage), so the baseline is 4. The description does not need to add parameter info, and it appropriately omits any.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool starts an OAuth authorization flow and returns a URL. It clearly distinguishes itself from sibling tools like oura_auth_status and oura_clear_auth by focusing on authentication initiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description specifies the tool is 'Used for re-authentication after refresh_token expires', providing clear context for when to use it. However, it does not explicitly state when not to use it or mention alternatives like oura_auth_status for checking existing auth.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

oura_auth_statusAuthentication statusA
Read-onlyIdempotent

Check current authentication state and token expiry.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and idempotentHint. The description adds value by specifying exactly what is checked (state and token expiry), providing context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Extremely concise single sentence with no wasted words. Front-loaded with the core functionality.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the tool is simple with no parameters, the description does not specify the output format or data structure. For complete understanding, an agent might need to know what the response contains (e.g., boolean, object). Adequate but could be more detailed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist; schema coverage is 100%. Baseline score of 4 is appropriate as description need not explain parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool checks authentication state and token expiry, using specific verb 'Check' and distinct resource. It is easily distinguishable from sibling tools like oura_authenticate or oura_clear_auth.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives such as oura_authenticate or oura_api_get. The description implies use for checking auth state but offers no exclusions or context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

oura_clear_authClear authenticationA
DestructiveIdempotent

Delete stored tokens. Re-authenticate via oura_authenticate after this.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations indicate destructiveHint: true and idempotentHint: true. The description adds context by noting that re-authentication is needed afterward, complementing the annotations. No contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with two sentences, each earning its place. It is front-loaded with the action and ends with a clear next step.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters, no output schema, and annotations covering destruction, the description is adequate. It could optionally mention implications for state or irreversible nature, but current information is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, and schema description coverage is 100%. Per guidelines, baseline is 4. No further parameter description needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states 'Delete stored tokens', clearly indicating the action and resource. It distinguishes from sibling tools like oura_authenticate and oura_auth_status by focusing on clearing authentication.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear usage guideline: 'Re-authenticate via `oura_authenticate` after this.' It implies when to use (to reset auth) and suggests an alternative tool, but does not explicitly state when not to use.

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. 5 tool updatesv0.2.13
    • First observedoura_api_get
    • First observedoura_api_list_paths
    • First observedoura_auth_status
    • First observedoura_authenticate
    • First observedoura_clear_auth

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a distinct purpose: listing endpoints, generic GET requests, initiating OAuth, checking auth status, and clearing tokens. No overlap or ambiguity in their roles.

Naming Consistency4/5

All tools share the 'oura_' prefix, and most follow a verb_noun pattern (e.g., oura_authenticate, oura_auth_status). Minor inconsistency with 'oura_api_get' and 'oura_api_list_paths' mixing 'api' with the verb, but overall pattern is maintained.

Tool Count5/5

With only 5 tools, the server is well-scoped for its purpose: authentication management and a generic GET endpoint. No unnecessary tools.

Completeness3/5

The server covers authentication and read operations via a generic GET, but lacks write operations (POST/PUT/DELETE) or any specialized endpoints. This may be sufficient for some use cases but leaves gaps for a full API surface.

Maintenance

ActivityInactive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server for the Withings Health API with per-user OAuth2, enabling users to securely access their own health data (measures, activity, sleep, workouts, heart rate, devices, and goals) and optionally add measurements.
    12
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that exposes the WHOOP v2 API, enabling users to retrieve health data such as cycles, recovery, sleep, and workouts. It uses GitHub OAuth for authentication and is designed for remote use over HTTP.
    MIT