Live hotel rates for any AI agent — Claude, ChatGPT, Gemini, Perplexity, Comet & more
/mcp-server.php?route=tools
🤖 Perplexity Guide →
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"
}
}
}
}
Advanced setups can point directly at the live config endpoint:
https://www.businesshotels.com/mcp-server.php?route=config.
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"
Your tool definition uses the OpenAI-compatible JSON Schema format — the universal standard accepted by all leading AI platforms. The MCP discovery endpoint enables zero-config auto-registration.
?route=toolsRun 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 = "Marriott Marquis, San Francisco, US"
checkinDate = "2026-03-15"
checkoutDate = "2026-03-17"
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\":\"Marriott Marquis, San Francisco, US\",\"checkinDate\":\"2026-03-15\",\"checkoutDate\":\"2026-03-17\",\"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": "Marriott Marquis, San Francisco, US",
"checkinDate": "2026-03-15",
"checkoutDate": "2026-03-17",
"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: "Marriott Marquis, San Francisco, US",
checkinDate: "2026-03-15",
checkoutDate: "2026-03-17",
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",
"address": "780 Mission St, San Francisco, CA 94103",
"rates": {
"display_all_in_total": 389.50,
"currency": "USD",
"price_info": "Price includes all tax and fees",
"ppn_bundle": "HEA_..."
},
"booking_page_live_rates": "https://www.businesshotels.com/reservation.php?hotel-id=...&checkin-date=2026-03-15&checkout-date=2026-03-17&language=en&USER-CURRENCY=USD&USER-COUNTRY=US&NUM-ADULTS=2&prid=ai&ppn_bundle=...",
"latitude": 37.7842,
"longitude": -122.4016,
"best_match_score": 0.97,
"response_time_ms": 612
}
MCP-compatible apps can auto-discover and register your tool in seconds — no API key setup required for end users.
Claude auto-discovers the tool and calls it whenever a user asks for hotel rates or booking links.
Works in Perplexity Mac app and Comet browser agent. Remote MCP rolling out to paid users.
X-API-KEY headerWorks via OpenAI-compatible function calling in both the Assistants API and Chat Completions.
Any editor or agent framework that implements the MCP spec will auto-discover and register the tool.
Copilot can integrate with this API in two ways depending on your setup. In both cases the schema is already compatible — no changes needed.
X-API-KEY: test-live-hotel-rates2025For MCP-compatible Copilot deployments, point at the auto-discovery endpoint:
https://www.businesshotels.com/mcp-server.php?route=toolsCopilot reads the tools/list response, registers the tool automatically, and calls it whenever a user asks for hotel rates or booking links — no glue code required.
When a user says:
Copilot automatically generates and sends:
{
"hotelName": "Marriott Marquis, New York, US",
"checkinDate": "2026-04-10",
"checkoutDate": "2026-04-12",
"adults": 1,
"currency": "USD"
}
Copilot then parses the response and returns a conversational summary with the live price and a Book Now link — no developer glue code needed.
Any MCP-compatible agent can auto-discover and register this tool in a single GET request — no manual schema entry, no SDK, no configuration files.
GET /mcp-server.php?route=tools — receives the full tools/list JSONinput_schema and description fieldsget_live_hotel_rates as a callable tool internally| Manifest Field | What the Agent Uses It For |
|---|---|
description | Decides when to call the tool — the trigger condition |
input_schema.required | Knows which fields to collect from the user before calling |
input_schema.properties | Understands data types, formats, and defaults for each field |
default values | Auto-fills adults: 2 and currency: USD when not specified |
format: date | Converts natural language dates ("next Friday") to YYYY-MM-DD automatically |
import requests
# Step 1: Fetch the tool manifest from the discovery endpoint
manifest = requests.get(
"https://www.businesshotels.com/mcp-server.php?route=tools"
).json()
# Step 2: Extract tools — ready to pass directly to any LLM API
tools = manifest["tools"]
print(f"Registered {len(tools)} tool(s):")
for t in tools:
print(f" • {t['name']} — {t['description'][:60]}...")
# Step 3: Pass directly to OpenAI / Perplexity / Anthropic SDK
# e.g. client.chat.completions.create(tools=tools, ...)
Required headers:
Content-Type: application/json &
X-API-KEY: test-live-hotel-rates2025
Returns the full MCP tools/list envelope — paste this URL into any MCP-compatible client to auto-register the tool.
| API Key | Use | Rate Limit | Notes |
|---|---|---|---|
test-live-hotel-rates2025 |
Development, testing & light production | 100 req/hour | Returns live data — safe for demos and low-volume agents |
| Your production key | Live applications | Custom | Contact for production key |
This OpenAI-compatible schema works with Claude, ChatGPT, Gemini, Perplexity, and any OpenAI-format function calling API. Copy and paste directly into your tool definition.
{
"type": "function",
"name": "get_live_hotel_rates",
"description": "Use this tool whenever the user asks for live price,
total cost with taxes and fees, availability, or a booking/checkout
link for a specific hotel for given dates. Returns an all-in final
price (taxes included) and a direct price-locked booking URL.",
"parameters": {
"type": "object",
"additionalProperties": false,
"required": ["hotelName", "checkinDate", "checkoutDate"],
"properties": {
"hotelName": {
"type": "string",
"description": "REQUIRED. Hotel name + City + 2-letter country code.
Example: 'InterContinental Mark Hopkins, San Francisco, US'.
If user omits city/country, infer from context or ask before calling."
},
"checkinDate": { "type": "string", "format": "date", "description": "YYYY-MM-DD. Convert relative dates before calling." },
"checkoutDate": { "type": "string", "format": "date", "description": "YYYY-MM-DD. Must be after checkinDate." },
"adults": { "type": "integer", "default": 2, "description": "Guests (1–4). Default 2 if not specified." },
"currency": { "type": "string", "default": "USD", "description": "ISO 4217 code. Default USD." }
}
}
}
| Parameter | Type | Required | Description |
|---|---|---|---|
hotelName | string | ✅ Yes | Hotel + city + country (e.g., "Hilton Garden Inn, Seattle, US") |
checkinDate | string | ✅ Yes | Check-in date — YYYY-MM-DD |
checkoutDate | string | ✅ Yes | Check-out date — YYYY-MM-DD, must be after check-in |
adults | integer | No (default: 2) | Number of guests (1–4) |
currency | string | No (default: USD) | ISO 4217 currency code |
tools/list ResponseThe GET ?route=tools endpoint returns this envelope. MCP-compatible clients use it to auto-discover and register the tool — no manual schema entry needed.
{
"protocol": "mcp",
"version": "1.0",
"server_name": "BusinessHotels MCP Server",
"tools": [
{
"name": "get_live_hotel_rates",
"title": "BusinessHotels Live Hotel Rates",
"description": "Use whenever user asks for live price, taxes-included total,
availability, or booking link for a specific hotel and dates.",
"input_schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["hotelName", "checkinDate", "checkoutDate"],
"additionalProperties": false,
"properties": {
"hotelName": { "type": "string" },
"checkinDate": { "type": "string", "format": "date" },
"checkoutDate": { "type": "string", "format": "date" },
"adults": { "type": "integer", "default": 2 },
"currency": { "type": "string", "default": "USD" }
}
}
}
]
}
{
"hotel_id": "700076955",
"hotel_name": "Luxor",
"hotel_address": "3900 Las Vegas Boulevard South",
"city_name": "Las Vegas",
"state_code": "NV",
"country_code": "US",
"postal_code": "89119",
"latitude": "36.096806",
"longitude": "-115.173001",
"booking_page_live_rates": "https://www.businesshotels.com/reservation.php?hotel-id=700076955&checkin-date=...&checkout-date=...&language=en&USER-CURRENCY=USD&USER-COUNTRY=US&NUM-ADULTS=2&prid=ai&ppn_bundle=...",
"rates": {
"display_all_in_total": "356.06",
"currency": "USD",
"price_info": "Price includes all tax and fees",
"ppn_bundle": "HEA_OqStb8TUtNnSS-nry..."
},
"best_match_score": 0.87
}
| Field | Type | Agent Instruction |
|---|---|---|
hotel_name | string | Confirm with user when query was ambiguous or best_match_score < 0.85 |
hotel_address | string | Display for logistical clarity — helps user confirm correct property |
latitude / longitude | float | Map trigger: use for pins, distance calculations, neighborhood context |
rates.display_all_in_total | float | Quote as the Final Price for the entire stay — taxes & fees already included |
booking_page_live_rates | URL | Present as the primary Book Now action — rate locked ~20 min |
rates.ppn_bundle | string | Internal rate token — do not modify; already embedded in booking URL |
hotel_id | string | Store for session follow-ups about the same property |
best_match_score | float 0–1 | See Match Logic below — confirm with user if < 0.85 |
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-04-20",
"checkoutDate": "2026-04-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-04-20",
"checkoutDate": "2026-04-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-04-20",
"checkoutDate": "2026-04-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)