fitbit-googlehealth-mcp

fitbit-googlehealth-mcp

This MCP server enables Claude to access and log Fitbit health data, including activity, sleep, heart rate, and nutrition, with the ability to log meals by analyzing photos through Claude's vision capabilities.

Category
Visit Server

README

fitbit-googlehealth-mcp

Fitbit の広範なヘルスデータを取得し、食事写真から食事ログを書き込める Model Context Protocol (MCP) サーバー。TypeScript 実装、Cloudflare Workers にデプロイ。Claude モバイル / Claude Desktop / Claude.ai から接続して使えます。

個人利用前提の設計で、fork してあなた自身の Fitbit アプリ + Cloudflare アカウントで独立運用できます。

何ができる

  • Fitbit データの取得(Read tool 16 個)
    • Activity(歩数・距離・カロリー・運動ログ)
    • Heart Rate(日別 + 1秒〜15分の Intraday)
    • Sleep v1.2(stage 含む)
    • Body(体重・体脂肪・BMI)
    • Nutrition(食事ログ・水分)
    • SpO2 / 呼吸数 / 皮膚温 / HRV / VO2 Max
    • デバイス情報
  • 書き込み(Write tool 8 個)
    • 食事(log_food・日本語 OK)
    • 水分・体重・体脂肪・活動・睡眠の手動ログ
    • delete_food_log で個別エントリ取り消し
  • log_meal_photo: Claude モバイルで食事写真を添付 → Claude が視覚解析して栄養を推定 → 一括で Fitbit 食事ログに記録

⚠ 2026/09 の Fitbit Web API 停止について

Fitbit は 2026 年 9 月に既存の Web API(api.fitbit.com)を完全停止し、後継の Google Health API(health.googleapis.com/v4)に移行します。

  • 既存の Fitbit OAuth トークンは 移行不可 → Google OAuth で再同意が必要
  • あわせて、Fitbit アカウント自体を 2026/05/19 までに Google Account に統合必要(未統合は 2026/07/15 にデータ削除)
  • 本実装は Provider-agnostic 設計 を採っており、停止前に Google Health API 実装(src/providers/google-health/)を追加して差し替え予定

詳細は docs/research.md を参照。


前提

  • Fitbit アカウント(Google Account と統合済みが望ましい)
  • Fitbit Personal App(dev.fitbit.com で作成、callback http://127.0.0.1:8787/fitbit/callback)
  • Cloudflare アカウント(無料プランで十分)
  • Claude.ai アカウント(Web から Custom Connector を追加、モバイルに自動同期)
  • Node.js 20+ / pnpm 9+(ローカルビルド用)

セットアップ(5 ステップ)

1. Clone + install

git clone https://github.com/tachibanayu24/fitbit-googlehealth-mcp.git
cd fitbit-googlehealth-mcp
pnpm install

2. Fitbit Personal App 作成

dev.fitbit.com/apps/newPersonal タイプのアプリを作成:

  • OAuth 2.0 Application Type: Personal
  • Callback URL: http://127.0.0.1:8787/fitbit/callback

発行された Client IDClient Secret を控える。

3. 初回認可と Cloudflare への投入

# 認可フローを開始(ブラウザが開く)
export FITBIT_CLIENT_ID=<your-client-id>
export FITBIT_CLIENT_SECRET=<your-client-secret>
pnpm run setup:fitbit

ブラウザで承認すると refresh_token が取れて、以降表示される wrangler secret put / wrangler kv key put コマンドをコピペして実行:

# wrangler.toml は .gitignore 対象。テンプレからコピーして自分の値を入れる
cp wrangler.toml.example wrangler.toml

# KV namespace(一回きり)
pnpm wrangler kv namespace create TOKENS
pnpm wrangler kv namespace create CACHE
# 返ってきた id を wrangler.toml の <your-...-id> に貼り付け

# Secret(MCP_SHARED_SECRET は URL-safe な hex を推奨)
pnpm wrangler secret put FITBIT_CLIENT_ID
pnpm wrangler secret put FITBIT_CLIENT_SECRET
openssl rand -hex 32 | pnpm wrangler secret put MCP_SHARED_SECRET

# Fitbit トークン(setup:fitbit の出力をそのままコピペ、--remote 重要)
pnpm wrangler kv key put --remote --binding=TOKENS refresh_token '<paste>'
pnpm wrangler kv key put --remote --binding=TOKENS access_token  '<paste>'
pnpm wrangler kv key put --remote --binding=TOKENS expires_at    '<paste>'
pnpm wrangler kv key put --remote --binding=TOKENS user_id       '<paste>'

4. デプロイ

pnpm deploy
# → https://fitbit-googlehealth-mcp.<your-sub>.workers.dev

5. Claude.ai に Custom Connector として登録

  1. claude.ai で Settings → Connectors → Add Custom Connector
  2. URL に https://fitbit-googlehealth-mcp.<your-sub>.workers.dev/mcp/<MCP_SHARED_SECRET> を貼る
  3. 認証方式は OAuth なし(URL に secret を埋め込んでいるため)
  4. 保存すると Claude モバイル / Desktop / Web に自動同期される

モバイルで新規会話を開き、+ → Connectors → Fitbit を ON にして完了。


ツール一覧

Read(16)

Tool 引数 概要
get_profile プロフィール(単位系・身長・タイムゾーン)
list_devices デバイス一覧(バッテリ、最終同期時刻)
get_daily_summary date? 歩数・カロリー・心拍ゾーン・active minutes
get_activity_timeseries resource, start, end steps / distance / calories 等の時系列
get_exercise_list beforeDate?, limit? 運動ログ履歴
get_heart_rate_range start, end 日別心拍(resting + zones)
get_heart_rate_intraday date, detailLevel Intraday(1sec/1min/5min/15min)
get_sleep date? Sleep v1.2(stage 含む)
get_sleep_range start, end 期間 Sleep
get_body_log start, end 体重 + 体脂肪
get_food_log date? 食事ログ + 水分 + 栄養サマリ
get_spo2 start, end 血中酸素飽和度
get_respiratory_rate start, end 呼吸数
get_skin_temperature start, end 皮膚温(nightly relative)
get_hrv start, end HRV(RMSSD)
get_cardio_fitness date? Cardio Fitness Score(VO2 Max)

Write(7)

Tool 引数 概要
log_food foodName, calories, mealType, date?, nutritionalValues? 食事を 1 件記録(日本語 OK、PFC 保持)
log_meal_photo mealType, items[], date?, notes? 写真解析結果を一括で記録(Claude が視覚解析 → items を渡す前提)
log_water amountMl, date? 水分(ml)
log_weight weightKg, date?, time? 体重
log_body_fat fatPercent, date?, time? 体脂肪率
log_activity activityId or activityName+manualCalories, startTime, durationMs, date?, distanceKm? 手動で運動ログ
log_sleep startTime, durationMs, date? 手動で睡眠ログ

Delete(6)

Tool 引数 概要
delete_food_log logId, date? 食事エントリ削除
delete_water_log logId, date? 水分エントリ削除
delete_weight_log logId, date? 体重エントリ削除
delete_body_fat_log logId 体脂肪エントリ削除
delete_activity_log logId, date? 運動ログ削除
delete_sleep_log logId, date? 睡眠ログ削除

Meal preset(4)

作り置き用の再利用可能な栄養プロファイルを MCP サーバー側(Workers KV)に保存して、ログ時に栄養素込みで Fitbit へ投入する仕組み。Fitbit の Create Food API は栄養素を保存しない仕様なので、PFC 追跡にはこちらを使う。

Tool 引数 概要
save_meal_preset name, calories, protein?, carbs?, fat?, fiber?, sodium?, sugar?, notes? preset を保存(同名で上書き)
list_meal_presets 保存済み preset 一覧
log_preset name, mealType, date?, amount? preset を今日/指定日の食事ログに記録
delete_meal_preset name preset 削除(既存 log には影響なし)

date? は省略時 JST の今日 にフォールバック。Tool 総数 33(Read 16 + Write 7 + Delete 6 + Preset 4)。


使用例

写真で食事記録

🤳 モバイルで昼食の写真を添付
🧑 「これを lunch で記録して」
🤖 Claude が視覚解析 → log_meal_photo を呼ぶ

Logged 3 item(s) for Lunch on 2026-04-22:
  • 親子丼(1人前、推定 680 kcal、高信頼度)
  • 味噌汁(1杯、推定 40 kcal、中信頼度)
  • 小鉢(ほうれん草、推定 60 kcal、中信頼度)

睡眠の分析

🧑 「昨日の睡眠を見せて」
🤖 Claude が get_sleep を呼び、stage の内訳や minutesAsleep / efficiency を要約

活動トレンド

🧑 「先週の歩数どうだった?」
🤖 get_activity_timeseries(resource: "steps", start: ..., end: ...) → 週平均・目標達成率を計算


ローカル開発

# ローカルで Worker 起動(local KV、local secret)
echo 'MCP_SHARED_SECRET=dev-secret' > .dev.vars
pnpm dev

# Lint / Format / Typecheck / Test
pnpm lint
pnpm format
pnpm typecheck
pnpm test

# MCP Inspector で tool schema 確認
npx @modelcontextprotocol/inspector
# URL: http://127.0.0.1:8787/mcp/dev-secret
# CF-Connecting-IP ヘッダで 160.79.104.5 を送る設定が必要

アーキテクチャ

Claude mobile / Desktop / Web
      │ (public URL: Streamable HTTP)
      ▼
Anthropic Cloud  (outbound CIDR 160.79.104.0/21)
      │
      ▼
Cloudflare Workers  /mcp/<SECRET>
  ├─ guard middleware  (SECRET + CIDR allowlist)
  ├─ @hono/mcp  Streamable HTTP transport
  └─ McpServer
       ├─ HealthProvider interface
       │   └─ FitbitProvider
       │       ├─ OAuth refresh (Workers KV: TOKENS)
       │       └─ FitbitClient (fetch wrapper, 401/429 retry)
       └─ tools/read/*, tools/write/*
            └─ getCached → Workers KV: CACHE  (TTL 1h)
  • Provider 抽象: 2026/09 以降、GoogleHealthProvider に差し替えて継続運用
  • Cache: Read 結果を KV に 1h キャッシュ、Fitbit の 150/h/user 制限を温存
  • 画像は MCP サーバーを通らない: Claude が視覚解析して items[] を引数として渡す

セキュリティ

個人用シンプル認証 の構成です。

  • SECRET + Anthropic CIDR の 2 層防御:
    1. URL パス末尾の <MCP_SHARED_SECRET> が一致しなければ 401(constant-time 比較)
    2. CF-Connecting-IPALLOWED_CIDRS env の CIDR のいずれにも属さなければ 403
  • Anthropic outbound CIDR は公開情報 160.79.104.0/21。claude.ai 経由のリクエストだけを通す
  • MCP_SHARED_SECRET は Workers Secret に保管、コードには入れない
  • ローテーションは wrangler secret put + claude.ai の URL 更新だけで完結。Fitbit トークンに影響なし

脅威モデル: SECRET が漏れて攻撃者が Anthropic CIDR 内からアクセスできる場合のみ、あなたの Fitbit データ閲覧・偽書き込みが可能。Fitbit アカウント自体の乗っ取りは不可(refresh_token は Worker 内にのみ存在)。

複数ユーザー配布が必要なら @cloudflare/workers-oauth-provider で本格 OAuth AS 化する方針に切り替え可能(本リポはそれを選んでいない — 個人用最小構成)。


既知の制約(Fitbit API 側の仕様、本実装で対処済みのもの)

食事ログ周り

  • Search Foods 障害(2025/11〜): Fitbit 公式 API の /foods/search が不安定。本実装は意図的に foodName + calories 直書きしか使わない
  • POST /foods/log.jsonunitId を必須化(unitName は受け付けない)。本実装は foodName モードで unitId: 304 (= serving) を自動付与
  • 栄養素キー名が非対称(実測結果、2026-04):
    • protein / totalFat / totalCarbohydrate / dietaryFiber / sodium / sugars — これらのキー名で送らないと Fitbit 側で無視される
    • 旧 docs の nutritionalValues.protein 形式も、proteinGrams / totalCarbs 等も 2026-04 時点では効かない
  • Create Food(カスタム食品)は calories のみ保存:protein/carbs/fat を送っても silent drop される。本実装は create_custom_food を廃止し、栄養素を保持したい場合は MCP サーバー側プリセット(save_meal_preset + log_preset)で foodName 経路に流している
  • sugar は get_food_log の echo に含まれない — 保存されたかは視認できない

Intraday(心拍数)

  • 運動ログがある日は Fitbit が intraday の dataset を pruningすることがある(実測:運動日は朝〜夕方の dataset が欠落、運動無しの日は終日揃う)。zone summary は別パイプラインで残るので get_heart_rate_range はフォールバックに使える
  • 1sec 粒度:運動記録中以外は 1 秒粒度が保証されない

その他

  • Sleep は v1.2 のみ(v1 は deprecated)
  • Claude モバイルから Custom Connector の新規追加は不可: 必ず claude.ai(Web)から追加
  • レート制限: 150 req/h/user。LLM が連続呼び出しする場合に備えて全 read に 1h キャッシュ。429 時は Retry-After を 30s までクランプして 1 回リトライ

開発ノート

  • docs/research.md — 設計前に行った調査(Fitbit API の現状、MCP / Claude モバイルの仕様、先行実装サーベイ、出典付き)
  • docs/journal.md — 開発ログ(決定理由、ハマり、使用感)
  • scripts/diagnose-food-log.ts — Fitbit の foodLog API の挙動(栄養素キー名など)を直接確認するための reproducer。API が再び形を変えた時にパターン追加して実行すれば原因特定できるよう in-tree 保持

Contributing

Issue / Pull Request 歓迎。設計判断は docs/journal.md を参照してください。


License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured