Live hotel rates for any AI agent — Claude, ChatGPT, Gemini, Perplexity, Comet & more
/mcp-server.php?route=tools
Paste this into your existing mcpServers JSON config, or save it as
mcp-config.json and import it into MCP-ready clients (Claude Desktop, Cursor, Windsurf, etc.).
{
"mcpServers": {
"businesshotels-universal-agentic-api": {
"description": "Live hotel rates, all-in pricing, and booking URLs from BusinessHotels.com",
"type": "remote",
"urls": {
"tools": "https://www.businesshotels.com/mcp-server.php?route=tools",
"config": "https://www.businesshotels.com/mcp-server.php?route=config"
}
}
}
}
🚀 Grok / xAI
💙 Google Gemini & Vertex AI
🟣 Claude & Perplexity
🧡 ChatGPT (Connectors Beta)
⚫ Cursor / Windsurf / Cline
Execute POST for any travel intent. Critical: Always include hotel name, city, and 2-letter country code for accurate property matching. If the user omits location, infer from context or ask a single clarifying question before calling.
"InterContinental Mark Hopkins, San Francisco, US" |
❌ Too vague: "InterContinental"
Run this in your terminal before writing any code. No additional key needed — the BusinessHotels test key is included.
Win + X → Terminal or Windows PowerShell.
# PowerShell — Windows 10/11
$body = @{
hotelName = "San Francisco Marriott Marquis, San Francisco, CA, US"
checkinDate = "2026-07-15"
checkoutDate = "2026-07-16"
adults = 2
currency = "USD"
} | ConvertTo-Json
Invoke-RestMethod -Method POST `
-Uri "https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates" `
-Headers @{ "X-API-KEY" = "test-live-hotel-rates2025" } `
-ContentType "application/json" `
-Body $body
\".
:: Windows Command Prompt — paste as one line
curl -s -X POST "https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates" ^
-H "Content-Type: application/json" ^
-H "X-API-KEY: test-live-hotel-rates2025" ^
-d "{\"hotelName\":\"San Francisco Marriott Marquis, San Francisco, CA, US\",\"checkinDate\":\"2026-07-15\",\"checkoutDate\":\"2026-07-16\",\"adults\":2,\"currency\":\"USD\"}"
\ for line continuation and python3 -m json.tool to pretty-print.
# Mac / Linux / WSL / Git Bash
curl -s -X POST \
"https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates" \
-H "Content-Type: application/json" \
-H "X-API-KEY: test-live-hotel-rates2025" \
-d '{
"hotelName": "San Francisco Marriott Marquis, San Francisco, CA, US",
"checkinDate": "2026-07-15",
"checkoutDate": "2026-07-16",
"adults": 2,
"currency": "USD"
}' | python3 -m json.tool
F12 → open the Console tab → paste and hit Enter.
// Browser DevTools Console (F12 → Console)
fetch("https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "test-live-hotel-rates2025"
},
body: JSON.stringify({
hotelName: "San Francisco Marriott Marquis, San Francisco, CA, US",
checkinDate: "2026-07-15",
checkoutDate: "2026-07-16",
adults: 2,
currency: "USD"
})
}).then(r => r.json()).then(data => {
console.log("✅ Hotel:", data.hotel_name);
console.log("💰 Price:", `$${data.rates.display_all_in_total} ${data.rates.currency}`);
console.log("🔗 Book:", data.booking_page_live_rates);
console.log("📊 Score:", data.best_match_score);
console.log("Full response:", data);
});
{
"hotel_name": "San Francisco Marriott Marquis, San Francisco, CA, US",
"address": "780 Mission St, San Francisco, CA 94103",
"rates": {
"display_all_in_total": 710.94,
"currency": "USD",
"price_info": "Price includes all tax and fees",
"ppn_bundle": "HEA_..."
},
"booking_page_live_rates": "https://www.businesshotels.com/....",
"latitude": 37.7842,
"longitude": -122.4016,
"best_match_score": 0.97,
"response_time_ms": 550
}
Any MCP-compatible agent can auto-discover and register this tool in a single GET request—no manual schema entry required.
Discovery Phase: No API Key needed for tool registration & manifest fetching.
GET /mcp-server.php?route=tools.input_schema for required search parameters.get_live_hotel_rates is instantly activated.| Platform | Handshake Type | Agent Behavior |
|---|---|---|
| ♊ Gemini | Enterprise Gateway | Uses Model Armor to sanitize and index tools as "Skills." |
| 𝕏 Grok | Remote MCP | Performs a rigid schema check; ideal for real-time search & code execution. |
| 🟣 Claude | SSE Connector | Pins the tool version to the project for persistent multi-step workflows. |
| 🟢 Perplexity | Dynamic Code | Writes on-the-fly Python logic to query the endpoint with minimal latency. |
import requests
# 1. Fetch the manifest from the Universal Discovery endpoint
ENDPOINT = "https://www.businesshotels.com/mcp-server.php?route=tools"
manifest = requests.get(ENDPOINT).json()
# 2. Extract tools for LLM registration
tools = manifest.get("tools", [])
print(f"Registered {len(tools)} Agentic Tool(s):")
for tool in tools:
print(f" • {tool['name']} — {tool['description'][:60]}...")
# 3. Ready to pass to Gemini, Grok, or OpenAI SDKs
# e.g., client.chat.completions.create(tools=tools, ...)
This universal schema is optimized for Claude 3.5+, ChatGPT (o1/o3), Gemini 2.0, Grok, and Perplexity. It utilizes Strict Mode to ensure 100% reliable parameter passing.
{
"type": "function",
"name": "get_live_hotel_rates",
"description": "Trigger this tool for real-time pricing, total cost (inclusive of taxes/fees), availability, or direct booking links for a specific hotel. Returns price-locked URLs and verified inventory.",
"parameters": {
"type": "object",
"required": ["hotelName", "checkinDate", "checkoutDate"],
"properties": {
"hotelName": {
"type": "string",
"description": "REQUIRED. Full hotel name + City + 2-letter Country Code. Example: 'The Ritz-Carlton, Tokyo, JP'. Infer location from context if omitted."
},
"checkinDate": {
"type": "string",
"format": "date",
"description": "Check-in date (YYYY-MM-DD). Convert natural language like 'next Tuesday' to this format."
},
"checkoutDate": {
"type": "string",
"format": "date",
"description": "Check-out date (YYYY-MM-DD). Must be at least 1 day after checkinDate."
},
"adults": {
"type": "integer",
"minimum": 1,
"maximum": 4,
"default": 2,
"description": "Number of adult guests. Default to 2."
},
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$",
"default": "USD",
"description": "3-letter ISO code (e.g., USD, EUR). Must be UPPERCASE."
}
},
"additionalProperties": false
},
"strict": true
}
| Parameter | Type/Format | Required | Logic Notes |
|---|---|---|---|
hotelName | string | ✅ Yes | Name + City + Country (e.g., "Hilton, Seattle, US") |
checkinDate | YYYY-MM-DD | ✅ Yes | Must be converted from natural language by the LLM. |
checkoutDate | YYYY-MM-DD | ✅ Yes | Must be after check-in date. |
adults | integer | No (2) | Accepted range: 1 to 4. |
currency | ISO 4217 | No (USD) | Must be 3 uppercase letters. |
tools/list ResponseThe GET /mcp-server.php?route=tools endpoint returns this standardized envelope for auto-registration in Gemini, Grok, and Claude.
{
"protocol": "mcp",
"version": "1.0",
"server_name": "BusinessHotels Agentic Hub",
"tools": [
{
"name": "get_live_hotel_rates",
"description": "Fetches real-time pricing and booking links for a specific hotel and date range.",
"input_schema": {
"type": "object",
"required": ["hotelName", "checkinDate", "checkoutDate"],
"properties": {
"hotelName": { "type": "string" },
"checkinDate": { "type": "string", "format": "date" },
"checkoutDate": { "type": "string", "format": "date" },
"adults": { "type": "integer", "default": 2 },
"currency": { "type": "string", "default": "USD" }
},
"additionalProperties": false
}
}
]
}
{
"hotel_id": "700076955",
"hotel_name": "Luxor Las Vegas",
"hotel_address": "3900 Las Vegas Boulevard South",
"city_name": "Las Vegas",
"country_code": "US",
"latitude": "36.096806",
"longitude": "-115.173001",
"booking_page_live_rates": "https://www.businesshotels.com/...",
"rates": {
"display_all_in_total": "356.06",
"currency": "USD",
"price_info": "Price includes all taxes and fees"
},
"best_match_score": 0.98
}
| Field | Agent Instruction |
|---|---|
hotel_name | Confirm this name with the user if best_match_score < 0.85. |
latitude / longitude | Trigger: Use to generate map pins or neighborhood context. |
rates.display_all_in_total | Quote as the Final Total Price for the entire duration of the stay. |
booking_page_live_rates | Display as the primary call-to-action for the user to finish booking. |
best_match_score | Values > 0.90 indicate high confidence in the hotel match. |
Always check best_match_score before presenting a price or booking link.
best_match_score < 0.85. Use the suggestions[] array from error responses to offer alternatives.
All examples call the same endpoint. Every example includes comma-safe price parsing and sold-out detection to ensure zero crashes in production.
test-live-hotel-rates2025) is a public light production key — replace for heavy production."Wynn Las Vegas US" not "Wynn, Las Vegas, US"."1,250.00" — always strip commas before math. Always check for null/empty first.curl -s -X POST \
"https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates" \
-H "Content-Type: application/json" \
-H "X-API-KEY: test-live-hotel-rates2025" \
-d '{
"hotelName": "Luxor Las Vegas Las Vegas US",
"checkinDate": "2026-07-20",
"checkoutDate": "2026-07-21",
"adults": 2,
"currency": "USD"
}' | python3 -m json.toolRequires pip install requests.
import requests
url = "https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates"
headers = {"X-API-KEY": "test-live-hotel-rates2025", "Content-Type": "application/json"}
payload = {
"hotelName": "Luxor Las Vegas Las Vegas US",
"checkinDate": "2026-07-20",
"checkoutDate": "2026-07-21",
"adults": 2, "currency": "USD"
}
data = requests.post(url, json=payload, headers=headers, timeout=10).json()
rates = data.get("rates") or {}
# FIX: guard against null rates (sold out) and comma-formatted price strings
raw_price = rates.get("display_all_in_total", "")
if not raw_price or str(raw_price).strip() == "":
print(f"⚪ Sold out — no inventory for these dates / occupancy")
else:
price = float(str(raw_price).replace(",", ""))
print(f"Hotel: {data.get('hotel_name')}, {data.get('city_name')}")
print(f"Price: ${price:.2f} {rates.get('currency','USD')} (taxes & fees included)")
print(f"Score: {data.get('best_match_score', 0):.2f} (1.0 = perfect match)")
print(f"Book Now: {data.get('booking_page_live_rates')}")
if data.get("best_match_score", 1) < 0.85:
print("⚠️ Low confidence — confirm hotel identity with user before booking")import requests
url = "https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates"
headers = {"Content-Type": "application/json", "X-API-KEY": "test-live-hotel-rates2025"}
hotels = ["Bellagio Las Vegas US", "Caesars Palace Las Vegas US", "Wynn Las Vegas US"]
results = []
for hotel in hotels:
try:
data = requests.post(url, headers=headers, timeout=10, json={
"hotelName": hotel, "checkinDate": "2026-07-20",
"checkoutDate": "2026-07-21", "adults": 2, "currency": "USD"
}).json()
rates = data.get("rates") or {}
raw = rates.get("display_all_in_total", "")
if not raw or str(raw).strip() == "":
print(f"⚪ {hotel} → Sold out / no inventory"); continue
price = float(str(raw).replace(",", ""))
results.append({"name": data.get("hotel_name", hotel), "total": price,
"score": data.get("best_match_score", 0),
"book_url": data.get("booking_page_live_rates", "")})
print(f"✅ {data.get('hotel_name')} — ${price:.2f} (score: {data.get('best_match_score',0):.2f})")
except Exception as e:
print(f"❌ {hotel}: {e}")
if results:
winner = min(results, key=lambda x: x["total"])
print(f"\n🏆 Best Value: {winner['name']} at ${winner['total']:.2f}")
print(f"🔗 Book Now: {winner['book_url']}")async function getHotelRates(hotelName, checkinDate, checkoutDate, adults = 2, currency = "USD") {
const res = await fetch(
"https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates",
{
method: "POST",
headers: { "Content-Type": "application/json", "X-API-KEY": "test-live-hotel-rates2025" },
body: JSON.stringify({ hotelName, checkinDate, checkoutDate, adults, currency })
}
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
const data = await getHotelRates("Luxor Las Vegas Las Vegas US", "2026-04-20", "2026-04-21");
// GUARD: rates may be null when hotel is sold out
const rawPrice = data?.rates?.display_all_in_total;
if (!rawPrice || String(rawPrice).trim() === "") {
console.log("⚪ Sold out / no inventory for these dates.");
} else {
// Always strip commas — price is a comma-formatted string, not a number
const price = parseFloat(String(rawPrice).replace(/,/g, ""));
console.log(`${data.hotel_name} — $${price.toFixed(2)} total (taxes included)`);
console.log(`Book: ${data.booking_page_live_rates}`);
if (data.best_match_score < 0.85)
console.warn(`⚠️ Low confidence (${data.best_match_score}) — verify hotel before booking.`);
}
window.businessHotelsAPI = { getHotelRates };from openai import OpenAI
import requests, json
client = OpenAI(api_key="YOUR_OPENAI_API_KEY")
BH_KEY = "test-live-hotel-rates2025"
tools = [{
"type": "function",
"function": {
"name": "get_live_hotel_rates",
"description": (
"Get live, all-inclusive hotel rates and a direct booking URL. "
"IMPORTANT: 'display_all_in_total' is a comma-formatted STRING (e.g. '1,250.00'). "
"Strip commas before numeric operations. "
"If rates is null or display_all_in_total is empty, the property is sold out — tell the user."
),
"parameters": {
"type": "object",
"properties": {
"hotelName": {"type": "string", "description": "Hotel + city + country, no commas. E.g. 'Wynn Las Vegas US'"},
"checkinDate": {"type": "string", "format": "date"},
"checkoutDate": {"type": "string", "format": "date"},
"adults": {"type": "integer", "default": 2},
"currency": {"type": "string", "default": "USD"}
},
"required": ["hotelName", "checkinDate", "checkoutDate"]
}
}
}]
messages = [{"role": "user", "content": "Rates for Luxor Las Vegas, April 20-21 2026?"}]
r1 = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools, tool_choice="auto")
msg = r1.choices[0].message
messages.append(msg)
if msg.tool_calls:
for tc in msg.tool_calls:
result = requests.post(
"https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates",
headers={"X-API-KEY": BH_KEY, "Content-Type": "application/json"},
json=json.loads(tc.function.arguments), timeout=10
).json()
messages.append({"role": "tool", "tool_call_id": tc.id, "content": json.dumps(result)})
r2 = client.chat.completions.create(model="gpt-4o", messages=messages)
print(r2.choices[0].message.content)import google.generativeai as genai
import requests, json
genai.configure(api_key="YOUR_GEMINI_API_KEY")
BH_KEY = "test-live-hotel-rates2025"
get_live_hotel_rates = genai.protos.Tool(
function_declarations=[genai.protos.FunctionDeclaration(
name="get_live_hotel_rates",
description=(
"Fetch live hotel rates and a direct booking URL. "
"IMPORTANT: 'display_all_in_total' is a comma-formatted STRING. "
"Strip commas before numeric comparison. "
"If rates is null or price is empty, the property is sold out."
),
parameters=genai.protos.Schema(
type=genai.protos.Type.OBJECT,
properties={
"hotelName": genai.protos.Schema(type=genai.protos.Type.STRING),
"checkinDate": genai.protos.Schema(type=genai.protos.Type.STRING),
"checkoutDate": genai.protos.Schema(type=genai.protos.Type.STRING),
"adults": genai.protos.Schema(type=genai.protos.Type.NUMBER),
"currency": genai.protos.Schema(type=genai.protos.Type.STRING)
},
required=["hotelName", "checkinDate", "checkoutDate"]
)
)]
)
model = genai.GenerativeModel(model_name="gemini-1.5-pro", tools=[get_live_hotel_rates])
chat = model.start_chat(history=[])
resp = chat.send_message("Find live rates for Luxor Las Vegas, April 20-21 2026.")
for part in resp.candidates[0].content.parts:
if part.function_call.name == "get_live_hotel_rates":
result = requests.post(
"https://www.businesshotels.com/mcp-server.php?route=tools/get_live_hotel_rates",
headers={"X-API-KEY": BH_KEY, "Content-Type": "application/json"},
json=dict(part.function_call.args), timeout=10
).json()
chat.send_message(genai.protos.Content(parts=[genai.protos.Part(
function_response=genai.protos.FunctionResponse(
name="get_live_hotel_rates", response={"result": result}
)
)]))
final = chat.send_message("Summarize the best price and booking link.")
print(final.text)