Google Workspace CLI — one command-line tool for the Google Health API. Includes AI agent skills.
# Add to your Claude Code skills
git clone https://github.com/Google-Health-API/google-health-cliGuides for using ai agents skills like google-health-cli.
google-health-cli is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by Google-Health-API. Google Workspace CLI — one command-line tool for the Google Health API. Includes AI agent skills. It has 52 GitHub stars.
google-health-cli's catalog security scan is still queued. You can run an instant dependency and prompt-injection check now with the "Scan for vulnerabilities" button above.
Clone the repository with "git clone https://github.com/Google-Health-API/google-health-cli" and add it to your Claude Code skills directory (see the Installation section above).
google-health-cli is primarily written in Go. It is open-source under Google-Health-API on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh google-health-cli against similar tools.
No comments yet. Be the first to share your thoughts!
Unlocks once the catalog security scan passes (runs nightly).
The deep catalog scan for this skill is still queued. Run an instant dependency check now instead.
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
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