- TypeScript 100%
Adversarial review before publish turned up a truncation-honesty failure: list_cities silently caps at 100. Portugal returns 13, but an unfiltered call and country="United States" both return exactly 100. search_hotels caps at 10, which the tool description does document. Neither tool exposes pagination, so both specs now carry a `truncated` flag rather than quietly presenting a capped list as complete. Also retry once on HTTP 429 honoring Retry-After (clamped to 60s) — hotelist's fair-use limit is 30 req/min, which a fan-out workflow can reach — and log entry/completion in every method. Pure helpers are exported so the parse and error paths are testable without a network; 20 tests cover them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| extensions/models | ||
| workflows/hotel-recommendation | ||
| .gitignore | ||
| CLAUDE.md | ||
| LICENSE.txt | ||
| manifest.yaml | ||
| README.md | ||
@keeb/hotelist
A swamp extension that wraps hotelist.com's MCP server — hotel search with 0-10 ratings computed by AI from reviews and photos across sources, with no pay-to-play placement.
The endpoint (https://hotelist.com/mcp) is a stateless streamable-HTTP MCP
server: tools/call works without an initialize handshake, a session header,
or any authentication. This extension exposes all three of its tools as model
methods.
Installation
swamp extension install @keeb/hotelist
Usage
Add a model definition. The only global argument is the endpoint, which defaults to the public server:
models:
- name: hotelist
type: "@keeb/hotelist"
search_hotels
Top matching hotels in a city (max 10), with AI rating, nightly USD price, and AI-summarized pros/cons.
swamp model method run hotelist search_hotels \
--input city=Raleigh --input min_rating=8.5 --input max_price_usd=400
Arguments: city (required), query, min_rating, max_price_usd,
sort (best | cheapest | priciest | newest).
The city filter is fuzzy. hotelist returns hotels in surrounding towns too — a search for Raleigh also returns results in Cary, Durham, and Smithfield. Filter on the
cityfield of each result if you need strict in-city matches. The bundled workflow does this.
The server caps results at 10. When it returns a full page, the truncated
field on the result is true, meaning more hotels may exist than were
returned — narrow with query, min_rating, or max_price_usd.
get_hotel
Full detail for one hotel: AI description, per-dimension rating breakdown (cleanliness / newness / ambiance / amenities), amenity tags, measured wifi speed, year built, and a photo.
swamp model method run hotelist get_hotel \
--input hotel=tempo-by-hilton-raleigh-downtown-65720
Arguments: hotel (required — a hotelist.com URL, slug, or name), city to
disambiguate a bare name.
list_cities
Cities hotelist covers, with hotel counts and average AI rating.
swamp model method run hotelist list_cities --input country="United States"
This caps at 100 cities — undocumented upstream, but observable: an unfiltered
call and country="United States" both return exactly 100, while Portugal
returns 13. The result carries truncated: true when the cap is hit; filter by
country to get a complete list.
Bundled workflow
@keeb/hotel-recommendation shortlists a city, asserts at least one result is
actually in that city, then pulls full detail on the top in-city pick.
swamp workflow run @keeb/hotel-recommendation --input city=Raleigh
Inputs: city (required, default Raleigh), min_rating (default 8.5),
max_price_usd (default 400), sort (default best).
The workflow's steps reference a model named hotelist, so name your model
definition hotelist or copy the workflow and adjust modelIdOrName.
Results land in three data resources — read them with swamp data get:
swamp data get hotelist search # the city shortlist
swamp data get hotelist hotel # full detail on the top pick
swamp data get hotelist cities # coverage from list_cities
Notes
- Methods throw when a search returns nothing rather than emitting an empty result, so a bad city name fails loudly instead of quietly recommending nothing.
- Fair use, per hotelist: 30 requests/minute, 400/day, and 50 full hotel
details/day per IP. It is not a bulk-export API. A
429is retried once, honoringRetry-After(clamped to 60s); a second429fails the method. - hotelist asks that you link the
hotelist.comURL of any hotel you recommend; every result carries one in itsurlfield.
License
MIT — see LICENSE.txt.