paddleocr
Reads text from scanned pages, photos and PDFs and returns it as structured Markdown or JSON, so you can pull tables, formulas and headers out of a document without retyping them. Covers many languages and works as input for AI tools.
CLI for the Google Health API v4, built for AI agents and developers. 40 verified data types: steps, heart rate, exercise, sleep, weight, SpO2, HRV, ECG, blood glucose, nutrition, and more Agent-first: simplified JSON output, deterministic exit codes.
Claude Code
$ npx -y skills add Google-Health-API/google-health-cli --agent claude-code
Codex
$ npx skills add Google-Health-API/google-health-cli -a codex
Cursor
$ npx skills add Google-Health-API/google-health-cli -a cursor
Gemini CLI
$ npx skills add Google-Health-API/google-health-cli -a gemini-cli
GitHub Copilot
$ npx skills add Google-Health-API/google-health-cli -a github-copilot
OpenCode
$ npx skills add Google-Health-API/google-health-cli -a opencode
Windsurf
$ npx skills add Google-Health-API/google-health-cli -a windsurf
CLI for the Google Health API v4 — built for AI agents and developers.
--dry-run, --rawgo build -o ghealth .ghealth setup # One-time: GCP project + OAuth
ghealth data steps daily-rollup --from 2026-03-22 --to 2026-03-29 # Weekly step totals
ghealth data heart-rate list --from today --limit 10 # Recent heart rate readings
ghealth schema types # See all available data types
Download and Install Go
git clone https://github.com/Google-Health-API/google-health-cli.git
cd google-health-cli
go build -o ghealth .
ghealth setup
Walks you through: GCP project ID, OAuth credentials (download from Console — Desktop application type), Health API enablement, scope selection, and browser-based OAuth login.
Files written under ~/.config/ghealth/ (override with GHEALTH_CONFIG_DIR):
client_secret.json — your OAuth client (mode 0600)credentials.json — access + refresh tokens (mode 0600, plaintext JSON)config.toml — active profile (project, scopes)Tokens refresh automatically.
ghealth setup \
--project-id my-project \
--client-secret ~/Downloads/client_secret_123.json \
--scopes-preset readonly \
--skip-enable-api \
--no-prompt
Add --non-interactive-auth to skip the browser step too — complete later with ghealth auth login --complete <code> (see below).
| Scenario | Method |
|---|---|
| Interactive | ghealth setup or ghealth auth login |
| Headless / no browser | ghealth auth login --non-interactive → click URL on any device → ghealth auth login --complete <code> |
| Move tokens between machines | ghealth auth export → ghealth auth import |
| Pre-configured token | export GHEALTH_ACCESS_TOKEN=ya29... |
| Credential file | export GHEALTH_CREDENTIALS_FILE=/path/to/creds.json |
| GCP environment | Application Default Credentials (automatic) |
Precedence: GHEALTH_ACCESS_TOKEN > GHEALTH_CREDENTIALS_FILE > stored credentials > ADC.
# 1. On the host running ghealth:
ghealth auth login --non-interactive --scopes-preset readonly
# → JSON with auth_url (PKCE S256 challenge + random state baked in)
# and a complete_command. pending_auth.json holds the verifier locally.
# 2. Open auth_url in any browser, click "Allow".
# The browser will redirect to a localhost URL that fails to load — expected.
# Copy either the full redirected URL or just the 'code' query parameter.
# 3. Back on the ghealth host (both forms work):
ghealth auth login --complete 'http://localhost/?code=4/0AX4XfWh...&state=cQq...'
ghealth auth login --complete 4/0AX4XfWh...
# → state validated, PKCE verifier sent on exchange, tokens persisted.
State mismatch (URL paste with the wrong state parameter) clears the pending flow and returns exit 2. The bare-code form skips state validation but still consumes the pending file, so a stale flow can't be replayed.
# source (already authenticated):
ghealth auth export > /tmp/ghealth-creds.json
scp /tmp/ghealth-creds.json target:
# target (also needs client_secret.json — either run 'ghealth setup --non-interactive-auth' or copy it):
ghealth auth import --file /tmp/ghealth-creds.json
When no OAuth client_secret.json is configured, every auth command returns a
structured error with a next_steps array — the same six steps every time —
so an agent can relay it to a user verbatim without scraping prose:
ghealth auth login
# → exit 5, JSON on stderr:
# {
# "error": {
# "type": "config", "code": 5,
# "message": "No OAuth client_secret.json configured",
# "hint": "Run 'ghealth setup' to create or import OAuth credentials",
# "next_steps": [
# "Open https://console.cloud.google.com/apis/credentials",
# "Create or select a Google Cloud project",
# "Enable the Google Health API (...)",
# "Create OAuth client ID with Application type: Desktop app",
# "Download the client_secret JSON",
# "Run: ghealth setup --client-secret /path/to/client_secret.json"
# ]
# }
# }
Same next_steps are emitted by:
ghealth auth login (interactive / --non-interactive / --complete)ghealth auth status when neither stored creds nor env creds are presentghealth auth refresh, ghealth auth export (when nothing to refresh/export)ghealth setup --no-prompt when --client-secret is missingTo fetch the checklist without triggering an error (e.g. so an agent can display the bootstrap steps before calling auth at all):
ghealth setup --instructions
# → exit 0, JSON on stdout with status: "instructions" and the next_steps array
40 types verified against the live API. Run ghealth schema types for the full list.
| Type | Key Values | Operations |
|---|---|---|
steps | (use daily-rollup for countSum) | list, rollup, daily-rollup, reconcile |
heart-rate | beatsPerMinute | list, rollup, daily-rollup, reconcile |
exercise | type, duration, calories, avgHeartRate, notes | list, get, create, update, delete, reconcile, export-tcx |
sleep | minutesAsleep, minutesAwake, stageMinutes | list, get, create, update, delete, reconcile |
weight | weightGrams | list, get, create, update, delete, rollup, daily-rollup, reconcile |
body-fat | percentage | list, get, create, update, delete, rollup, daily-rollup, reconcile |
height | heightMillimeters | list, get, create, update, delete, reconcile |
distance | (use daily-rollup for millimetersSum) | list, rollup, daily-rollup, reconcile |
heart-rate-variability | RMSSD | list, reconcile |
oxygen-saturation | percentage (SpO2) | list, reconcile |
altitude | altitude value | list, rollup, daily-rollup, reconcile |
active-zone-minutes | activeZoneMinutes, heartRateZone | list, daily-rollup, reconcile |
activity-level | SEDENTARY, LIGHT, MODERATE, VIGOROUS | list, reconcile |
basal-energy-burned | kcal per interval (BMR) | list, reconcile |
active-energy-burned | kcal per interval (activity) | list, rollup, daily-rollup, reconcile |
vo2-max | VO2 max value | list, reconcile |
total-calories | (use daily-rollup for kcalSum) | daily-rollup |
sedentary-period | sedentary intervals | list, daily-rollup, reconcile |
swim-lengths-data | swimStrokeType, strokeCount (use daily-rollup for strokeCountSum) | list, rollup, daily-rollup, reconcile |
hydration-log | milliliters consumed | list, get, daily-rollup, reconcile |
nutrition-log | nutrients, energy, mealType, food | list, get, rollup, daily-rollup, reconcile |
food | nutrient profiles, servings (catalog — no time filter) | list, get |
food-measurement-unit | displayName (catalog — no time filter) | list, get |
blood-glucose | mg/dL, mealType, measurementTiming | list, get, rollup, daily-rollup, reconcile |
core-body-temperature | temperatureCelsius | list, get, rollup, daily-rollup, reconcile |
electrocardiogram | waveform, resultClassification (requires ecg.readonly) | list |
irregular-rhythm-notification | alert windows (requires irn.readonly) | list |
daily-resting-heart-rate | beatsPerMinute per day | list, reconcile |
daily-heart-rate-variability | daily HRV summary | list, reconcile |
daily-oxygen-saturation | daily SpO2 summary | list, reconcile |
daily-respiratory-rate | daily respiratory rate | list, reconcile |
daily-vo2-max | daily VO2 max | list, reconcile |
daily-sleep-temperature-derivations | temp deviation from baseline | list, reconcile |
respiratory-rate-sleep-summary | per-stage respiratory rate | list, reconcile |
run-vo2-max | VO2 max from running | list, daily-rollup, reconcile |
floors | (rollup only — countSum) | rollup, daily-rollup, reconcile |
active-minutes | (rollup only) | rollup, daily-rollup, reconcile |
time-in-heart-rate-zone | (rollup only) | daily-rollup, reconcile |
calories-in-heart-rate-zone | (rollup only — caloriesInHeartRateZones array per bucket) | rollup, daily-rollup, reconcile |
daily-heart-rate-zones | (reconcile only) | reconcile |
export-tcx writes the raw Google TCX, or — with --as csv — flattens it to one row per trackpoint (time, activity, lap, sport, latitude_deg, longitude_deg, altitude_m, distance_m, heart_rate_bpm, cadence_rpm, speed_mps, watts) for direct pd.read_csv consumption. Indoor activities have no track and yield a header-only CSV; their summary/notes live in data exercise list. Pass --output - to stream to stdout instead of a file.
ghealth data exercise export-tcx --id <id> --output ride.csv --as csv
ghealth data exercise export-tcx --id <id> --output - --as csv | head # stream to stdout
# Recent heart rate (sample-type: returns individual readings)
ghealth data heart-rate list --from today --limit 10
# Daily step totals for a week (rollup: returns aggregated counts)
ghealth data steps daily-rollup --from 2026-03-22 --to 2026-03-29
# Exercises this month
ghealth data exercise list --from 2026-03-01
# Weight history
ghealth data weight list --limit 20
# Sleep (summary by default, --detail for stage-by-stage breakdown)
ghealth data sleep list --limit 5
ghealth data sleep list --limit 5 --detail
Every read (list, get, rollup, daily-rollup, reconcile) returns the same JSON shape — an object {"dataPoints": [...]} with optional _hints and nextPageToken — so the rows are always under dataPoints.
list returns up to --limit rows (default 500). When more exist it includes a nextPageToken; pass it back with --page-token to fetch the next page losslessly (no rows skipped or repeated):
ghealth data heart-rate list --from 2026-06-15 --limit 500 # → {"dataPoints":[…], "nextPageToken":"ABC"}
ghealth data heart-rate list --from 2026-06-15 --limit 500 --page-token ABC
Some types (steps, distance) return time intervals without values from list. Use daily-rollup to get totals:
# This returns minute-by-minute intervals (no step count):
ghealth data steps list --from today --limit 5
# This returns daily totals with actual counts:
ghealth data steps daily-rollup --from 2026-03-22 --to 2026-03-29
# → {"dataPoints": [{"date": "2026-03-28", "countSum": "9037"}, ...]}
For the presence-aware types — altitude, distance, floors, steps, total-calories — a date that is absent from rollup output means the device was not worn (or did not sync) that day, not that the value was zero. A bucket with countSum: "0" is a true zero: the device was worn and genuinely recorded no activity.
countSum: "0" → true zero (worn, no activity)Reads text from scanned pages, photos and PDFs and returns it as structured Markdown or JSON, so you can pull tables, formulas and headers out of a document without retyping them. Covers many languages and works as input for AI tools.
Gives your AI assistant a memory that persists across sessions, so it remembers your preferences and earlier work in this repository instead of starting fresh. Search, forget, pause and resume memories with simple commands.
Gives AI agents a library of ready-made skills for scientific work such as metabolic flux analysis, protein experiment design, time series modeling, and analytical method validation, so research tasks need less hand-built code. It works with any agent that supports the open Agent Skills standard.
Gives Claude Code skills, agents, and commands for PostHog analytics, session replay, feature flags, error tracking, and LLM observability. Includes MCP server setup and project access checks.
CLI for the Google Health API v4, built for AI agents and developers. 40 verified data types: steps, heart rate, exercise, sleep, weight, SpO2, HRV, ECG, blood glucose, nutrition, and more Agent-first: simplified JSON output, deterministic exit codes. Install it with the command on its page. It includes ghealth-shared, ghealth. Its skills do not fire on their own yet. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it