mcpField
T
TrainBud

TrainBud

ローカル
github.comヘルスケア06 週間前に更新

TrainBud について

TrainBudは、AIクライアントからGarmin Connectのトレーニングデータを照会できるオープンソースのMCPサーバーです。ローカル履歴と個人の基準値を活用し、運動、睡眠、回復、傾向のツールに加え、ダッシュボードとウォッチウィジェットを備えます。

主な機能

  1. 01Garmin Connectのフィットネスデータ照会
  2. 02SQLiteによるローカル履歴とキャッシュ
  3. 03個人の28日間基準値に基づく所見
  4. 04ダッシュボード、音声機能、ウォッチウィジェット
  5. 05運動、睡眠、回復のツール

活用シーン

  1. 01AIクライアントで最近の運動や睡眠を質問
  2. 02現在の指標を個人の基準値と比較
  3. 03トレーニング傾向や週次サマリーを確認
  4. 04Garminウォッチで回復や睡眠情報を表示

MCP 対応

Claude DesktopやCursorなどのクライアントにstdio MCPでフィットネスデータ用ツールを提供し、`trainbud serve`ではリモートHTTP MCPも利用できます。ツールはアクティビティ、睡眠、心拍数、回復、体組成、傾向、個人のコンテキストを扱います。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"zsadigzade-trainbud": {
"command": "npx",
"args": [
"-y",
"trainbud"
],
"env": {
"GARMIN_EMAIL": "<GARMIN_EMAIL>",
"GARMIN_PASSWORD": "<GARMIN_PASSWORD>",
"ANTHROPIC_API_KEY": "<ANTHROPIC_API_KEY>"
}
}
}
}
起動コマンドnpx -y trainbud
設定が必要な環境変数
GARMIN_EMAILThe email address for your Connect account. Stored only in your local .env; `npx trainbud setup` writes it for you.
GARMIN_PASSWORDシークレットYour Connect password. Stored only in your local .env. Accounts with MFA enabled are not supported, because the unofficial library this drives cannot complete that flow.
ANTHROPIC_API_KEYシークレットOptional, and only for the watch app's Ask card and daily insight. The MCP tools themselves need no model key: every finding is computed in code, and the model only phrases it.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmtrainbud0.9.0
ocighcr.io/zsadigzade/trainbud:0.9.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

TrainBud

トレーニングデータに話しかけましょう。

TrainBud は、Garmin Connect のフィットネスデータを Claude、Cursor、その他の AI アシスタントに接続するオープンソースの MCP サーバーです。ワークアウト、睡眠、心拍数、回復、体組成について、自然な英語で質問できます。データはプライベートに、ご自身のマシン上で管理できます。

免責事項: TrainBud は非公式のコミュニティプロジェクトです。Garmin Ltd. との提携、同社による推奨、または同社の後援を受けていません。Garmin Connect は Garmin Ltd. の商標です。

npm CI License: MIT Node 22.12+ Trainbud MCP server — quality and maintenance score on Glama

Trainbud MCP server — license, quality, and maintenance card on Glama

試してみる

MCP クライアントに接続したら、次のように質問してみてください。

  • 「今日は何をしましたか?」
  • 「今週の睡眠はどうですか?」
  • 「明日はハードなトレーニングをしても大丈夫なくらい回復していますか?」
  • 「安静時心拍数は下がっていますか?」

アイデアについては、examples/prompts.md をご覧ください。

TrainBud を選ぶ理由

  • プライベート — 認証情報はローカルの .env に保存され、データはお使いのマシンにキャッシュされます
  • ローカル優先 — SQLite キャッシュと、.trainbud/ に保存されるセッショントークンを使用します
  • どこでも使えます — Windows、macOS、Linux(Node.js 22.12 以降)
  • あらゆる MCP クライアントに対応 — Claude Desktop、Cursor、その他の stdio 対応クライアント
  • スマートなデータ取得 — API 呼び出しをまとめて行い、セッションの期限切れ時には自動で再認証します

クイックスタート

npx trainbud setup

セットアップウィザードで、認証情報の設定、認証、Cursor または Claude Desktop への接続を順に行えます。MCP 設定ファイルを編集する必要はありません。その後、MCP クライアントを再起動して、今日何をしたか尋ねてみてください。

毎回 npx を入力せずに trainbud を PATH から実行するには、次のようにします。

npm install -g trainbud
trainbud setup

Node 22.12 以降が必要です。詳しい手順は QUICKSTART.md をご覧ください。

ソースから実行(コントリビューター、または未リリースのコミットを実行する場合)
git clone https://github.com/Zsadigzade/trainbud.git
cd trainbud
npm install
npm run build
npm link          # puts `trainbud` on your PATH; undo with `npm unlink -g trainbud`
trainbud setup

npm link を使わない場合、この README 内のすべての trainbud <command> は、リポジトリのルートから node dist/index.js <command> を実行する形になります。dist/ がまだ存在しない場合は、先に npm run build を実行してください。

Claude Code プラグイン(推奨)

Claude Code プラグインとしてインストールすると、スキルと MCP サーバーを一度に導入できます。

/plugin marketplace add Zsadigzade/trainbud
/plugin install trainbud@trainbud

認証情報を設定してから、Claude Code を再起動してください。

export GARMIN_EMAIL="[email protected]"
export GARMIN_PASSWORD="yourpassword"
コマンド機能
/trainbud:trainbud-setup初回セットアップと診断
/trainbud:trainbudワークアウト、睡眠、回復、HR、ストレス、VO2 max について質問します

プラグインファイルは plugin/ にあります。詳細は plugin/README.md をご覧ください。

Claude Code スキル(リポジトリ内)

このリポジトリには、プラグインをインストールせずに開発するためのプロジェクトスキルも .claude/skills/ に含まれています。

コマンド機能
/trainbud-setupインストール、認証、MCP の設定、ライブチェックの実行
/trainbudワークアウト、睡眠、回復、HR、ストレス、VO2 max について質問します

Claude Code でリポジトリを開くと(このディレクトリで claude を実行)、スキルが自動的に読み込まれます。

プラグインを使わず、すべてのプロジェクトでスキルを使うには、スキルを ~/.claude/skills/ にコピーしてください。

セットアップ後、MCP クライアントを再起動し、「今日は何をしましたか?」と尋ねて /trainbud を試してみてください。

ダッシュボード

trainbud serve を実行すると、/dashboard にダッシュボードが表示されます。ペアリングの際、コードを承認するときはスマートフォンを持って時計のそばにいるため、スマートフォンでの利用を優先して設計されています。

ローカルの履歴ストアからデータを読み込むため、すぐに表示され、Connect セッションの有効期限が切れていても機能します。今日のデータを自身の基準値と比較した際の注目点、今週と先週の比較、安静時心拍数と睡眠の自身の30日間の中央値との比較を確認できます。グラフの線が途切れている箇所は、その日の測定値がないことを示しており、ゼロではありません。

また、TrainBud が誰について話すのかを設定する場所でもあります。

設定変更内容
名前、単位、メインのスポーツ、週間目標すべての表示と、AI に伝えるあなたの情報
しきい値緑から黄、黄から赤に変わる基準。時計にも適用されます
時計のカード手首に表示するカードとその順序。次回の同期時に反映されます
AI モデル、口調、回答の長さAsk カードと毎日のインサイトの話し方
独自の Ask 質問それぞれ32文字まで、最大5件です。時計の Ask メニューの先頭に表示され、残りの枠には検出された内容に基づいて自動生成された質問が入ります
月間利用上限任意です。上限を超えて利用する代わりに、上限に達した後の Ask を拒否します
プライバシーローカルの機能利用カウンター。デフォルトで有効で、削除ボタンがあります

利用状況。 TrainBud はご自身の AI プロバイダーのキーを使うため、すべての質問と毎日のインサイトの料金はご自身に請求されます。ダッシュボードには、呼び出しごとのトークン数と料金、当月の累計、30日間のグラフが表示されます。このビルドで料金が公開されていないモデルは、ゼロではなく料金を不明として記録します。料金ゼロの呼び出しがあると、上限が決して適用されなくなるためです。

このページの情報がマシンの外部に送信されることはありません。情報を送信するエンドポイントもありません。

Garmin ウォッチウィジェット(Connect IQ)

ciq/ の Connect IQ ウィジェットを使って、Garmin ウォッチで回復、睡眠、アクティビティ、ストレス、VO2 max を確認できます。

必要なもの: trainbud serve の実行と HTTPS トンネル(Web AI と同じセットアップ)。

  1. サーバーとトンネルを起動します。
    trainbud serve
    cloudflared tunnel --url http://127.0.0.1:3847
    
  2. ウィジェットをビルドしてサイドロードします。ciq/README.md を参照してください。
  3. Garmin Connect Mobile → Connect IQ → TrainBud の設定を開き、次の項目を設定します。
    • Server URL — トンネルの URL(例:https://abc.trycloudflare.com)
  4. ウォッチでウィジェットを開くと、ペアリングコードが表示されます。ダッシュボード(/dashboard?token=YOUR_API_KEY)で承認してセットアップを完了します。ダッシュボードはそのトークンをセッション Cookie に置き換えて URL から削除するため、その後はアドレスバーを安全にスクリーンショットに撮れます。

グランス画面には、直近のキャッシュ済みサマリーから回復と睡眠、または数文字で表した最も重要な検出結果(「RHR +4 bpm」など)が表示されます。ネットワークを待たずに描画され、2時間以上古くなるとその旨が表示されます。ウィジェットを開き、タップまたはスワイプすると、ダッシュボードで有効にしたカードを順に切り替えられます。ウォッチから呼び出すのは GET /api/watch です。これは完全な MCP プロトコルではなく、簡潔な JSON サマリーを返します。

Today カードでは、START(またはタップ)を押すと、検出結果の詳細と該当するルールが表示されます。たとえば「直近3日間はそれぞれ、28日間の中央値である48 bpmを3 bpm以上、標準偏差2つ分上回っています」といった内容です。そこから3日間ミュートできます(POST /api/mute)。Sleep カードには、昨夜の睡眠で自身の通常の夜と比べて変化した内容が表示されます(「Deep 40m (1h24m)」など)。ウィジェットの容量が64 KBの Forerunner 55 では、残りの機能を収めるため、この2つのカードはビルドから除外されます。

検出ルール

すべての検出結果は、確認や変更が可能なルールに基づいています。ダッシュボードの検出ルールセクションでは、各種しきい値を設定できます。安静時心拍数の対象日数・bpm・標準偏差、睡眠負債の時間数、HRV の低下、トレーニング負荷の比率、「複数のシグナルが同時に発生」(安静時心拍数の上昇、HRV の低下、睡眠ストレスの上昇が同時に起きた場合)などが含まれます。どの設定を選んでも、毎日または一日も検出されない状態にならないよう、値には範囲が設定されています。すべての画面で、検出結果が発生したルールと、そのとき適用されていた数値を確認できます。

音声(/voice)

スマートフォンのボタンを長押しして、声に出して質問すると、回答が読み上げられます。 最初に一度だけ https://YOUR-HOST/voice?token=YOUR_API_KEY を開くと、キーが Cookie に交換され、 URL がすっきりした状態にリダイレクトされます。

  • Android / Chrome — 音声認識はブラウザー内で行われます。無料で、キーは不要です。
  • iPhone / Safari — 音声を録音し、サーバー側で Groq を使って文字起こしします (whisper-large-v3-turbo、音声 1 時間あたり約 $0.04)。ダッシュボードでキーを追加してください。
  • 両方 — 回答が読み上げられます。また、今日の予定を読み上げて / 今日の気づきを読み上げて は、すでにあるデータをもとにコードで作成され、費用は一切かかりません。生成されるものではありません。

時計の機能ではなく、時計の機能にすることもできません。Connect IQ はウィジェットに マイクやスピーカーを公開していません。また、ハンズフリーでもありません。モバイルブラウザーではタブが バックグラウンドになるとマイクが一時停止するため、ページを表示したままスマートフォンを起動しておく必要があります。

詳細:docs/VOICE.md

常時稼働(/voice と時計を、ターミナルを見守らずに使う)

ターミナルで実行する trainbud serve は、ターミナルを閉じるまでしか動作しません。再起動後にサーバーと トンネルを自動で再開するには、次のようにします。

.\scripts\install-always-on.ps1 -Hostname trainbud.example.com

これにより、サーバーのスケジュールタスクと、5 分ごとに両方を確認する監視プロセスが登録されます。 応答するトンネルが、応答するサーバーとは限らないためです。背後に何もないトンネルは、ステータスコード 200 のまま 独自のエラーページを返すため、リンクは正常に見えても、時計には HTTP -400 と表示されます。systemd、launchd、Docker Compose の設定例はガイドにあります。

詳細(Cloudflare のネームドトンネルを含む):docs/ALWAYS-ON.md

Claude Desktop に接続する

claude_desktop_config.json を編集します。

Windows: %APPDATA%\Claude\claude_desktop_config.json
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "trainbud": {
      "command": "node",
      "args": ["C:/path/to/trainbud/dist/index.js", "start"],
      "env": {
        "GARMIN_EMAIL": "[email protected]",
        "GARMIN_PASSWORD": "yourpassword"
      }
    }
  }
}

trainbud が PATH 上にある場合(npm install -g trainbud を実行するか、クローンから npm link を実行します)は、 パスではなくコマンドをクライアントに指定します。

{
  "mcpServers": {
    "trainbud": {
      "command": "trainbud",
      "args": ["start"]
    }
  }
}

MCP クライアントを再起動して、質問を始めてください。

ツール

ツール回答する内容
get_latest_activity直近のワークアウト — 距離、ペース、心拍数、標高
get_activities_range2 つの日付の間のアクティビティ
get_sleep_data睡眠時間、睡眠ステージ、スコア、覚醒回数 — 昨夜のどの部分がいつもと違っていたか
get_heart_rate_trends安静時、最大、平均心拍数の推移
get_recovery_statusHRV、睡眠、ストレス、安静時心拍数から算出した回復スコア
get_body_composition体重、体脂肪、筋肉量の推移
get_stress_levels日々のストレス平均値と推移
get_vo2_max_trendsVO2 max のフィットネス推移
get_training_insights週ごとの統合サマリー(アクティビティ、睡眠、回復、ストレス)
get_findingsあなた自身の 28 日間の基準値と比べて目立つ点と、各点が検出されたルール
get_week_review今週と先週の比較、負荷予測、睡眠負債、次のレース
compare_workouts1 回のワークアウトを、同じ種類・距離の過去のワークアウトと比較
remember_context目標、レースとその日付、けが、メモを記録
get_user_contextどの日付でも、あなたについて記録されている内容
log_subjectiveセッションの実際の感覚 — RPE、筋肉痛、気分

CLI

trainbud setup          # Interactive first-time setup (recommended)
trainbud serve          # Remote HTTP MCP for web AI (claude.ai, ChatGPT)
trainbud check          # Live diagnostics against all tools
trainbud doctor         # What the watch would see: public URL, AI key, history depth
trainbud backfill       # Pull Garmin history into the local store (resumable)
trainbud findings       # What stands out against your own baselines, and the rule each fired on
trainbud rederive       # Rebuild sleep measurements (deep, REM, awakenings) from the local archive — no Garmin requests
trainbud start          # Start the MCP server (stdio)
trainbud auth           # Force re-authentication
trainbud cache clear    # Clear cached data
trainbud devices        # List paired watches
trainbud devices revoke <id>   # Take one watch's access away
trainbud rotate status  # Which secrets are set, and whether their two homes agree
trainbud rotate api-key # Replace TRAINBUD_API_KEY, and say what that invalidates
trainbud rotate ai-key  # Replace the AI key in BOTH .env and app.db
trainbud status         # Show session and cache status
trainbud --version      # Print version

rotate ai-key は意図的に両方の保存先へ書き込みます。AI キーは .env と app.db の両方に保存されます。実際に読み込まれるのはデータベース内のコピーです。ファイルだけを手動で編集すると、 キーをローテーションしても反映されません。

これらのコマンドはすべて、インストールせずに npx trainbud <command> としても実行できます。

トラブルシューティング:trainbud: command not found

npx trainbud <command> を使うか、npm install -g trainbud でグローバルにインストールしてください。クローンから実行する場合は、 リポジトリのルートで一度 npm link を実行するか、ビルド後(npm run build)、node dist/index.js doctor で ビルド済みのエントリーポイントを直接呼び出してください。

設定

変数デフォルト説明
GARMIN_EMAIL—Garmin Connect のメールアドレス
GARMIN_PASSWORD—Garmin Connect のパスワード
TRAINBUD_SESSION_PATH.trainbud/session.jsonセッショントークンの保存先
TRAINBUD_LOG_PATH.trainbud/mcp.logログファイルのパス
TRAINBUD_CACHE_PATH.trainbud/cache.dbSQLite キャッシュデータベース
CACHE_TTL_ACTIVITIES1800アクティビティキャッシュの TTL(秒)
CACHE_TTL_SLEEP7200睡眠キャッシュの TTL(秒)
CACHE_TTL_STATS3600統計キャッシュの TTL(秒)
TRAINBUD_API_KEYauto-generatedHTTP MCP(trainbud serve)用のベアラートークン
TRAINBUD_HOST127.0.0.1HTTP サーバーのバインドホスト
TRAINBUD_PORT3847HTTP サーバーのバインドポート

セキュリティとプライバシー

  • 認証情報はローカルの .env ファイル内にのみ保存され、第三者に送信されることはありません
  • .trainbud/session.json 内のセッショントークンは、パスワードと同様に機密性の高い情報です
  • ツールのエラーは、AI クライアントに渡る前にサニタイズされます
  • 非公式の garmin-connect npm パッケージを使用しています(Garmin のエンタープライズ OAuth API は使用していません)
  • MFA は基盤となるライブラリでサポートされていません。MFA を無効にするか、アプリ固有のパスワードを使用してください
  • デフォルトではサーバーは 127.0.0.1 にバインドされます。トンネルを接続しない限りインターネットからアクセスできず、/health 以外のすべてのルートには API キーが必要です
  • ダッシュボードは /dashboard?token=… でキーを一度だけ受け取り、それを HttpOnly セッション Cookie と交換して、URL をクリーンな状態にリダイレクトします。そのため、キーがアドレスバー、履歴、スクリーンショットに残ることはありません
  • **ペアリング済みのウォッチは、そのウォッチに限定されたトークンを保持します。**ペアリング時に発行され、サーバーには SHA-256 ハッシュとして保存されます。trainbud devices で一覧表示でき、trainbud devices revoke <id> で取り消せます。ダッシュボード、/mcp、その他のウォッチからログアウトする必要はありません。0.5.2 より前にペアリングしたウォッチは API キー自体を保持しているため、スコープ付きトークンに切り替えるには再ペアリングしてください
  • 401 を含むすべてのレスポンスには、Content-Security-Policy、X-Content-Type-Options、X-Frame-Options、Referrer-Policy が含まれます。HSTS は実際に TLS 経由で届いたリクエストにのみ送信されるため、ループバックのダッシュボードには引き続きアクセスできます
TrainBud ではないもの
  • **ホステッドサービスではありません。**TrainBud アカウントも TrainBud サーバーもありません。ご自身のマシンで、ご自身の Garmin 認証情報を使って実行します
  • **Garmin の公式連携ではありません。**Connect の Web API に対して非公式ライブラリを使用します。Garmin は予告なく API を変更する可能性があり、実際に変更しています
  • **MFA に対応していません。**Connect アカウントで MFA が有効な場合、ログインできません
  • **無料で利用できるわけではありません。**AI 機能はご自身の Anthropic キーを使って実行され、料金はご自身に請求されます。ダッシュボードではすべての呼び出しが計測され、設定した上限を超えると拒否されることがあります

トラブルシューティング

問題対処方法
認証に失敗する.env の認証情報を確認し、trainbud auth を実行してください
アカウントで MFA が有効になっているMFA を無効にするか、アプリ固有のパスワードを使用してください
データが古いtrainbud cache clear を実行してください
レート制限がかかっている60 秒待ってください。利用可能な場合はキャッシュされたレスポンスが使用されます
ウォッチに「Not a TrainBud server」またはエラー -400 と表示される公開 URL が TrainBud の JSON 以外のものを返しています。通常はトンネルが停止しています。trainbud doctor を実行すると、何が返されたかが正確に表示されます
ウォッチに「Watch not authorised」と表示されるウォッチのペアリング後に API キーが変更されています。ダッシュボードから再度ペアリングしてください
ウォッチに「AI not set up」と表示されるAI はご自身のキーを使用します。ダッシュボードに Anthropic キーを貼り付けてください
睡眠/HR データがないGarmin デバイスが Garmin Connect と同期されていることを確認してください
サーバーが起動しない.env に GARMIN_EMAIL と GARMIN_PASSWORD が設定されていることを確認してください

Docker

プッシュのたびに CI でビルドとテストを実施する公開済みイメージです。放置されて使えなくなるようなものではありません。

docker pull ghcr.io/zsadigzade/trainbud:latest

または、このリポジトリから自分でビルドできます。

docker build -t trainbud .

何よりも重要なのは、/app/.trainbud にボリュームをマウントすることです。 ここには SQLite の履歴、キャッシュされたセッション、ログが保存されます。マウントしないと、コンテナを再起動するたびにダウンロード済みの履歴が失われ、最初から再認証が必要になります。

デスクトップクライアントの MCP サーバーとして

デフォルトのエントリーポイントは stdio 経由で MCP と通信するため、クライアントがコンテナを起動します。

{
  "mcpServers": {
    "trainbud": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "GARMIN_EMAIL", "-e", "GARMIN_PASSWORD",
        "-v", "trainbud-data:/app/.trainbud",
        "trainbud"
      ]
    }
  }
}

-i は必須です。指定しないとコンテナに標準入力がなく、クライアントには接続後すぐに応答しなくなるサーバーが表示されます。値を指定しない 2 つの -e フラグは、変数を自身の環境から引き継ぐため、認証情報を設定ファイルに記述せずに済みます。

ウォッチアプリまたはウェブクライアント用の HTTP サーバーとして
docker run --rm -p 3847:3847 \
  -e GARMIN_EMAIL -e GARMIN_PASSWORD \
  -e TRAINBUD_API_KEY \
  -e TRAINBUD_HOST=0.0.0.0 \
  -v trainbud-data:/app/.trainbud \
  --entrypoint node trainbud dist/index.js serve

コンテナ内では TRAINBUD_HOST=0.0.0.0 が必要です。サーバーはデフォルトで 127.0.0.1 にバインドします。これはノートパソコンでは適切なデフォルト設定ですが、コンテナの外部からはアクセスできません。

履歴の補完

trainbud setup は対話型で、ターミナルがあることを前提としています。そのため、Docker では一度限りのバックフィルを直接実行してください。

docker run --rm -e GARMIN_EMAIL -e GARMIN_PASSWORD \
  -v trainbud-data:/app/.trainbud \
  --entrypoint node trainbud dist/index.js backfill

同じ方法で doctor、check、devices も実行できます。

開発

npm install
npm run build
npm test          # the whole suite, via the Node test runner
npm run lint
npm run dev       # Start with auto-reload

Node 22 には nvm/fnm で .nvmrc を使用してください。npm run test:coverage は Node 独自のテストランナーを使ってカバレッジをレポートし、npm run test:watch は変更時にテストを再実行します。

アーキテクチャと設計に関するメモについては、CONTRIBUTING.md と docs/VAULT.md(このリポジトリ外の Obsidian vault)を参照してください。

ロードマップ

  • VO2 最大値の推移
  • ストレスレベル
  • トレーニングに関する分析
  • ワークアウトの比較
  • Docker イメージ — ghcr.io/zsadigzade/trainbud で公開

ライセンス

MIT — LICENSE を参照してください。

Garmin Connect は Garmin Ltd. の商標です。このプロジェクトは Garmin Ltd. と提携していません。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。