Garmin Mcp について
Garmin Mcpは、Garmin Connectのフィットネス・健康データを参照、管理するMCPサーバーです。個人利用やコーチング向けに、アクティビティ、健康指標、トレーニング、ワークアウト、栄養を扱います。
主な機能
- 01アクティビティの参照と編集
- 02健康・身体指標の取得
- 03トレーニング状況と傾向の追跡
- 04ワークアウトの作成とスケジュール
- 05ギア、コース、栄養の管理
- 06アクティビティファイルのダウンロード
活用シーン
- 01最近のワークアウトとラップの確認
- 02睡眠、ストレス、心拍データの比較
- 03トレーニング計画の作成と予定設定
- 04サイクリングパワーとアクティビティファイルの分析
MCP 対応
Garmin Connectのデータと操作を、ClaudeなどのMCP対応クライアント向けのツールとして公開します。ツールプロファイルや許可リストで登録対象を絞れます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Garmin MCP サーバー
この Model Context Protocol(MCP)サーバーは Garmin Connect に接続し、フィットネスと健康データを Claude やその他の MCP 互換クライアントに公開します。
Garmin の API には、優れた python-garminconnect ライブラリを介してアクセスします。
機能
- ページネーションに対応した最近のアクティビティの一覧表示
- アクティビティの詳細情報の取得
- アクティビティの編集:名前、タイプ、説明/メモ、イベントタイプ、主観的運動強度(RPE)、感覚、筋力トレーニングのセット
- 健康指標へのアクセス(歩数、心拍数、睡眠、ストレス、呼吸)
- 体組成データの表示
- トレーニングステータスとレディネスの追跡
- サイクリングの FTP と乳酸閾値の指標へのアクセス
- ギアと装備の管理。
get_gearが返す自由記述のメモにも対応 - ワークアウトとトレーニングプランへのアクセス
- 繰り返しグループや水泳ペースの目標を含む、詳細なワークアウトのステップ構造の確認
- 週ごとの健康データ集計(歩数、ストレス、運動強度分数)
- 高度なサイクリング分析:パワーゾーン、FIT ファイル分析、DI2 電子シフトインテリジェンス
- トレーニング負荷の推移(CTL/ATL/TSB)、HRV の推移、VO2 max の推移、呼吸数の推移
- パワー持続時間曲線、VAM による登坂検出、心臓ドリフト(有酸素デカップリング)、W/kg の計算
ツールの対応範囲
この MCP サーバーは 110 個以上のツールを実装しており、python-garminconnect ライブラリ(v0.3.2)の約 90% をカバーしています。
- ✅ アクティビティ管理(21 個のツール) - タイプ、説明、イベントタイプ、主観的運動強度、感覚、エクササイズセットの書き込みツールを含みます
- ✅ 健康とウェルネス(34 個のツール) - 独自の軽量サマリーツールを含みます
- ✅ トレーニングとパフォーマンス(13 個のツール) - CTL/ATL/TSB、HRV、VO2 max、呼吸の推移を含みます
- ✅ ワークアウト(8 個のツール)
- ✅ デバイス(8 個のツール) - デバイスへのワークアウト送信を含みます
- ✅ ギア管理(5 個のツール)
- ✅ 体重の追跡(5 個のツール)
- ✅ チャレンジとバッジ(10 個のツール)
- ✅ 栄養(9 個のツール) - 食事ログ、食事、独自の食品、食事記録、複数日にわたる摂取量のサマリー
- ✅ 女性の健康(3 個のツール)
- ✅ ユーザープロフィール(3 個のツール)
- ✅ 高度なワークアウトビルダー(4 個のツール) - JSON を記述せずにワークアウトを作成、スケジュール設定できます
- ✅ コース(5 個のツール) - 一覧表示/詳細の取得/GPX をコースとしてアップロード/GPX のダウンロード/コースの削除
- ✅ アクティビティ分析(2 個のツール) - FIT ファイルの解析、パワー持続時間曲線。パワーメーターおよび/または Di2 が必要です
- ✅ アクティビティファイルのダウンロード(2 個のツール) - アクティビティファイルを FIT、GPX、TCX、または CSV 形式でダウンロード
注: アクティビティ分析ツールには、対応するパワーメーター(Garmin Rally、Favero Assioma、PowerTap P1 など)および/または Shimano Di2/SRAM eTap 電子変速システムが必要です。
fitparse依存関係は自動的にインストールされます。
ギアのメモ
get_gear が返す gear 配列の各項目には、Garmin Connect に表示される自由記述の「メモ」の値を含む notes フィールドがあります。メモの値がないギアの場合は null が返され、既存のギアフィールドはすべて変更されません。
アクティビティファイルのダウンロード
生のアクティビティファイルをディスクにダウンロードするツールが2つあります。
download_activity_file(activity_id, format="fit", output_dir=None)— アクティビティをダウンロードし、設定済みのディレクトリに保存します。formatにはfit(デフォルト)、gpx、tcx、csvを指定できます。set_fit_download_dir(path)— デフォルトのダウンロードディレクトリを設定し、保存します(設定ファイルに書き込まれます)。
ファイルの保存先(優先順位):
output_dir引数 — 1回限りの上書きで、保存されません。GARMIN_FIT_DOWNLOAD_DIR環境変数。set_fit_download_dirで設定した保存済みの設定。
初回実行時の動作: ディレクトリが設定されていない場合、download_activity_file は status: "needs_setup" を返します。アシスタントがファイルの保存先を尋ねます(デフォルトとして現在のディレクトリを提案します)。選択内容を保存するために set_fit_download_dir を呼び出し、その後ダウンロードを自動的に再試行します。
筋力トレーニングのセット
set_activity_exercise_sets(activity_id, sets) は、記録済みの筋力トレーニングアクティビティに構造化されたセットを記録します。Garmin Connect の「セットを編集」画面で保存されるセットごとのグリッドと同じ形式で、Garmin のエクササイズ履歴やボリュームチャートに表示されます。この処理では、ウォッチが検出したセットも含め、既存のセットがすべて置き換えられます。残したいセットがある場合は、先に get_activity_exercise_sets で読み取ってください。
各セットには category と、任意の exercise_name を指定します。これらには Exercises.json にある Garmin のキーを使用します。また、任意で reps、weight_kg または weight_lb(自重の場合は省略)、duration_seconds、rest_seconds を指定できます。Garmin は未知のキーを拒否し、アクティビティを変更しません。
ウォッチが正しいセットを記録したものの、エクササイズを誤って識別した場合は、keep_timing: true を指定してください。記録された開始時刻、継続時間、休憩時間を維持し、エクササイズ、回数、重量のみを順番に置き換えます。セット数は、アクティビティに記録されたアクティブなセット数と一致する必要があります。
{
"activity_id": 12345678901,
"sets": [
{"category": "DEADLIFT", "exercise_name": "BARBELL_DEADLIFT", "reps": 5, "weight_kg": 150, "rest_seconds": 180},
{"category": "PULL_UP", "reps": 8}
]
}
意図的にスキップしたエンドポイント
パフォーマンスまたは複雑さを考慮し、一部のエンドポイントは実装されていません。
データ量が多いエンドポイント:
get_activity_details()— 大量の GPS トラックやチャートデータ(50KB~500KB)を返します。代わりにget_activity()で概要を取得してください。
特殊なワークアウト形式:
upload_running_workout()、upload_cycling_workout()、upload_swimming_workout()— スポーツ別のワークアウトをアップロードします。一般的なワークアウトにはupload_workout()を使用してください。
保守および破壊的な操作:
delete_blood_pressure()— 破壊的な操作には慎重な検討が必要です。delete_activity()は確認ゲート付きで実装されています。まず1回呼び出してプレビューし、削除するにはもう一度confirm=trueを指定して呼び出します。削除は stderr に記録されます。取り消しはできません。- 内部/認証メソッド:
login()、resume_login()、connectapi()、download()— ライブラリが自動的に処理します。
これらのエンドポイントが必要な場合は、issue を作成してください。
ツールのフィルタリング
このサーバーはデフォルトで155個のツールを登録します。これは、すべてのセッションでLLMが保持するにはかなり多い数です。次の3つの任意の環境変数を使って、必要なツールだけを公開できます。
| 環境変数 | 効果 |
|---|---|
GARMIN_TOOL_PROFILE | 領域ごとに組み込まれたサブセットを指定します:minimal、health、activities、workouts、training、nutrition、またはall(デフォルト)。カンマ区切りで複数を組み合わせられます。例:health,training。 |
GARMIN_ENABLED_TOOLS | カンマ区切りの許可リストです。設定すると、これらのツールのみが登録されます。プロファイルも指定した場合、許可リストのツールはプロファイルに追加されます。 |
GARMIN_DISABLED_TOOLS | カンマ区切りの拒否リストです。指定したツールはスキップされます。許可リストが設定されている場合は無視されます。ただしプロファイルも設定されている場合は、プロファイルからツールを除外します。 |
ツール名では大文字と小文字が区別されません。いずれも設定しない場合は、すべてのツールが登録されます(デフォルトの動作は変わりません)。どのツールにも一致しない名前は警告とともにstderrに出力されるため、入力ミスを簡単に見つけられます。不明なプロファイル名を指定すると、既知のプロファイル一覧とともにサーバーの起動が停止します。
プロファイル
| プロファイル | ツール数 | 対象範囲 |
|---|---|---|
minimal | 20 | スプリット付きの最近のアクティビティ、日次統計、睡眠、HRV、ストレス、ボディバッテリー、トレーニングレディネス、ステータス |
health | 53 | すべてのhealth_wellnessツールに加え、体重、体組成、血圧、水分補給、女性の健康、フィットネス年齢、HRV、呼吸の傾向 |
activities | 41 | アクティビティ一覧、詳細、スプリット、編集、FIT分析、パワーカーブ、ギア、コース |
workouts | 26 | ワークアウトライブラリ、アップロード、スケジュール設定、削除、高レベルビルダー、カレンダー |
training | 38 | トレーニングステータス、負荷、効果、VO2max、FTP、乳酸閾値、持久力スコア、登坂スコア、レディネス、回復時間、自己記録、レース予測、目標、バッジ |
nutrition | 23 | 食事ログ、カスタム食品、日次の栄養設定、水分補給、エネルギーバランス |
各プロファイルには、本人確認と単位のツール(get_full_name、get_heart_rate_zones、get_unit_system、get_user_profile、get_userprofile_settings)も含まれます。これにより、クライアントは取得した数値にラベルを付けられます。
例 — トレーニング指標とワークアウトツールを必要とするコーチングセッション:
"env": {
"GARMIN_TOOL_PROFILE": "training,workouts"
}
例 — 書き込みツールを使わずに、healthプロファイルと最近のアクティビティを使用する場合:
"env": {
"GARMIN_TOOL_PROFILE": "health",
"GARMIN_ENABLED_TOOLS": "get_activities,get_activity",
"GARMIN_DISABLED_TOOLS": "add_weigh_in,add_weigh_in_with_timestamps,delete_weigh_ins,add_body_composition,add_hydration_data,set_blood_pressure"
}
例 — プロファイルを使わずにツールを個別に選択する場合:
"env": {
"GARMIN_ENABLED_TOOLS": "get_sleep_data,get_stress_summary,get_activities"
}
高レベルのワークアウトツール
これらのビルダーツールを使うと、LLMはGarminの生のJSONを書かずにワークアウトを作成し、スケジュールに登録できます。
create_walk_run_workout
任意の心拍ゾーン目標を設定して、ウォーキング/ランニングのインターバルワークアウトを作成します。
{
"name": "W3 Mié 2:2",
"run_seconds": 120,
"walk_seconds": 120,
"repeats": 9,
"warmup_min": 10,
"cooldown_min": 8,
"hr_zone": "Z3"
}
戻り値:{"status": "success", "workout_id": 1234567890, ...}
create_z2_walk_workout
一定ペースのZ2ウォーキングワークアウトを作成します。
{
"name": "Z2 Walk 45m",
"duration_min": 45,
"hr_min": 110,
"hr_max": 130
}
戻り値:{"status": "success", "workout_id": 1234567890, ...}
create_strength_workout
エクササイズのリストから筋力トレーニングのワークアウトを作成します。各エクササイズは、名前をステップの説明に保持したまま、回数ベースのステップになります。名前はexerciseNameとしても送信されますが、Garminが保持するのはGarmin独自のエクササイズキー(例:FARMERS_CARRY)に一致する場合のみです。それ以外の値は受け付けられますが、保存時には空になります。
categoryは任意で、そのまま渡されます。省略すると、キー自体がペイロードに含まれませんが、これはGarminで受け付けられます。指定する場合は、Garminのエクササイズカテゴリのいずれかでなければなりません。OTHERやUNASSIGNEDを含む、それ以外の値は400 - Invalid categoryで拒否されます。カテゴリの全リストはExercises.jsonで公開されています。
{
"name": "Full Body A",
"exercises": [
{"name": "Sentadillas", "sets": 3, "reps": 12, "rest_seconds": 90},
{"name": "Flexiones", "sets": 3, "reps": 15, "rest_seconds": 60},
{"name": "Peso muerto", "sets": 3, "reps": 10, "rest_seconds": 90},
{"name": "Farmers Carry 40m", "sets": 3, "reps": 1, "rest_seconds": 90, "category": "CARRY"}
]
}
戻り値:{"status": "success", "workout_id": 1234567890, ...}
schedule_week
1回の呼び出しで複数のワークアウトをスケジュールに登録します。
{
"week": [
{"date": "2026-05-12", "workout_id": 1234567890},
{"date": "2026-05-14", "workout_id": 1234567891}
]
}
戻り値:{"status": "complete", "scheduled": [...]}
一連の流れの例
create_walk_run_workout(name="W3 Mié 2:2", run_seconds=120, walk_seconds=120,
repeats=9, warmup_min=10, cooldown_min=8)
→ workout_id = 1560092011
schedule_workout(workout_id=1560092011, date="2026-05-06")
→ OK
ウォッチを同期すると、ワークアウトがForerunner 965のカレンダーに表示されます。
Raw upload_workout の終了条件
upload_workout または upload_workouts 用のカスタムワークアウト JSON を作成する場合、endCondition.conditionTypeId と
endCondition.conditionTypeKey は、Garmin の正式なマッピングに一致させる必要があります。Garmin では数値の
conditionTypeId が正とされます。キーと ID が矛盾する場合、Garmin は ID に対応する条件を保存します。
たとえば、ID 4 は heart.rate ではなく calories なので、次の設定は心拍数の終了条件として無効です。
{
"endCondition": {
"conditionTypeId": 4,
"conditionTypeKey": "heart.rate"
},
"endConditionValue": 145
}
心拍数には ID 6 を使用します。
{
"endCondition": {
"conditionTypeId": 6,
"conditionTypeKey": "heart.rate"
},
"endConditionValue": 145
}
ゾーンに基づく心拍数の終了条件では、同じ endCondition オブジェクトに
endConditionZone(1~5)を指定し、endConditionValue は省略します。両方を送信した場合、
Garmin はゾーンを保持し、値を破棄します(2026-09-01 に本番 API で確認済み)。
{
"endCondition": {
"conditionTypeId": 6,
"conditionTypeKey": "heart.rate",
"endConditionZone": 2
}
}
一般的な終了条件 ID:
| ID | キー |
|---|---|
| 1 | lap.button |
| 2 | time |
| 3 | distance |
| 4 | calories |
| 5 | power |
| 6 | heart.rate |
| 7 | iterations |
| 8 | fixed.rest |
| 9 | fixed.repetition |
| 10 | reps |
| 11 | training.peaks.tss |
Raw upload_workout のターゲットタイプ
Garmin の生ワークアウト JSON を作成する場合、targetType.workoutTargetTypeId と
targetType.workoutTargetTypeKey は、Garmin の正式なマッピングに従う必要があります。Garmin では数値 ID が
優先されます。たとえば、{"workoutTargetTypeId": 6, "workoutTargetTypeKey": "heart.rate"} のように
値が一致しないデータは、ID 6 が pace.zone を意味するため、pace.zone として保存されます。
カスタム心拍数範囲には、ターゲットタイプ ID 4 と heart.rate.zone を使用し、bpm の範囲を
targetValueOne/targetValueTwo に指定します。これらの値フィールドはワークアウトステップの
targetType と同じ階層に置きます。targetType オブジェクト内にはネストしないでください。
{
"targetType": {
"workoutTargetTypeId": 4,
"workoutTargetTypeKey": "heart.rate.zone"
},
"targetValueOne": 143,
"targetValueTwo": 157
}
カスタムランニングペース範囲も同じ構造を使用します。ペースの境界値にはメートル毎秒を使用します。
{
"targetType": {
"workoutTargetTypeId": 6,
"workoutTargetTypeKey": "pace.zone"
},
"targetValueOne": 1.9607843,
"targetValueTwo": 2.0833333
}
この例は 8:00–8:30 min/km を表します。心拍数の例と順序を統一するため、数値の小さい境界値を先に記載しています。Garmin はどちらの順序でも正規化します。Garmin は targetType 内にネストされた値を黙って破棄するため、有効な範囲のないペースターゲットが残ります。アップロードツールは、この曖昧さのないネストの誤りを修正しますが、ネストされた値とステップレベルの値が矛盾する場合はリクエストを拒否します。
Garmin の名前付き HR ゾーンには、代わりに同じターゲットタイプで zoneNumber を使用します。
{
"targetType": {
"workoutTargetTypeId": 4,
"workoutTargetTypeKey": "heart.rate.zone"
},
"zoneNumber": 3
}
ターゲットには zoneNumber または targetValueOne/targetValueTwo のどちらか一方を使用し、両方は使用しないでください。Garmin は名前付きゾーンを優先し、併存するカスタム範囲を黙って破棄するため、アップロードツールはこの曖昧な構造を拒否します。
ワンクリックインストール(Claude Desktop)
このサーバーを Claude Desktop に追加する最も簡単な方法は、.dxt Desktop Extension ファイルを使用することです。JSON を編集する必要はありません。
ダウンロードとインストール
- Releases page から最新の
garmin-mcp.dxtをダウンロードします。 .dxtファイルを Claude Desktop のウィンドウにドラッグするか、ダブルクリックするか、Settings → Extensions → Install Extension に移動してファイルを選択します。- Claude Desktop から、任意の設定(トークンのパス、メールアドレス、パスワード)を求められます。
初回認証
拡張機能はサーバーを自動的にインストールして実行しますが、データを取得する前に Garmin で一度認証する必要があります。
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-auth
OAuth トークンが ~/.garminconnect に保存されます。その後は、設定に認証情報を記述しなくてもサーバーを使用できます。
注: トークンの有効期間は約 6 か月です。期限が切れたら
garmin-mcp-authを再実行してください。
.dxt を自分でビルドする
bash scripts/build_dxt.sh # produces garmin-mcp.dxt in the repo root
セットアップ
MCP クライアントのクイックスタート
この MCP サーバーを Claude Desktop、Codex、または別の MCP クライアントで使用する最も簡単な方法は、サーバーを設定に追加する前に一度認証することです。
前提条件
- Python 3.12+
- Garmin Connect アカウント
- アカウントで有効になっている場合、MFA が必要になることがあります
ステップ 1:事前認証(一度のみ)
MCP クライアントにサーバーを追加する前に、ターミナルで一度認証します。
# Install and run authentication tool
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-auth
# You'll be prompted for:
# - Email (or set GARMIN_EMAIL env var)
# - Password (or set GARMIN_PASSWORD env var)
# - MFA code (if enabled on your account)
# OAuth tokens will be saved to ~/.garminconnect
資格情報はいつでも次のコマンドで確認できます。
uv run garmin-mcp-auth --verify
注: 環境変数を使って資格情報を設定することもできます。
[email protected] GARMIN_PASSWORD=secret garmin-mcp-auth
MFA を有効にしていない場合は、garmin-mcp-auth を省略し、対応していれば GARMIN_EMAIL と GARMIN_PASSWORD を環境変数として MCP クライアントに直接渡すこともできます。セキュリティを高めるには、上記の事前認証フローを使用し、資格情報を MCP クライアントの設定に含めないことをおすすめします。
ステップ 2:Claude Desktop を設定する
資格情報を含めずに、Claude Desktop の MCP 設定に追加します。
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
}
}
}
重要: 設定に GARMIN_EMAIL や GARMIN_PASSWORD を含める必要はありません。サーバーは保存済みのトークンを使用します。
ステップ 3:MCP クライアントを再起動する
これで、Garmin のデータを MCP クライアントから利用できます。
Codex やその他のクライアントについては、以下の例を参照してください。
複数の Garmin アカウントを使用する
1 つのサーバープロセスは 1 つの Garmin アカウントに紐づきます。複数のアカウントを同時に使用するには、アカウントごとにサーバーインスタンスを 1 つずつ実行し、それぞれに独自のトークンディレクトリを設定します。トークンディレクトリは GARMINTOKENS 環境変数で指定します。
GARMINTOKENS のデフォルト値は ~/.garminconnect です。別の場所を指定すると、サーバーはデフォルトの保存先には触れず、指定した場所のトークンを読み書きします。
ステップ 1:各アカウントを個別のディレクトリに認証する
garmin-mcp-auth --token-path ~/.garminconnect-alice
garmin-mcp-auth --token-path ~/.garminconnect-bob
--token-path には $GARMINTOKENS も指定できます。そのため、GARMINTOKENS=~/.garminconnect-alice garmin-mcp-auth と同じ意味になります。
ステップ 2:アカウントごとにサーバーを定義する
{
"mcpServers": {
"garmin-alice": {
"command": "uvx",
"args": ["--python", "3.12", "--from", "git+https://github.com/Taxuspt/garmin_mcp", "garmin-mcp"],
"env": {
"GARMINTOKENS": "${HOME}/.garminconnect-alice"
}
},
"garmin-bob": {
"command": "uvx",
"args": ["--python", "3.12", "--from", "git+https://github.com/Taxuspt/garmin_mcp", "garmin-mcp"],
"env": {
"GARMINTOKENS": "${HOME}/.garminconnect-bob"
}
}
}
}
各サーバーは、起動時に認証に使用するディレクトリをログに記録します。設定を確認できます。
Trying to login to Garmin Connect using token data from directory '/home/you/.garminconnect-alice'...
注意事項
-
暗黙的なフォールバックはありません。
GARMINTOKENSが有効なトークンのないディレクトリを指し、ログインに失敗した場合、サーバーは失敗をログに記録し、ツールの呼び出しも失敗します。HTTP/readyzは利用できない状態(503)のままです。サーバーがデフォルトのトークン保存先に切り替わることはないため、2 つ目のサーバーの設定ミスによって 1 つ目のアカウントのセッションが意図せず再利用されることはありません。 -
${HOME}は展開されます。 MCP クライアントが未展開のまま渡した場合でも展開され、Windows では~がUSERPROFILEを使って機能します。 -
2 つ目以降のアカウントでは書き込みツールを制限してください。
upload_workoutやschedule_workoutなどのツールは、サーバーに紐づいたアカウントに書き込みます。GARMINTOKENSとGARMIN_ENABLED_TOOLS(ツールのフィルタリングを参照)を組み合わせて、アカウントを読み取り専用にできます。"env": { "GARMINTOKENS": "${HOME}/.garminconnect-bob", "GARMIN_ENABLED_TOOLS": "get_activities,get_activities_by_date,get_activity,get_activity_splits" } -
トークンディレクトリには長期間有効な資格情報が保存されます。 ディレクトリは所有者のみがアクセスできる権限で作成されます。共有フォルダーや同期フォルダーには置かないでください。
開発環境のセットアップ
- 新しい環境に必要なパッケージをインストールします。
uv sync
サーバーの実行
設定
Garmin Connect の資格情報は環境変数から読み込まれます。
GARMIN_EMAIL:Garmin Connect のメールアドレスGARMIN_EMAIL_FILE:Garmin Connect のメールアドレスを含むファイルのパスGARMIN_PASSWORD:Garmin Connect のパスワードGARMIN_PASSWORD_FILE:Garmin Connect のパスワードを含むファイルのパスGARMIN_IS_CN:国際版の代わりに Garmin Connect China(garmin.cn)を使用する場合はtrueに設定します(デフォルト:false)GARMIN_FIT_DOWNLOAD_DIR:ダウンロードしたアクティビティファイルのデフォルトディレクトリです。設定すると、download_activity_fileの初回実行時の設定プロンプトが省略されます。GARMIN_FIT_CONFIG:ダウンロードディレクトリの永続化された設定ファイルのパスです(デフォルト:~/.garminconnect_fit_config.json)。
ファイルベースのシークレットは、Docker コンテナー内など、特定の環境で役立ちます。GARMIN_EMAIL と GARMIN_EMAIL_FILE を同時に設定することはできません。同様に、GARMIN_PASSWORD と GARMIN_PASSWORD_FILE も同時に設定できません。
トランスポート
デフォルトでは、サーバーは stdio 経由で通信します。Claude Desktop、MCP Inspector、ほとんどのローカルクライアントがこの方式を想定しています。代わりに HTTP 経由で提供する場合(コンテナーや Kubernetes で実行する場合など)は、環境変数でトランスポートを設定します。
GARMIN_MCP_TRANSPORT:stdio(デフォルト)、streamable-http、またはsseGARMIN_MCP_HOST:HTTP トランスポートのバインドアドレス(デフォルトは127.0.0.1。0.0.0.0に設定するのは、GARMIN_MCP_HTTP_TOKENも設定する場合、または認証を行うリバースプロキシの背後で実行する場合に限ってください)GARMIN_MCP_PORT:HTTP トランスポートのバインドポート(デフォルトは8000)GARMIN_MCP_HTTP_TOKEN:HTTP トランスポート用の共有シークレット。設定すると、/mcp、/sse、/messages/へのすべてのリクエストにAuthorization: Bearer <token>が必要になります。それ以外のリクエストには401が返されます。/healthzと/readyzはプローブ用に認証なしで利用できます。HTTP エンドポイントの保護を参照してください。GARMIN_MCP_STATELESS_HTTP:trueに設定すると、セッションなしでstreamable-httpを実行します(デフォルトはfalse)。MCP SDK は、ステートフルセッションをアイドル状態が 30 分続くと破棄するため、アイドル状態の後の最初の呼び出しは404 Session not foundになります。一部のクライアント(claude.ai のカスタムコネクターを含む)は、再初期化して再試行する代わりに、これをツール呼び出しの失敗として報告します。ステートレスモードでは、期限切れになるセッションがありません。このサーバーのツールはどれもセッション状態に依存しないため、失われるものはありません。長時間稼働するリモートデプロイにはこのモードを推奨します。GARMIN_MCP_CALL_TIMEOUT:Garmin への呼び出しに対するリクエストごとのタイムアウト(秒単位、デフォルトは90)。Garmin の API は、単一のリクエストが無期限に停止することがあります。この上限がないと、MCP クライアント自身のタイムアウトが発生してサーバー全体が応答していないと報告されるまで、呼び出しが停止します。タイムアウト時には、ツールが再試行可能であることを明示したエラーを返します。上限を無効にするには0を設定します。
GARMIN_MCP_TRANSPORT=streamable-http garmin-mcp
HTTP トランスポートを選択した場合:
- MCP クライアントは
/mcpパスに接続します(例:http://localhost:8000/mcp)。 GET /healthzはサーバーの起動直後からokを返します。ライブネスプローブとして使用してください。GET /readyzは Garmin へのログインが完了したかどうかを報告します。レディネスプローブとして使用してください。ログインに成功すると200 {"status": "ready"}を返します。ログインが進行中の場合は503と{"status": "pending"}を、失敗した場合は{"status": "failed"}を返します(garmin-mcp-authを再実行して再起動してください)。
HTTP エンドポイントの保護
HTTP トランスポートは Garmin アカウントへの完全な読み書きアクセスを公開するため、 サーバーはデフォルトでループバックアドレスにバインドします。他のマシンからアクセス可能にする場合は、 共有シークレットを設定し、クライアントからベアラートークンとして送信してください。
export GARMIN_MCP_HTTP_TOKEN="$(openssl rand -hex 32)"
GARMIN_MCP_TRANSPORT=streamable-http GARMIN_MCP_HOST=0.0.0.0 garmin-mcp
# rejected: 401 {"error": "unauthorized", ...}
curl -i http://localhost:8000/mcp
# accepted (the MCP handshake then proceeds as usual)
curl -i -H "Authorization: Bearer $GARMIN_MCP_HTTP_TOKEN" http://localhost:8000/mcp
ほとんどの MCP クライアントは、リモートサーバー用のカスタムヘッダーに対応しています(Claude Desktop と
claude.ai のコネクター、MCP Inspector、SDK クライアントはいずれも対応しています)。同じ
Authorization: Bearer … ヘッダーを設定してください。比較処理は定時間で行われます。
/healthz と /readyz ではトークンは必要ありません。これらのエンドポイントは、プロセスが起動しているか、
Garmin へのログインが完了したかを報告するだけだからです。
トークンがなくてもサーバーは起動しますが、GARMIN_MCP_HOST が
ループバックアドレスでない場合、アカウントが公開されていることを示す警告が stderr に出力されます。
独自の認証機能を備えたリバースプロキシ(nginx、Traefik、Authelia など)も有効な選択肢です。
トークンは、一般的なセルフホストの用途に適した、簡単に利用できる組み込みの選択肢です。
Garmin Connect China(garmin.cn)
国際版ではなく Garmin Connect China(garmin.cn)を使用する場合は、環境変数 GARMIN_IS_CN を true に設定します。
# Pre-authenticate with Garmin Connect China
GARMIN_IS_CN=true garmin-mcp-auth
# Or use the CLI flag
garmin-mcp-auth --is-cn
Claude Desktop では、env セクションに GARMIN_IS_CN を追加します。
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
],
"env": {
"GARMIN_IS_CN": "true"
}
}
}
}
Docker では、.env ファイルに GARMIN_IS_CN=true を追加するか、docker-compose.yml 内のコメントを解除してください。
MCP Inspector を使ったローカルでのサーバーのテスト
Inspector はインストール不要で、npx から直接実行できます。プロジェクトのルートから次を実行します。
npx @modelcontextprotocol/inspector uv run garmin-mcp
ツールを調査してテストできるようになります。
Claude Desktop での使用
- Claude Desktop で設定を作成します。
Claude Desktop の設定ファイルを編集します。
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Claude で MCP をローカル実行する方法は 2 つあります。
リポジトリをクローンせず、GitHub から直接実行する場合
- 次のサーバー設定を追加します。
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
],
"env": {
"GARMIN_EMAIL": "YOUR_GARMIN_EMAIL",
"GARMIN_PASSWORD": "YOUR_GARMIN_PASSWORD"
}
}
}
}
uvx のフルパスを追加する必要がある場合があります。which uvx を実行するとフルパスを確認できます。
- Claude Desktop を再起動します。
リポジトリのローカルコピーから直接実行する場合
- 次のサーバー設定を追加します。
{
"mcpServers": {
"garmin-local": {
"command": "uv",
"args": [
"--directory",
"<full path to your local repository>/garmin_mcp",
"run",
"garmin-mcp"
]
}
}
}
- Claude Desktop を再起動します。
Codex での使用
Codex は MCP サーバーの設定に TOML を使用します。garmin-mcp-auth で認証した後、次のいずれかの項目を ~/.codex/config.toml に追加します。
MCP に対応したクライアントに設定を依頼することもできます。たとえば、次のようにします。
Install the Garmin MCP server from https://github.com/Taxuspt/garmin_mcp, authenticate with garmin-mcp-auth, and add it to my MCP configuration without storing my Garmin email or password.
リポジトリをクローンせず、GitHub から直接実行する場合
[mcp_servers.garmin]
command = "uvx"
args = [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
リポジトリのローカルコピーから直接実行する場合
[mcp_servers.garmin-local]
command = "uv"
args = [
"--directory",
"/full/path/to/garmin_mcp",
"run",
"garmin-mcp"
]
ファイルを保存した後、MCP クライアントを再起動します。
opencode での使用
opencode はリポジトリのルートから起動すると、プロジェクトレベルの opencode.json を自動的に読み込みます。そのため、このリポジトリをクローンした開発者は、追加設定なしでローカルソースを使用するよう Garmin MCP を設定できます。
このリポジトリのクローンから実行する(開発に推奨)
このリポジトリには、uv run garmin-mcp で MCP を実行する opencode.json が含まれているため、常に作業ツリーの内容が反映されます。
git clone https://github.com/Taxuspt/garmin_mcp.git
cd garmin_mcp
uv sync # install dependencies
garmin-mcp-auth # one-time Garmin login (skip if ~/.garminconnect already exists)
opencode # launches with the garmin MCP attached
サーバーが接続されていることを確認します。
opencode mcp list
# ● ✓ garmin connected
# uv run garmin-mcp
その他のディレクトリから実行する(GitHub からインストール)
garmin-mcp-auth を実行した後、グローバル opencode 設定の ~/.config/opencode/opencode.json にサーバーを追加します。
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"garmin": {
"type": "local",
"command": [
"uvx",
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
],
"enabled": true,
"timeout": 30000
}
}
}
ファイルを保存した後、opencode を再起動します。初回の uvx 実行時にパッケージがダウンロードされ、キャッシュされるため、最初の起動には数秒かかる場合があります。
Docker での使用
Docker を使うと、MCP サーバーを分離された一貫性のある環境で実行できます。
Docker Compose ですぐに始める(推奨)
- 認証情報を記載した
.envファイルを作成します。
echo "[email protected]" > .env
echo "GARMIN_PASSWORD=your_password" >> .env
- コンテナを起動します。
docker compose up -d
- ログを表示してサーバーを監視します。
docker compose logs -f garmin-mcp
Docker を直接使用する
# Build the image
docker build -t garmin-mcp .
# Run the container
docker run -it \
-e GARMIN_EMAIL="[email protected]" \
-e GARMIN_PASSWORD="your_password" \
-v garmin-tokens:/root/.garminconnect \
garmin-mcp
ファイルベースのシークレットを使用する(より安全)
特に本番環境でセキュリティを強化するには、環境変数ではなく、ファイルベースのシークレットを使用します。
- シークレット用のディレクトリを作成し、認証情報を追加します。
mkdir -p secrets
echo "[email protected]" > secrets/garmin_email.txt
echo "your_password" > secrets/garmin_password.txt
chmod 600 secrets/*.txt
- docker-compose.yml を編集し、secrets セクションのコメントを解除します。
services:
garmin-mcp:
environment:
- GARMIN_EMAIL_FILE=/run/secrets/garmin_email
- GARMIN_PASSWORD_FILE=/run/secrets/garmin_password
secrets:
- garmin_email
- garmin_password
secrets:
garmin_email:
file: ./secrets/garmin_email.txt
garmin_password:
file: ./secrets/garmin_password.txt
- コンテナを起動します。
docker compose up -d
Docker で MFA を処理する
Garmin アカウントで多要素認証(MFA)を有効にしている場合:
- サービスのトークンボリュームを指定して認証 CLI を実行します。
docker compose run --rm --entrypoint garmin-mcp-auth garmin-mcp
- プロンプトが表示されたら、MFA コードを入力します。
Garmin Connect MFA required. Please check your email/phone for the code.
Enter MFA code: 123456
-
OAuth トークンは Docker ボリューム(
garmin-tokens)に保存されるため、以降の実行では再認証する必要はありません。 -
MFA の設定後は、通常どおりコンテナを実行できます。
docker compose up -d
Docker ボリュームの管理
再認証を避けるため、OAuth トークンは永続的な Docker ボリュームに保存されます。
# List volumes
docker volume ls
# Inspect the tokens volume
docker volume inspect garmin_mcp_garmin-tokens
# Remove the volume (will require re-authentication)
docker volume rm garmin_mcp_garmin-tokens
Docker を介して Claude Desktop で使用する
Docker 化した MCP サーバーを Claude Desktop で使用するには、コンテナと通信するように設定できます。ただし、MCP サーバーは通常 stdio で通信するため、プロセスを直接実行する方法が最適です。Docker ベースでデプロイする場合は、代わりに「Claude Desktop での使用」セクションに記載されている標準の uvx 方法を検討してください。
使用例
Claude に接続すると、次のような質問をすることができます。
- "最近のアクティビティを表示して"
- "昨夜の睡眠はどうだった?"
- "昨日は何歩歩いた?"
- "最新のランニングの詳細を表示して"
- "直近のライドのパワーゾーンを分析して、トレーニングゾーンと比較して"
- "過去 6 週間の CTL、ATL、TSB の推移を表示して"
- "昨日のライドのパワー持続時間曲線はどうだった?FTP を推定して"
- "直近のサイクリングアクティビティの FIT データを分析して。登りでの変速品質はどうだった?"
- "過去 2 週間の HRV の推移を表示して、回復に関する懸念があれば知らせて"
- "シーズン最高の 20 分間パワーはいくつで、いつ記録した?"
トラブルシューティング
有効なアクティビティに対して get_training_effect が HTTP 403 を返す
Garmin のアクティビティ詳細エンドポイント(/activity-service/activity/{id})は、
同じアクティビティがリストツールで表示されていても、403 Forbidden を返すことがあります。
get_training_effect はアクティビティリスト検索にフォールバックするようになり、最近のアクティビティについては
有酸素/無酸素のトレーニング効果も引き続き含まれます。
アクティビティが最近の検索対象期間より古い場合は、get_activities/get_activities_by_date で
アクティビティを一覧表示して再試行するか、リストに含まれるフィールドを直接使用してください。
Garmin Connect に存在する目標が get_goals で返されない
Garmin の goal-service は、リクエストで Sec-Fetch-Site: same-origin を送信し、
1 始まりの start を使用した場合に限り、Connect の現在の目標 UI で作成された目標
(月間サイクリング目標など、距離/時間を指定した目標)を返します。start=0 の場合、
空のリストが返されます。python-garminconnect の get_goals() はこの両方を行わないため
(0.3.16 まで)、ここでの get_goals は Connect の目標ページと同じ方法で
/goal-service/goal/goals を直接呼び出し、ライブラリの呼び出しはフォールバックとしてのみ使用します。
「プロセスの起動に失敗しました:そのようなファイルまたはディレクトリはありません」
Claude Desktop が uvx を見つけられない場合、Claude Desktop が使用する PATH に uvx が含まれていないことが原因です。修正するには:
uvxのインストール場所を確認します:
which uvx
- 設定でフルパスを使用します。たとえば、
uvxが/Users/username/.cargo/bin/uvxにある場合:
{
"mcpServers": {
"garmin": {
"command": "/Users/username/.cargo/bin/uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
}
}
}
Windows:Smart App Control が uv/uvx をブロックする
Smart App Control が有効な Windows 11 では、Garmin_MCP の起動時に uv.exe/uvx.exe がブロックされることがあります。uv がローカルの .venv から署名されていない garmin-mcp.exe を読み込もうとする場合も同様です。
これは Microsoft Defender Antivirus の隔離とは異なります。Smart App Control の場所は次のとおりです:
Windows セキュリティ → アプリとブラウザー コントロール → Smart App Control
症状
uv、uvx、またはcommand: "uvx"を指定した Claude Desktop の実行時に Smart App Control の通知が表示されるuvxがインストールされているように見えるにもかかわらず、Claude Desktop がサーバーの起動に失敗する- イベント ビューアー → アプリケーションとサービス ログ → Microsoft → Windows → CodeIntegrity → Operational に、
uv.exeとgarmin-mcp.exeに関する CodeIntegrity エラー 3077 が表示される(ポリシー/Enterprise 署名レベル)
確認方法
- Smart App Control がオン(評価または適用)になっていることを確認します。
- 起動に失敗した時刻付近の CodeIntegrity Operational ログで、イベント 3077 を確認します。
- Defender の「ウイルスと脅威の防止」の履歴が空でも、SAC が原因ではないとは限りません。
復旧方法(Smart App Control をオンのままにする方法を優先してください)
- パッケージ化された配布経路から
uvをインストールまたは再インストールし、PowerShell で確認します:winget install --id=astral-sh.uv -e # or: scoop install main/uv uvx --version - Claude Desktop で
uvx.exeのフルパスを指定します(上記の PATH のトラブルシューティングと同様)。例:"command": "C:\\Users\\<you>\\.local\\bin\\uvx.exe" - 適用状態でも
garmin-mcp.exeの読み込みがブロックされる場合は、そのバイナリのパスに対する管理者/ポリシーの例外が必要になることがあります。Smart App Control を全体的にオフにするのは最終手段であり、通常は推奨されません。 - ローカルの uvx が引き続きブロックされる場合は、Docker Compose によるインストール方法を使用してください。
ログインの問題
ログイン時に問題が発生した場合:
- 認証情報が正しいことを確認します
- Garmin Connect で追加の認証が必要か確認します
- garminconnect パッケージが最新であることを確認します
ログ
その他の問題については、以下の Claude Desktop ログを確認してください。
- macOS:
~/Library/Logs/Claude/mcp-server-garmin.log - Windows:
%APPDATA%\Claude\logs\mcp-server-garmin.log
Garmin Connect の多要素認証(MFA)
MCP サーバーでの MFA の仕組み
MCP サーバーは、ターミナルに直接アクセスできないバックグラウンドプロセスとして実行されます。Garmin アカウントで MFA が有効になっている場合、サーバーを実行する前に、事前認証ツールを使って一度認証する必要があります。
推奨:事前認証ツール
MFA に対応する最も簡単な方法は、専用の認証ツールを使うことです。
garmin-mcp-auth
OAuth トークンが今後の利用に備えて ~/.garminconnect に保存されます。サーバーは、Claude Desktop やその他の MCP クライアントで実行するときに、このトークンを自動的に使用します。
その他のオプション:
# Use environment variables for credentials
[email protected] GARMIN_PASSWORD=secret garmin-mcp-auth
# Verify existing tokens
garmin-mcp-auth --verify
# Show where tokens are looked up, what is on disk, and whether they work
garmin-mcp-auth --diagnose
# Force re-authentication (e.g., when tokens expire)
garmin-mcp-auth --force-reauth
# Use custom token location
garmin-mcp-auth --token-path ~/.garmin_tokens
代替方法:手動での初回実行
ファイルから認証情報を CLI に渡して認証できます。
# Store credentials in files for security
echo "[email protected]" > ~/.garmin_email
echo "your_password" > ~/.garmin_password
chmod 600 ~/.garmin_email ~/.garmin_password
# Run the authentication CLI before starting the server
GARMIN_EMAIL_FILE=~/.garmin_email GARMIN_PASSWORD_FILE=~/.garmin_password \
uvx --python 3.12 --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp-auth
# Enter MFA code when prompted
# Tokens will be saved automatically
# Now add to Claude Desktop config without credentials
初回認証後、認証情報を指定せずに Claude Desktop を設定してください(トークンはすでに保存されています)。
{
"mcpServers": {
"garmin": {
"command": "uvx",
"args": [
"--python",
"3.12",
"--from",
"git+https://github.com/Taxuspt/garmin_mcp",
"garmin-mcp"
]
}
}
}
MFA で Docker を使用する
Docker を使用する場合は、永続的なトークンストレージを使って簡単に設定できるよう、上記のDocker での MFA の処理セクションに従ってください。
MFA のトラブルシューティング
エラー:「MFA required; run 'garmin-mcp-auth' before starting the server.」
解決方法:
- ターミナルを開きます
- 次を実行します:
garmin-mcp-auth - 認証情報と MFA コードを入力します
- Claude Desktop を再起動します
トークンの有効期限切れ
OAuth トークンは定期的に期限切れになります(約 6 か月ごと)。再認証してください。
garmin-mcp-auth --force-reauth
トークンの動作を確認する
garmin-mcp-auth --verify
garmin-mcp-auth は成功しましたが、サーバーがまだログインできません
サーバーは、トークンディレクトリ($GARMINTOKENS、デフォルトは ~/.garminconnect)内の garmin_tokens.json からのみトークンを読み込みます。起動時のエラーには、ディレクトリがない、トークンファイルがない、ファイルを読み取れない、または Garmin にトークンを拒否された、のいずれが見つかったかが示されます。よくある原因は、MCP クライアントが garmin-mcp-auth を実行したシェルとは異なる GARMINTOKENS または HOME でサーバーを起動していることです(Windows の Claude Desktop でよく発生します)。そのため、解決されるディレクトリが異なります。次のコマンドで比較してください。
garmin-mcp-auth --diagnose
garmin-mcp-auth が書き込む ~/.garminconnect_base64 ファイルは、garminconnect ベースの他のツール向けのコピーです。サーバーはこのファイルを読み込みません。
テスト
このプロジェクトには、すべての MCP ツールを対象とした包括的なテストが含まれています。現在、すべてのテストが合格しています(100%)。
テストの実行
# Run unit and integration tests (default - uses mocked Garmin API, e2e tests are deselected)
uv run pytest
# Run only the integration tests
uv run pytest tests/integration/
# Run tests with verbose output
uv run pytest tests/integration/ -v
# Run a specific test module
uv run pytest tests/integration/test_health_wellness_tools.py -v
# Run end-to-end tests (requires real Garmin credentials).
# Some of these create and delete foods, food logs and workouts in your account.
uv run pytest tests/e2e/ -m e2e -v
テスト構成
- 統合テスト(200 件以上):FastMCP の統合機能とモック化した Garmin API レスポンスを使用して、すべての MCP ツールをテストします
- エンドツーエンドテスト(
tests/e2e/):実際の MCP サーバーと Garmin API を使用してテストします(有効な認証情報が必要です)。-m e2eを指定した場合にのみ実行してください。
ローカルパスからの再インストール
ローカルのチェックアウトまたはフォークから作業している場合:
uv tool install --python 3.12 --force C:\Users\aresd\Desktop\programacion\garmin_mcp
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。
