caddie-mcp について
caddie-mcp は、Garmin のゴルフデータを Claude などの MCP クライアントにつなぎ、ラウンドや健康状態を分析するゴルファー向けのサーバーです。データをローカルの DuckDB に同期し、ショット単位の GPS、ストロークゲイン、クラブ距離、睡眠・回復状況を分析できます。
主な機能
- 01Garmin のラウンドとショットを同期
- 02ショット GPS と位置を分析
- 03ストロークゲインと成績統計を算出
- 04実測クラブ距離を比較
- 05睡眠・回復データとの相関を分析
- 06ローカルキャッシュを読み取り専用 SQL で検索
活用シーン
- 01ホールやクラブごとの成績分析
- 02コース上のショット位置のマッピング
- 03睡眠とスコアの関連性の評価
- 04実測距離とコース戦略の確認
MCP 対応
ローカルキャッシュ内の Garmin ゴルフ・健康データを扱うツール、プロンプト、リソースを MCP クライアントに提供します。認証付き HTTP リモートサーバーにも対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
13掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
Caddie
あなたが打ったすべてのショットを実際に把握している、AI キャディです。
Caddie は、Claude(または MCP 対応の LLM)を Garmin のゴルフデータに接続する MCP サーバーです。すべてのラウンド、すべての GPS ショット、ストロークゲインド、実際のクラブの飛距離、実際のプレー条件に応じたヤーデージ、そして各スコアの背景にある睡眠や回復の状況を確認できます。何でも質問できます。「なぜパー5で大崩れするのか?」、「ホームコースでのドライバーショットを地図に表示して」、「睡眠不足は本当に打数を増やすのか?」
- ローカル優先でプライベート:データは一度だけお使いのマシン上の DuckDB ファイルに同期され、認証情報や健康データが外部に送信されることはありません。
- 非公式:Caddie は Garmin Connect アプリと同じ非公開 API を(python-garminconnect 経由で)使用します。読み取るのはご自身のアカウントのみです。エコシステムが追いつくまでは、Garmin の変更によっていつでも動作しなくなる可能性があります。その点を理解したうえでご利用ください。
- サポート:可能な範囲で対応します。イシューやプルリクエストを歓迎します。OneClub の作者によるプロジェクトです。
仕組み
Garmin Connect ──sync──► local DuckDB cache ──MCP tools──► your LLM
データは一度だけローカルデータベース(~/.caddiemcp/golf.duckdb)に同期され、すべての質問にはキャッシュから回答します。高速で、プライベートで、Garmin のサーバーにも負荷をかけません。認証情報がマシンの外に出ることはありません。
セットアップ
ソースから(このディレクトリ):
python3 -m venv .venv && .venv/bin/pip install -e .
.venv/bin/caddie-mcp login # one-time; MFA supported
.venv/bin/caddie-mcp sync --max-rounds 50
ターミナルではなくブラウザーを使いたいですか?caddie-mcp login --web を実行すると、ローカルページ(127.0.0.1 のみ)が開き、メールアドレス、パスワード、MFA 用の専用入力欄を使えます。トークンの保存先は同じですが、より使いやすい画面を利用できます。
ビルド済み wheel から(チェックアウトは不要です。dist/ に両方含まれています):
pipx install ./dist/caddie_mcp-1.0.0-py3-none-any.whl # or pip install
caddie-mcp login && caddie-mcp sync
PyPI に公開されると、これは uvx caddie-mcp / pipx install caddie-mcp で利用できます。
Claude Desktop / Claude Code
claude_desktop_config.json(Claude Code の場合は .mcp.json)に追加します:
{
"mcpServers": {
"caddie-mcp": {
"command": "/ABSOLUTE/PATH/TO/caddie-mcp",
"args": ["serve"]
}
}
}
コマンドのパスには、which caddie-mcp(pipx)または /path/to/caddie-mcp/.venv/bin/caddie-mcp(ソースからのインストール)を使用してください。このリポジトリの .mcp.json では、このフォルダーで開始した Claude Code セッション用にすでに設定されています。
リモートサーバー(マルチユーザー、HTTP)
同じサーバーをストリーミング可能な HTTP 経由で実行できます。ベアラートークン認証とユーザーごとの完全な分離に対応しており、各ユーザーはそれぞれ専用のデータベースと Garmin トークンストアを ~/.caddiemcp/users/<name>/(または $CADDIEMCP_HOME)に持ちます。
caddie-mcp user add marcos # prints the access token (shown once)
caddie-mcp serve-http --host 0.0.0.0 --port 8724
ユーザーはブラウザーで自分の Garmin アカウントをリンクします。管理者がターミナルで操作する必要はありません。https://your-host/garmin/login を案内すると、ユーザーはそこでアクセストークンと Garmin の認証情報を入力できます(2 段階 MFA に対応)。トークンはユーザー専用のサーバーディレクトリに保存されます。代替手段として、管理者が操作する caddie-mcp user login <name> も引き続き利用できます。
クライアントは Authorization: Bearer <token> ヘッダーを使って http://host:8724/mcp に接続します。Claude Code での例:
claude mcp add --transport http golf http://host:8724/mcp \
--header "Authorization: Bearer <token>"
Docker:
python -m build # wheel must exist in dist/
docker build -t caddie-mcp .
docker run -d -v caddie_data:/data -p 8724:8724 caddie-mcp
docker exec -it <container> caddie-mcp user add marcos
docker exec -it <container> caddie-mcp user login marcos
セキュリティに関する注意:トークンは 256 ビットのシークレットで、SHA-256 ハッシュのみが保存され、定時間比較で照合されます。caddie-mcp user rotate-token <name> でローテーションしてください。TLS の背後(Caddy/nginx/Cloudflare Tunnel)で実行してください。トークンはヘッダー内を通過します。--no-auth モードはローカルホスト限定の単一ユーザー利用向けに用意されており、ループバック以外のアドレスへのバインドは拒否されます。認証不要のルートは /health のみです。/data ボリュームには Garmin の認証情報が含まれるため、バックアップの取り扱いには注意してください。
claude.ai カスタムコネクター(OAuth)
claude.ai はベアラーヘッダーではなく、OAuth(動的クライアント登録 + PKCE)経由でリモート MCP サーバーに接続します。次のようにして有効にします:
caddie-mcp serve-http --host 0.0.0.0 --oauth \
--public-url https://golf.example.com
その後、claude.ai で https://golf.example.com/mcp をカスタムコネクターとして追加します。初回接続時には同意ページが表示され、ユーザーはそこで caddie-mcp のアクセストークンを一度だけ貼り付けます。以降は OAuth トークン(有効期間 1 時間のアクセストークンと、ローテーションされるリフレッシュトークン。ハッシュ化して保存)によって接続が維持され、そのユーザーのデータに限定されます。静的ベアラートークンも OAuth と併用できます。TLS 対応の実ドメインが必要です。claude.ai は HTTP には接続しません。
バックグラウンド同期
サーバーモードでは、リンク済みの各ユーザーのデータを常に最新の状態に保つことができます:
caddie-mcp serve-http --host 0.0.0.0 --sync-every 6h
Garmin API へのリクエストが一斉に集中しないよう、ユーザーは順番に(差分同期し、ジッターを加え、ユーザーごとにエラーを分離して)同期されます。
Claude Desktop 拡張機能
python scripts/build_mcpb.py を実行すると、dist/caddie-mcp.mcpb が生成されます。これは Claude Desktop にダブルクリックでインストールできるバンドルで、公開済みパッケージを uvx 経由で起動します。マシンに uv がインストールされ、パッケージが PyPI に公開されている必要があります。初回の uvx caddie-mcp login は引き続きターミナルで実行します(認証情報がデスクトップアプリを経由することはありません)。
PyPI への公開(メンテナー向け)
.venv/bin/python -m build # sdist + wheel into dist/
pipx run twine upload dist/* # needs a PyPI API token
データ品質と修復
caddie-mcp repair は Garmin を呼び出さずに、キャッシュ内のすべての計算フィールドを再導出します(クラブ名、ライ/ショットタイプの正規化、GPS からピンまでの距離、GIR/フェアウェイの推定)。各同期の最後に自動実行されるため、手動で実行する必要があるのはコネクターをアップグレードした後だけです。
対応済みの Garmin の既知の仕様:ウォッチは TEEBOX/TEE/UNKNOWN の列挙値を報告します。パットは、グリーン上のショットがなく、ホールごとの合計数として記録されることがよくあります。グリーンに届くショットの終了位置はピンにスナップされます(そのため、グリーンに乗ったショットの後の距離は正確には NULL となり、パッティングのストロークゲインには推定値であることを示すフラグが付けられます)。
ツール
| ツール | 回答する内容 |
|---|---|
garmin_status | 接続されていますか?キャッシュ済みのデータと、まだ Garmin 上にあるデータはどれくらいですか? |
sync_garmin_data | Garmin からラウンド/ショット/クラブを取得します。分割して取得(1 回あたり 25 件、rounds_remaining を報告)するため、チャットから複数年分の全履歴を安全に読み込めます |
list_rounds | 「最近のラウンドを表示」— 簡潔な概要 |
get_round | 1 ラウンドの詳細:スコアカード、ホール、ショット |
get_shots | ショット単位の GPS/クラブ/ライデータ。地図用の format="geojson" |
get_club_stats | クラブごとの実測距離と Garmin の推定値 |
get_strokes_gained | ラウンドごとの Broadie ストロークゲイン:ティーショット/アプローチ/ショートゲーム/パッティング。ハンディキャップ相当のレベルまたはスクラッチと比較 |
get_performance_stats | PGA 形式の約 40 項目の統計(ドライビング、距離別 GIR、スクランブリング、パッティング、スコアリング)。任意でハンディキャップのベンチマークを指定可能 |
get_handicap | WHS 形式のインデックス、採用ディファレンシャル、推移 |
get_course_intel | 1 コースのホールごとの難易度と、通常使用するティーショットのクラブ |
get_health_context | ラウンド当日の睡眠、HRV、Body Battery、レディネス、ストレス |
correlate_health_performance | 「睡眠の質が悪いとスコアも悪くなりますか?」— 対応するデータと、誠実な相関分析 |
query_golf_data | キャッシュに対する読み取り専用 SQL で、あらゆる質問に回答 |
同期では daily_health も取得します(ラウンドの日付ごとに Garmin への呼び出しが 4 回追加されます)。
睡眠スコア/時間、安静時心拍数、HRV ステータス、Body Battery の範囲、トレーニングレディネス、ストレス、歩数に加え、各ラウンドのラウンド時間帯のデータ補完も行います。ティーオフ時の Body Battery とプレー中の消費量、ラウンド中の平均/最大心拍数とストレス、そして対応する Garmin アクティビティから取得したラウンド時の天候(気温、風、湿度、状況)が含まれます。
Garmin からショットのばらつきデータが送られない場合、GPS の幾何情報からショットのミスオフセット(dx/dy)を導出します。ドライバーショットはティーからピンへの線に対する左右のずれ、アプローチ/チップショットはピンを基準に算出します。これにより、ショットの GPS データがあればどのウォッチでも、ミスの方向や傾向に関する統計を利用できます。
すべてのショットにはプレー上の距離も設定されます。ショット位置とピン位置の地形標高は無料の Open-Meteo 標高 API から取得し、ローカル DB に無期限でキャッシュされます。plays_like_yds では標準的な 1 対 1 の上り/下り補正を適用するため、「150 ヤードのショット」を実際のプレー上の距離に基づいて分析できます。
プロンプト(ワークフローのパッケージ):post_round_report、practice_plan、
course_strategy、health_check_in、season_review。
リソース:schema://data-dictionary(列、単位、列挙値)、
docs://metric-definitions(各統計の算出方法)、および
docs://getting-started(推奨するツールの使用手順)。
規則
- 距離はヤード、座標は十進度、時刻は ISO 8601 形式です。
- ライ:
tee | fairway | rough | sand | green | recovery | penalty。 - ショットタイプ:
drive | approach | chip | putt | penalty。 - 不明な値は捏造せず
NULLにします。ホールの最後のショットには計測された終了距離がなく、ツールもその旨を示します。
セキュリティに関する注意事項
- Garmin トークンは
~/.garminconnect(モード 0600)に保存されます。パスワードと同様に扱ってください。 - SQL ツールは読み取り専用で、単一のステートメントのみ実行でき、SELECT のみを受け付け、上限が設定されています。
- これは、ご自身の Garmin データを対象とする非公式コネクターです。
開発
.venv/bin/python -m pytest tests/ -q
mcp-name: io.github.mbrionesalvarez/caddie-mcp
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。