BookHotels.direct MCP
An MCP server that allows AI assistants to compare hotel prices on a hotel's own website against Booking.com for the same stay, providing a verdict on which is cheaper without taking bookings or payments.
Endpoint and access
No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.
https://bookhotels.direct/mcpWhat you can do with it
- Check if a hotel is cheaper on its own website than on Booking.com
- Report hotel price details for a specific stay
- Report when a traveller books after a price check
Source and maintenance
Protocol and capabilities
- Server
- bookhotels-direct 0.62.0
- MCP protocol
- 2025-06-18
- Tools
- 3 advertised
- Resources
- 1 advertised
- Resource templates
- 0 advertised
- Prompts
- Not advertised
{
"tools": {
"listChanged": false
},
"resources": {
"listChanged": false
}
}Server-provided instructions
Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.
Tools
3 advertised
check_direct_price — Check the hotel's own price against Booking.com
Checks whether a hotel is cheaper on its own website than on Booking.com, for one stay. Give the hotel, the dates, the guests and, when you have it, the total Booking.com shows for the whole stay with its meal plan and cancellation terms. BookHotels.direct reads the hotel's own booking site live, applying the public promo codes and free-club prices it knows for that hotel, or uses a traveller's read of the same stay from the last 24 hours, and compares like for like: same hotel, dates and guests, with every difference in room, meal plan or cancellation stated. The answer is honest either way: when Booking.com is cheaper, it says so. When the hotel's site cannot be read automatically, the answer gives the link to the hotel's own site for these dates and asks you to report the prices shown there with report_hotel_price. Without a Booking.com total, the answer gives the hotel's own price and, when the evidence allows, an estimated saving, always labelled as an estimate with its basis. Only Booking.com prices can be compared. One room per check.
{
"type": "object",
"required": [
"hotel",
"checkin",
"checkout"
],
"properties": {
"city": {
"type": "string",
"description": "The town or city the hotel is in, e.g. \"Sitges\". Helps find hotels we have not checked before."
},
"hotel": {
"type": "string",
"description": "The hotel's name as the traveller sees it, e.g. \"Hotel Calipolis\"."
},
"adults": {
"type": "integer",
"maximum": 8,
"minimum": 1,
"description": "Number of adults (default 2)."
},
"checkin": {
"type": "string",
"description": "Check-in date, YYYY-MM-DD."
},
"checkout": {
"type": "string",
"description": "Check-out date, YYYY-MM-DD."
},
"language": {
"enum": [
"en",
"es"
],
"type": "string",
"description": "Language of the check page for the traveller (default en)."
},
"booking_url": {
"type": "string",
"description": "Optional: the Booking.com address of the hotel's page (https://www.booking.com/hotel/…). Only the address is read, to recognise the hotel and the dates; the page is never opened."
},
"booking_room": {
"type": "string",
"description": "The room name of the Booking.com offer, when shown."
},
"booking_total": {
"type": "number",
"description": "The total Booking.com shows for the whole stay, in euros, when known. Without it you get the hotel's own price and, when the evidence allows, an estimated saving.",
"exclusiveMinimum": 0
},
"children_ages": {
"type": "array",
"items": {
"type": "integer",
"maximum": 17,
"minimum": 0
},
"maxItems": 6,
"description": "Each child's age on the day of check-out, one number per child. Leave out when no children travel. Hotels price children by age, so ages are needed for families."
},
"booking_meal_plan": {
"enum": [
"room_only",
"breakfast",
"half_board",
"full_board",
"all_inclusive"
],
"type": "string",
"description": "The meal plan of the Booking.com offer, when Booking.com shows it."
},
"booking_taxes_extra": {
"type": "number",
"minimum": 0,
"description": "Taxes Booking.com lists on top of its total, in euros (e.g. a city tax), when shown."
},
"booking_cancellation": {
"enum": [
"free",
"non_refundable",
"partial"
],
"type": "string",
"description": "The cancellation terms of the Booking.com offer, when Booking.com shows them: free cancellation, non-refundable, or partly refundable."
},
"booking_taxes_included": {
"type": "boolean",
"description": "true when Booking.com says its total includes taxes and charges; false when it lists taxes on top."
}
},
"additionalProperties": false
}{
"title": "Check the hotel's own price",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}report_hotel_price — Report the prices seen on the hotel's own site
After check_direct_price asked you to open the hotel's own website for a stay, report the prices that site showed for the same dates and guests, and get the honest comparison with Booking.com. Give the check_id from check_direct_price and one entry per room or rate you saw, each with its total for the whole stay in euros and, when shown, its meal plan and cancellation terms. Report only what the hotel's own site showed; leave a field out when the site did not say it. The report is kept anonymously so the next traveller asking about the same stay gets an answer at once.
{
"type": "object",
"required": [
"offers"
],
"properties": {
"city": {
"type": "string",
"description": "The town or city the hotel is in, e.g. \"Sitges\". Helps find hotels we have not checked before."
},
"hotel": {
"type": "string",
"description": "The hotel's name as the traveller sees it, e.g. \"Hotel Calipolis\"."
},
"adults": {
"type": "integer",
"maximum": 8,
"minimum": 1,
"description": "Number of adults (default 2)."
},
"offers": {
"type": "array",
"items": {
"type": "object",
"required": [
"total"
],
"properties": {
"code": {
"type": "string",
"description": "A promo code the hotel's site shows publicly and that this price uses, if any."
},
"rate": {
"type": "string",
"description": "Rate name, when shown (e.g. \"Non refundable\", \"Web offer\")."
},
"room": {
"type": "string",
"description": "Room name as the hotel's site shows it."
},
"total": {
"type": "number",
"description": "Total for the whole stay, in euros.",
"exclusiveMinimum": 0
},
"meal_plan": {
"enum": [
"room_only",
"breakfast",
"half_board",
"full_board",
"all_inclusive"
],
"type": "string"
},
"tourist_tax": {
"type": "number",
"minimum": 0,
"description": "The tourist tax amount for the stay, when the site states it."
},
"cancellation": {
"enum": [
"free",
"non_refundable",
"partial"
],
"type": "string"
},
"member_price": {
"type": "boolean",
"description": "true when this is a price for members of the hotel's free club."
},
"tourist_tax_included": {
"type": "boolean",
"description": "true when the site says the total includes the local tourist tax; false when it says the tax comes on top or is paid at the hotel."
}
},
"additionalProperties": false
},
"maxItems": 12,
"minItems": 1,
"description": "The rooms and rates the hotel's own site showed for the stay."
},
"checkin": {
"type": "string",
"description": "Check-in date, YYYY-MM-DD."
},
"check_id": {
"type": "string",
"description": "The check_id returned by check_direct_price."
},
"checkout": {
"type": "string",
"description": "Check-out date, YYYY-MM-DD."
},
"page_url": {
"type": "string",
"description": "The address of the hotel's page where you saw the prices (only its host is kept)."
},
"booking_url": {
"type": "string",
"description": "Optional: the Booking.com address of the hotel's page (https://www.booking.com/hotel/…). Only the address is read, to recognise the hotel and the dates; the page is never opened."
},
"booking_room": {
"type": "string",
"description": "The room name of the Booking.com offer, when shown."
},
"booking_total": {
"type": "number",
"description": "The total Booking.com shows for the whole stay, in euros, when known. Without it you get the hotel's own price and, when the evidence allows, an estimated saving.",
"exclusiveMinimum": 0
},
"children_ages": {
"type": "array",
"items": {
"type": "integer",
"maximum": 17,
"minimum": 0
},
"maxItems": 6,
"description": "Each child's age on the day of check-out, one number per child. Leave out when no children travel. Hotels price children by age, so ages are needed for families."
},
"booking_meal_plan": {
"enum": [
"room_only",
"breakfast",
"half_board",
"full_board",
"all_inclusive"
],
"type": "string",
"description": "The meal plan of the Booking.com offer, when Booking.com shows it."
},
"booking_taxes_extra": {
"type": "number",
"minimum": 0,
"description": "Taxes Booking.com lists on top of its total, in euros (e.g. a city tax), when shown."
},
"booking_cancellation": {
"enum": [
"free",
"non_refundable",
"partial"
],
"type": "string",
"description": "The cancellation terms of the Booking.com offer, when Booking.com shows them: free cancellation, non-refundable, or partly refundable."
},
"booking_taxes_included": {
"type": "boolean",
"description": "true when Booking.com says its total includes taxes and charges; false when it lists taxes on top."
}
},
"additionalProperties": false
}{
"title": "Report the hotel's prices",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}report_booking — Report that the traveller booked
When the traveller tells you they booked a hotel after a check_direct_price answer, report whether they booked it on the hotel's own website, with the check_id. Only report what the traveller told you. Nothing about the traveller is sent or kept: only that the check led to a booking, and its total when given.
{
"type": "object",
"required": [
"check_id",
"booked_direct"
],
"properties": {
"check_id": {
"type": "string",
"description": "The check_id returned by check_direct_price."
},
"total_paid": {
"type": "number",
"description": "The total the traveller says they paid, in euros, when they say it.",
"exclusiveMinimum": 0
},
"booked_direct": {
"type": "boolean",
"description": "true when the traveller booked on the hotel's own website; false when they booked elsewhere or not at all."
}
},
"additionalProperties": false
}{
"title": "Report a booking",
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}Prompts
Not advertised
Resources
1 advertised
check-card — BookHotels.direct check card
The verdict of a check: both prices or the estimate, the hotel's offer, and the link to book on the hotel's own site.
ui://bookhotels-direct/check-card-v1.html30-day availability
Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.
- Successful checks
- 1 of 1 (100%)
- Average latency
- 574 ms
- 95th percentile latency
- 574 ms
Maintenance history
Public check and source-refresh events. Editorial and ownership records remain private.
- · probe · passed · 574 ms · metadata changed · 3 tool(s), 1 resource(s), 0 resource template(s)
Connect from your client
Each snippet registers the same endpoint; pick the client you use.
Claude Code
claude mcp add --transport http bookhotels-direct-mcp https://bookhotels.direct/mcpCodex
codex mcp add bookhotels-direct-mcp --url https://bookhotels.direct/mcpCursor
{
"mcpServers": {
"bookhotels-direct-mcp": {
"url": "https://bookhotels.direct/mcp"
}
}
}Cline
{
"mcpServers": {
"bookhotels-direct-mcp": {
"type": "streamableHttp",
"url": "https://bookhotels.direct/mcp",
"disabled": false
}
}
}VS Code
{
"servers": {
"bookhotels-direct-mcp": {
"type": "http",
"url": "https://bookhotels.direct/mcp"
}
}
}Gemini CLI
gemini mcp add --transport http bookhotels-direct-mcp https://bookhotels.direct/mcpClaude Desktop
{
"mcpServers": {
"bookhotels-direct-mcp": {
"url": "https://bookhotels.direct/mcp"
}
}
}Windsurf
{
"mcpServers": {
"bookhotels-direct-mcp": {
"serverUrl": "https://bookhotels.direct/mcp"
}
}
}Let your agent find its tools
Find servers like BookHotels.direct MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.
Other commerce servers
Do you run BookHotels.direct MCP?
Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.