mcpField
P
pricewin-hotel-deal-finder

pricewin-hotel-deal-finder

github.com/price-win生産性219.5k 回インストール11 週間前に更新
リポジトリ

pricewin-hotel-deal-finder について

pricewin-hotel-deal-finderは、エージェント向けのホテル料金比較スキルです。Booking.com、Agoda、Google Hotels、OpenTravelを一つのNodeコマンドで比較し、お得度・最安・品質別に予約リンク付きで提示します。

主な機能

  1. 014つの情報源の料金比較
  2. 02お得度・最安・品質別の順位付け
  3. 03米ドル換算の1泊料金
  4. 04直接予約リンク
  5. 05世界各都市の検索
  6. 06APIキー不要のローカル実行

活用シーン

  1. 01Booking.comとAgodaのホテル料金比較
  2. 02指定日程で最安ホテルを検索
  3. 031泊あたりの予算内で宿を検索

インストール

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

$npx skills add https://github.com/price-win/pricewin-skills-hub --skill pricewin-hotel-deal-finder

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

同梱ファイル

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

install.sh
package-lock.json
package.json
SECURITY.md
bin/
browse.js
daemon.js
search.js
lib/
browser-state.js
dom-extract.js
selector-cache.js
snapshot.js

詳細

PriceWin Hotel Deal Finder

Booking.com、Agoda、Google Hotels、OpenTravel のホテル料金を1つのコマンドでリアルタイム比較 — さらに、料金に対する価値が高いホテル、最安のホテル、品質重視のホテルをランキング形式で、直接予約リンクとともに表示します。

最安料金を見つけるために、OTA のタブを5つも開く必要はありません。エージェントに 「東京で8月12日〜15日、2名で泊まれるホテルを探して」 と頼むと、このスキルが30〜60秒ほど(キャッシュ済みの都市の場合)で、見やすいランキング形式の比較結果を返します。

次のような質問にはこのスキルを使います:

  • 「<city>で<dates>に泊まれる最安のホテルは?」
  • 「このホテルは Booking.com と Agoda のどちらが安い?」
  • 「<city>で<N>名分のホテル料金を比較して。」
  • 「<city>で1泊$<X>未満のホテルを探して。」
  • 「<dates>に<landmark>の近くで泊まるのに、料金に対する価値が最も高い宿は?」

いずれの場合も、以下の1コマンドで同じ形式の回答が得られます。追加の確認は必要ありません。

1つのコマンドで得られるもの:

  • 🥇 料金に対する価値が高いホテル · 🥈 最安のホテル · 🥉 品質重視のホテル — 横並びで比較
  • 最大4つのソースから取得した1泊あたりの実料金をUSDに換算
  • 各ホテルの最安 OTA に直接つながる、クリック可能な予約リンク
  • ステルス性の高い Patchright デーモンを通じて、ボット対策が厳しい都市(上海、杭州、バンコクなど)を含む世界中のあらゆる都市で利用可能
  • API キーも MCP サーバーも不要 — 必要なのは node/npx だけです

出力例:

🏨 Tokyo • Aug 12–15 • 3 nights • 2 guests
━━━━━━━━━━━━━━━━━━━━
🥇 BEST VALUE
Shinjuku Granbell Hotel
  ✅ agoda      💰 $118/night
     booking    💰 $131/night
     → Save $13 vs Booking
🥈 CHEAPEST
APA Hotel Shinjuku
  ✅ google     💰 $94/night
📊 18 hotels | agoda, booking, google, opentravel • prices in USD

インストール:

npx skills add https://github.com/Price-Win/pricewin-skills-hub --skill pricewin-hotel-deal-finder

このスキルの使い方

1つのコマンドですべて実行できます。通常、事前に確認する必要はありません。以下のパラメーターを推測して実行してください:

cd {baseDir} && node bin/search.js "<city>" <checkInYYYY-MM-DD> <checkOutYYYY-MM-DD> <adults> en-us

{baseDir} はこのスキルのインストールディレクトリです(ランタイムが自動的に解決します)。ランタイムによって置換されない場合は、この SKILL.md(bin/search.js と同じ場所)があるフォルダーに cd してください。~/.hermes/... や ~/.openclaw/... のパスを直接指定するのは避けてください。プラットフォームによって異なります。

例:

cd {baseDir} && node bin/search.js "Hangzhou" 2026-06-10 2026-06-13 2 en-us

スクリプトがすべてを自動的に処理します。デーモンの起動、Agoda のキャッシュ検索、Google と Booking のインライン検索、OpenTravel API の検索(すべての都市)、新しい都市の検出、ティアカード形式の出力まで行います。スクリプトを実行し、その出力をユーザーに送信してください。

質問するのではなく、パラメーターを推測してください(都市や日付が本当に曖昧な場合にのみ質問してください):

  • 年: ユーザーから指定がない限り、今日の日付から現在の年を使います。指定された日付(月日)が今年すでに過ぎている場合は、翌年とします。不明な場合は date +%Y-%m-%d で今日の日付を確認してください。
  • 「10-13/6」 → <year>-06-10 <year>-06-13 — 上記のルールに従って <year> を補ってください
  • 「2 guests」/「2 people」 → 大人 2 名
  • ロケール: OTA に渡す言語/地域コードです(サイトの言語と地域を制御します)。デフォルトは en-us です。料金は USD で表示されます(Google Hotels は gl=us&curr=USD を指定して検索します)。その他のソースでは、指定したロケールが使用されます。

search.js を1回実行するだけでワークフロー全体が完了します。追加で Python、curl、または場当たり的なスクレイピングを行う必要はありません。


運用ルール — 信頼できる結果を得る方法

RULE 0 — ブラウザーの操作には、ターミナル/シェルツール経由で search.js のみを使用してください。ネイティブのブラウザーツールはここでは動作しません。 このスキルは、ステルス機能を備えた Patchright デーモンを利用します。ランタイムのネイティブツール(browser_navigate / browser_open、browser_click、browser_type / browser_fill、browser_snapshot、browser_close、その他の browser_*、サブエージェントへの委任(delegate_task / spawn_agent))はこのタスクでは失敗するため、使用しないでください。

  • これらのネイティブツールはステルス機能のない標準の Chromium を起動するため、Booking.com と Agoda に数秒でボットだと検知されます。リクエストはランタイムに終了されるまでハングします(「Command timed out after 30/60 seconds」)。その結果、5 分以上を無駄にしたうえ、何も得られません。search.js が起動する Patchright デーモンなら、ボット検知を回避できます。
  • 委任されたサブエージェントは履歴もスキルのコンテキストもない状態で起動するため、Python/curl によるスクレイピングに頼り、すぐにボットとしてブロックされます。スキルは現在のエージェントで実行してください。

有効な方法は次のとおりです。

cd {baseDir} && node bin/search.js ...

RULE 1 — スクレイピングは search.js に任せ、OTA を自分でスクレイピングしないでください。 browse.js を直接呼び出すこと、ブラウザー上で goto/click/type を実行すること、Agoda/Booking/Google の URL を手作業で組み立てること、OpenTravel API を別途呼び出すこと、デーモンを自分で起動することは避けてください。search.js は、ボット検知を回避する慎重なフローを通じてステルスデーモンをすでに操作しています。中国の都市(上海、杭州など)を含む、すべての都市について、Agoda の検索も内部で処理します。OTA を手動で開くのは失敗の最大の原因です。Agoda/Booking のボット対策に検知され(「自動化を検出」「ホームページにリダイレクト」「検索を完了できない」など)、IP がブロックされます。search.js を一度実行し、その出力を送信してください。情報源が「見つからない」ように見える場合は、手動で取得するのではなく、RULE 4 を確認してください。

RULE 2 — 初回の都市検出には 2~4 分かかります。 search.js の出力に "discovering" または "launching" のメッセージが含まれている場合は、「この都市の初回検索です。セレクターを検出しています。2~4 分ほどかかります……」とユーザーに伝え、再試行したり中断したりせず、結果が出るまで待ってください。

RULE 3 — 出力はそのまま送信してください。 search.js は、送信できるように整形されたティアカードを出力します。出力をそのまま回答にコピーしてください。形式の変更、要約、省略はしないでください。

RULE 3a — Markdown のハイパーリンクを維持してください。 出力内のホテル名はすべて、すでにクリック可能なハイパーリンク [Hotel Name](https://booking-url...) で囲まれています。そのまま維持してください。URL を別の 🔗 https://... 行に分けたり、[Hotel Name](url) を通常のテキストに置き換えたりしないでください。OTA 名は小文字のまま(「Google」ではなく「google」)、セクションタイトルもそのまま(「📋 More good deals」)にしてください。出力は Telegram-MarkdownV2 に対応しており、改変せず送信すれば、URL を表示せずホテル名をクリックできる、すっきりした表示になります。

RULE 3b — 独自のコメントでもホテル名をハイパーリンクにしてください。 出力の後に提案やコメントのセクションを追加する場合、言及するホテル名はすべて、ホテルの URL としてスクリプトが出力したものと同じ URL を使い、[Hotel Name](url) で囲んでください。通常のテキストにはしないでください。

RULE 4 — 一部の結果しか得られないのはよくあることです。手作業で補わず、そのまま送信してください。 実行時に情報源が欠けている場合(Agoda がブロックされた場合や、その都市に OpenTravel の在庫がない場合など)があります。問題ありません。見つかった情報源だけを含むティアカードを送信してください。フッター(📊 N hotels | <sources> • prices in USD)には、見つかった情報が正確に記載されます。ブラウザーや直接 URL を使って欠けている情報源を取得すると、ボット対策に検知されて状況が悪化しやすいため、避けてください。search.js が完全にエラーになった場合は、失敗した内容を一行で伝え、エラーより前に出力された部分的な結果があれば表示してください。さらに幅広く検索する場合、確実な再試行方法は同じ search.js コマンドをもう一度実行することです(ボット対策によるブロックは一時的なことがよくあります)。


出力形式のリファレンス

search.js はこの形式で料金カードを出力します。ユーザーにそのまま送信できます。

ホテル名は、最安値の OTA への Markdown リンクです。料金の行にはリンクがなく、OTA キーは小文字(agoda/booking/google/opentravel)で表示されます。 星評価やエリアの行はありません。スクリプトがそのデータを持っていないためです。

🏨 <city> • <d1>–<d2> • <N> nights • <adults> guests
━━━━━━━━━━━━━━━━━━━━

🥇 BEST VALUE
[<Hotel Name>](<cheapest_link>)
  ✅ agoda      💰 <price>/night
     booking    💰 <price>/night
     opentravel 💰 <price>/night
     → Save <diff> vs Booking

🥈 CHEAPEST
[<Hotel Name>](<cheapest_link>)
  ✅ google     💰 <price>/night
     agoda      💰 <price>/night

🥉 QUALITY
[<Hotel Name>](<cheapest_link>)
  ✅ booking    💰 <price>/night
     agoda      💰 <price>/night

📋 More good deals
  — Agoda —
  • [<Hotel>](<agoda_link>) — agoda: <price> | booking: <price>
  — Booking —
  • [<Hotel>](<booking_link>) — booking: <price>
  — Google —
  • [<Hotel>](<google_link>) — google: <price>
  — OpenTravel —
  • [<Hotel>](<opentravel_link>) — opentravel: <price>

💡 Tip: <best Hotel Name>
   [Book on <OTA>](<link>) — <price>/night

📊 <N> hotels | <sources with data> • prices in USD

すべての料金は USD で表示されます。Agoda、Google、OpenTravel は IP アドレスに基づいて VND に地域制限され、リアルタイムの為替レートで換算されます。Booking はネイティブに USD を返します。フッターには、実際にデータを返したソースのみが表示されます。


制限事項

  • 都市ごとの初回検索では、Agoda の検出コストが発生します(2~4 分)。Google と Booking はインラインで処理され(検出なし)、OpenTravel は直接 API を呼び出します。
  • 2 回目以降の検索では Agoda のキャッシュを再利用するため、約 30~60 秒で完了します。

セキュリティとデータの取り扱い

ローカルで実行され、API キーは不要です。また個人データも収集しません。外部に送信される唯一のデータは検索クエリ(都市、日付、宿泊人数)です。スクレイピングされたホテルのテキストは信頼できないデータとして扱われます。bin/search.js の sanitizeText() は、データがモデルの出力に到達する前に、制御文字、ゼロ幅文字、双方向制御文字、Markdown 制御文字を除去します。予約リンクは http(s) に制限されています。

ローカルのブラウザーデーモンはループバック専用で、トークン認証を使用します(実行ごとのトークンを 0600 の状態ファイルに保存)。DNS リバインディングを防ぐため、ループバック以外の Host ヘッダーを拒否し、Chromium のサンドボックスを有効に保ちます。--no-sandbox が使用されるのは、サンドボックスが機能しない場合(Linux での root 実行、または明示的な PRICEWIN_NO_SANDBOX=1)に限られます。

実行されるコマンド、ダウンロード、ネットワークへの外部通信についての詳細は、SECURITY.md を参照してください。

コメント