MCP Server
Connect StayAPI to Claude, Claude Code, Cursor, and other Model Context Protocol clients. Your AI agent queries hotel data directly from natural-language prompts — no glue code.
User:
"Get me the latest reviews for booking.com/hotel/us/the-line-la.html"
Agent:
→ calls booking_hotel_reviews(url=…) → returns structured reviews
What you get
-
No new credentials. Uses your existing StayAPI
X-API-Key. - Same quota and billing as the REST API — one tool call = one API request.
- Same SLA — calls go through the same scrapers and proxies as the REST API.
- Works in Claude, Claude Code, Cursor out of the box.
- ChatGPT custom connectors not supported in v1 — they require OAuth.
Quick Start
Have an account? Use the pre-filled setup
Get your API key
Sign up for a free StayAPI account (no credit card required), then copy your API key from the dashboard.
Already have an account? Sign in.
Add the MCP server to your agent
Pick the snippet for your AI client
mcp-remote bridge because its JSON config doesn't accept HTTP servers directly.
Claude Code
Run from your terminal:
claude mcp add --scope user --transport http stayapi https://api.stayapi.com/mcp --header "X-API-Key: YOUR_API_KEY"
Then open a new Claude Code session (already-running sessions won't see the new server). Confirm with claude mcp list — should show stayapi: … (HTTP) - ✓ Connected.
Cursor
One click installs the connector in Cursor:
Add to Cursor
After installing, replace YOUR_API_KEY in Cursor's MCP settings with your real key.
Or sign in for a one-click button with your key already baked in.
Prefer to set it up by hand? Add to ~/.cursor/mcp.json (create if missing), then restart Cursor:
{
"mcpServers": {
"stayapi": {
"type": "http",
"url": "https://api.stayapi.com/mcp",
"headers": {
"X-API-Key": "YOUR_API_KEY"
}
}
}
}
Claude Desktop
Add to your claude_desktop_config.json (create if missing):
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
macOS / Linux:
{
"mcpServers": {
"stayapi": {
"command": "npx",
"args": [
"-y",
"mcp-remote@0.1.18",
"https://api.stayapi.com/mcp",
"--header",
"X-API-Key:YOUR_API_KEY"
]
}
}
}
Windows:
Claude Desktop doesn't inherit your shell PATH, so a bare npx throws spawn npx ENOENT. Point command at the absolute path to npx.cmd:
{
"mcpServers": {
"stayapi": {
"command": "C:\\Program Files\\nodejs\\npx.cmd",
"args": [
"-y",
"mcp-remote@0.1.18",
"https://api.stayapi.com/mcp",
"--header",
"X-API-Key:YOUR_API_KEY"
]
}
}
}
- Verify Node in Command Prompt (not the Node.js app / REPL) with
where npx. If it points elsewhere, use that path; the default isC:\Program Files\nodejs\npx.cmd. - Keep
mcp-remote@0.1.18pinned — newer builds can throwUnexpected content type: null.
- Fully quit Claude Desktop with ⌘ Q — closing the window leaves it running in the menu bar and the new server won't load.
- Relaunch. First launch may take ~30 seconds while
npxdownloadsmcp-remotefrom npm; subsequent launches are instant. On a fully locked-down machine, IT may need to allowregistry.npmjs.org. - In a new conversation, click the 🔌 icon —
stayapishould appear.
Why mcp-remote? Claude Desktop's JSON config doesn't natively support HTTP MCP servers yet — it requires stdio entries (command/args), and the mcp-remote adapter bridges the gap. (The Settings → Developer → Add MCP Server GUI is OAuth-oriented and doesn't accept custom headers, so it can't be used for an X-API-Key server — edit the JSON as shown above.)
Try it
Ask your agent something like:
- "What's the destination ID for Lisbon on Booking.com?"
- "Get me 10 of the most recent reviews for https://www.booking.com/hotel/us/the-line-la.html"
- "Look up Google reviews for 'Bellagio Las Vegas'"
Available tools
Most agents will discover and call the right tool automatically based on your prompt — you don't need to memorize tool names.
| Tool | What it does |
|---|---|
booking_lookup_destination |
Free-form name (e.g., "Lisbon") → Booking.com dest_id. First step before booking_search_hotels when you only have a city name. |
booking_search_hotels |
List hotels in a destination for a stay window. Takes a dest_id (negative integers like -3233180 are valid — preserve the sign). |
booking_hotel_details |
Get one hotel's details by hotel_id (fast) or canonical Booking URL (slower — 5–40 s for URL→ID resolution). |
booking_hotel_rooms |
Get room types and live availability for one hotel by hotel_id or URL, for a stay window. Returns bookable rate blocks plus availability_summary.total_available_rooms — a deduplicated count across rate plans. |
booking_hotel_reviews |
Get reviews for a hotel by hotel_id or URL, with sort and pagination. Use sort=recent_desc for date-bounded backfills. |
booking_hotel_photos |
Get a hotel's full photo gallery by hotel_id or URL. Returns signed, ready-to-use image URLs at thumbnail, medium, and large sizes. |
airbnb_listing_details |
Get an Airbnb listing's details by listing_id or any Airbnb URL (URL→ID is instant). |
airbnb_listing_reviews |
Get reviews for an Airbnb listing by listing_id or URL, with sort + pagination. |
google_hotels_search |
Search hotels via Google Hotels (SerpAPI-backed). |
google_reviews_for_place |
Get Google reviews for a place — by Google data_id or by query + optional location. |
google_travel_resolve |
Hotel name → Google Travel entity_token candidates. First step for the other google_travel_* tools. |
google_travel_search |
Free-text hotel search ("hotels in Lisbon") → ~20 hotel cards per page, each with rating, price, star class, coordinates, and its own entity_token to pivot into the other google_travel_* tools. |
google_travel_summary |
A hotel's review summary by entity_token: overall rating, total count, star histogram, and review-topic sub-scores. |
google_travel_info |
A hotel's identity/metadata by entity_token: name, star class, coordinates, address, phone, check-in/out times, website, and Maps ids. |
google_travel_photos |
A hotel's photo gallery by entity_token (https URLs, dimensions, and occasional AI caption highlights). |
google_travel_prices |
A hotel's nightly rate, usual-price band, and partner booking offers by entity_token for Google's default dates; currency shapes money fields. |
google_travel_similar |
Similar hotels + vacation rentals near a hotel (entity_token), each with its own token to pivot to. |
google_travel_nearby |
Nearby points of interest (attractions, transit, airports, restaurants) with ratings and drive/walk times, by entity_token. |
google_travel_reviews |
A hotel's individual Google reviews by entity_token — rating, text, reviewer, owner response — with sort (most_relevant / newest / highest_rating / lowest_rating) and cursor pagination. |
accor_search |
Search Accor (ALL — Sofitel, Fairmont, Novotel, Ibis, etc.) hotels by latitude+longitude (+radius_km) or destination_slug, with each property's best available offer. |
accor_hotel_rooms |
Get bookable room offers for an Accor property by hotel_id (from accor_search), grouped into room types with rate plans, prices, and policies. |
accor_hotel_photos |
Get an Accor property's full photo/video gallery by hotel_id. Public image URLs at every published size. |
accor_price_calendar |
Get a per-date cheapest-offer calendar for an Accor property by hotel_id (window up to 60 days). |
tripadvisor_geo_search |
Free-form place name (e.g., "Paris") → TripAdvisor geo_id. First step before tripadvisor_search_hotels if you only have a place name. |
tripadvisor_search_hotels |
List TripAdvisor hotels in a geo_id area for an optional stay window. Each hotel carries a location_id for the other TripAdvisor tools. |
tripadvisor_hotel_details |
Get one TripAdvisor hotel's details by location_id or any TripAdvisor hotel URL (URL→ID is instant). |
tripadvisor_hotel_reviews |
Get reviews for a TripAdvisor hotel by location_id or URL, with page/per_page and language. |
tripadvisor_hotel_prices |
Get live provider offers (Booking.com, Agoda, etc.) for a TripAdvisor hotel by location_id or URL for a required stay window. |
opentable_search_restaurants |
Search OpenTable restaurants near a latitude+longitude for a date/time/party_size. Returns name, cuisine, price band, rating, address, phone, and photos. |
opentable_private_dining_restaurants |
Search OpenTable private-dining venues near a latitude+longitude, with cuisine_ids/instant_book/radius/min_capacity filters. Returns the private-dining contact (name/phone/email), largest-space capacity, plus cuisine, rating, and photos. Pass with_facets=true to discover cuisine IDs. |
meta_coordinates_lookup |
Resolve a place name (e.g. "Manhattan") to coordinates. Returns matching locations with latitude/longitude, type, country, and place_id — use it to get the lat/lng the other tools need. |
airbnb_search_listings |
⚠️ Not yet available — returns a clear "feature unavailable" message with a request link to info@stayapi.com. Not billed. |
URL vs ID
For Booking, Airbnb, and TripAdvisor tools that fetch a single item, you can pass either an id or a url:
- ID is faster — no resolution step needed.
- URL works too — the server resolves it internally. Booking URLs are slower to resolve.
If you only have a URL, pass it. If you have the ID from a previous call, prefer it.
Quota and billing
| Call type | Counts against your quota? |
|---|---|
initialize, tools/list, notifications |
No (free housekeeping) |
tools/call on a supported tool |
Yes — 1 quota unit per call |
tools/call on airbnb_search_listings (stub) |
No (not billed for unavailable features) |
tools/call on an unknown tool name |
No |
Rate limits and monthly quotas are the same as the REST API — your tier dictates both. When you hit a quota limit, the tool returns a structured quota_exhausted error with retry_after and the reset time, so the agent can back off intelligently.
Per-tool usage appears in your activity dashboard as /mcp/tools/<tool_name> — so you can see which tools your agents call most.
Structured errors
When something goes wrong, tools return a structured dict your agent can read and react to, rather than a generic failure:
| Error | When | Shape |
|---|---|---|
invalid_input | Missing or bad parameter | {error, message, field} |
url_resolution_failed | Couldn't extract an ID from your URL | {error, message, provider, outcome} |
upstream_error | Provider (Booking, Airbnb, Google) returned an error | {error, message, provider} |
no_results | Query was valid but nothing matched | {error, message, provider} |
rate_limited | Internal scraper queue saturated | {error, message, provider, retry_after} |
quota_exhausted | Monthly quota is used up | {error, message, retry_after, reset_at, remaining_quota} |
feature_unavailable | Feature isn't built yet (see airbnb_search_listings) | {error, message, support_email} |
Auth failures (missing or invalid key) come back as JSON-RPC error code -32001 with HTTP 401 or 403.
What's NOT supported in v1
- Airbnb listing search by location/dates — only details and reviews work today. Email info@stayapi.com if you need search.
- JSON-RPC batches — send one tool call at a time. Batched requests return JSON-RPC
-32600. - ChatGPT custom connectors — they require OAuth, which v1 doesn't support. Use Claude / Claude Code / Cursor instead.
- Google Hotels max-price filter — the underlying provider doesn't expose one.
min_ratingworks; for price caps, your agent can filter the response client-side. - Pagination on
google_reviews_for_placebyquery—next_page_tokenonly works when you initially called withdata_id. The query path returns the first page plus the resolveddata_idso you can paginate from there.
Troubleshooting
Claude Desktop on Windows: mcp-remote won't start
The Windows failure ladder, in the order you'll hit it. All three are client-side — the server is fine.
| Symptom | Cause | Fix |
|---|---|---|
spawn npx ENOENT |
Claude Desktop can't find npx on its PATH. |
Use the absolute path to npx.cmd (see the Windows snippet above). Verify Node with where npx in Command Prompt — not the Node.js app / REPL. |
'npx' is not recognized |
Node isn't installed, or PATH was stripped by corporate policy. | Install Node LTS and restart the machine. If where npx is still blank in cmd but works elsewhere, use the absolute path. |
Unexpected content type: null |
A mcp-remote version regression. |
Pin mcp-remote@0.1.18. |
Check the server is reachable from your machine
Before blaming your client config, confirm the server answers from your network. Run this in Command Prompt (swap in your real key):
curl.exe -i -X POST https://api.stayapi.com/mcp -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -H "X-API-Key: YOUR_API_KEY" -d "{\"jsonrpc\":\"2.0\",\"id\":0,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-11-25\",\"capabilities\":{},\"clientInfo\":{\"name\":\"curl\",\"version\":\"1.0\"}}}"
If it returns 200 and serverInfo: StayAPI, the server is fine and the problem is your client config.
PowerShell users: use curl.exe, not curl
curl is an alias for Invoke-WebRequest, which silently ignores -H/-d. Use curl.exe (as above) or run the command from Command Prompt.
401 Unauthorized on initialize
Your X-API-Key header is missing or wrong. Sign in and copy your current key from the dashboard and re-add the connector.
403 Forbidden
Your account is blocked or your IP isn't in your account's allowlist (Enterprise tier feature). Contact info@stayapi.com.
quota_exhausted on every tool call
You've used your monthly quota. The error includes reset_at — wait until then or upgrade your plan.
url_resolution_failed from Booking tools
The URL didn't resolve to a hotel. Use a canonical Booking URL (https://www.booking.com/hotel/{cc}/{slug}.html), not a search-results URL. Or pass hotel_id directly if you have it.
feature_unavailable from airbnb_search_listings
Airbnb search isn't built yet. Email info@stayapi.com to vote for it.
Tool calls take a long time
booking_hotel_details(url=…) and booking_hotel_reviews(url=…) resolve the URL via a real-browser fetch — 5–40 seconds worst case. Pass hotel_id directly if you have it. Other tools should respond in 1–5 seconds.
My agent isn't using the StayAPI tools
Some agents need the tool descriptions to clearly match the request. Try mentioning a hotel name, URL, or the platform explicitly: "use StayAPI to find…".
Privacy & security
- Your
X-API-Keyis sent on every request as a custom HTTP header. Treat it like any other API credential — don't paste it into shared chats or commit it to a repo. - Tool inputs (URLs, hotel IDs, queries) are logged for analytics and debugging, same as REST API calls.
- All connections to
https://api.stayapi.com/mcpare TLS-encrypted. - The MCP server runs on the same infrastructure as the REST API. Same SLA, same data residency, same incident response.