{"id":50508745,"url":"https://github.com/drakulavich/oura-cli","last_synced_at":"2026-06-02T18:30:46.221Z","repository":{"id":357565761,"uuid":"1173457186","full_name":"drakulavich/oura-cli","owner":"drakulavich","description":"Own your Oura Ring data — local CLI with TTY-aware output and JSON manifest, built for humans and AI agents","archived":false,"fork":false,"pushed_at":"2026-05-13T10:49:50.000Z","size":121,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-13T11:12:41.715Z","etag":null,"topics":["ai-agent","bun","cli","health","mcp","oura","oura-ring","quantified-self","sleep","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@drakulavich/oura-cli","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drakulavich.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-05T11:40:58.000Z","updated_at":"2026-05-13T10:49:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/drakulavich/oura-cli","commit_stats":null,"previous_names":["drakulavich/oura-cli"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/drakulavich/oura-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drakulavich%2Foura-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drakulavich%2Foura-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drakulavich%2Foura-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drakulavich%2Foura-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drakulavich","download_url":"https://codeload.github.com/drakulavich/oura-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drakulavich%2Foura-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33833277,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","bun","cli","health","mcp","oura","oura-ring","quantified-self","sleep","typescript"],"created_at":"2026-06-02T18:30:45.615Z","updated_at":"2026-06-02T18:30:46.213Z","avatar_url":"https://github.com/drakulavich.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eoura-cli\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://flakiness.io/Laputa/oura-cli\"\u003e\u003cimg src=\"https://img.shields.io/endpoint?url=https%3A%2F%2Fflakiness.io%2Fapi%2Fbadge%3Finput%3D%257B%2522badgeToken%2522%253A%2522badge-2qTwJcrJSmhJmKfKklQkKG%2522%257D\" alt=\"Tests\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@drakulavich/oura-cli\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@drakulavich/oura-cli\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://bun.sh\"\u003e\u003cimg src=\"https://img.shields.io/badge/runtime-Bun-f9f1e1?logo=bun\" alt=\"Bun\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/openclaw/openclaw\"\u003e\u003cimg src=\"https://img.shields.io/badge/OpenClaw-compatible-5b21b6\" alt=\"OpenClaw compatible\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cb\u003eOwn your Oura Ring data.\u003c/b\u003e 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.\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/drakulavich/oura-cli/raw/main/assets/demo.gif\" alt=\"oura-cli demo: --version, db today, db week, report, describe\" width=\"720\"\u003e\n\u003c/p\u003e\n\n- **Offline-first.** Everything caches into `~/.oura-cli/oura.db` after one `oura-cli sync`. Reports keep working when your internet doesn't.\n- **Real terminal reports.** `oura-cli report` writes a weekly or monthly digest with averages, trend deltas, and \"you slept poorly Tuesday\" callouts. No dashboards, no logging in.\n- **Pipe-friendly.** Output auto-switches to stable JSON when stdout isn't a terminal. Analyse with `jq`, plot with `gnuplot`, or feed it into your own scripts.\n- **Single 100 kB binary, MIT, no telemetry.** Built on Bun; zero native dependencies.\n\n## Install\n\n```bash\ncurl -fsSL https://bun.sh/install | bash   # if you don't have Bun yet\nbun add -g @drakulavich/oura-cli\n```\n\nYou'll also need a [Personal Access Token from Oura](https://cloud.ouraring.com/personal-access-tokens). Paste it into `oura-cli login` once — it lands at `~/.oura-token` with `0600` perms.\n\n## First five minutes\n\n```bash\noura-cli login          # paste your PAT, one time\noura-cli sync           # backfill recent days into ~/.oura-cli/oura.db\noura-cli report         # weekly digest in the terminal\n```\n\nThat's it. Subsequent `oura-cli sync` pulls only new days.\n\n## Daily use\n\n### Today\n\n```bash\noura-cli db today\n```\n\nToday's scores from the local cache. If you forgot to sync, run `oura-cli sync` first.\n\n### A specific day\n\n```bash\noura-cli db date 2026-05-10\n```\n\n### Last week, at a glance\n\n```bash\noura-cli db week                  # local cache summary, no API hit\noura-cli sleep week               # fresh sleep details direct from Oura\n```\n\n### Reports\n\n```bash\noura-cli report                   # weekly (default)\noura-cli report --period month    # 30-day window with weekly buckets\n```\n\nReports cover daily scores, averages, deltas vs the previous window, sleep details, and a short recommendation block.\n\n### Trends and stats\n\n```bash\noura-cli db trends 30             # score trends across the last 30 days\noura-cli db stats                 # row counts, date range, personal bests\n```\n\n### Per-endpoint detail\n\nWhen you want raw Oura V2 data, every endpoint shares the same shape — `today | date \u003cday\u003e | week`:\n\n```bash\noura-cli sleep today\noura-cli readiness date 2026-05-10\noura-cli activity week\noura-cli hr week\noura-cli spo2 week\noura-cli stress week\noura-cli workout week\n```\n\n### Piping to other tools\n\nOutput auto-switches to JSON the moment you pipe it:\n\n```bash\noura-cli sleep week | jq '.[] | {day, score, hrv: .contributors.hrv_balance}'\noura-cli db trends 90 \u003e trends.json\n```\n\n## Configuration\n\n| Setting          | Flag        | Env var            | Default                     |\n|------------------|-------------|--------------------|-----------------------------|\n| Token            | `--token`   | `OURA_TOKEN`       | (file)                      |\n| Token file path  |             | `OURA_TOKEN_PATH`  | `~/.oura-token`             |\n| Database path    | `--db`      | `OURA_DB_PATH`     | `~/.oura-cli/oura.db`       |\n| Timezone         | `--tz`      | `OURA_TZ`          | system timezone, else `UTC` |\n| Output format    | `--format`  |                    | auto-detect (TTY → table)   |\n\n## Security\n\nThis tool reads your personal health data — handle the token with care.\n\n- `~/.oura-token` is written with `0600` permissions on POSIX (`oura-cli login` does it for you). On Windows the file is written but ACL hardening is left to you.\n- `OURA_TOKEN` as an env var is convenient for scripts and CI, but it shows up in `ps auxe`, heap dumps, and core dumps. Prefer the file for interactive use.\n- `--token \u003cpat\u003e` is the least safe option: the value lands in shell history. Avoid it outside throw-away scripts.\n- Revoke a token at [cloud.ouraring.com/personal-access-tokens](https://cloud.ouraring.com/personal-access-tokens), not via this CLI.\n- API error messages truncate response bodies to 200 chars and redact `Bearer` tokens and `\"token\":\"…\"` patterns before printing.\n\n**oura-cli performs no telemetry.** The only outbound network traffic is your authenticated Oura Cloud API calls.\n\n## What's inside\n\n| Endpoint   | Source                              | Cached table          |\n|------------|-------------------------------------|-----------------------|\n| Sleep      | Oura V2 `daily_sleep`               | `daily_sleep`         |\n| Readiness  | Oura V2 `daily_readiness`           | `daily_readiness`     |\n| Activity   | Oura V2 `daily_activity`            | `daily_activity`      |\n| Heart rate | Oura V2 `heartrate`                 | `heartrate`           |\n| SpO₂       | Oura V2 `daily_spo2`                | `daily_spo2`          |\n| Stress     | Oura V2 `daily_stress`              | `daily_stress`        |\n| Workouts   | Oura V2 `workout`                   | `workouts`            |\n| Sleep model      | Oura V2 `sleep`               | `sleep_model`         |\n| Cardiovascular age | Oura V2 `cardiovascular_age` | `cardiovascular_age`  |\n\nRuntime: [Bun](https://bun.sh). Storage: built-in `bun:sqlite`. CLI parsing: [citty](https://github.com/unjs/citty). Output styling: [chalk](https://github.com/chalk/chalk). One 100 kB `dist/index.js`, no native deps.\n\n## Automation (LLM agents, scripts, MCP)\n\nIf you're driving the CLI from a script or LLM harness:\n\n- `oura-cli describe` — JSON manifest of every command, argument, and output schema. Agents discover capabilities without scraping `--help`.\n- `oura-cli healthcheck` — `{ok, version, latencyMs}` JSON for liveness probes.\n- Errors emit a stable JSON envelope on stderr: `{\"error\":{\"code\":\"…\",\"message\":\"…\",\"hint\":\"…\"}}`.\n- Documented exit codes: `0` success, `1` user error, `2` auth, `3` API, `4` storage.\n- JSON Schemas under [`docs/schemas/`](docs/schemas/) describe every output shape, semver-stable.\n\nPlays cleanly with [OpenClaw](https://github.com/openclaw/openclaw) — `oura-cli manifest` returns the tool-registry shape. A first-party `oura-mcp` companion is on the roadmap.\n\n## Requirements\n\n- [Bun](https://bun.sh) \u003e= 1.0\n- macOS, Linux, or Windows (WSL)\n- An [Oura Personal Access Token](https://cloud.ouraring.com/personal-access-tokens)\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports and pull requests welcome at [drakulavich/oura-cli/issues](https://github.com/drakulavich/oura-cli/issues).\n\n## License\n\nMade with 💍🤖 under MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrakulavich%2Foura-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrakulavich%2Foura-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrakulavich%2Foura-cli/lists"}