mcpField
C
chase-travel

chase-travel

github.com/borskiその他78070 回インストール2 日前に更新
リポジトリ

chase-travel について

Chase Travel ポータルで航空券とホテルを検索するコマンドラインスキルです。現金・ポイント価格、Points Boost、Chase Edit の特典を取得します。ポータル予約と現金運賃、航空会社へのポイント移行を比較する用途向けで、Patchright とヘッド付きブラウザーが必要です。

主な機能

  1. 01航空券とホテルの検索
  2. 02現金・ポイント・併用価格の表示
  3. 03Points Boost オファーの検索
  4. 04Chase Edit ホテル特典の確認
  5. 05SMS とアプリ承認の二要素認証
  6. 06JSON 形式での結果出力

活用シーン

  1. 01ポータル価格と現金運賃の比較
  2. 02ポイント利用と移行の価値評価
  3. 03Edit 特典付きホテルの検索
  4. 04予約前の航空券候補の確認

MCP 対応

入力では旅行検索スキルと説明されていますが、MCP 連携については記載されていません。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/borski/travel-hacking-toolkit --skill chase-travel

インストール後、Claude Code で/chase-travelを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

Dockerfile
scripts/
record_search.py
search_flights.py
tests/
test_2fa_method.py

詳細

Chase Travel Portal の検索

Patchright を使用して、Chase Ultimate Rewards の旅行ポータルでフライトやホテルを検索します。現金価格、UR ポイントでの価格、Points Boost の特典、Chase Edit のホテル特典を取得します。

Patchright が必要です(検出回避機能を備えた Playwright のフォーク)。Chase は標準の Playwright と agent-browser をブロックします。

ヘッド付き(headless=False)で実行する必要があります。 Chase はヘッドレスブラウザーを検出します。macOS では Chrome のウィンドウが一時的に表示されます。バックグラウンドで実行する場合は、Docker を使用してください。

前提条件

pip install patchright && patchright install chromium

または、Docker を使用します(ローカルへのインストールは不要です)。

docker pull ghcr.io/borski/chase-travel:latest
# or build locally:
docker build -t chase-travel skills/chase-travel/

使用する場面

  • UR ポータルの価格を現金価格や特典航空券の価格と比較する
  • Points Boost の特典を確認する(一部の予約で cpp が 1.5 倍から 2.0 倍)
  • 100 ドル分の施設クレジットと毎日の朝食が付く Chase Edit のホテルを探す
  • ポイント払いと航空会社へのポイント移行の価値を比較する

使用しない場面

  • 購入の完了。 フライトとホテルを探す場合に限ります。予約しないでください。
  • Chase 以外のカード。 このスキルには Sapphire Reserve または Sapphire Preferred のカードが必要です。

カードの選択

スクリプトはアカウントセレクターから Sapphire Reserve カードを自動的に選択します(旅行予約では Points Boost の倍率が変動し、CSR では通常約 1.5~2.0 cpp ですが、最低倍率が保証されているわけではありません。Edit のホテル特典も利用できます)。Reserve が見つからない場合は、Sapphire Preferred にフォールバックします。Edit のホテル特典と旅行ポータルの価格が表示されるのは、これらのカードのみです。

使用方法

フライト検索
# Local (opens a Chrome window briefly)
python3 scripts/search_flights.py --origin SFO --dest CDG --depart 2026-08-11

# Round-trip business
python3 scripts/search_flights.py --origin SFO --dest CDG --depart 2026-08-11 --return 2026-09-02 --cabin business

# JSON output
python3 scripts/search_flights.py --origin SFO --dest CDG --depart 2026-08-11 --json

# Docker
docker run --rm \
    -v ~/.chase-travel-profiles:/profiles \
    -v /tmp:/tmp/host \
    -e CHASE_USERNAME -e CHASE_PASSWORD \
    ghcr.io/borski/chase-travel script /scripts/search_flights.py \
    --origin SFO --dest CDG --depart 2026-08-11 --cabin business --json
ホテル検索
# Local
python3 scripts/search_flights.py --hotel --dest "Paris" --checkin 2026-08-11 --checkout 2026-08-15

# Docker
docker run --rm \
    -v ~/.chase-travel-profiles:/profiles \
    -v /tmp:/tmp/host \
    -e CHASE_USERNAME -e CHASE_PASSWORD \
    ghcr.io/borski/chase-travel script /scripts/search_flights.py \
    --hotel --dest "Oslo" --checkin 2026-08-13 --checkout 2026-08-15 --json
記録モード(API の調査)

手動検索中のネットワークトラフィックを記録します。デバッグや新しい API エンドポイントの発見に役立ちます。

# Local only (needs interactive browser)
python3 scripts/record_search.py

2FA のフロー

Chase の 2FA では、SMS またはモバイルアプリのプッシュ通知が使用されます(アカウントによってはプッシュ通知のみの場合があります)。初回ログイン時は、手動で 2FA を完了する必要があります。その後はデバイスの信頼状態が維持され、同じプロファイルから次回以降に実行する際は 2FA がスキップされます。スクリプトはアカウントで利用できる方式を自動検出し、該当するフローを実行します。

仕組み: 2FA が開始されると、スクリプトは stdout に次のいずれかのセンチネルを出力し、その後、最長 3 分間ポーリングします。

  • 2FA_CODE_NEEDED — SMS。Chase からコードが送信されました。下記の手順でコードを入力してください。
  • MOBILE_APP_APPROVAL_NEEDED — モバイルアプリのプッシュ通知。コードはありません。ユーザーが Chase モバイルアプリでサインインを承認すると、ページが先に進んだ時点でスクリプトが続行します。

エージェント向け(SMS): 2FA_CODE_NEEDED が表示されたら、Chase から携帯電話に届いた SMS コードをユーザーに尋ねてください。コードを受け取ったら、コードファイルに書き込みます。

echo "12345678" > /tmp/chase-2fa-code.txt

スクリプトはファイルを自動的に検出し、ログインを続行します。

エージェント向け(モバイルプッシュ): MOBILE_APP_APPROVAL_NEEDED が表示されたら、Chase モバイルアプリでサインインを承認するようユーザーに伝えてください。入力するコードはありません。スクリプトは最長 3 分間、承認が届くまでポーリングしてから続行します。

コマンドフック(任意、完全自動化向け): CHASE_2FA_COMMAND に、コードを取得するまで処理をブロックし、その後 stdout にコードを出力するコマンドを設定します。スクリプトはファイルのポーリングの代わりに、このコマンドを実行します(SMS のフローのみが対象です)。

Docker: 一時ディレクトリを共有するには、-v /tmp:/tmp/host を使用します。スクリプトは /tmp/host/chase-2fa-code.txt と /tmp/chase-2fa-code.txt の両方を確認します。

初回ログインが成功してデバイスが信頼済みになると、次回以降の実行では 2FA がスキップされます。

認証情報は解決済みの値を指定してください

CHASE_USERNAME/CHASE_PASSWORDには、このスクリプトに渡す時点で実際のユーザー名とパスワードを設定する必要があります。シークレットをシークレットマネージャーに保管している場合は、起動前に参照先を環境変数に解決してください(ほとんどのマネージャーには、まさにその用途のexec/runラッパーが用意されています)。

解決されていない参照(scheme://vault/itemという文字列のままのプレースホルダー)はログインフォームに入力され、Chaseから「そのユーザー名とパスワードが見つかりません。もう一度お試しください。」と返されます。これはボット検出と誤解されやすいエラーです(ボット検出ではありません。Dockerからの新しい自動ログインは、実際の認証情報を使えば問題なく動作します。保存済みのCookieが期限切れの場合も含め、2026年7月にライブ環境で確認済みです)。

このような間違いは、どちらの場合もスクリプトが即座に検知して停止します。認証情報がまだシークレット参照のように見える場合、またはChaseからユーザー名/パスワードが見つからないと通知された場合、標準出力に**CHASE_BAD_CREDENTIALS**を出力し、2FAステータスファイルにBAD_CREDENTIALSを書き込みます。**エージェント向け:**このセンチネルを受け取った場合は再試行しないでください。認証情報の注入方法を修正してから、再実行してください。

動作の仕組み

フライト検索アーキテクチャ
  1. **認証:**Patchrightがログイン、2FA、Cookieの永続化、カード選択を処理します。アカウント識別子はポータルURLから自動抽出されます。
  2. セッション:v1/session/createへのPOSTでCXL旅行セッションを確立します。識別子はCookieから自動抽出されます。
  3. **検索API:**Chaseの内部CTE APIにPOSTし、フライト検索セッションを作成します(sessionIdを返します)。
  4. **結果:**ブラウザーでtravelsecure.chase.com/results/flights/outbound?ssid={sessionId}&cnxtoken={redirectionToken}に移動します。スクリプトはpage.on('response')でAPIレスポンスをインターセプトし、legwiseResultsのJSONを取得します。
  5. **ページネーション:**JavaScriptでShadow DOMの「さらに表示」ボタン(<orxe-button>)をクリックし、すべてのフライトを読み込みます(1回に10件)。
  6. **Points Boost:**Shadow DOMのトグル(<orxe-toggle class="points-offer">)を有効にします。ブーストカードのカルーセルを解析し、割引後のポイント価格を取得します。
ホテル検索アーキテクチャ
  1. **検索API:**Chaseのホテル検索エンドポイントにPOSTし、セッションを作成します。
  2. **結果:**ブラウザーで結果ページに移動します。スクリプトはhotel/v1.0/search/resultsのAPIレスポンスをインターセプトします。
  3. Editの検出:prm[].c == "Signature Amenities"のホテルはEdit対象施設です。特典は埋め込みJSONから取得します。
  4. Boostの検出:rwd[].rdp.rcm.t.ofr.d == "Points offer applied"のホテルにはPoints Boostが適用されています。
  5. **ページネーション:**フライトと同じShadow DOMのパターンを使います。
データ構造

フライトの結果には、次の情報が含まれます。

  • 現金価格、ポイント価格、現金とポイントを組み合わせた価格
  • 元のポイント数とブースト後のポイント数を示すPoints Boostのオファー
  • 運賃クラス(エコノミー、ベーシックエコノミー、ビジネススタンダード、ビジネスフレックスなど)
  • 航空会社、時刻、所要時間、乗り継ぎ、機材を含むフライト区間
  • 払い戻しの可否と変更ポリシー

ホテルの結果には、次の情報が含まれます。

  • 1泊あたりの現金価格と合計金額
  • ポイント価格
  • 特典(朝食、クレジット、アップグレードなど)を含むEditプログラムの会員特典
  • Points Boostの利用可否と適用レート
  • 星評価、住所、アメニティ、払い戻しの可否

出力形式

必ずMarkdownの表を使用してください。

フライト
#航空会社ルート乗り継ぎ所要時間現金ポイントBoostCPP
1Air FranceSFO-CDG直行10h 40m$5,397539,683269,8412.0
ホテル
#ホテルプログラム1泊あたり合計ポイント特典
1SommerroEDIT, BOOST$408$81681,600朝食、$100のクレジット、アップグレード
表の後に
  • Edit対象のホテルを特典とあわせて記載します
  • ポイントでの特典交換におけるCPPを計算します
  • Points Boostのオファーには実質cppを示します
  • 可能であれば、直接予約価格と比較します
  • チェックアウト時に実際のPoints Boostの見積もりを取得します。CSRの価格設定は変動制で、固定倍率ではありません。

ポータルの料金に関する注意事項

  • CSR の Chase ポータルの料金は、動的な Points Boost 方式です。従来の固定 1.5 倍の倍率は廃止されています。予約ごとに必要なポイント数が提示されます。CSR では実質的な cpp は通常 1.5〜2.0 cpp の範囲ですが、すべての予約で保証される最低値ではありません。
  • Points Boost のオファーは、割引後のポイント価格が表示された個別のカードとして表示されます(実質的には通常 1.5〜2.0 cpp)。
  • cash_plus_points 料金では、利用可能な UR ポイントをすべて使い、残額を現金で支払います。
  • Chase のセッションはブラウザーを閉じると保持されません。Docker を実行するたびに新たにログインする必要があります(デバイスが信頼済みの場合、2FA は省略されます)。

環境変数

変数必須説明
CHASE_USERNAMEはいChase オンラインバンキングのユーザー名
CHASE_PASSWORDはいChase オンラインバンキングのパスワード
CHASE_2FA_COMMANDいいえSMS コードを受信するまでブロックし、標準出力に表示するコマンド
CHASE_PROFILEいいえブラウザープロファイルのディレクトリ(デフォルト:~/.chase-travel-profiles/default)

トラブルシューティング

  • Docker のログインページで「Access Denied」と表示される: Chase は Docker からの secure01ea.chase.com へのアクセスをブロックします。スクリプトは代わりに chase.com のホームページからログインします(認証エンドポイントが異なり、Docker で動作します)。
  • 動画のモーダルによってクリックできない: スクリプトには、モーダルを自動的に削除する MutationObserver が含まれています。モーダルが表示され続ける場合は、オブザーバーが再レンダリングを処理します。
  • API を直接呼び出すと CSRF エラーが発生する: travelsecure.chase.com の検索結果 API には、React アプリが管理する CSRF トークンが必要です。スクリプトは API を直接呼び出す代わりにレスポンスのインターセプトを使うため、CSRF を完全に回避できます。
  • フライトが見つからない: Chase が検索結果をまだ読み込んでいない可能性があります。スクリプトはインターセプトによって API レスポンスを待機するため、この問題は発生しないはずです。ログインが成功したか確認してください。

制限事項

  • ヘッド付きモードが必須です。 Chase はヘッドレスモードを検出します。回避策として Docker と xvfb を使用します。
  • 検索あたり約 30 秒かかります。 ログイン、ポータルの移動、検索、結果の読み込みが含まれます。
  • ブラウザーを閉じるとセッションが終了します。 セッションは保持されません。実行のたびにログインが必要です(初回の信頼済み設定後は 2FA が省略されます)。
  • React の制御対象入力フィールド: フォームの自動操作は不安定です。スクリプトはフォーム入力ではなく、検索の作成に API 呼び出しを使用します。

コメント