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.
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.