Skip to main content
Glama

Booking.com Hotel Search (Live Prices)

Server Details

Real-time Booking.com rates for agents. Three things people do with this server. Scan for rate gaps: price_as_seen_from prices the same room from another market, so an agent can sample a property across countries and compare. Put live search in your app: search a destination or look a property up by name, no internal IDs, room-level rates as flat JSON. Run a 24/7 AI travel agent: add the server, sign in with Google, and schedule it. No ads, no sponsored content. You bring your own RapidAPI key, so every search is billed to your plan and never to anyone else's. Add https://hotels.flightpowers.com/mcp , click Sign in, sign in with Google, and paste your RapidAPI key once on the page that opens. Scripts and clients without a sign-in button send the key as x-rapidapi-key on the same URL.

Ownership verified
Status
Healthy
Uptime
99.9% over 42 days
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
Repository
mtnrabi/google-flights-mcp
GitHub Stars
1
Server Listing
google-flights-mcp

TDQS

A4.7/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: search_hotels finds properties by destination, find_hotel_by_name looks up a specific property, and compare_hotel_rates compares prices across sources. Despite some parameter overlap, the outputs are fundamentally different and descriptions are unambiguous.

Naming Consistency5/5

All three tools follow a consistent verb_noun pattern with underscores: compare_hotel_rates, find_hotel_by_name, search_hotels. This is predictable and easy to understand.

Tool Count5/5

Three tools is well-scoped for a hotel search server, covering the essential workflows of searching, specific property lookup, and cross-source comparison without unnecessary redundancy.

Completeness5/5

The tool set covers the core domain of hotel search and price comparison. It provides search results with pricing and reviews, single-property details, and multi-source rate comparisons. The ability to price multiple stays and handle different providers makes it comprehensive for its stated purpose.

Available Tools

3 tools
compare_hotel_ratesFlightPowers: compare hotel rates across sourcesA
Read-only
Inspect

FlightPowers cross-source comparison: prices one stay on every source you have a key for. Input: a free-text destination the way a person would say it ("Rome", "Tokyo Shibuya"), check-in and check-out dates, and how many adults. Returns one row per source: the cheapest and the median stay total, how many places were found, the currency and when it was read.

Read the caveats on every row before you say one source is cheaper. rating_scale is 10 on Booking and 5 on Airbnb. taxes_included is true on Booking, where excluded taxes are folded into the price, and null on Airbnb, where we have not established the tax treatment of the display total; a null is not a no. A source you have no key for is listed in providers_skipped with a subscribe link and is not counted anywhere in the comparison.

Rates go stale within minutes: never reuse an earlier result, compare again.

Requires the caller's own RapidAPI key for the Booking Live API. Get one (free tier available) at https://rapidapi.com/mtnrabi/api/booking-live-api, then pass it as an x-rapidapi-key header (preferred), a ?rapidapi_key= query parameter on the server URL, or your client's own API key field -- first non-empty wins. Usage counts against the caller's own RapidAPI plan, not ours; every response reports what it spent and what is left in api_usage. No key? Sign in with Google and the first 10 searches each day are free on this server -- ad-free, nothing to paste. Connect your own RapidAPI key at https://hotels.flightpowers.com/connect to remove the cap.

ParametersJSON Schema
NameRequiredDescriptionDefault
adultsNoNumber of adult guests. Defaults to the upstream default when omitted.
childrenNoNumber of children sharing the room.
currencyNoISO currency code for every row, e.g. "usd". Sources are asked for the same currency so the totals are comparable; a row that came back in a different one says so in its own currency field and is not converted.
providersNoWhich sources to price, e.g. ["booking", "airbnb"]. Defaults to both. A source you have no RapidAPI key for is not called and appears in providers_skipped.
destinationYesWhere to stay, in free text the way a person would say it, e.g. "Rome" or "Tokyo Shibuya". A city, district, landmark or region all work; no internal location ID is needed.
checkin_dateYesFirst night of the stay, "YYYY-MM-DD".
checkout_dateYesDeparture morning, "YYYY-MM-DD". Must be after checkin_date.

Output Schema

ParametersJSON Schema
NameRequiredDescription
adultsNo
nightsNoNights between the two dates, or null when the dates could not be read as dates.
caveatsNoSentences that must be read before one source is called cheaper than another -- differing rating scales, differing tax treatment, differing currencies, a source that did not answer.
messageNo
childrenNo
currencyNoThe currency every source was ASKED for.
api_usageNoWhat this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed.
providersYes
signup_urlNoWhere the caller subscribes or changes plan.
destinationNo
checkin_dateNo
checkout_dateNo
needs_api_keyNoTrue when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it.
quota_exhaustedNoTrue when the caller's RapidAPI plan has no requests left for the current period.
providers_skippedNoSources that were NOT called, each named with why and where to subscribe. A source here contributed nothing to results and is counted nowhere. It is listed rather than dropped because a silently missing source is indistinguishable from a source that had nothing.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes far beyond the annotations (readOnlyHint/openWorldHint/destructiveHint). It discloses that rates go stale within minutes, that rating_scale differs by source, that taxes_included is null-and-not-a-no on Airbnb, that keyless providers appear in providers_skipped and are excluded, and that usage counts against the caller's RapidAPI plan with api_usage reporting. These are exactly the behavioral traits an agent needs and that annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, followed by correctness-critical caveats, then freshness, then auth — a logical order where each paragraph earns its place. The auth section is somewhat long (five sentences on key acquisition, header precedence, and free-tier fallback), but that detail is operationally necessary for an agent to invoke the tool with a key.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with this complexity — 7 params, external RapidAPI dependency, cross-source semantics, and freshness constraints — the description is remarkably complete. It covers inputs, output shape, per-source caveats, staleness, auth requirements and key precedence. An output schema exists, so return-value documentation is not the description's job, and nothing needed for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema entries are already rich (e.g., destination free-text semantics, currency non-conversion, providers skipping). The description's input summary ('free-text destination the way a person would say it...') largely restates the schema. With full coverage, the baseline 3 applies; the description adds little parameter meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line states a specific verb and resource: 'prices one stay on every source you have a key for' — a cross-source price comparison. This differentiates it from siblings find_hotel_by_name and search_hotels, which are lookup tools, so an agent can route correctly without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear operational context: use it to price a single stay across all keyed sources, and 'never reuse an earlier result, compare again' because rates go stale. It does not explicitly name sibling tools or state when-not-to-use-this, so it falls short of a 5, but the usage context is unmistakable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_hotel_by_nameFlightPowers: find one hotel by nameA
Read-only
Inspect

FlightPowers single-property lookup: live Booking.com availability and pricing for one named property. Input: the hotel name a person would type (adding the city helps when a chain has many properties) plus check-in and check-out dates -- no internal property ID needed, the resolution is done for you. Returns the property's price, review score, room type and a booking link. Use it to check one specific hotel, or to track a single property's price over time.

A date range and a nights value price several stays in one call, like the flights tools: pass checkin_date_from, checkin_date_to and nights (a number, or a list like [2, 3, 7]) instead of a fixed checkin_date/checkout_date, and this property is priced for every check-in date -- a rate calendar for one hotel. The answer is stays, one entry per date with that date's price and per-night rate, plus cheapest_overall. Each stay is one request billed to your plan; max_searches caps it, and a range that expands past the cap is sampled evenly across the calendar and says so in search_coverage.

price_as_seen_from prices the stay as a shopper resident in that country would see it. Gaps are real but usually modest and property-dependent, and rates move between calls, so call each country a few times on this same property before reporting a gap.

Rates go stale within minutes: never reuse an earlier result.

Requires the caller's own RapidAPI key for the Booking Live API. Get one (free tier available) at https://rapidapi.com/mtnrabi/api/booking-live-api, then pass it as an x-rapidapi-key header (preferred), a ?rapidapi_key= query parameter on the server URL, or your client's own API key field -- first non-empty wins. Usage counts against the caller's own RapidAPI plan, not ours; every response reports what it spent and what is left in api_usage. No key? Sign in with Google and the first 10 searches each day are free on this server -- ad-free, nothing to paste. Connect your own RapidAPI key at https://hotels.flightpowers.com/connect to remove the cap.

ParametersJSON Schema
NameRequiredDescriptionDefault
adultsNoNumber of adult guests.
nightsNoHow many nights to stay, as a number (3) or a list ([2, 3, 7]) to price several lengths. Derives the check-out date from each check-in date, so it replaces checkout_date rather than joining it.
childrenNoNumber of children sharing the room.
currencyNoISO currency code for the prices returned, e.g. "usd".
hotel_nameYesThe property name a person would type, e.g. "Hotel Artemide". Adding the city ("Hotel Artemide Rome") disambiguates a chain with many properties. No internal property ID is needed.
checkin_dateNoFirst night of the stay, "YYYY-MM-DD". Give this with checkout_date for one stay, or use checkin_date_from plus checkin_date_to for a rate calendar.
max_searchesNoThe billed requests this call may make, up or down. One stay is one request; the cap rises by itself to cover a month-sized request, and anything past the cap in force is sampled evenly across the calendar rather than cut short at the front.
checkout_dateNoDeparture morning, "YYYY-MM-DD". Must be after checkin_date. Give either this or nights, not both.
checkin_date_toNoLast check-in date of the range, "YYYY-MM-DD".
checkin_date_fromNoFirst check-in date of a range, "YYYY-MM-DD". Needs checkin_date_to and nights, and prices this property on every check-in date in the range -- one call, a rate calendar.
price_as_seen_fromNoTwo-letter country code, e.g. "de". Prices the stay as a shopper resident in that country would see it. Call each country a few times on this same property before reporting a gap, because rates move between calls and gaps are usually modest and property-dependent.

Output Schema

ParametersJSON Schema
NameRequiredDescription
staysNoOne entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it. Read this rather than inferring coverage from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that.
caveatsNoSentences that must be read before one source is called cheaper than another -- differing rating scales, differing tax treatment, differing currencies, a source that did not answer.
messageNo
partialNoPresent when some stays failed but others were priced. Plain text saying how much of the request the answer covers.
resultsYesThe itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'.
api_usageNoWhat this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed.
providersNoOne entry per source that was called, in the order they were requested. Only present when `providers` named more than the default source.
signup_urlNoWhere the caller subscribes or changes plan.
result_countNo
needs_api_keyNoTrue when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it.
search_statusNoDate-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help -- ask for fewer dates or nights, or move to a larger plan.
applied_filtersNoWhich of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through.
quota_exhaustedNoTrue when the caller's RapidAPI plan has no requests left for the current period.
search_coverageNoWhat was actually priced on a date-range search. Present whether or not the request was truncated, so a model can state honestly what its answer rests on.
cheapest_overallNoThe cheapest stay across everything priced, or null when nothing was. `results` holds this stay's full property list.
results_for_stayNoWhich stay `results` belongs to on a date-range search, or null when nothing was priced. Without it the rows read as 'the search's results' and get quoted against the wrong dates.
providers_skippedNoSources that were NOT called, each named with why and where to subscribe. A source here contributed nothing to results and is counted nowhere. It is listed rather than dropped because a silently missing source is indistinguishable from a source that had nothing.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, and the description adds substantial behavioral detail beyond that: 'Rates go stale within minutes: never reuse an earlier result,' the max_searches cap with even sampling, the price_as_seen_from caveat to call multiple times before reporting a gap, and billing/API key implications. No contradiction exists; the description enriches an already well-annotated safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured and front-loaded with the core purpose. Each paragraph has a distinct role: inputs, rate calendar, currency handling, staleness, and authentication. Some redundancy exists with schema descriptions (e.g., hotel_name can include the city, no internal ID needed), but the length is justified by the tool's complexity and the need to explain billing and data freshness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (11 parameters, rate calendars, billing caps, auth requirements, live data variability), the description is remarkably complete. It covers the return shape (price, review score, room type, booking link; stays for calendars), explains max_searches sampling, warns about stale rates, details authentication paths, and sets expectations for price_as_seen_from. The presence of an output schema further reduces the need to spell out every field, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful relational context: it explains how checkin_date_from/checkin_date_to/nights create a rate calendar, clarifies that nights replaces checkout_date rather than joining it, and describes max_searches sampling behavior. These go beyond the schema's per-parameter descriptions, making the combined guidance more actionable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'single-property lookup: live Booking.com availability and pricing for one named property.' It clearly differentiates from siblings by stating it finds exactly one hotel by name, and later reinforces 'Use it to check one specific hotel, or to track a single property's price over time.' This leaves no ambiguity about what the tool does or how it differs from search or comparison tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when to use the tool: checking one specific hotel or tracking a single property over time. It also explains the rate calendar flow and when to use date ranges instead of fixed dates. However, it does not explicitly name sibling tools or state when not to use this tool in favor of compare_hotel_rates or search_hotels, so it falls just short of full explicitness.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_hotelsFlightPowers: search hotelsA
Read-only
Inspect

FlightPowers hotel search: live Booking.com availability and nightly prices for a destination and date range. Input: a free-text destination the way a person would say it ("Rome", "Tokyo Shibuya"), plus check-in and check-out dates. Returns each property's price, review score, room type, location and a booking link.

Set price_as_seen_from to a two-letter country code to price the same stay the way a shopper resident in that country would see it, which no other travel tool here can do. Gaps are real but usually modest and property-dependent, and rates move between calls, so hold one named property fixed, call each country a few times, and never read one call per country as a gap.

A date range and a nights value price several stays in one call, like the flights tools: pass checkin_date_from, checkin_date_to and nights (a number, or a list like [2, 3, 7]) instead of a fixed checkin_date/checkout_date, and every check-in date is priced separately. The answer is stays -- one entry per stay with its cheapest property, per-night price and median -- plus cheapest_overall, and the full property list for the cheapest stay only. Each stay is one request billed to your plan; max_searches caps it, and a request that expands past the cap is sampled evenly across the range and says so in search_coverage.

Set providers to price the same stay on more than one source in one call: ["booking"] (the default), ["airbnb"], or both. Booking rows rate out of 10 and Airbnb rows out of 5, so read rating_scale on every row before comparing two of them. A source you have no RapidAPI key for is not called and is named in providers_skipped with a subscribe link, never quietly dropped.

Rates go stale within minutes: never reuse an earlier result, search again.

Requires the caller's own RapidAPI key for the Booking Live API. Get one (free tier available) at https://rapidapi.com/mtnrabi/api/booking-live-api, then pass it as an x-rapidapi-key header (preferred), a ?rapidapi_key= query parameter on the server URL, or your client's own API key field -- first non-empty wins. Usage counts against the caller's own RapidAPI plan, not ours; every response reports what it spent and what is left in api_usage. No key? Sign in with Google and the first 10 searches each day are free on this server -- ad-free, nothing to paste. Connect your own RapidAPI key at https://hotels.flightpowers.com/connect to remove the cap.

ParametersJSON Schema
NameRequiredDescriptionDefault
adultsNoNumber of adult guests. Defaults to the upstream default when omitted.
nightsNoHow many nights to stay, as a number (3) or a list ([2, 3, 7]) to price several lengths. Derives the check-out date from each check-in date, so it replaces checkout_date rather than joining it.
filtersNoProperty filters to apply, e.g. ["free_cancellation", "breakfast_included"]. An unknown name is rejected with the list of valid ones rather than being ignored.
childrenNoNumber of children sharing the room.
currencyNoISO currency code for the prices returned, e.g. "usd".
providersNoWhich sources to price this stay on, e.g. ["booking"], ["airbnb"] or ["booking", "airbnb"]. Defaults to ["booking"]. Each source is a separate RapidAPI subscription, so a source you have no key for is not called; it comes back named in providers_skipped with the reason and where to subscribe, rather than silently missing. filters and price_as_seen_from apply to booking only; airbnb takes price_min, price_max and room_types instead, and rows from it carry rating_scale 5 where booking's carry 10.
destinationYesWhere to stay, in free text the way a person would say it, e.g. "Rome" or "Tokyo Shibuya". A city, district, landmark or region all work; no internal location ID is needed.
checkin_dateNoFirst night of the stay, "YYYY-MM-DD". Give this with checkout_date for one stay, or use checkin_date_from plus checkin_date_to for a range of check-in dates.
max_searchesNoThe billed requests this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- the cap rises to cover a request that size by itself. Set it lower to spend less, or higher (hard maximum 200) for a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front.
checkout_dateNoDeparture morning, "YYYY-MM-DD". Must be after checkin_date. Give either this or nights, not both.
checkin_date_toNoLast check-in date of the range, "YYYY-MM-DD".
budget_per_nightNoOnly return properties at or below this nightly price, in `currency`.
checkin_date_fromNoFirst check-in date of a range, "YYYY-MM-DD". Needs checkin_date_to and nights, and prices one stay per check-in date in the range -- the hotel equivalent of the flights date range.
price_as_seen_fromNoTwo-letter country code, e.g. "de". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. For a rate-parity check hold one named property fixed and call each country a few times, because rates move between calls and one call per country can show a gap that is not there. Omit it for a neutral price.

Output Schema

ParametersJSON Schema
NameRequiredDescription
staysNoOne entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it. Read this rather than inferring coverage from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that.
caveatsNoSentences that must be read before one source is called cheaper than another -- differing rating scales, differing tax treatment, differing currencies, a source that did not answer.
messageNo
partialNoPresent when some stays failed but others were priced. Plain text saying how much of the request the answer covers.
resultsYesThe itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'.
api_usageNoWhat this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed.
providersNoOne entry per source that was called, in the order they were requested. Only present when `providers` named more than the default source.
signup_urlNoWhere the caller subscribes or changes plan.
result_countNo
needs_api_keyNoTrue when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it.
search_statusNoDate-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help -- ask for fewer dates or nights, or move to a larger plan.
applied_filtersNoWhich of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through.
quota_exhaustedNoTrue when the caller's RapidAPI plan has no requests left for the current period.
search_coverageNoWhat was actually priced on a date-range search. Present whether or not the request was truncated, so a model can state honestly what its answer rests on.
cheapest_overallNoThe cheapest stay across everything priced, or null when nothing was. `results` holds this stay's full property list.
results_for_stayNoWhich stay `results` belongs to on a date-range search, or null when nothing was priced. Without it the rows read as 'the search's results' and get quoted against the wrong dates.
providers_skippedNoSources that were NOT called, each named with why and where to subscribe. A source here contributed nothing to results and is counted nowhere. It is listed rather than dropped because a silently missing source is indistinguishable from a source that had nothing.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, openWorldHint), the description discloses significant behavioral traits: rates go stale within minutes, sources without keys are skipped with a subscribe link, usage counts against the caller's RapidAPI plan, and every response reports api_usage. It also explains sampling behavior with max_searches and the consistency of rating_scale across providers. These add substantial context at no contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place. It front-loads the core purpose, then flows through key features, rate-parity, multi-stay pricing, providers, staleness, and auth. While dense, it avoids redundancy and is logically structured into themed paragraphs, making it efficient for the complexity it covers.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 14 parameters, annotations, and an output schema, the description fully covers what an agent needs: destination format, date handling (fixed vs. range), nights vs. checkout_date, providers selection, price_as_seen_from purpose, max_searches billing and sampling, output structure (stays, cheapest_overall, search_coverage), and authentication requirements. No critical behavioral or setup detail is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds deep semantics: explains the interaction between nights and checkout_date, the behavior of checkin_date_from requiring nights, the sampling even distribution when max_searches is exceeded, the difference between booking (rating 10) and airbnb (rating 5) scale, and how providers_skipped reports missing keys. These go far beyond the schema's field descriptions, making parameter usage unambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'FlightPowers hotel search: live Booking.com availability and nightly prices for a destination and date range', a specific verb and resource with a clear scope. It distinguishes itself from siblings by describing a general search (vs. compare_hotel_rates for rate comparison and find_hotel_by_name for targeted lookups) and explicitly notes the unique price_as_seen_from capability, making the tool's purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers guidance on when to use specific features (e.g., price_as_seen_from for rate-parity checks, providers for multi-source pricing) but does not explicitly state when to use this tool versus siblings like compare_hotel_rates or find_hotel_by_name. It differentiates itself by saying 'no other travel tool here can do' for price_as_seen_from, providing implicit context, but lacks direct alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updates
    • Changedcompare_hotel_rates2 fields changed
      • addedOutput schema / properties / api_usage / properties / hub_requests_billed
        Added value: +{
        +  "description": "How many HTTP requests RapidAPI actually billed. Larger than requests_used_by_this_call when a search failed with a server error and was retried, because the retry is billed too. This is the figure the invoice will show.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / api_usage / properties / requests_used_by_this_call / description
        Added value: +"How many date/destination combinations were searched -- what the answer COVERS."
    • Changedfind_hotel_by_name6 fields changed
      • changedInput schema / properties / max_searches / description
        Previous value: -"Cap the billed requests this call may make. One stay is one request; lower it and the range is sampled evenly across the calendar rather than cut short at the front."New value: +"The billed requests this call may make, up or down. One stay is one request; the cap rises by itself to cover a month-sized request, and anything past the cap in force is sampled evenly across the calendar rather than cut short at the front."
      • addedOutput schema / properties / api_usage / properties / hub_requests_billed
        Added value: +{
        +  "description": "How many HTTP requests RapidAPI actually billed. Larger than requests_used_by_this_call when a search failed with a server error and was retried, because the retry is billed too. This is the figure the invoice will show.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / api_usage / properties / requests_used_by_this_call / description
        Added value: +"How many date/destination combinations were searched -- what the answer COVERS."
      • addedOutput schema / properties / search_coverage / properties / stopped_early
        Added value: +{
        +  "description": "Present when something other than the cap ended the fan-out. 'deadline': the call reached its time limit and the remaining combinations were never sent or billed, so the results are real but do not cover the whole range.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / search_status / description
        Previous value: -"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help."New value: +"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help -- ask for fewer dates or nights, or move to a larger plan."
      • changedOutput schema / properties / search_status / enum
        Previous value: -[
        -  "ok",
        -  "empty",
        -  "partial",
        -  "degraded",
        -  "trial_exhausted"
        -]New value: +[
        +  "ok",
        +  "empty",
        +  "partial",
        +  "degraded",
        +  "trial_exhausted",
        +  "quota_exceeded"
        +]
    • Changedsearch_hotels6 fields changed
      • changedInput schema / properties / max_searches / description
        Previous value: -"Cap the billed requests this call may make. One stay is one request, so a 30-day range at two lengths is 60; lower this to spend less and the range is sampled evenly across the calendar rather than cut short at the front."New value: +"The billed requests this call may make, up or down. One stay is one request, so a 30-day range at two lengths is 60 and a month at three is 93 -- the cap rises to cover a request that size by itself. Set it lower to spend less, or higher (hard maximum 200) for a wider grid; either way the range is sampled evenly across the calendar rather than cut short at the front."
      • addedOutput schema / properties / api_usage / properties / hub_requests_billed
        Added value: +{
        +  "description": "How many HTTP requests RapidAPI actually billed. Larger than requests_used_by_this_call when a search failed with a server error and was retried, because the retry is billed too. This is the figure the invoice will show.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / api_usage / properties / requests_used_by_this_call / description
        Added value: +"How many date/destination combinations were searched -- what the answer COVERS."
      • addedOutput schema / properties / search_coverage / properties / stopped_early
        Added value: +{
        +  "description": "Present when something other than the cap ended the fan-out. 'deadline': the call reached its time limit and the remaining combinations were never sent or billed, so the results are real but do not cover the whole range.",
        +  "type": "string"
        +}
      • changedOutput schema / properties / search_status / description
        Previous value: -"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help."New value: +"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help. 'quota_exceeded': the search was refused because the caller's remaining allowance or plan quota cannot cover the number of combinations asked for; combos_requested and combos_allowed_now carry the two numbers. Nothing was searched beyond what it cost to read the quota. Retrying the same search does not help -- ask for fewer dates or nights, or move to a larger plan."
      • changedOutput schema / properties / search_status / enum
        Previous value: -[
        -  "ok",
        -  "empty",
        -  "partial",
        -  "degraded",
        -  "trial_exhausted"
        -]New value: +[
        +  "ok",
        +  "empty",
        +  "partial",
        +  "degraded",
        +  "trial_exhausted",
        +  "quota_exceeded"
        +]
  2. 2 tool updates
    • Changedfind_hotel_by_name2 fields changed
      • changedOutput schema / properties / search_status / description
        Previous value: -"Date-range searches only. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry."New value: +"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help."
      • changedOutput schema / properties / search_status / enum
        Previous value: -[
        -  "ok",
        -  "empty",
        -  "partial",
        -  "degraded"
        -]New value: +[
        +  "ok",
        +  "empty",
        +  "partial",
        +  "degraded",
        +  "trial_exhausted"
        +]
    • Changedsearch_hotels2 fields changed
      • changedOutput schema / properties / search_status / description
        Previous value: -"Date-range searches only. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry."New value: +"Date-range searches only, except 'trial_exhausted'. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry. 'trial_exhausted': the free signed-in allowance on this server is spent for today, so nothing was searched and nothing was billed; it renews at 00:00 UTC and connecting your own RapidAPI key removes the cap. Retrying does not help."
      • changedOutput schema / properties / search_status / enum
        Previous value: -[
        -  "ok",
        -  "empty",
        -  "partial",
        -  "degraded"
        -]New value: +[
        +  "ok",
        +  "empty",
        +  "partial",
        +  "degraded",
        +  "trial_exhausted"
        +]
  3. 3 tool updates
    • Addedcompare_hotel_rates
    • Changedfind_hotel_by_name23 fields changed
      • addedInput schema / properties / checkin_date / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / checkin_date / default
        Added value: +null
      • changedInput schema / properties / checkin_date / description
        Previous value: -"First night of the stay, \"YYYY-MM-DD\"."New value: +"First night of the stay, \"YYYY-MM-DD\". Give this with checkout_date for one stay, or use checkin_date_from plus checkin_date_to for a rate calendar."
      • removedInput schema / properties / checkin_date / type
        Removed value: -"string"
      • addedInput schema / properties / checkin_date_from
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "First check-in date of a range, \"YYYY-MM-DD\". Needs checkin_date_to and nights, and prices this property on every check-in date in the range -- one call, a rate calendar."
        +}
      • addedInput schema / properties / checkin_date_to
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Last check-in date of the range, \"YYYY-MM-DD\"."
        +}
      • addedInput schema / properties / checkout_date / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / checkout_date / default
        Added value: +null
      • changedInput schema / properties / checkout_date / description
        Previous value: -"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date."New value: +"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date. Give either this or nights, not both."
      • removedInput schema / properties / checkout_date / type
        Removed value: -"string"
      • addedInput schema / properties / max_searches
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Cap the billed requests this call may make. One stay is one request; lower it and the range is sampled evenly across the calendar rather than cut short at the front."
        +}
      • addedInput schema / properties / nights
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "items": {
        +        "type": "integer"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "How many nights to stay, as a number (3) or a list ([2, 3, 7]) to price several lengths. Derives the check-out date from each check-in date, so it replaces checkout_date rather than joining it."
        +}
      • changedInput schema / required
        Previous value: -[
        -  "hotel_name",
        -  "checkin_date",
        -  "checkout_date"
        -]New value: +[
        +  "hotel_name"
        +]
      • changedOutput schema / description
        Previous value: -"A completed hotel search. The hotels upstream reports no search-status header, so these results carry no search_status field."New value: +"A completed hotel search. A single stay carries no search_status: the hotels upstream reports no search-status header, and one call either answered or raised. A DATE-RANGE search does carry one, derived from the fan-out rather than from the upstream -- some of its stays can fail while others answer, and `results` then holds only the cheapest stay's properties, so `stays` is where the shape of the answer lives."
      • addedOutput schema / properties / caveats
        Added value: +{
        +  "description": "Sentences that must be read before one source is called cheaper than another -- differing rating scales, differing tax treatment, differing currencies, a source that did not answer.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / cheapest_overall
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "properties": {
        +        "checkin_date": {
        +          "type": "string"
        +        },
        +        "checkout_date": {
        +          "type": "string"
        +        },
        +        "currency": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "nights": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "price_per_night": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "property": {
        +          "anyOf": [
        +            {
        +              "additionalProperties": true,
        +              "type": "object"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."
        +        },
        +        "total": {
        +          "type": "number"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The cheapest stay across everything priced, or null when nothing was. `results` holds this stay's full property list."
        +}
      • addedOutput schema / properties / partial
        Added value: +{
        +  "description": "Present when some stays failed but others were priced. Plain text saying how much of the request the answer covers.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / providers
        Added value: +{
        +  "description": "One entry per source that was called, in the order they were requested. Only present when `providers` named more than the default source.",
        +  "items": {
        +    "additionalProperties": true,
        +    "description": "What one accommodation source answered. Present for every source that was CALLED, whether or not it answered: a source with search_status 'degraded' carries a reason, a null count and no prices, which is not the same answer as a source that found nothing.",
        +    "properties": {
        +      "cheapest_link": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "cheapest_name": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "cheapest_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "count": {
        +        "anyOf": [
        +          {
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "How many properties from this source carried a price. Null when the source did not answer -- zero would read as 'nothing there', which a failed search does not know."
        +      },
        +      "currency": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "The currency THIS row's totals are in. Rows in different currencies are not comparable and nothing is converted."
        +      },
        +      "detail": {
        +        "description": "Plain text for the model to relay to a human.",
        +        "type": "string"
        +      },
        +      "median_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "provider": {
        +        "description": "Which source this row is about, e.g. 'booking'.",
        +        "type": "string"
        +      },
        +      "rating_scale": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "What a review score from this source is out of: 10 on Booking, 5 on Airbnb. Read it before comparing two scores."
        +      },
        +      "retrieved_at": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "When these rows were read, taken from the rows themselves rather than from when this answer was assembled."
        +      },
        +      "search_reason": {
        +        "type": "string"
        +      },
        +      "search_status": {
        +        "description": "'ok': the source answered with priced results. 'empty': it answered and had nothing for that stay -- a real answer. 'degraded': it was asked and could not answer, so count is null and an empty list from it means nothing.",
        +        "enum": [
        +          "ok",
        +          "empty",
        +          "degraded",
        +          "skipped"
        +        ],
        +        "type": "string"
        +      },
        +      "taxes_included": {
        +        "anyOf": [
        +          {
        +            "type": "boolean"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Whether this source's totals include tax. Null means it has not been established for that source, not that tax is excluded."
        +      },
        +      "top": {
        +        "description": "The cheapest few priced rows from this source.",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "provider",
        +      "search_status"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / providers_skipped
        Added value: +{
        +  "description": "Sources that were NOT called, each named with why and where to subscribe. A source here contributed nothing to results and is counted nowhere. It is listed rather than dropped because a silently missing source is indistinguishable from a source that had nothing.",
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "detail": {
        +        "type": "string"
        +      },
        +      "provider": {
        +        "type": "string"
        +      },
        +      "reason": {
        +        "description": "'no_key': no RapidAPI key for that source's listing arrived with the call. 'not_subscribed': the key supplied is not subscribed to that listing. 'key_rejected': the key was refused outright.",
        +        "type": "string"
        +      },
        +      "subscribe_url": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "provider",
        +      "reason"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / results_for_stay
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Which stay `results` belongs to on a date-range search, or null when nothing was priced. Without it the rows read as 'the search's results' and get quoted against the wrong dates."
        +}
      • addedOutput schema / properties / search_coverage
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "What was actually priced on a date-range search. Present whether or not the request was truncated, so a model can state honestly what its answer rests on.",
        +  "properties": {
        +    "checkin_dates_searched": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "max_searches_per_request": {
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "requested_combinations": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "searched_combinations": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "stays_searched": {
        +      "description": "The exact date pairs priced.",
        +      "items": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "checkin_date": {
        +            "type": "string"
        +          },
        +          "checkout_date": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "description": "True when the request expanded past this call's spend ceiling and was sampled. A stay absent from stays_searched was never priced, which is not the same as having no rooms.",
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / search_status
        Added value: +{
        +  "description": "Date-range searches only. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry.",
        +  "enum": [
        +    "ok",
        +    "empty",
        +    "partial",
        +    "degraded"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / stays
        Added value: +{
        +  "description": "One entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it.\n\nRead this rather than inferring coverage from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that.",
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "cheapest": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."
        +      },
        +      "cheapest_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "checkin_date": {
        +        "type": "string"
        +      },
        +      "checkout_date": {
        +        "type": "string"
        +      },
        +      "currency": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "median_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Median stay total over this stay's priced properties -- what the date costs generally, next to what its one cheapest room costs."
        +      },
        +      "nights": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "price_per_night": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "cheapest_total divided by nights, rounded."
        +      },
        +      "priced_count": {
        +        "anyOf": [
        +          {
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "How many of those carried a price. The others are not evidence about what the stay costs."
        +      },
        +      "property_count": {
        +        "anyOf": [
        +          {
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Properties returned for this stay. Null when it was not searched or its search errored."
        +      },
        +      "reason": {
        +        "enum": [
        +          "ok",
        +          "no_availability",
        +          "no_price",
        +          "search_failed",
        +          "not_searched"
        +        ],
        +        "type": "string"
        +      },
        +      "search_status": {
        +        "enum": [
        +          "ok",
        +          "empty",
        +          "degraded",
        +          "not_searched"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "checkin_date",
        +      "checkout_date",
        +      "search_status",
        +      "reason"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
    • Changedsearch_hotels24 fields changed
      • addedInput schema / properties / checkin_date / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / checkin_date / default
        Added value: +null
      • changedInput schema / properties / checkin_date / description
        Previous value: -"First night of the stay, \"YYYY-MM-DD\"."New value: +"First night of the stay, \"YYYY-MM-DD\". Give this with checkout_date for one stay, or use checkin_date_from plus checkin_date_to for a range of check-in dates."
      • removedInput schema / properties / checkin_date / type
        Removed value: -"string"
      • addedInput schema / properties / checkin_date_from
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "First check-in date of a range, \"YYYY-MM-DD\". Needs checkin_date_to and nights, and prices one stay per check-in date in the range -- the hotel equivalent of the flights date range."
        +}
      • addedInput schema / properties / checkin_date_to
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Last check-in date of the range, \"YYYY-MM-DD\"."
        +}
      • addedInput schema / properties / checkout_date / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / checkout_date / default
        Added value: +null
      • changedInput schema / properties / checkout_date / description
        Previous value: -"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date."New value: +"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date. Give either this or nights, not both."
      • removedInput schema / properties / checkout_date / type
        Removed value: -"string"
      • addedInput schema / properties / max_searches
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Cap the billed requests this call may make. One stay is one request, so a 30-day range at two lengths is 60; lower this to spend less and the range is sampled evenly across the calendar rather than cut short at the front."
        +}
      • addedInput schema / properties / nights
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "integer"
        +    },
        +    {
        +      "items": {
        +        "type": "integer"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "How many nights to stay, as a number (3) or a list ([2, 3, 7]) to price several lengths. Derives the check-out date from each check-in date, so it replaces checkout_date rather than joining it."
        +}
      • addedInput schema / properties / providers
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Which sources to price this stay on, e.g. [\"booking\"], [\"airbnb\"] or [\"booking\", \"airbnb\"]. Defaults to [\"booking\"]. Each source is a separate RapidAPI subscription, so a source you have no key for is not called; it comes back named in providers_skipped with the reason and where to subscribe, rather than silently missing. filters and price_as_seen_from apply to booking only; airbnb takes price_min, price_max and room_types instead, and rows from it carry rating_scale 5 where booking's carry 10."
        +}
      • changedInput schema / required
        Previous value: -[
        -  "destination",
        -  "checkin_date",
        -  "checkout_date"
        -]New value: +[
        +  "destination"
        +]
      • changedOutput schema / description
        Previous value: -"A completed hotel search. The hotels upstream reports no search-status header, so these results carry no search_status field."New value: +"A completed hotel search. A single stay carries no search_status: the hotels upstream reports no search-status header, and one call either answered or raised. A DATE-RANGE search does carry one, derived from the fan-out rather than from the upstream -- some of its stays can fail while others answer, and `results` then holds only the cheapest stay's properties, so `stays` is where the shape of the answer lives."
      • addedOutput schema / properties / caveats
        Added value: +{
        +  "description": "Sentences that must be read before one source is called cheaper than another -- differing rating scales, differing tax treatment, differing currencies, a source that did not answer.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / cheapest_overall
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "properties": {
        +        "checkin_date": {
        +          "type": "string"
        +        },
        +        "checkout_date": {
        +          "type": "string"
        +        },
        +        "currency": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "nights": {
        +          "anyOf": [
        +            {
        +              "type": "integer"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "price_per_night": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "property": {
        +          "anyOf": [
        +            {
        +              "additionalProperties": true,
        +              "type": "object"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."
        +        },
        +        "total": {
        +          "type": "number"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The cheapest stay across everything priced, or null when nothing was. `results` holds this stay's full property list."
        +}
      • addedOutput schema / properties / partial
        Added value: +{
        +  "description": "Present when some stays failed but others were priced. Plain text saying how much of the request the answer covers.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / providers
        Added value: +{
        +  "description": "One entry per source that was called, in the order they were requested. Only present when `providers` named more than the default source.",
        +  "items": {
        +    "additionalProperties": true,
        +    "description": "What one accommodation source answered. Present for every source that was CALLED, whether or not it answered: a source with search_status 'degraded' carries a reason, a null count and no prices, which is not the same answer as a source that found nothing.",
        +    "properties": {
        +      "cheapest_link": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "cheapest_name": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "cheapest_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "count": {
        +        "anyOf": [
        +          {
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "How many properties from this source carried a price. Null when the source did not answer -- zero would read as 'nothing there', which a failed search does not know."
        +      },
        +      "currency": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "The currency THIS row's totals are in. Rows in different currencies are not comparable and nothing is converted."
        +      },
        +      "detail": {
        +        "description": "Plain text for the model to relay to a human.",
        +        "type": "string"
        +      },
        +      "median_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "provider": {
        +        "description": "Which source this row is about, e.g. 'booking'.",
        +        "type": "string"
        +      },
        +      "rating_scale": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "What a review score from this source is out of: 10 on Booking, 5 on Airbnb. Read it before comparing two scores."
        +      },
        +      "retrieved_at": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "When these rows were read, taken from the rows themselves rather than from when this answer was assembled."
        +      },
        +      "search_reason": {
        +        "type": "string"
        +      },
        +      "search_status": {
        +        "description": "'ok': the source answered with priced results. 'empty': it answered and had nothing for that stay -- a real answer. 'degraded': it was asked and could not answer, so count is null and an empty list from it means nothing.",
        +        "enum": [
        +          "ok",
        +          "empty",
        +          "degraded",
        +          "skipped"
        +        ],
        +        "type": "string"
        +      },
        +      "taxes_included": {
        +        "anyOf": [
        +          {
        +            "type": "boolean"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Whether this source's totals include tax. Null means it has not been established for that source, not that tax is excluded."
        +      },
        +      "top": {
        +        "description": "The cheapest few priced rows from this source.",
        +        "items": {
        +          "additionalProperties": true,
        +          "type": "object"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "required": [
        +      "provider",
        +      "search_status"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / providers_skipped
        Added value: +{
        +  "description": "Sources that were NOT called, each named with why and where to subscribe. A source here contributed nothing to results and is counted nowhere. It is listed rather than dropped because a silently missing source is indistinguishable from a source that had nothing.",
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "detail": {
        +        "type": "string"
        +      },
        +      "provider": {
        +        "type": "string"
        +      },
        +      "reason": {
        +        "description": "'no_key': no RapidAPI key for that source's listing arrived with the call. 'not_subscribed': the key supplied is not subscribed to that listing. 'key_rejected': the key was refused outright.",
        +        "type": "string"
        +      },
        +      "subscribe_url": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "provider",
        +      "reason"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / results_for_stay
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Which stay `results` belongs to on a date-range search, or null when nothing was priced. Without it the rows read as 'the search's results' and get quoted against the wrong dates."
        +}
      • addedOutput schema / properties / search_coverage
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "What was actually priced on a date-range search. Present whether or not the request was truncated, so a model can state honestly what its answer rests on.",
        +  "properties": {
        +    "checkin_dates_searched": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "max_searches_per_request": {
        +      "minimum": 1,
        +      "type": "integer"
        +    },
        +    "note": {
        +      "type": "string"
        +    },
        +    "requested_combinations": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "searched_combinations": {
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "stays_searched": {
        +      "description": "The exact date pairs priced.",
        +      "items": {
        +        "additionalProperties": true,
        +        "properties": {
        +          "checkin_date": {
        +            "type": "string"
        +          },
        +          "checkout_date": {
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "truncated": {
        +      "description": "True when the request expanded past this call's spend ceiling and was sampled. A stay absent from stays_searched was never priced, which is not the same as having no rooms.",
        +      "type": "boolean"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedOutput schema / properties / search_status
        Added value: +{
        +  "description": "Date-range searches only. 'ok': every stay searched was priced. 'empty': they all answered and none had priced availability -- a real answer. 'partial': some stays were priced and some errored. 'degraded': every stay errored, so nothing is known; safe to retry.",
        +  "enum": [
        +    "ok",
        +    "empty",
        +    "partial",
        +    "degraded"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / stays
        Added value: +{
        +  "description": "One entry per stay the REQUEST asked for, in request order, present whether or not that stay was priced. Only on a date-range search (checkin_date_from / checkin_date_to / nights); a single stay does not carry it.\n\nRead this rather than inferring coverage from `results`: `results` holds the full property list for the CHEAPEST stay only, so a stay missing from it looks identical to a stay that had nothing. `reason` says which kind of hole an unpriced stay is: 'no_availability' (searched, answered, nothing came back), 'no_price' (properties came back, none carried a price), 'search_failed' (the search errored, so nothing is known -- not 'no rooms') or 'not_searched' (the per-call fan-out cap sampled it away). Counts are null rather than zero on those last two, because zero reads as 'nothing there' and neither case knows that.",
        +  "items": {
        +    "additionalProperties": true,
        +    "properties": {
        +      "cheapest": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": true,
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "The cheapest priced property for this stay, or null when it has none. The same row the upstream returned, minus its image URL: on a measured search 73% of the payload was URLs, and an image CDN link is the half no model can open. The booking link is kept."
        +      },
        +      "cheapest_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "checkin_date": {
        +        "type": "string"
        +      },
        +      "checkout_date": {
        +        "type": "string"
        +      },
        +      "currency": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "median_total": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Median stay total over this stay's priced properties -- what the date costs generally, next to what its one cheapest room costs."
        +      },
        +      "nights": {
        +        "anyOf": [
        +          {
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "price_per_night": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "cheapest_total divided by nights, rounded."
        +      },
        +      "priced_count": {
        +        "anyOf": [
        +          {
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "How many of those carried a price. The others are not evidence about what the stay costs."
        +      },
        +      "property_count": {
        +        "anyOf": [
        +          {
        +            "minimum": 0,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Properties returned for this stay. Null when it was not searched or its search errored."
        +      },
        +      "reason": {
        +        "enum": [
        +          "ok",
        +          "no_availability",
        +          "no_price",
        +          "search_failed",
        +          "not_searched"
        +        ],
        +        "type": "string"
        +      },
        +      "search_status": {
        +        "enum": [
        +          "ok",
        +          "empty",
        +          "degraded",
        +          "not_searched"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "checkin_date",
        +      "checkout_date",
        +      "search_status",
        +      "reason"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
  4. 2 tool updates
    • Changedfind_hotel_by_name1 field changed
      • changedInput schema / properties / price_as_seen_from / description
        Previous value: -"Two-letter country code, e.g. \"de\". Prices the stay as a shopper resident in that country would see it, which is what makes a rate-parity check on one property possible."New value: +"Two-letter country code, e.g. \"de\". Prices the stay as a shopper resident in that country would see it. Call each country a few times on this same property before reporting a gap, because rates move between calls and gaps are usually modest and property-dependent."
    • Changedsearch_hotels1 field changed
      • changedInput schema / properties / price_as_seen_from / description
        Previous value: -"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. This is what makes rate-parity and geo-pricing checks possible; omit it for a neutral price."New value: +"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. For a rate-parity check hold one named property fixed and call each country a few times, because rates move between calls and one call per country can show a gap that is not there. Omit it for a neutral price."
  5. 2 tool updates
    • Changedfind_hotel_by_name4 fields changed
      • addedOutput schema / description
        Added value: +"A completed hotel search. The hotels upstream reports no search-status header, so these results carry no search_status field."
      • addedOutput schema / properties
        Added value: +{
        +  "api_usage": {
        +    "additionalProperties": true,
        +    "description": "What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed.",
        +    "properties": {
        +      "note": {
        +        "description": "The same figures as a sentence, for the model to relay.",
        +        "type": "string"
        +      },
        +      "plan_requests_limit": {
        +        "type": "integer"
        +      },
        +      "plan_requests_remaining": {
        +        "type": "integer"
        +      },
        +      "requests_used_by_this_call": {
        +        "minimum": 0,
        +        "type": "integer"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "applied_filters": {
        +    "description": "Which of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through."
        +  },
        +  "message": {
        +    "type": "string"
        +  },
        +  "needs_api_key": {
        +    "description": "True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it.",
        +    "type": "boolean"
        +  },
        +  "quota_exhausted": {
        +    "description": "True when the caller's RapidAPI plan has no requests left for the current period.",
        +    "type": "boolean"
        +  },
        +  "result_count": {
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "results": {
        +    "description": "The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'.",
        +    "items": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  "signup_url": {
        +    "description": "Where the caller subscribes or changes plan.",
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "results"
        +]
      • addedOutput schema / title
        Added value: +"Hotel search result"
    • Changedsearch_hotels4 fields changed
      • addedOutput schema / description
        Added value: +"A completed hotel search. The hotels upstream reports no search-status header, so these results carry no search_status field."
      • addedOutput schema / properties
        Added value: +{
        +  "api_usage": {
        +    "additionalProperties": true,
        +    "description": "What this call cost the caller's own RapidAPI plan, and what remains on it. Present on every response that reached the upstream, including a degraded one -- a search that failed was still billed.",
        +    "properties": {
        +      "note": {
        +        "description": "The same figures as a sentence, for the model to relay.",
        +        "type": "string"
        +      },
        +      "plan_requests_limit": {
        +        "type": "integer"
        +      },
        +      "plan_requests_remaining": {
        +        "type": "integer"
        +      },
        +      "requests_used_by_this_call": {
        +        "minimum": 0,
        +        "type": "integer"
        +      }
        +    },
        +    "type": "object"
        +  },
        +  "applied_filters": {
        +    "description": "Which of the requested filters the upstream actually applied. Untyped: the shape is the upstream's, echoed through."
        +  },
        +  "message": {
        +    "type": "string"
        +  },
        +  "needs_api_key": {
        +    "description": "True when no usable RapidAPI key arrived with the call, or the upstream rejected the one that did. No search was run and nothing was billed; signup_url and message say how to fix it.",
        +    "type": "boolean"
        +  },
        +  "quota_exhausted": {
        +    "description": "True when the caller's RapidAPI plan has no requests left for the current period.",
        +    "type": "boolean"
        +  },
        +  "result_count": {
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "results": {
        +    "description": "The itineraries or properties found, already sorted and deduplicated. An empty array is only meaningful when search_status is 'empty'.",
        +    "items": {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  "signup_url": {
        +    "description": "Where the caller subscribes or changes plan.",
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "results"
        +]
      • addedOutput schema / title
        Added value: +"Hotel search result"
  6. 2 tool updates
    • Changedfind_hotel_by_name7 fields changed
      • addedInput schema / properties / adults / description
        Added value: +"Number of adult guests."
      • addedInput schema / properties / checkin_date / description
        Added value: +"First night of the stay, \"YYYY-MM-DD\"."
      • addedInput schema / properties / checkout_date / description
        Added value: +"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date."
      • addedInput schema / properties / children / description
        Added value: +"Number of children sharing the room."
      • addedInput schema / properties / currency / description
        Added value: +"ISO currency code for the prices returned, e.g. \"usd\"."
      • addedInput schema / properties / hotel_name / description
        Added value: +"The property name a person would type, e.g. \"Hotel Artemide\". Adding the city (\"Hotel Artemide Rome\") disambiguates a chain with many properties. No internal property ID is needed."
      • addedInput schema / properties / price_as_seen_from / description
        Added value: +"Two-letter country code, e.g. \"de\". Prices the stay as a shopper resident in that country would see it, which is what makes a rate-parity check on one property possible."
    • Changedsearch_hotels9 fields changed
      • addedInput schema / properties / adults / description
        Added value: +"Number of adult guests. Defaults to the upstream default when omitted."
      • addedInput schema / properties / budget_per_night / description
        Added value: +"Only return properties at or below this nightly price, in `currency`."
      • addedInput schema / properties / checkin_date / description
        Added value: +"First night of the stay, \"YYYY-MM-DD\"."
      • addedInput schema / properties / checkout_date / description
        Added value: +"Departure morning, \"YYYY-MM-DD\". Must be after checkin_date."
      • addedInput schema / properties / children / description
        Added value: +"Number of children sharing the room."
      • addedInput schema / properties / currency / description
        Added value: +"ISO currency code for the prices returned, e.g. \"usd\"."
      • addedInput schema / properties / destination / description
        Added value: +"Where to stay, in free text the way a person would say it, e.g. \"Rome\" or \"Tokyo Shibuya\". A city, district, landmark or region all work; no internal location ID is needed."
      • addedInput schema / properties / filters / description
        Added value: +"Property filters to apply, e.g. [\"free_cancellation\", \"breakfast_included\"]. An unknown name is rejected with the list of valid ones rather than being ignored."
      • addedInput schema / properties / price_as_seen_from / description
        Added value: +"Two-letter country code, e.g. \"de\". Prices the stay through a residential connection in that country, so the result is what a shopper resident there would be quoted. This is what makes rate-parity and geo-pricing checks possible; omit it for a neutral price."
  7. 2 tool updates
    • First observedfind_hotel_by_name
    • First observedsearch_hotels

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides two MCP servers: one for searching real-time flight prices via FlightAPI.io and another for hotel prices via Booking.com through RapidAPI, both accessible over Streamable HTTP.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Book hotels worldwide — search, price, prebook & book across 249 countries. 65 tools for hotel search, flights, loyalty, analytics. Zero API keys needed. at best prices for hotels 3 M+ property
    5 npm
    1
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Hotel booking MCP server — the first transaction-complete hotel booking integration for AI agents. Search 300K+ properties in 140+ countries, get live rates and room details, and generate secure checkout URLs. No payment in the AI conversation — guests complete booking at a hosted checkout page and receive a real hotel confirmation number. Set your own booking fee via Stripe Connect.
    8
    33 npm
    3
    -
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.