io.github.mafedelahoz/cuddlynest-mcp

Official registry Search and web

Search CuddlyNest hotels and read rooms, prices, availability and cancellation policies

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

NPM package cuddlynest-mcp
Claude Code
claude mcp add cuddlynest-mcp -e 'CUDDLYNEST_SCRAPE_TIMEOUT_MS=<CUDDLYNEST_SCRAPE_TIMEOUT_MS>' -- npx -y cuddlynest-mcp@0.2.1
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "cuddlynest-mcp": {
            "command": "npx",
            "args": [
                "-y",
                "cuddlynest-mcp@0.2.1"
            ],
            "env": {
                "CUDDLYNEST_SCRAPE_TIMEOUT_MS": "<CUDDLYNEST_SCRAPE_TIMEOUT_MS>"
            }
        }
    }
}

Environment variables

  • CUDDLYNEST_SCRAPE_TIMEOUT_MS Max ms to wait for a listing page's rooms/prices to render (default 35000)

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. CuddlyNest Search & Listings — MCP Server
  2. How it gets the data
  3. Requirements
  4. Installation
  5. Tools
  6. Development
  7. Architecture
  8. License

CuddlyNest Search & Listings — MCP Server

A Model Context Protocol (MCP) server for searching CuddlyNest hotels and retrieving listing details, including room options, prices, availability and cancellation policies.

Read-only by design: search and listing details only. No booking, no payment.

How it gets the data

This server reads that data the same way a visitor does: it opens the real, public listing page in a headless browser (Playwright/Chromium), lets the page's own JavaScript load the rooms, waits for them to render, and reads the result out of the DOM.

DataSource
Name, description, address, coordinates, star rating, amenities, imagesListing page schema.org ld+json + Open Graph tags (cuddlynest.ts)
Room title, partner, unit_price, remaining_rooms, price_breakdown, cancellation_policy (incl. .text), room_filtersRendered listing page DOM, via a React-fiber walk (scrape-listing.ts)
Destination → place candidates + top hotelsautosuggestion-2-0.cuddlynest.com (public, no auth)
Destination → broader city hotel list (~60–250)discovery-pages.cuddlynest.com/fetch_geopage/<ct-id> (public); <ct-id> recovered from a hotel's product-detail breadcrumbs
product_id → name / city / breadcrumbsldp-2-0-product-details.cuddlynest.com/api/v1/productDetail (public)
product_id → canonical listing path/hotel/-<id> server redirect
The DOM extraction, and how it breaks

extractRoomsFromDom() walks every price-shaped text node (COL$742,637), then walks up its React fiber tree to the nearest ancestor component whose props carry both unit_price and roomGroups. Those props are the room offer the page already rendered.

This is coupled to CuddlyNest's current frontend internals (a React prop shape, not a stable contract). If they ship a frontend change it can start returning zero rooms even though the public page still shows prices. The single place to update is the detector condition 'unit_price' in p && 'roomGroups' in p in scrape-listing.ts. npm run e2e:sansiraka is meant to catch that early (non-zero exit, not a silent empty result).

The fromPriceText ("From COL$…") field uses a looser heuristic and can come back null even on a healthy scrape; rooms.fromPrice (cheapest extracted unit) is the reliable figure.


Requirements

  • Node.js 18+
  • A Chromium build for Playwright. npm install runs playwright install chromium automatically (postinstall); if that is blocked in your environment, run npx playwright install chromium once by hand.

Installation

Published as cuddlynest-mcp on npm and listed in the official MCP registry as io.github.mafedelahoz/cuddlynest-mcp.

{
  "mcpServers": {
    "cuddlynest": {
      "command": "npx",
      "args": ["-y", "cuddlynest-mcp"]
    }
  }
}

Add "--ignore-robots-txt" to args to bypass robots.txt for the listing-page fetches. CUDDLYNEST_SCRAPE_TIMEOUT_MS (default 35000) caps how long the browser waits for prices to render.

An MCPB bundle (.mcpb) for Claude Desktop is attached to each GitHub release — note it does not bundle Chromium, so run npx playwright install chromium once after installing it that way.

Remote / Streamable HTTP

Default transport is stdio. For a hosted deployment, run it over 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

Tools

Both tools are annotated readOnlyHint: true — they never write, book, or pay.

Search a destination and the top hotels there, from public CuddlyNest APIs (autosuggestion-2-0 for the fuzzy match, discovery-pages geo pages for the broader city list). Prices are not here — pass a hotel's productId to cuddlynest_listing_details.

ParameterRequiredDescription
destinationyesCity / area string, e.g. "Cartagena, Colombia"
hotelsOnlynoOmit the places[] block (default false)
fullCityListnoAlso pull the geo-page city list (~60–250 hotels) when it can be resolved and verified against the destination — a few extra requests (default true)
checkin, checkout, adults, children, childAges, infants, rooms, currencynoechoed back for downstream use

Returns: { query, guests, places[], city, hotelSource, hotelCount, hotels[], note }. Each hotels[] entry: productId, name, url, slug, propertyType, starRating, guestRating (/10) + guestRatingText, reviewCount, and — from the geo page — images[], distanceFromCenterKm, featuredAmenities[]. hotelSource is "autosuggest" or "autosuggest+geopage". The list is top-matches scale, not full inventory — CuddlyNest's real results page (/sr/…) is bot-blocked and Disallowed in robots.txt.

cuddlynest_listing_details

Static basics and rooms/pricing for one hotel.

ParameterRequiredDescription
hotelyesListing URL or numeric product_id (trailing number in the URL)
checkin, checkoutfor pricingYYYY-MM-DD — required to read rooms/prices
adults, children, childAges, infants, roomsnodefaults 2 / 0 / – / 0 / 1
currencynoISO 4217, default USD
ignoreRobotsTextnoignore robots.txt for the static fetch

Returns: { productId, hotelUrl, guests, staticListing, staticError, rooms, roomsError, notes }. rooms.units[] is the extracted room offers, each with title, partnerName, unitPrice, currency, remainingRooms, guests, cancellationPolicyType, cancellationPolicyText, priceBreakdown, roomFilters. rooms also carries fromPrice, partnersSeen, listingUrl, scrapedAt.


Development

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

Architecture

  • index.ts — MCP server, tool schemas, stdio and Streamable HTTP transports, robots.txt handling
  • cuddlynest.ts — hotel-URL parsing, static-listing ld+json parse, destination autosuggestion, result shaping
  • scrape-listing.ts — resolveListingPath, buildListingUrl, scrapeListing (headless browser), extractRoomsFromDom (React-fiber walk)
  • util.ts — generic object/JSON helpers

License

MIT — see LICENSE.

Frequently asked questions

What is io.github.mafedelahoz/cuddlynest-mcp?

Search CuddlyNest hotels and read rooms, prices, availability and cancellation policies

How do I install io.github.mafedelahoz/cuddlynest-mcp?

It runs on your machine. In Claude Code: claude mcp add cuddlynest-mcp -e 'CUDDLYNEST_SCRAPE_TIMEOUT_MS=<CUDDLYNEST_SCRAPE_TIMEOUT_MS>' -- npx -y cuddlynest-mcp@0.2.1. For other clients, paste the JSON configuration from this page into their MCP settings.

Does io.github.mafedelahoz/cuddlynest-mcp need an API key?

Its registry entry lists no required key or secret. Some features may still need an account with the service it connects to.

Is io.github.mafedelahoz/cuddlynest-mcp open source?

Yes. Its code is on GitHub under the MIT license.

Who maintains io.github.mafedelahoz/cuddlynest-mcp?

It is published by mafedelahoz. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.