mcpField
R
Runspector — AI running coach for Garmin

Runspector — AI running coach for Garmin

ローカル
github.com/edxleonヘルスケア9今日更新

Runspector — AI running coach for Garmin について

Runspectorは、ランナー向けのローカルなGarminトレーニングコーチです。ルールベースのコンディション判定をClaudeが解説し、ワークアウトを計画します。ウェブアプリと、Claudeクライアント向けのMCPサーバーを備えています。

主な機能

  1. 01GarminデータをローカルSQLiteに同期
  2. 02ルールベースの日次コンディション判定
  3. 03Claudeによる解説と週間計画
  4. 04ウォッチ向けワークアウトの提案・適用・取り消し
  5. 05ローカルウェブアプリとデモモード

活用シーン

  1. 01強度を上げる、軽く走る、休むの判断
  2. 02回復指標とランニング傾向の確認
  3. 03ワークアウトを計画し、承認後にGarminウォッチへ送信

MCP 対応

Runspectorは16のMCPツールを通じて、Claude Code、Claude DesktopなどJSON設定に対応するMCPクライアントにGarminデータとコーチ機能を公開します。コンディション、ランニング記録、トレーニング負荷、同期、ウォッチ向けワークアウトの提案・適用・取り消しを扱います。

設定

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

mcp.json · 共通設定
{
"mcpServers": {
"edxleon-runspector": {
"command": "uvx",
"args": [
"runspector"
]
}
}
}
起動コマンドuvx runspector

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

パッケージ
pypirunspector0.7.0

ツール

16

掲載時のツール一覧 · 今日に更新

このツールにパラメーターはありません。

詳細

Runspector — Garmin 向け AI ランニングコーチ

ci PyPI evals 32/32 license MIT

Garmin ウォッチ向けの、無料でオープンソースの AI ランニングコーチです。 Runspector は、Garmin Connect のデータ(HRV、睡眠、Body Battery、安静時心拍数、トレーニング負荷、すべてのランニング)を同期して、お使いのコンピューター上のファイルに保存します。毎日、ハードに走るか、軽めに走るか、休むかを判断し、Claude にその理由の説明や週間プランの作成を任せられます。小さなローカルウェブアプリとして、または Claude Code や Claude Desktop で Garmin MCP サーバーとして利用できます。クラウドも API キーも不要です。ご自身の Claude Code サインインだけで利用できます。

https://github.com/user-attachments/assets/0b4d7d86-5ab7-439b-82cb-89a004b71405

ナレーション付きの90秒デモです。scripts/video.pyでこのリポジトリから再構築した合成デモアスリートを使用しています(ファイル)。上にプレーヤーが表示されない場合は、GitHub モバイルアプリでは動画が表示されません。ブラウザーで▶ デモを再生してください。

Runspector の Today タブ:Garmin データによるトレーニング準備状況の判定、今日の決定、週間プラン、HRV、睡眠、Body Battery Runspector の Coach タブ:Garmin データをもとに Claude が作成したコーチングカード Runspector の Runs タブ:各ランニングの強度ゾーンと検出されたインターバル構成 Runspector の Trend タブ(ライトテーマ):段階表示の VO2max、乳酸閾値、強度の80/20配分

組み込みの合成アスリート(runspector serve --demo)。画像はすべてpython scripts/screenshots.pyで再生成されます。コーチングカードは、同じデモデータベースに対してエージェントを実行して生成した、編集を加えていないものです。アプリとの食い違いが生じないよう、demo-card.jsonに保存しています。カードが説明する判断(ハードなセッションの翌日のEASY)は、その横にある Today タブの判断と同じです。docs/screenshots/には、5つのタブそれぞれの全体表示を、両方のテーマで収録しています。例:today.pngとtoday-light.png。

私はランニングを始めたのが遅く、長い間 VO2max が伸びませんでした。以前からたくさんトレーニングしていましたが、その数値にはほとんど反映されなかったため、同じことを続ければいつか効果が出ると思っていました。そうはなりませんでした。私は間違った方法でトレーニングしていたのです。手首のウォッチにはそれを示すデータがあったのに、教えてくれませんでした。Garmin はあらゆるデータを集めますが、何も説明しません。

これが出発点でした。データはすでにあります。AI に読み取らせてコーチングをさせればいいのです。目標は距離を稼ぐことではなく、VO2max を上げることに明確に定め、判断ルールも明文化して、コーチがそのルールを説明できるようにします。即興で判断するのではありません。このリポジトリは、あるアスリートのためのツールとして始まりました。現在は Garmin ウォッチと Claude Code があれば誰でもインストールできます(Claude のプランがあれば十分です)。

クラウドバックエンドも API キーも Docker も不要です。Python パッケージひとつで、Garmin データをお使いのマシン上の SQLite ファイルに同期し、小さなウェブアプリで表示して、Claude をコーチとして利用できます。その基盤には決定論的な準備状況エンジンがあるため、AI は判断を作り出すのではなく、その理由を説明します。 実行ではなくエンジニアリングに関心がある方へ、このリポジトリが実際に扱う5つの判断と、それぞれの根拠となる測定結果は、 設計上の判断にあります。要点は次のとおりです。判定は 純粋なコードで行い、AI が担うのは説明だけです · エージェントは 拒否リストではなく許可リスト(--tools ""、MCP サーバー1つ、空の一時作業ディレクトリ)で実行します · プロンプトは回帰テストの対象で、LLM-as-judge スイートの最新実行結果は リポジトリ内にあります · 2つの言語にまたがって存在する数量は、 同梱の JavaScript を Python に対して実行して固定します · そして リリースゲートは誤検知となる反例も含め、バイナリもスキャンします。CI では、3つの OS と2つの Python バージョンで、リンター、995件のテスト、80件のフロントエンドテスト、ゲートを実行し、すべてのアクションをコミット SHA に固定しています。さらに、2つ目のジョブでは、全3システムでwheel をビルドし、ユーザーと同じ方法でインストールして、このクイックスタートを通じてインストール済みの実行ファイルを動かします。テストスイートが証明するのはコードであり、パッケージを証明するのはインストールだけだからです。

以前は runcoach-ai という名称でした。v0.5.0 で改名しましたが、プロジェクトは同じです。古いリンクはここにリダイレクトされます。旧プロジェクトから移行する場合は、切り替えの3つの手順をご覧ください。データは自動的に移行されます。

Garmin とは提携していません。ご自身のアカウントに対して、非公式の python-garminconnect ライブラリを使用します。 これはトレーニング用ツールであり、医療上のアドバイスではありません。

クイックスタート

# 1. install (needs uv: https://docs.astral.sh/uv/)
uv tool install runspector
#    without uv: pipx install runspector

# 2. look around without any account
runspector serve --demo

# 3. the real thing
runspector serve        # first start: checks Garmin and Claude, opens http://127.0.0.1:8765 -
                        # sign in to Garmin right there (Setup → Sign in to Garmin; only a
                        # session token is stored) - and syncs the last 30 days in the background

Garmin へのサインインはページ上で行います(Setup → Garmin にサインイン、またはセッションの期限が切れた場合は 再度サインイン)。メールアドレス、パスワード、アカウントで使用している場合は Garmin のコードを入力すると、すぐに同期が始まります。runspector login を使えば、どのターミナルからでも同じ操作ができ、アプリの実行中に ↻ を押すと再起動せずに反映されます。Claude が必要なのはコーチカードのみです。詳しくはClaude の接続をご覧ください。

runspector doctor は不足しているものを知らせます。Garmin のセッションを実際に使用して確認し、データの経過時間も報告します。トークンが気付かれないまま期限切れになることが、この種のアプリが動かなくなる原因だからです。Garmin への接続を省略するには、runspector doctor --offline を使用します。終了コード 1 は修正が必要な項目があることを意味するため、cron で runspector doctor || notify-me のように使えます。Claude CLI が見つからない場合も報告されますが、終了コードには影響しません。コーチカード以外の機能はすべて Claude なしで利用できるためです。

Claude Code と Claude Desktop 向け Garmin MCP サーバー

同じデータと同じルールを、16個のツールを備えた MCP サーバーとして利用できます。ツールには、今日のコンディション判定、回復状況、トレーニング負荷、最近のラン、強度分布、VO2max の履歴、コーチがあなたについて学習した内容、Garmin の同期のほか、ウォッチ上のワークアウトの提案、適用、取り消しが含まれます。

claude mcp add runspector -- runspector mcp
# then just ask: "should I train today?"
# or: "plan me an easy 40 minutes for tomorrow" - you see the session, and it goes
# on your watch only after you say yes ("take it back off" undoes it)

Claude Desktop、または JSON 設定を使用する任意の MCP クライアントで利用できます(先に一度サインインしてください:runspector login)。

{ "mcpServers": { "runspector": { "command": "uvx", "args": ["runspector", "mcp"] } } }

アプリを使わずに最新の状態を保つには(cron / Task Scheduler)、runspector sync を実行します。

後からインストールする場合:

uv tool upgrade runspector     # the newest release; your data and Garmin session stay where they are
uv tool uninstall runspector   # removes the program only - delete ~/.runspector yourself if you want the data gone

uv tool install runspector は PyPI から最新リリースをインストールします(runspector==0.5.1 で特定のバージョンに固定できます。pipx install runspector と pipx upgrade runspector でも uv を使わずに同じ操作ができます)。 uv tool install git+https://github.com/edxleon/runspector は main の内容をインストールします。

Claude への接続

runspector は Claude 自体には接続せず、Claude のパスワードやキーを尋ねることもありません。コーチ機能は、Anthropic 独自のサインインを通じて、ご自身のアカウントでサインインした Claude ソフトウェア上で動作します。

目的必要なもの
今日の判定とその理由、ラン、傾向、同期Claude のものは不要です
Web アプリ内のコーチカード(Ask the coach、Should I train today?、Analyze this run、Review my week)と、ウォッチに送信するセッションこのコンピューターにインストールされ、サインイン済みの Claude Code
チャットでコーチ機能を使い、ウォッチへのセッション送信も行うMCP サーバーとして runspector を追加した Claude Desktop または Claude Code

「Claude のプラン」とは。 Claude Code を使うには、claude.com/pricing に記載されている有料の Claude サブスクリプション(Pro、Max、Team、Enterprise)、または従量課金の Anthropic Console(API)アカウントが必要です。無料の Claude プランには Claude Code は含まれていません。有料プランを利用している場合、コーチカードの使用量は他の Claude Code の使用と同様に、そのプランの使用量に加算されます。キーを作成する必要はなく、カードごとの請求もありません。runspector 自体は無料です。

Claude Code を使う場合(コーチカードに必要)

Claude Code は Anthropic のコマンドラインツールです。一度だけインストールしてサインインすれば、runspector がカードごとにバックグラウンドで起動します。

# 1. install - macOS / Linux (Windows PowerShell: irm https://claude.ai/install.ps1 | iex)
curl -fsSL https://claude.ai/install.sh | bash        # or: brew install --cask claude-code

# 2. sign in - opens your browser, sign in with your Claude account
claude auth login

# 3. check
runspector doctor        # "Claude: signed in with your Claude subscription"

その他のインストール方法(WinGet、npm、Linux パッケージ)については、Claude Code のセットアップをご覧ください。runspector serve の起動時に Claude Code が見つからなかった場合は、その後ページを再読み込みしてください。再起動は不要です。

Claude Code がプランではなく Console API キーまたはクラウドプロバイダー(Bedrock、Vertex)でサインインしている場合、カードはその環境で動作し、そこで課金されます。セットアップ時のチェックでその旨が表示されます。ほかの作業用にシェルでのみエクスポートされている ANTHROPIC_API_KEY は、RUNSPECTOR_ALLOW_API_KEY=1 を設定しない限り、カードの実行時には削除されます。

Claude Desktop だけを使う場合(Claude 用のコマンドラインツールなし)

Claude デスクトップアプリ(claude.ai/download)を使っている場合、Claude Code がなくてもチャットでコーチ機能を使えます。

  1. runspector をインストールし、Garmin に一度サインインします(runspector login、または runspector serve のページから行えます)。
  2. Claude Desktop で、Claude メニュー → Settings… → Developer → Edit Config を開き、次を追加します。
    { "mcpServers": { "runspector": { "command": "runspector", "args": ["mcp"] } } }
    
    (macOS のファイルは ~/Library/Application Support/Claude/claude_desktop_config.json、Windows のファイルは %APPDATA%\Claude\claude_desktop_config.json です。すでにあるサーバー設定は残してください。)
  3. Claude Desktop を終了して再起動し、"should I train today?" と尋ねます。

サーバーが表示されない場合、Claude Desktop がコマンドを見つけられていない可能性があります。which runspector で確認したフルパスを "command" に指定してください(Windows では where runspector を使います)。Web アプリのコーチカードには引き続き Claude Code が必要ですが、Desktop では同じコーチ機能をチャットで利用できます。

Claude を使わない場合

コンディション判定とその理由、ラン、傾向、同期はすべて利用できます。Claude が必要なのは、コーチが作成するすべての内容、つまりカードと、ウォッチ用に提案するセッションです。

よくある質問

Garmin に AI コーチはありますか?

Garmin は独自のコーチ機能を 3 種類提供しています。Garmin Coach は Garmin Connect で利用できる無料のアダプティブトレーニングプランで、5K、10K、ハーフマラソンに対応し、記録したランに合わせて調整されます。多くのウォッチでは、トレーニングステータスと VO2max の推定値が表示されるようになると、アクティビティをもとに作成された毎日のおすすめワークアウトが表示されます。2025 年 3 月から有料サブスクリプションとなった Garmin Connect+ では、ベータ版として、日中に AI を活用したインサイトや提案を行う Active Intelligence が追加されました。Garmin Connect でそれまで利用できた機能は、すべて引き続き無料です。Runspector も同じ Garmin データを読み取りますが、別の種類のツールです。今日の判定とその理由を、読めるルールに基づいてすべて明示し、自分の言葉でコーチに質問でき、セッションは自分のコンピューター上で、あなたが承認した後にだけウォッチに送信されます。

Garmin 向けの無料 AI ランニングコーチはありますか?

Runspector は無料のオープンソース(MIT)ソフトウェアです。PyPI からインストールでき、データはご自身のコンピューターに保存されます。 今日の判定、ランニング記録、傾向、同期には Garmin アカウント以外は必要ありません。コーチ自体は、Claude Code または Claude Desktop を通じて、ユーザー自身の Claude アカウントで Claude を実行します。必要なプランについては、Claude への接続をご覧ください。Garmin 独自の Garmin Coach プランも無料です。

どの Garmin ウォッチに対応していますか?

Garmin Connect と同期する Garmin ウォッチであれば、Runspector にランニング記録を取り込めます。今日の判定では、4 つの回復シグナル(HRV ステータス、睡眠スコア、Body Battery、個人の基準値と比較した安静時心拍数)に加え、トレーニング負荷を確認します。夜間の HRV ステータスを記録しないウォッチでも、ほかのシグナルから判定できますが、2 つ未満のシグナルに基づく GO は EASY になります。データが少ない状態は、無条件に問題なしとは判断できません。セッションをウォッチに送るには、Garmin Connect の構造化ワークアウトに対応し、心拍数またはペースの目標を設定できる必要があります。対応機種の例として、現行の Forerunner、fenix、epix、Venu、Instinct モデルがあります。HRV ステータスや Body Battery を記録するかどうかは、Garmin のウェブサイトにある各モデルの仕様をご確認ください。

Garmin のデータを Claude に接続するにはどうすればよいですか?

Runspector をインストールし、Garmin に一度サインインします(runspector login を実行するか、ページ上のボタンを使います)。その後、アプリを開く(runspector serve)か、MCP サーバーとして Claude Code に追加します。 claude mcp add runspector -- runspector mcp。次に、「今日はトレーニングすべきですか?」と尋ねてください。Claude Desktop については、MCP サーバーをご覧ください。

Garmin の開発者アカウントや API キーは必要ですか?

いいえ。Runspector はコミュニティライブラリを通じて、ご自身の Garmin アカウントにサインインします。詳しくは、下記の「Garmin にアカウントをブロックされることはありますか?」をご覧ください。Claude 側でも API キーは必要ありません。Claude のプランと Claude Code があれば使えます。

Apple Watch、Coros、Polar、Strava でも使えますか?

いいえ。Garmin 専用です。Garmin Connect から取得する数値(Garmin 独自の測定値である HRV ステータス、Body Battery、トレーニング負荷、VO2max を含む)と、計画したワークアウトを Garmin ウォッチに送信する機能を使用します。

Garmin のパスワードは保存されますか?

いいえ。サインイン時に Garmin へ一度送信されるだけです。Garmin からセッショントークンが返され、それだけがご自身のコンピューターに保存されます。保存先のフォルダーを読み取れるのは、ご自身のユーザーアカウントのみです。ページでのサインインでは、Runspector を実行しているコンピューター上でのみパスワードを入力します。スマートフォンからページを開いた場合、ネットワーク上では通常の HTTP 通信になるため、代わりに runspector login を実行するよう案内されます。

追加料金はかかりますか?

Runspector は無料(MIT)です。コーチカードは、ほかの Claude Code の利用と同じように Claude のプランを使用します。API キーもカードごとの請求もありません。Claude がなくても、カード以外の機能はすべて使えます。

Claude に何が見えますか?

このアプリが表示する数値(準備状況、最近のランニング記録、ゾーン、週間負荷)です。カードを開始したとき、または Claude Code で質問したときに限られます。Garmin のパスワード、セッショントークン、未加工のファイルが Claude に見られることはありません。データは、ご自身のアカウントを通じて、プランの利用規約に従って Claude に送信されます。

ウォッチやカレンダーに誤った変更を加えることはありますか?

自動で行うのは読み取りだけです。Garmin にデータを送るのは、「ウォッチに登録」を押すか、Claude Code で許可したときだけで、その場合も表示されているセッションのみです。「ウォッチから削除」を選ぶと、セッションを削除できます。コーチカード自体の実行からデータを書き込むことはできません。

Garmin にアカウントをブロックされることはありますか?

Runspector は、Garmin が公式にサポートしていないコミュニティライブラリの python-garminconnectを通じて サインインします。毎日の同期で約 25~40 件のリクエストを送信し、最初の同期(1 か月分のデータ)では数百件になります。ワークアウトのダウンロードの間には待機時間を設け、90 日を超えるデータは取得しません。また、レート制限の応答を最初に受け取った時点で処理を停止し、再試行を繰り返しません。保証はできませんが、スクレイピングも行っていません。

医療上のアドバイスですか?

いいえ。トレーニング用のツールです。痛み、めまい、または異常を感じた場合は、医師に相談してください。コーチも、そうした症状を考慮してトレーニングを計画するのではなく、医師への相談を勧めます。

すべて削除するにはどうすればよいですか?

~/.runspector(アプリのフッターにフォルダーが表示されています)を削除し、 uv tool uninstall runspectorを実行してください。Garmin 側でもトークンを無効にするには、Garmin のパスワードを変更してください。

利用できる機能

タブ確認できる内容
TodayGO/EASY/REST の判定とその根拠となるシグナル、今日の判断を示す1文、ハードな日にはどのハードセッションを行うか(VO2max インターバル、閾値反復走、または Garmin が VO2max を測定する定常走)、VO2max と前回実際に変化してからの日数、今週の計画と実績、昨夜の睡眠、ゾーンの範囲とその根拠
Runsすべてのランニングと、その強度帯、実際のインターバル構成(「5 分」ではなく5×4′)、ゾーン、天候、パフォーマンスコンディション — さらにこのランニングを分析ボタン
TrendVO2max の実際の段階的な推移(測定時期かどうかも表示)、乳酸閾値の履歴、週のハードな運動時間の割合と 80/20 目標、有酸素効率(一定の心拍数でのペース)とばらつき・傾向、運動量、分極化、ACWR、さらに Garmin 独自の負荷フォーカス(各強度帯の 4 週間の負荷と目標範囲)をセカンドオピニオンとして表示
Coach自分の言葉でコーチに何でも質問できます(何がうまくいっていないの?)。重要なものから順に示す、短いカードで回答します。Claude によるワンタップ分析は短いカード形式で、同じ種類の前回のカードを記憶し、👍/👎による評価を受け付け、追加質問にも答え、削除できます。2 つはここから始められます(VO2max はなぜ変化している?・今週を振り返る)。ほかの 2 つは、それぞれの内容に関連する場所から始められます。*今日はトレーニングすべき?*は Today タブから、このランニングを分析はランニングから始められます
Youあなたの週は、プランナーが基準とする情報です。週あたりのランニング回数、曜日、ロングラン、ランニングできない日、別のスポーツを、履歴から読み取って最新の状態に保ち、変更できます。設定した内容は、元に戻すまで優先されます。コーチ向けメモには、自分の言葉でメモ(「月・水・金はジム」「12 月まで時間が少ない」など)を残せます。コーチは回答する前にこのメモを読みます。また、コーチがあなたについて学習した内容と、それぞれの根拠も確認できます。どのくらい継続できているか、強度のパターン、VO2max の傾向、Garmin の負荷フォーカス、安静時心拍数の基準値、ゾーン、さらにそれがいつからか、どこで変化したかを表示します。すべてのカードと MCP ツールget_athlete_profileは、この 3 つすべてを読み取ります

仕組み

flowchart TD
    G[Garmin Connect] -- "token resume, read" --> S[sync.py]
    S --> DB[(SQLite<br/>~/.runspector)]
    DB --> L[logic.py<br/>readiness · decision<br/>intervals · bands]
    L --> SNAP[snapshot.py]
    SNAP --> WEB[web app<br/>127.0.0.1:8765]
    L --> MCP[MCP server<br/>16 tools<br/>13 read-only · sync · apply · undo]
    WEB -- "spawn job" --> A["claude --print<br/>(your Claude sign-in)"]
    A -- "only mcp__runspector__*" --> MCP
    A -- "JSON card" --> WEB
    MCP --- CC[Claude Code / Desktop]

設計上の判断

判定はコードで行い、説明は AI が行います。 GO/EASY/REST、今日の判断、インターバル検出、強度帯は、logic.py内の純粋関数で処理されます。ユニットテスト済みで、ネットワークもLLMも必要ありません。事実と判断はそこで一度だけ計算され、エージェントにはget_training_readinessを通じて完成した判断が渡されます。独自に判断を導き出させることはありません。コーチカードはその判断を読み解くものであり、独立して作られた別の判定ではありません。Claude は説明を加えたり、ルールでは扱えない背景を補足したりできます。あるいは判断に異議を唱える場合は、どの数値に異議があるのかを示す必要があります。Claude の役割は、ルールが苦手とする部分、つまり相反する要素を比較し、計画を言葉にし、追加質問に答えることです。

アプリにキーを設定せず、自分の Claude Code サインインを使います。 コーチの処理は、Claude Code にサインインしたときと同じ方法で認証された状態で、サブプロセスとしてclaude --printを実行します。Claude のプランを利用する場合、漏洩するキーも、トークンごとの請求も、設定も必要ありません。他の作業用にエクスポートした API キーの環境変数は、カードの実行時にはデフォルトで取り除かれるため、依頼していないカードで請求が発生することはありません。RUNSPECTOR_ALLOW_API_KEY=1を設定すると、環境変数をそのまま使います。Claude Code 自体で設定したキーやクラウドプロバイダーは、環境変数の設定に関係なく使用されます。カードはそれを使い、セットアップチェックでもその旨を表示します。このチェックは、カードの実行時と同じ環境で、同じ種類の空のディレクトリから Claude Code に問い合わせます。利用枠を使い切った場合、処理は失敗せず、次の利用枠が使えるまで待機します。 エージェントに渡すのは拒否リストではなく、許可リストです。 ワークアウトのタイトルは攻撃者が制御できるテキストであり、プロンプトに入ります。そのため、コーチエージェントは空の一時ディレクトリで、--tools ""(Bash、ファイルアクセス、Web を使用不可)、サーバーがこのサーバーだけに限定された --strict-mcp-config、そして事前承認された mcp__runspector__* のみを使って実行します。カードは JSON として返され、検証して書き込むのはアプリであり、エージェントではありません。また、ツールとのやり取りが一度もない回答は破棄されます。データにアクセスできないモデルは、それ以外の場合はデータを捏造してしまうためです(これは想定ではなく、実測した結果です)。 web/agent.py を参照してください。

これによって何ができて、何ができないのかを明確に説明します。埋め込まれたワークアウトのタイトルがアクセスできるのは、このアプリ独自のツールだけです。シェル、ファイルシステム、ネットワーク、ほかの MCP サーバーにはアクセスできず、カードの実行から書き込む手段もありません。すべてのツールは読み取り専用です。ただし、sync_garmin は認証済みのリクエストをあなた自身の Garmin アカウントに送信するため、レート制限を設けています。また、Garmin に書き込む唯一のツールである apply_workout は、アプリのカード実行からは一切呼び出せません(テストで固定された --disallowedTools による制限です)。提案を適用するのは、カード上で人がクリックしたとき、または Claude Code のセッションで人が指示したときに限られ、ジョブが決めることはありません。それでも、カードの内容に影響を与えることはできます。そして、カードこそがこのプロダクトです。カードは記憶されます。同じ種類の前回のカードが、次のカードのコンテキストとして渡されるため、不適切なカードは削除するまで後続のカードにも影響します(UI にはカードごとに削除ボタンがあります)。

モデルには集計値、UI には系列を渡します。 MCP ツールは、期間内の日ごとの行を返しません。日次系列はコンテキストウィンドウを膨らませ、誤読の原因になります。エージェントに渡すのは要約と週ごとの集計値だけです。曲線を描画するフロントエンドにのみ、各データ点を渡します。 誠実な数値。 実際にはどういう意味なのか、いくつか例を挙げます。

  • Garminは計測のない日にもVO2maxの値を引き継ぐため、変化が報告されるのは値が実際に変動したときだけです。期間の両端の値の差を変化として報告することはありません。
  • 自分で算出するACWRには、21日以上 かつ 8回以上のワークアウトが必要で、computedと表示されます。判定をEASYに引き下げることはありますが、RESTにすることはありません。
  • 回復シグナルが2つ未満でGOとなった場合は、判定を引き下げます。データが少ない状態は、良好とはみなしません。
  • 同期が古い場合、今日の判定は昨日の判定を今日のものに見せかけず、unknownになります。
  • カレンダーの月を最後まで取得できていない場合、ローカルミラーを置き換えません(取得元の状態が悪いのに「予定なし」とするのは嘘になります)。
  • Garminの乳酸閾値ペースのフィールドは値が10倍ずれているため、正規化して範囲をチェックし、単位が変わった場合は明確に破棄します。
  • 計画週はアスリート自身の曜日に合わせます。何日走るか、どの曜日に走るか、ロングランを何曜日に行うかは、ランニングをした直近8週間から読み取ります(半年さかのぼり、中断から復帰する場合は中断前も参照します)。質の高いセッションは、週1回の他のスポーツとその翌日を避けます。火曜日にジムに行くなら、質の高いセッションは2回ではなく1回にします。1日おきに走るローテーションには決まった曜日がないため、標準のリズムで計画します。各値にはその根拠を示します。「土曜日がロングラン:8週間中8週間で、最長のランが土曜日でした」。
  • 計画週の量は、アスリート自身のランニング週をもとに決めます。計画日を終点とするローリング週を使い、直近2週のうち大きいほうを10%以上超えることはありません。そのうえで、アスリートの履歴をコードで確認します。負荷比によって量を維持したり減らしたりでき、4週ごとにダウン週を設けます。10日間ランニングをしていない場合は、イージーランのみの復帰週とします(3週間を超えて休んだ場合は、それ以前の週の半分の量にします)。新しいVO2maxの値が28日間ない場合は、閾値の枠に一定ペースのブロックを入れます。予定日数に対して予算が足りない場合は、セッションを増やさずに短い週を計画します。3日走る場合は質の高いセッションを1回にし、きついセッションを1回だけ行うことはありません。質の高いセッションが1回の週は、次に必要なセッションを選びます(ゾーン5の刺激が設定されるまではVO2max、その後は閾値または計測値を使います)。中断からの復帰では、アスリートは徐々に再構築します。段階的な増加は直近7日間をもとにし、増加に追いつかない中央値は使いません。また、中断前の水準の80%まで週の量が戻るまではダウン週を設けません。次の段階の量が、その前に計画された週より少なくなることはありません。負荷比に応じて維持または減量した週が、それを超えることもありません。計画を超えて走った週が続くと、その週の量を維持するための中央値が上がり、これが負荷比を押し上げるためです。どのルールも提案内で明示された前提であり、プロンプトの裁量に委ねられてはいません。 きつい日の判定では、直近7日間に何があり、何がなかったかをもとに、どのきついセッションを行うかも示します。中断後は、その日はイージーになります。
  • 閾値ペースを計測していない場合、あるアスリートにだけ合う5:00/kmという初期値ではなく、Garmin独自の5 kmと10 kmの予測値をもとにセッションの量を決めます。
  • これらのルールは単体テストだけでなく、実際に実行されます。evals/sim.pyでは、計画どおりに進める人、40%を休む人、3週間休む人、病気になる人、常に強度を上げて走る人の8人の合成アスリートを、アプリ上の16週間にわたって毎日、実際のツールと照らし合わせて実行し、全期間を通じてランナーがコーチに期待する内容を検証します。この結果、上記のプランナーのバグが2つ見つかりました。トレーニングが効果的かどうかは分かりません。身体はおもちゃのようなものです。また、データモデルが把握していることしか見つけられないため、実際のアカウントでの実地テストは続きます。 プロンプトはコードと同じようにテストしています。 コーチの動作は、LLM を審査役にした回帰テストスイート(evals/)を備えた 2 つの Markdown ファイル(skills/)に記述されています。テストケースは 32 件で、たとえば 「今日はすでにランニングをした → ハードなセッションを追加しない」、「エネルギー利用可能量の低下を示す警告サインを、問題ないことにしない」、「ワークアウト名に含まれる指示には従わない」 といった内容です。Garmin のデータなしで実際の CLI に対して実行します。ただし、対象はこの 2 つのファイルだけで、出荷されるプロンプトの残り 2 つの要素(templates.json と web/agent.py の JSON カードのフレーム)は含まれません。こちらは代わりに tests/test_web.py で決定論的にテストします。また、スイートが指定されたモデルで --safe-mode を使って実行されますが、どちらも本番環境では使用できません。フレーミング自体はコピーではなくアプリからインポートするため、テストスイートと出荷版に差異が生じることはありません。--no-skills を指定すると、スキルファイルを取り除いてテストケースを再実行します。それでも合格するケースは、プロンプトではなくモデルをテストしています。

堅実な技術構成。 Python 標準ライブラリの HTTP サーバー、sqlite3、バニラ ES モジュール、インライン SVG チャートを使用しています。フレームワーク、ビルド工程、ORM はありません。SQL クエリは約 40 件で、すべて store.py にあります。Windows、macOS、Linux で動作します(CI マトリックス)。

詳細はこちら:docs/architecture.md。

プライバシー

すべてのデータは ~/.runspector/ に保存されます(RUNSPECTOR_HOME で変更できます)。対象は SQLite データベース、Garmin のセッショントークン、コーチカードです。パスワードは保存されません。Linux と macOS ではディレクトリが 0700 で作成されるため、共有マシン上でも他のローカルアカウントからファイルを読み取ることはできません。Windows では代わりに、ユーザープロファイルの ACL が継承されます。ただし、runspector serve の実行中は、これだけでは保護されません。 トークンがなければ、どのローカルアカウントやプロセスからでも 127.0.0.1:8765 にアクセスしてデータを取得でき、v0.2 以降は Garmin セッションを使って提案を適用または取り消すこともできます。共有マシンでは、RUNSPECTOR_TOKEN を設定して起動してください。サーバーはループバック接続にもトークンを要求し、最初に一度だけ開くリンクを表示します。外部への接続先は Garmin(同期時)と、あなたが コーチカードを実行したときの Claude(あなた自身の CLI セッション経由で、集計済みのトレーニングデータを送信)だけです。サーバーは 127.0.0.1 にバインドします。ネットワーク上で待ち受けるには RUNSPECTOR_TOKEN が必須で、設定されていない場合、サーバーは起動を拒否します。ただし、--host 0.0.0.0 を指定すると、TLS なしの HTTP で配信されます。そのため、そのネットワーク上ではトークンもアプリが返す情報もすべて暗号化されず、通信を見られる人なら誰でも読み取れます。この使い方は、自分が管理する LAN 上の自分のスマートフォン向けであり、管理していないネットワーク向けではありません。

設定

変数デフォルト用途
RUNSPECTOR_HOME~/.runspectorデータディレクトリ
RUNSPECTOR_TZsystem zone「このワークアウトを実行したのはいつか」の判定に使う IANA タイムゾーン
RUNSPECTOR_TOKEN–--host 0.0.0.0(自宅ネットワーク内のスマートフォン)で必須
RUNSPECTOR_MODELCLI defaultコーチカードに使用するモデル
RUNSPECTOR_GARMIN_TOKENS~/.runspector/garmin既存の python-garminconnect トークンディレクトリを再利用
RUNSPECTOR_AUTOSYNC_MIN30Claude Code / Desktop のチャットで、前回の同期からこの時間を超えている場合、get_training_readiness が最初に同期します。0 にすると無効になります
RUNSPECTOR_QUOTA_WAIT_S3600サブスクリプションのクォータを待機するジョブの時間
RUNSPECTOR_JOB_TIMEOUT_S600単一のコーチジョブの厳密なタイムアウト
RUNSPECTOR_ALLOW_API_KEY未設定1 にすると、コーチカードでエクスポート済みの ANTHROPIC_*(および Bedrock/Vertex)変数を保持し、トークンごとに課金されます。未設定の場合、カードからこれらの変数は取り除かれます。どちらの場合も、Claude Code 自体で設定したサインインが使用されます
RUNSPECTOR_ACTIVITY_BACKFILL_DAYS182同期で取得するワークアウト一覧の最小期間(習慣は過去26週間を対象とし、ゾーンの詳細は過去35日分を取得します)
RUNSPECTOR_LT_HISTORY_DAYS180乳酸閾値の履歴を遡って取得する期間
RUNSPECTOR_LOGWARNINGログレベル — 同期を確認するには INFO または DEBUG を設定します。INFO と DEBUG では、ウェブアプリのすべての HTTP リクエストもログに記録されます

内部処理とテスト用に、ほかに4つ(RUNSPECTOR_DB、RUNSPECTOR_DEMO、RUNSPECTOR_CLAUDE_CMD、RUNSPECTOR_PII_EXTRA)があります。これらはサポート対象のインターフェースには含まれません。

アスリートプロフィールは任意です:runspector profile --max-hr 182 --goal "sub-50 10k"。週の予定(日数、走る曜日、ロングラン、休養日、ほかのスポーツ)は、「You」タブ(または --days-per-week と --long-run-day)で設定します。指定しなかった項目は、プランナーが履歴を参照し、通常走る曜日と最長ランを行う曜日を判断します。休養日に予定が組まれることはありません。コーチへのメモはコーチに伝える文脈であり、ルールではありません。プランナーが守るのは曜日の設定です。

開発

git clone https://github.com/edxleon/runspector && cd runspector
uv run pytest -q                   # no database server, no network, no Garmin account needed
node --test "web-tests/*.test.mjs" # frontend logic
uv run ruff check                  # lint — config is real and the backlog is zero
npx --yes @biomejs/[email protected] lint --error-on-warnings   # frontend lint (biome.jsonc)
uv run python evals/run_evals.py   # prompt regression (uses your Claude subscription)
uv run python scripts/pii_gate.py  # release gate

状況とロードマップ

v0.1 は Garmin に対して読み取り専用でした。v0.2 では書き込み機能を追加します:propose_workout は、あなた自身のゾーンを使ってルートに合わせたセッションを作成し、登録します。propose_week は、ポラライズドトレーニングの1週間分をまとめて登録します。赤信号の日にカレンダーに予定されていた高負荷セッションを、提案で置き換えることもできます。また、apply_workout はワークアウトをアップロードして予定を設定し、ウォッチに送信したうえで、読み戻して検証します。アプリのカードからは何も適用できません。アプリではカード上のボタンをクリックして提案を適用し(「Put on watch」、2回タップ)、Claude Code ではあなたの回答で適用します。また、同じ方法で取り消せます。取り消せない書き込みは、誰も初回から行わないからです。

テストスイートで使う偽の Garmin クライアントだけでなく、実際のアカウントで実行した内容:2026-10-28、runspector mcp でイージーセッションを1件実行しました。アスリート自身のゾーンを使って提案し、アップロード、スケジュール設定、ウォッチへの送信、ウォッチ上での確認、読み戻しと検証を行った後、取り消しました。すべての手順は、独立した別の Garmin クライアントでも照合しました。アプリのボタンも同じ plan.apply と plan.undo を呼び出します。実際にはまだ実行していないもの:propose_week による一括登録と、カレンダーの予定を解除する赤信号日の入れ替えです。アスリート1名、アカウント1つ、ウォッチ1台です。

ロードマップ

docs/roadmap.md は、ランナーにとっての効果が高い順に並べたバックログです。体調不良や痛み、その日の感覚など、終わるまで有効なランナー自身のチェックイン、すべてのハードセッションに用意するより楽な選択肢、ペースごとのレップ目標、自分で構成したセッション、その後のランと照らし合わせた提案セッション、曜日ごとに自分が使える時間に合わせたセッションの規模、負荷を示す2つ目の指標としての単調さ、朝に使う runspector today、カード上の各記述の出典、Garmin独自のレディネス、体重、より深い履歴、そして目標レースに向けたレース準備です。v0.3では、次の計画を立てる際にプランナーが履歴を参照するようになりました。それ以外の項目については、理由と順序も含めて記載しています。

ライセンス

MIT

コメント

MCP は初めてですか?

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

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