ghealth について
ghealthはGoogle Health API v4向けのコマンドラインツールで、40種類のデータを読み取り、集計、照合、エクスポートし、一部を書き込めます。健康データを検索・分析するユーザー向けに、ページング、CSV出力、複数ソースの照合を備えています。
主な機能
- 0140種類のデータにアクセス
- 02測定値、セッション、日次サマリーの検索
- 03複数ソースの集計と照合
- 04CSVとTCXトラックのエクスポート
- 05書き込み可能なデータの作成・更新・削除
活用シーン
- 01歩数、距離、カロリーの日次集計
- 02心拍数、睡眠、運動記録の検索
- 03表計算での分析用データ出力
- 04複数ソースの健康データ照合
MCP 対応
入力にはMCP連携についての記載がありません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ google-health-api/ google-health-cli --skill ghealthインストール後、Claude Code で/ghealthを入力して読み込まれたか確認します。
詳細
ghealth
Google Health API v4 用 CLI。検証済みのデータ型が 40 種類あります。
前提条件: 認証、セットアップ、グローバルフラグについては ../ghealth-shared/SKILL.md を参照してください。
適切な操作の選び方
| 目的 | 操作 | 例 |
|---|---|---|
| 1 日の合計(歩数、距離、カロリー) | daily-rollup | ghealth data steps daily-rollup --from 2026-03-22 --to 2026-03-29 |
| 個々の測定値(HR、体重、SpO2) | list | ghealth data heart-rate list --from today --limit 20 |
| セッション(運動、睡眠) | list | ghealth data exercise list --from 2026-03-01 |
| 1 日ごとのサマリー(安静時 HR、HRV、呼吸数) | list | ghealth data daily-resting-heart-rate list --from 2026-03-01 |
| 複数ソースのデータを統合 | reconcile | ghealth data weight reconcile --from 2026-01-01 |
重要な理由: steps list は分単位の区間を返しますが、カウントは含まれません。実際の歩数合計(countSum)を取得するには daily-rollup を使います。distance(millimetersSum)と floors も同様です。
データ型の概要
最新バージョンは ghealth schema types を実行して確認してください。簡易リファレンス:
合計値には daily-rollup を使用:
steps→ 1 日ごとのcountSumdistance→ 1 日ごとのmillimetersSumtotal-calories→ 1 日ごとのkcalSum(rollup 専用)floors→countSum(rollup 専用)active-minutes→ (rollup 専用)swim-lengths-data→ 1 日ごとのstrokeCountSumcalories-in-heart-rate-zone→ 1 日ごとのcaloriesInHeartRateZones(rollup 専用)
測定値には list を使用:
heart-rate、weight(書き込み可能)、body-fat(書き込み可能)、height(書き込み可能)、oxygen-saturation、heart-rate-variability、altitude、vo2-max、active-zone-minutes、activity-level、basal-energy-burned、active-energy-burned、blood-glucose、core-body-temperature、respiratory-rate-sleep-summary、run-vo2-max、sedentary-period、swim-lengths-data、hydration-log
セッションには list を使用:
exercise(書き込み可能)— 種類、時間、カロリー、HR サマリー、メモを含みますsleep(書き込み可能)— デフォルトでサマリーを含みます。ステージごとの内訳を取得するには--detailを追加します。
心臓関連(専用スコープ、list のみ):
electrocardiogram— 波形サンプルとリズム分類。ecg.readonlyが必要です。irregular-rhythm-notification— アラートの時間帯。irn.readonlyが必要です。
栄養:
nutrition-log— 栄養素とエネルギーの内訳を含む記録済みの食品項目(list、get、rollup、daily-rollup、reconcile)food、food-measurement-unit— 参照カタログ(list、get のみ)。時間による絞り込みには対応していません —--from/--toは無視されます。
1 日ごとのサマリー(日付ごとに 1 つの値、日付で絞り込み):
daily-resting-heart-rate、daily-heart-rate-variability、daily-oxygen-saturation、daily-respiratory-rate、daily-vo2-max、daily-sleep-temperature-derivations
ID で単一のポイントを取得: exercise、sleep、weight、body-fat、height、hydration-log、nutrition-log、blood-glucose、core-body-temperature、food、food-measurement-unit では get --id <id> がサポートされています。
CLI では判断できないパターン
次の操作には、--help や schema では得られない判断が必要です。
日付に依存するデータをクエリする前に、ユーザーのタイムゾーンを取得します:
ghealth user settings get # → timeZone: "Europe/London", utcOffset: "3600s"
# Then use --from/--to with the correct local dates
この情報はアカウントのタイムゾーンを報告するだけです。CLI でそのタイムゾーンに基づいて日付を解決するには、ghealth config set timezone <IANA zone> で明示的に設定します。
睡眠/運動の 1 リクエストあたりのページサイズ上限は 25 件です(CLI が自動的にページネーションします):
ghealth data sleep list --limit 5 # CLI handles pagination internally
大量の list 結果をページングする。 list は最大 --limit 行(デフォルトは 500)を返します。さらに結果がある場合、レスポンスには nextPageToken とヒントが含まれます。--page-token でそのトークンを渡すと、前のページの末尾から正確に再開し、行のスキップや重複はありません:
ghealth data heart-rate list --from 2026-06-15 --limit 500
# → {"dataPoints":[…500…], "nextPageToken":"ABC", "_hints":[…]}
ghealth data heart-rate list --from 2026-06-15 --limit 500 --page-token ABC
# → next 500 rows
心拍数と運動セッションを関連付ける:
# 1. Get exercise time window
ghealth data exercise list --from today --limit 1
# → start: "2026-03-29T14:18:32+01:00", end: "2026-03-29T14:39:14+01:00"
# 2. Query HR for that window using --filter (raw API syntax, UTC required)
ghealth data heart-rate list --filter 'heart_rate.sample_time.physical_time >= "2026-03-29T13:18:32Z" AND heart_rate.sample_time.physical_time < "2026-03-29T13:40:00Z"'
分析用データのエクスポート
-o <file> を使うと、データをファイルに書き込めます。 -o を設定すると、stdout には列スキーマを含む概要のみが表示され、データ自体は表示されません。つまり、データを取得してすぐに、stdout に表示された列名を使って分析コードを書けます。ファイルを読み込む必要はありません。
ghealth data steps daily-rollup --from 2026-03-24 --to 2026-03-30 --format csv -o steps.csv
stdout に表示される内容(エージェントが確認できるのはこれだけです):
Wrote 6 rows to steps.csv
Columns: countSum, date
Preview:
countSum,date
4062,2026-03-29
9122,2026-03-28
2469,2026-03-27
ファイルに含まれる内容(stdout には出力されない完全な CSV):
countSum,date
4062,2026-03-29
9122,2026-03-28
2469,2026-03-27
6541,2026-03-26
4025,2026-03-25
3995,2026-03-24
これで、エージェントは列が countSum と date であるとわかるため、ファイルを一度も読み込まずに pd.read_csv("steps.csv") と記述できます。
ファイルへのパイプは使わないでください。代わりに -o を使ってください。パイプ(> file.csv)を使うと、すべてのデータがファイルに送られますが、stdout には何も出力されません。そのため、エージェントは列スキーマを確認できず、構造を知るためにファイルを読み込む必要があります。
その他の例:
# Sleep — nested stageMinutes auto-flattened to stageMinutes.AWAKE, stageMinutes.DEEP, etc.
ghealth data sleep list --from 2026-03-01 --format csv -o sleep.csv
# Exercise — metricsSummary.caloriesKcal, metricsSummary.averageHeartRateBeatsPerMinute, etc.
ghealth data exercise list --from 2026-03-01 --format csv -o exercise.csv
# Heart rate — 500 readings straight to file
ghealth data heart-rate list --from today --limit 500 --format csv -o hr.csv
エクスポートした運動の時系列データ(GPS/心拍数のトラック)を CSV に変換します。 export-tcx --as csv は TCX トラックをトラックポイントごとに 1 行に展開します。TCX XML を解析する代わりに、そのまま pd.read_csv で読み込めます。
# Find the exercise id first, then export its track
ghealth data exercise list --from 2026-06-01 --limit 10
ghealth data exercise export-tcx --id <id> --output ride.csv --as csv # or --output - for stdout
列(データフレーム向けに固定、安定):time, activity, lap, sport, latitude_deg, longitude_deg, altitude_m, distance_m, heart_rate_bpm, cadence_rpm, speed_mps, watts。存在しないセンサーの値は空のセル(pandas では NaN)になり、ゼロにはなりません。distance_m は累積値です。行数が 0 の場合は、屋内アクティビティまたはセンサーのないアクティビティです(Google はそのようなアクティビティのトラックを出力しません)。セッションの概要とワークアウトのメモはトラックのエクスポートではなく、data exercise list から取得できます。
データの書き込み
書き込み可能な型:exercise、sleep、weight、body-fat、height。書き込みは非同期です(API は Operation オブジェクトを返します)。
正しいペイロード形式を確認するには、--raw を指定して実際のレスポンスを調べます。
ghealth data weight list --raw --limit 1
# Use the response structure as a template for your create payload
書き込み操作では、create、update --id <id> [--update-mask fields]、delete --ids <ids> を使います。
注意事項
- データが欠けている日はゼロではありません(
altitude、distance、floors、steps、total-calories):集計結果に日付がない場合、デバイスが装着されていなかったか、同期されていません。ゼロではありません。countSum: "0"は実際のゼロ(装着されていたが、アクティビティがなかった)を意味します。欠損バケットを 0 に置き換えたり、欠損日をゼロとして週次/月次の平均を算出したりしないでください。統計値がひそかに過小評価されます。 - 文字列と数値の値は protobuf の JSON エンコーディングに従います。
int64フィールド(beatsPerMinute、countSum、minutesAsleep)は文字列です。int32/doubleフィールド(weightGrams、caloriesKcal、percentage)は数値です。 --filterの構文:使用できる比較演算子は>=と<のみです。市民時刻フィールド(Zなし):interval 型は{type}.interval.civil_start_time、sleep はsleep.interval.civil_end_time(終了時刻のみフィルター可能)、daily 型は{type}.dateです。物理時刻フィールド(Zあり):sample 型は{type}.sample_time.physical_timeです。- 書き込み操作は非同期です。API は作成/更新したデータではなく、Operation オブジェクトを返します。保存されたことを確認するには
listを使ってください。 - body fat の
deleteは HTTP 500 を返します。これは API のバグです。 - height の
updateは HTTP 400("updateMask not recognized")を返します。これは API のバグです。回避策としてcreateとdeleteを使ってください。 daily-rollupは市民時刻/現地日の単位で集計します(1 日のウィンドウ。--window-days Nで変更できます)。rollupは物理時刻で集計します(--window-size、既定値は86400s)。--from/--toに日付だけを指定すると、設定済みのタイムゾーン(ghealth config set timezone <IANA zone>)の午前 0 時を基準とします。未設定の場合はマシンのローカル時刻が使われます。現地日ごとの合計にはdaily-rollupを使ってください。どちらもウィンドウサイズを明示的に送信します。API はこれが省略されたリクエストを拒否します。