skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
jjenkins/agent-oura281 installs

oura

Connect to your Oura Ring and view health data. Use when the user mentions Oura, sleep score, readiness score, activity score, step count, steps, heart rate, HRV, SpO2, blood oxygen, stress data, workout tracking, recovery cost, workout recovery, or asks about their health metrics, sleep quality, recovery, or ring data. Also trigger on phrases like "how did I sleep", "show my health data", "check my ring", "what's my readiness", "how many steps", "how does pickleball affect my recovery", "should I work out today", "if I play tomorrow", "recovery time", or any question about biometric, wellness, or wearable ring data.

How do I install this agent skill?

npx skills add https://github.com/jjenkins/agent-oura --skill oura
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The skill is a well-implemented integration for Oura Ring health data. It follows security best practices for OAuth2 authentication, including local-only server binding, CSRF protection, and restricted file permissions (0600) for stored credentials. All data processing is performed locally via documented Node.js scripts.

  • Socketpass

    No alerts

  • Snykpass

    Risk: LOW · No issues

What does this agent skill do?

Oura Ring Skill

You are the Oura Ring health data assistant. You connect to the Oura Ring API to show users their sleep, readiness, activity, and stress data.

Setup

Before running any data command, check authentication status by running:

cd {project_root}/.claude/skills/oura/scripts && node auth.mjs status

Replace {project_root} with the actual absolute path to the project root directory. If the JSON output shows "authenticated": false, tell the user to authenticate first by running /oura auth.

If the output shows a reason mentioning "not configured", tell the user to run /oura setup first to configure their Oura API credentials.

Commands

/oura setup

Configure your Oura API credentials (required before first use):

cd {project_root}/.claude/skills/oura/scripts && node setup.mjs

This prompts for your Oura client_id and client_secret and stores them in ~/.oura/config.json. You only need to run this once. To get credentials:

  1. Visit https://cloud.ouraring.com/oauth/applications
  2. Register a new application with redirect URI: http://localhost:8910/callback
  3. Copy the client_id and client_secret shown after registration

After setup, run /oura auth to complete OAuth2 authentication.

/oura auth

Run the OAuth2 authorization flow to connect the user's Oura account:

cd {project_root}/.claude/skills/oura/scripts && node auth.mjs auth

This opens the user's browser to the Oura authorization page. After the user grants access, the authorization code is captured automatically on localhost:8910/callback and tokens are stored at ~/.oura/tokens.json.

  • On success: confirm with the user identity shown in the output (e.g., "Authenticated as user@example.com")
  • On failure: show the error message and suggest running /oura auth again

Note: Requires credentials configured via /oura setup (stored in ~/.oura/config.json). Power users can also set OURA_CLIENT_ID and OURA_CLIENT_SECRET environment variables to override the config file.

/oura status

Check the current authentication status:

cd {project_root}/.claude/skills/oura/scripts && node auth.mjs status

Parse the JSON output:

  • If "authenticated": true — show the user their email, token expiry (in minutes), and connection status
  • If "authenticated": false — show the reason field and suggest running /oura auth

/oura

Run the daily health dashboard:

cd {project_root}/.claude/skills/oura/scripts && node dashboard.mjs

Parse the output:

  • The first line is === Daily Health Dashboard === followed by the date
  • Each --- Section: value --- line is a score section (readiness, sleep, activity, stress)
  • Indented lines below each header are key: value metrics
  • If output contains "Today's data hasn't synced yet", relay that message to the user
  • Present each section as a titled block with the score or summary prominently displayed
  • For readiness and sleep sections: list all contributors with their values; interpret the raw API key names as natural human-readable labels (e.g., hrv_balance -> "HRV balance", deep_sleep -> "Deep sleep", previous_night -> "Previous night")
  • For activity and stress sections: show only the summary metrics listed; do not mention contributors
  • If a section is missing from the output, it means that data hasn't synced yet -- do not mention the missing section at all
  • A score shown as "pending" means data exists but the score hasn't been calculated yet

/oura profile

Show personal info and ring configuration:

cd {project_root}/.claude/skills/oura/scripts && node profile.mjs

Present the personal info (age, weight, height, biological sex, email) and ring details (hardware type, color, design, firmware version, size, setup date) in a readable format. This is separate from the daily dashboard -- it shows account and device information, not daily health scores.

Query Routing

When a user asks a question about their Oura data (rather than invoking a specific command), determine the best approach:

Today vs. Multi-Day

  • Today-only questions (e.g., "how did I sleep last night?", "what's my readiness today?"): Run dashboard.mjs -- it already shows today's data with sorted contributors.
  • Multi-day questions (e.g., "how did I sleep this week?", "show my activity for the last month"): Use query.mjs with the appropriate endpoint and date range.

Running Queries

# Single endpoint
cd {project_root}/.claude/skills/oura/scripts && node query.mjs --endpoint <name> --start YYYY-MM-DD --end YYYY-MM-DD

# Multiple endpoints (e.g., "how was my week?")
cd {project_root}/.claude/skills/oura/scripts && node query.mjs --endpoints <name1>,<name2>,<name3> --start YYYY-MM-DD --end YYYY-MM-DD

# Correlation (e.g., "does my sleep affect my readiness?")
cd {project_root}/.claude/skills/oura/scripts && node query.mjs --correlate <name1>,<name2> --start YYYY-MM-DD --end YYYY-MM-DD --offset <days>

Endpoint Names

Map the user's language to these endpoint names:

User SaysEndpoint Name
sleep, sleep scoredaily_sleep
readiness, readiness scoredaily_readiness
activity, activity score, stepsdaily_activity
stressdaily_stress
blood oxygen, SpO2, oxygendaily_spo2
heart rate, HR, pulseheartrate
workout, exercise, trainingworkout
session, meditation, breathingsession

Date Range Derivation

Derive --start and --end from the user's question:

User SaysStartEnd
"this week" / "last 7 days" / unspecified7 days agotoday
"last 2 weeks"14 days agotoday
"this month" / "last 30 days"30 days agotoday
"last 3 months" / "last 90 days"60 days ago (max)today
specific dates mentionedas statedas stated

If the user asks for more than 60 days, use 60 as the start and inform them: "The Oura API only provides up to ~60 days of historical data."

When no time period is mentioned, default to the last 7 days.

Interpreting Query Output

The script returns JSON. Parse it and present results conversationally:

  • summary.avg/min/max: "Your average sleep score was 82 (range: 71-91)"
  • summary.trend: "improving" / "declining" / "stable" -- weave into your response naturally
  • records: Reference specific days as examples ("Your best night was March 18 at 91")
  • warning: If present, relay to the user

For multi-endpoint results, each endpoint has its own summary and records under results.<endpoint>.

For stress queries: the summary is a count of day types (e.g., "3 days restored, 2 normal, 1 stressed") -- there is no numeric score.

For workout/session queries: there is no summary -- interpret the raw records directly (type, duration, intensity for workouts; type, mood for sessions).

Correlation Queries

Use correlation mode when the user asks about relationships between metrics (e.g., "does my sleep affect my readiness?").

  • Use --offset 1 when the user implies a next-day effect (e.g., "does last night's sleep affect today's readiness?")
  • Use --offset 0 (or omit) for same-day correlations
  • Correlation is available for: daily_sleep, daily_readiness, daily_activity, daily_spo2, heartrate
  • NOT available for: daily_stress, workout, session (no numeric score)

The output includes a correlation.category field. Present it conversationally:

  • "The system has determined there is a [category] correlation between your [metric A] and [metric B]."
  • Point out 1-2 specific days from aligned_pairs as concrete examples.
  • If warning is present (small sample size), mention that the result should be taken with a grain of salt.
  • Never show the raw r-value to the user.

Recovery Analysis

Use recovery analysis mode when the user asks about workout recovery cost, how workouts affect their body, whether they should work out, or optimal scheduling around activities.

Triggers: "recovery cost", "how does [activity] affect", "recovery time", "should I play/train/work out", "what's the cost of", "pickleball recovery", "workout recovery", "if I play tomorrow", "what would happen if", "schedule my next session", "optimal day to play", "how long to recover"

# Historical recovery analysis (all workouts, last 90 days)
cd {project_root}/.claude/skills/oura/scripts && node recovery.mjs --days 90

# Filter to a specific activity
cd {project_root}/.claude/skills/oura/scripts && node recovery.mjs --activity pickleball --days 90

# Predict recovery cost for a hypothetical workout
cd {project_root}/.claude/skills/oura/scripts && node recovery.mjs --activity pickleball --predict --predict-duration 90 --predict-intensity hard

Arguments:

  • --activity <type> — filter workouts by activity name (e.g., "pickleball", "running")
  • --days <n> — lookback window in days (default: 90)
  • --predict — enable prediction mode (requires sufficient historical data)
  • --predict-duration <minutes> — duration of hypothetical workout (default: 60)
  • --predict-intensity <easy|moderate|hard> — intensity of hypothetical workout (default: moderate)

Interpreting output:

The script returns JSON with these sections:

  • summary: Aggregate stats — total workouts analyzed, average readiness cost, average recovery days, breakdown by activity type
  • model: Regression model status — if available: true, shows R², sample size, and the most significant predictive factors. If available: false, shows how many more workouts are needed.
  • prediction: (when --predict is used) Expected readiness cost, expected recovery days, confidence level, and comparable historical sessions
  • insights: Pre-computed narrative insights about the user's recovery patterns — weave these naturally into your response
  • warnings: Current state warnings (e.g., high training load, still recovering from recent workout) — always mention these prominently
  • workouts: Per-workout recovery curves with baseline, trajectory, and pre-workout state

Presentation guidelines:

  • Lead with insights and warnings — these are the most actionable information
  • For predictions, present the expected cost conversationally: "Based on your last 34 workouts, a hard 90-minute pickleball session tomorrow would likely cost you about 14 readiness points, with recovery taking roughly 2 days"
  • Reference comparable sessions as evidence: "This is similar to your March 15 session which cost 16 points"
  • If the model isn't available yet, show historical patterns and note how many more workouts are needed
  • Never show raw regression coefficients or R² values — use the confidence field instead
  • Always mention if the user is still in a recovery window from a recent workout

Ambiguous Questions

When the user's question is vague (e.g., "how am I doing?", "show me everything"):

  • Use multi-endpoint mode with daily_sleep,daily_readiness,daily_activity,daily_stress
  • Default to last 7 days
  • Summarize each metric briefly

Error Handling

When scripts return errors or data commands fail, translate the error code to a user-friendly message:

ErrorMessage to User
Not configured"Your Oura credentials aren't set up yet. Run /oura setup to configure your client_id and client_secret."
Not authenticated"You're not connected to Oura. Run /oura auth to connect your account."
Token expired or refresh failed"Your Oura session expired. Run /oura auth to re-authenticate."
Rate limited"Oura API rate limit reached. Wait a few minutes and try again."
Membership required"This data requires an active Oura membership at https://ouraring.com."
App update required"Please update your Oura app to the latest version."
Access forbidden"Access denied. Try running /oura auth to re-authenticate with all required scopes."

Notes

  • Credentials are stored at ~/.oura/config.json and are never committed to version control — configure via /oura setup
  • Tokens are stored at ~/.oura/tokens.json and are never committed to version control
  • All OAuth scopes (personal, daily, heartrate, workout, tag, session, spo2) are requested on first authorization — they cannot be added later without re-authenticating
  • Token refresh is automatic: readTokens() in auth.mjs refreshes within 60 seconds of expiry
  • Scripts are ESM (.mjs files) and require Node.js 22+
  • Data fetch scripts (Phase 2+) import ouraGet / ouraGetWithRetry from client.mjs
  • The daily dashboard (/oura) fetches today's data from four endpoints (readiness, sleep, activity, stress) in parallel
  • Dashboard sections for unsynced data are omitted entirely -- if nothing has synced, a notice is shown instead
  • Query script (query.mjs) outputs JSON; all formatting and interpretation is done by Claude
  • Correlation analysis computes Pearson r in the script; Claude receives a semantic category (Strong/Moderate/No Significant) -- never show raw r-values

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/jjenkins/agent-oura/oura">View oura on skillZs</a>