cuddlynest-mcp について
cuddlynest-mcpは、CuddlyNestのホテルを検索し、掲載情報を取得するMCPサーバーです。旅行先の調査向けに、予約や支払いを行わず、客室、料金、空室状況、キャンセルポリシーを読み取ります。
主な機能
- 01目的地とホテルの検索
- 02ホテルの基本情報の取得
- 03客室と料金の抽出
- 04空室数とキャンセルポリシーの確認
- 05stdioとStreamable HTTPに対応
活用シーン
- 01都市のホテル候補を探す
- 02客室タイプと料金を比較する
- 03残室数とキャンセル条件を確認する
MCP 対応
クライアント向けに、目的地検索とホテル詳細取得のツールを提供します。読み取り専用で、予約や支払いは行いません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| rooms | number | いいえ | 客室数(デフォルト:1) |
| adults | number | いいえ | 大人の人数(デフォルト:2) |
| checkin | string | いいえ | チェックイン日(YYYY-MM-DD) |
| infants | number | いいえ | 乳幼児の人数(デフォルト:0) |
| checkout | string | いいえ | チェックアウト日(YYYY-MM-DD) |
| children | number | いいえ | 子どもの人数(デフォルト:0。childAges から算出することもできます) |
| currency | string | いいえ | 料金に使用する ISO 4217 通貨コード(デフォルト:USD)、例:USD、EUR、COP |
| childAges | array | いいえ | チェックイン時の各子どもの年齢。例:[2, 7]。指定すると `children` が設定されます。 |
| hotelsOnly | boolean | いいえ | ホテル一覧のみを返し、場所の候補を省略します(デフォルト false)。 |
| destination | string | はい | 検索する目的地(都市/地域)。例:'Santa Marta, Colombia'。 |
| fullCityList | boolean | いいえ | 解決できる場合は、geo-page API からより広範な都市ホテル一覧(約 60 件)も取得します。追加のリクエストが数回発生します。デフォルト true。 |
詳細
CuddlyNest の検索と掲載情報 — MCP サーバー
CuddlyNestのホテルを検索し、客室の選択肢、料金、 空室状況、キャンセルポリシーなどの掲載情報を取得するための Model Context Protocol(MCP)サーバーです。
設計上、読み取り専用です。検索と掲載情報の取得のみで、予約や支払いは行いません。
データの取得方法
このサーバーは、訪問者と同じ方法でデータを読み取ります。ヘッドレスブラウザー(Playwright/Chromium)で実際の 公開掲載ページを開き、ページ独自の JavaScript が客室を読み込むのを待ち、 客室がレンダリングされた後、DOM から結果を読み取ります。
| データ | ソース |
|---|---|
| 名前、説明、住所、座標、星評価、アメニティ、画像 | 掲載ページの schema.org ld+json + Open Graph タグ(cuddlynest.ts) |
客室名、パートナー、unit_price、remaining_rooms、price_breakdown、cancellation_policy(.text を含む)、room_filters | React ファイバーの走査による、レンダリング済み掲載ページの DOM(scrape-listing.ts) |
| 目的地 → 候補地 + 上位ホテル | autosuggestion-2-0.cuddlynest.com(公開、認証不要) |
| 目的地 → より広範な都市のホテル一覧(約60~250件) | discovery-pages.cuddlynest.com/fetch_geopage/<ct-id>(公開)。<ct-id> はホテルの商品詳細ページのパンくずリストから取得 |
product_id → 名前 / 都市 / パンくずリスト | ldp-2-0-product-details.cuddlynest.com/api/v1/productDetail(公開) |
product_id → 正規の掲載パス | /hotel/-<id> サーバーリダイレクト |
DOM 抽出と、その問題点
extractRoomsFromDom() は価格形式のテキストノード(COL$742,637)をすべて走査し、
React ファイバーのツリーを上へたどり、props に unit_price と roomGroups の両方を持つ最も近い祖先コンポーネントを探します。その props は、ページですでにレンダリングされた客室オファーです。
これは CuddlyNest の現在のフロントエンド内部実装(安定した仕様ではなく、React の prop 形状)に依存しています。フロントエンドに変更が加わると、公開ページには価格が表示されているにもかかわらず、客室数が 0 件になる可能性があります。更新する箇所は、scrape-listing.ts の検出条件 'unit_price' in p && 'roomGroups' in p だけです。npm run e2e:sansiraka は、この問題を早期に検出するためのものです(終了コードは 0 以外になり、結果が無言で空になることはありません)。
fromPriceText(「From COL$…」)フィールドは、より緩やかなヒューリスティックを使うため、正常にスクレイピングできていても null になる場合があります。信頼できる値は rooms.fromPrice(抽出した客室のうち最も安い料金)です。
要件
- Node.js 18+
- Playwright 用の Chromium ビルド。
npm installの実行時にplaywright install chromiumが自動実行されます(postinstall)。お使いの環境でこれがブロックされる場合は、npx playwright install chromiumを一度手動で実行してください。
インストール
npm で cuddlynest-mcp として公開されており、
公式 MCP レジストリ
にも io.github.mafedelahoz/cuddlynest-mcp として登録されています。
{
"mcpServers": {
"cuddlynest": {
"command": "npx",
"args": ["-y", "cuddlynest-mcp"]
}
}
}
掲載ページの取得時に robots.txt を無視するには、args に "--ignore-robots-txt" を追加してください。CUDDLYNEST_SCRAPE_TIMEOUT_MS(デフォルトは 35000)で、ブラウザーが価格のレンダリングを待つ時間の上限を設定します。
Claude Desktop 用の MCPB バンドル(.mcpb)は、各
GitHub リリースに添付されています。ただし、Chromium はバンドルに含まれていないため、この方法でインストールした後に npx playwright install chromium を一度実行してください。
リモート / Streamable HTTP
デフォルトのトランスポートは stdio です。ホスト型のデプロイでは、Streamable HTTP を使って実行してください。
node dist/index.js --http 8080 # or: MCP_TRANSPORT=http PORT=8080 node dist/index.js
# POST http://<host>:8080/mcp — JSON-RPC (stateless, no sessions)
# GET http://<host>:8080/health — liveness
ツール
どちらのツールにも readOnlyHint: true が注釈されており、書き込み、予約、支払いは行いません。
cuddlynest_search
公開されている CuddlyNest API を使用して、目的地とその周辺の人気ホテルを検索します
(あいまい検索には autosuggestion-2-0 を、より広範な都市一覧には
discovery-pages の地理ページを使用します)。料金は 含まれません。ホテルの
productId を cuddlynest_listing_details に渡してください。
| パラメーター | 必須 | 説明 |
|---|---|---|
destination | はい | 都市/地域の文字列。例:"Cartagena, Colombia" |
hotelsOnly | いいえ | places[] ブロックを省略します(デフォルトは false) |
fullCityList | いいえ | 解決でき、目的地との照合を確認できる場合は、地理ページの都市一覧(約60〜250件のホテル)も取得します。リクエストが数回増えます(デフォルトは true) |
checkin、checkout、adults、children、childAges、infants、rooms、currency | いいえ | 後続処理用に値を返します |
戻り値: { query, guests, places[], city, hotelSource, hotelCount, hotels[], note }。
各 hotels[] エントリーには、productId、name、url、slug、propertyType、
starRating、guestRating(/10)、guestRatingText、reviewCount が含まれます。
さらに、地理ページから取得した images[]、distanceFromCenterKm、featuredAmenities[]
も含まれます。hotelSource は "autosuggest" または "autosuggest+geopage" です。
一覧は人気候補の範囲であり、全在庫ではありません。CuddlyNest の実際の検索結果ページ
(/sr/…)はボットによってブロックされており、robots.txt でも Disallow されています。
cuddlynest_listing_details
1軒のホテルについて、基本情報 と 客室/料金を取得します。
| パラメーター | 必須 | 説明 |
|---|---|---|
hotel | はい | リスティングの URL または 数値の product_id(URL末尾の数字) |
checkin、checkout | 料金取得時は必須 | YYYY-MM-DD — 客室/料金の読み取りに必要です |
adults、children、childAges、infants、rooms | いいえ | デフォルトはそれぞれ 2 / 0 / – / 0 / 1 です |
currency | いいえ | ISO 4217。デフォルトは USD です |
ignoreRobotsText | いいえ | 静的データの取得時に robots.txt を無視します |
戻り値: { productId, hotelUrl, guests, staticListing, staticError, rooms, roomsError, notes }。
rooms.units[] は抽出された客室オファーで、それぞれに title、partnerName、
unitPrice、currency、remainingRooms、guests、cancellationPolicyType、
cancellationPolicyText、priceBreakdown、roomFilters が含まれます。rooms には
fromPrice、partnersSeen、listingUrl、scrapedAt も含まれます。
開発
npm install # installs deps + Chromium (postinstall)
npm run build # sync-version + tsc -> dist/
npm run typecheck
npm test # offline: smoke test (stdio) + scraper tests
npm run e2e:sansiraka # ONLINE: real scrape of cuddlynest.com, structural asserts
npm run watch
アーキテクチャ
index.ts— MCP サーバー、ツールスキーマ、stdio および Streamable HTTP トランスポート、robots.txtの処理cuddlynest.ts— ホテル URL の解析、静的リスティングのld+json解析、 目的地のオートサジェスト、結果の整形scrape-listing.ts—resolveListingPath、buildListingUrl、scrapeListing(ヘッドレスブラウザー)、extractRoomsFromDom(React-fiber の走査)util.ts— 汎用オブジェクト/JSON ヘルパー
ライセンス
MIT — LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。