v0.4.4 · MIT licensed · Bun + TypeScript

Own your Oura data. Sleep, readiness, HRV and workouts — straight to your terminal.

Pull your Oura Ring data from the cloud, cache it locally in SQLite, and read it on your own terms. Weekly digests, daily scores, raw V2 endpoints, pipe-friendly JSON. No mobile app. No dashboards. No telemetry.

Terminal recording of oura-cli running --version, db today, db week, report, and describe
$ bun add -g @drakulavich/oura-cli
  • 9 Oura V2 endpoints
  • 1 SQLite file
  • 0 Native deps
  • 100% Your data, local

Capabilities

Your ring, in a single CLI.

Nine endpoints, one SQLite cache. Use the high-level digests or drop down to raw Oura V2 — same shape across every command.

Offline-first SQLite cache

One oura-cli sync lands everything in ~/.oura-cli/oura.db. Every report, trend and lookup after that hits local disk — no API call, no mobile app, no internet required. Subsequent syncs pull only new days.

  • bun:sqlite
  • ~/.oura-cli/oura.db
  • incremental sync
  • 9 cached tables

Real terminal reports

oura-cli report prints a weekly or monthly digest: daily scores, averages, deltas vs the previous window, sleep detail, and a short recommendation block. "You slept poorly Tuesday" callouts included.

  • --period week
  • --period month
  • trend deltas
  • recommendations

Pipe-friendly by default

Output auto-switches to stable JSON the moment stdout isn't a terminal. Pipe to jq, plot with gnuplot, or feed it straight into your own scripts and dashboards.

Trends & personal bests

oura-cli db trends 30 walks score history across the last N days. oura-cli db stats surfaces row counts, the full date range, and your personal bests.

  • db trends
  • db stats

Sleep, readiness & HR

Every Oura V2 endpoint — daily sleep, readiness, activity, heart rate, SpO₂, stress, workouts, sleep model, cardiovascular age — exposed with the same today | date | week shape.

Stable JSON envelope

Errors emit a deterministic JSON shape on stderr — code, message, hint. Documented exit codes for success, user errors, auth, API, and storage. Predictable for CI and agents.

Auto timezone

Uses your system timezone by default, falls back to UTC. Override per-invocation with --tz or OURA_TZ when you sync from a different machine.

No telemetry, ever

The only outbound network calls are your authenticated requests to Oura Cloud. No analytics. No phone-home. Token files written with 0600 on POSIX so only you can read them.

Bun + TypeScript, one binary

Built on Bun with bun:sqlite, citty for CLI parsing and chalk for output. One ~100 kB dist/index.js. Zero native deps.

OpenClaw-ready

oura-cli manifest returns the OpenClaw tool-registry shape. Drop your ring data straight into an LLM agent.

Quick start

Three commands to your first weekly digest.

Requires Bun ≥ 1.0 and an Oura Personal Access Token. Works on macOS, Linux, and Windows (WSL).

01

Install Bun & oura-cli

Skip the first line if you already have Bun.

$ curl -fsSL https://bun.sh/install | bash
$ bun add -g @drakulavich/oura-cli
02

Paste your token

One time. Lands at ~/.oura-token, 0600.

$ oura-cli login
# paste PAT from cloud.ouraring.com
03

Sync & report

Backfill recent days, then print your week.

$ oura-cli sync
$ oura-cli report
# Today, from local cache
$ oura-cli db today

# A specific day
$ oura-cli db date 2026-05-10

# Last week at a glance — no API hit
$ oura-cli db week

# Pull the latest days into the cache
$ oura-cli sync
# Weekly digest (default)
$ oura-cli report

# 30-day window with weekly buckets
$ oura-cli report --format month

# Score trends across the last 30 days
$ oura-cli db trends 30

# Row counts, date range, personal bests
$ oura-cli db stats
# Every endpoint shares the same shape: today | date | week
$ oura-cli sleep today
$ oura-cli readiness date 2026-05-10
$ oura-cli activity week

# Fresh sleep detail straight from Oura
$ oura-cli sleep week

# Heart rate, SpO₂, stress, workouts
$ oura-cli hr week
$ oura-cli spo2 week
$ oura-cli stress week
$ oura-cli workout week
# Output auto-switches to JSON the moment you pipe
$ oura-cli sleep week | jq '.[] | {day, score, hrv: .contributors.hrv_balance}'

# Dump 90 days of trends to a file
$ oura-cli db trends 90 > trends.json

# Pipe a digest into your favorite LLM
$ oura-cli report | llm "Summarize my week and call out anything concerning"

What's inside

Nine endpoints, one SQLite file.

Every Oura V2 endpoint lands in its own cached table. Same date range, same shape, same JSON. Inspect with the sqlite3 CLI if you want — it's your data.

Endpoint Source Cached table CLI
Sleep Oura V2 daily_sleep daily_sleep oura-cli sleep …
Readiness Oura V2 daily_readiness daily_readiness oura-cli readiness …
Activity Oura V2 daily_activity daily_activity oura-cli activity …
Heart rate Oura V2 heartrate heartrate oura-cli hr …
SpO₂ Oura V2 daily_spo2 daily_spo2 oura-cli spo2 …
Stress Oura V2 daily_stress daily_stress oura-cli stress …
Workouts Oura V2 workout workouts oura-cli workout …
Sleep model Oura V2 sleep sleep_model via report
Cardiovascular age Oura V2 cardiovascular_age cardiovascular_age via report

Storage: bun:sqlite. CLI parsing: citty. Output: chalk.

Configuration

Sensible defaults. Override anything.

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, else UTC
Output format --format auto (TTY → table)

Automation

Built for agents as well as humans.

If you're driving the CLI from a script or LLM harness, the introspection surface is first-class — and the output contracts are semver-stable.

oura-cli describe

A JSON manifest of every command, argument and output schema. Agents discover capabilities without scraping --help.

oura-cli healthcheck

Returns {ok, version, latencyMs} for liveness probes. Wire it straight into your monitoring stack or agent harness.

OpenClaw skill

oura-cli manifest returns the tool-registry shape. A first-party oura-mcp companion is on the roadmap.

Learn more →

Stable JSON schemas

Schemas under docs/schemas/ describe every output. Exit codes are documented: 0 ok, 1 user, 2 auth, 3 API, 4 storage.

Browse schemas →

Security

Your health data.
Handled carefully.

This tool reads personal health data. The CLI is designed to keep your token off disk in obvious places, out of shell history, and out of error logs.

  • 0600 Token file perms on POSIX
  • 200 Char cap on API error bodies
  • 0 Telemetry calls, ever
Read the full security notes
  • file ~/.oura-token written with 0600 by oura-cli login. Only your user can read it.
  • env OURA_TOKEN works for CI & scripts — but shows up in ps auxe and core dumps. Prefer the file.
  • avoid --token <pat> lands in shell history. Throw-away scripts only.
  • redact API errors truncate response bodies to 200 chars and redact Bearer tokens and "token":"…" patterns.
  • revoke Lost device? Revoke at cloud.ouraring.com — not via this CLI.

Ready to own your data?

Open source, MIT licensed, no telemetry. Star the repo, grab the binary, paste your token — your weekly digest is one command away.

Copied