Own your Oura Ring data. Pull your sleep, readiness, activity, heart rate, SpO₂, stress, and workouts from the Oura Cloud API straight to your terminal. No mobile app. No telemetry. Just SQLite and your data.
- Offline-first. Everything caches into
~/.oura-cli/oura.dbafter oneoura-cli sync. Reports keep working when your internet doesn't. - Real terminal reports.
oura-cli reportwrites a weekly or monthly digest with averages, trend deltas, and "you slept poorly Tuesday" callouts. No dashboards, no logging in. - Pipe-friendly. Output auto-switches to stable JSON when stdout isn't a terminal. Analyse with
jq, plot withgnuplot, or feed it into your own scripts. - Single 100 kB binary, MIT, no telemetry. Built on Bun; zero native dependencies.
curl -fsSL https://bun.sh/install | bash # if you don't have Bun yet
bun add -g @drakulavich/oura-cliYou'll also need a Personal Access Token from Oura. Paste it into oura-cli login once — it lands at ~/.oura-token with 0600 perms.
oura-cli login # paste your PAT, one time
oura-cli sync # backfill recent days into ~/.oura-cli/oura.db
oura-cli report # weekly digest in the terminalThat's it. Subsequent oura-cli sync pulls only new days.
oura-cli db todayToday's scores from the local cache. If you forgot to sync, run oura-cli sync first.
oura-cli db date 2026-05-10oura-cli db week # local cache summary, no API hit
oura-cli sleep week # fresh sleep details direct from Ouraoura-cli report # weekly (default)
oura-cli report --period month # 30-day window with weekly bucketsReports cover daily scores, averages, deltas vs the previous window, sleep details, and a short recommendation block.
oura-cli db trends 30 # score trends across the last 30 days
oura-cli db stats # row counts, date range, personal bestsWhen you want raw Oura V2 data, every endpoint shares the same shape — today | date <day> | week:
oura-cli sleep today
oura-cli readiness date 2026-05-10
oura-cli activity week
oura-cli hr week
oura-cli spo2 week
oura-cli stress week
oura-cli workout weekOutput auto-switches to JSON the moment you pipe it:
oura-cli sleep week | jq '.[] | {day, score, hrv: .contributors.hrv_balance}'
oura-cli db trends 90 > trends.json| Setting | Flag | Env var | Default |
|---|---|---|---|
| Token | --token |
OURA_TOKEN |
(file) |
| Token file path | OURA_TOKEN_PATH |
~/.oura-token |
|
| Database path | --db |
OURA_DB_PATH |
~/.oura-cli/oura.db |
| Timezone | --tz |
OURA_TZ |
system timezone, else UTC |
| Output format | --format |
auto-detect (TTY → table) |
This tool reads your personal health data — handle the token with care.
~/.oura-tokenis written with0600permissions on POSIX (oura-cli logindoes it for you). On Windows the file is written but ACL hardening is left to you.OURA_TOKENas an env var is convenient for scripts and CI, but it shows up inps auxe, heap dumps, and core dumps. Prefer the file for interactive use.--token <pat>is the least safe option: the value lands in shell history. Avoid it outside throw-away scripts.- Revoke a token at cloud.ouraring.com/personal-access-tokens, not via this CLI.
- API error messages truncate response bodies to 200 chars and redact
Bearertokens and"token":"…"patterns before printing.
oura-cli performs no telemetry. The only outbound network traffic is your authenticated Oura Cloud API calls.
| Endpoint | Source | Cached table |
|---|---|---|
| Sleep | Oura V2 daily_sleep |
daily_sleep |
| Readiness | Oura V2 daily_readiness |
daily_readiness |
| Activity | Oura V2 daily_activity |
daily_activity |
| Heart rate | Oura V2 heartrate |
heartrate |
| SpO₂ | Oura V2 daily_spo2 |
daily_spo2 |
| Stress | Oura V2 daily_stress |
daily_stress |
| Workouts | Oura V2 workout |
workouts |
| Sleep model | Oura V2 sleep |
sleep_model |
| Cardiovascular age | Oura V2 cardiovascular_age |
cardiovascular_age |
Runtime: Bun. Storage: built-in bun:sqlite. CLI parsing: citty. Output styling: chalk. One 100 kB dist/index.js, no native deps.
If you're driving the CLI from a script or LLM harness:
oura-cli describe— JSON manifest of every command, argument, and output schema. Agents discover capabilities without scraping--help.oura-cli healthcheck—{ok, version, latencyMs}JSON for liveness probes.- Errors emit a stable JSON envelope on stderr:
{"error":{"code":"…","message":"…","hint":"…"}}. - Documented exit codes:
0success,1user error,2auth,3API,4storage. - JSON Schemas under
docs/schemas/describe every output shape, semver-stable.
Plays cleanly with OpenClaw — oura-cli manifest returns the tool-registry shape. A first-party oura-mcp companion is on the roadmap.
- Bun >= 1.0
- macOS, Linux, or Windows (WSL)
- An Oura Personal Access Token
See CONTRIBUTING.md. Bug reports and pull requests welcome at drakulavich/oura-cli/issues.
Made with 💍🤖 under MIT License.
