Skip to content

MCP server

Give AI agents hotel, flight and vacation-rental prices: connect Claude Code, Cursor or Claude Desktop to the ScraperCompany MCP server with your API key.

The ScraperCompany MCP server exposes the API's hotel, flight and vacation-rental data as tools an AI agent can call. Any Model Context Protocol client that can send a header works: Claude Code, Cursor, and Claude Desktop through a small bridge.

Overview

Endpoint
https://api.scrapercompany.com/mcp
Transport
Streamable HTTP (MCP 2025-06-18; 2025-03-26 is also accepted). Stateless JSON responses: no sessions and no server-sent stream. The older HTTP+SSE transport (2024-11-05) is not served.
Auth
Your API key, as x-api-key: YOUR_API_KEY or Authorization: Bearer YOUR_API_KEY (details)
Billing
Each tool call is the API call it wraps: priced, rate-limited and recorded in your request history exactly as that call would be. Failed or empty results are free.
Tools
18, all read-only

Connect a client

Claude Code

Add the server once; the key is read from your environment when you run the command.

Terminal
claude mcp add --transport http scrapercompany https://api.scrapercompany.com/mcp \
  --header "x-api-key: $SCRAPERCOMPANY_API_KEY"

Cursor and other header-capable clients

In ~/.cursor/mcp.json (or your client's equivalent config), point a server at the URL and pass the key as a header:

mcp.json
{
  "mcpServers": {
    "scrapercompany": {
      "url": "https://api.scrapercompany.com/mcp",
      "headers": {
        "x-api-key": "YOUR_API_KEY"
      }
    }
  }
}

Claude Desktop and stdio-only clients

Clients that only launch local (stdio) servers connect through the mcp-remote bridge. In claude_desktop_config.json:

claude_desktop_config.json
{
  "mcpServers": {
    "scrapercompany": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.scrapercompany.com/mcp",
               "--header", "x-api-key:${SCRAPERCOMPANY_API_KEY}"],
      "env": { "SCRAPERCOMPANY_API_KEY": "YOUR_API_KEY" }
    }
  }
}

claude.ai and ChatGPT connectors are not supported yet

Those connectors authenticate remote servers with OAuth, and this endpoint takes an API key. OAuth support is on the roadmap.

Check the connection

Listing the tools is free and needs no session. A plain HTTP client gets the same JSON-RPC reply an MCP client does:

cURL
curl -X POST "https://api.scrapercompany.com/mcp" \
  -H "x-api-key: $SCRAPERCOMPANY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'

A 401 means the key is missing or wrong. Treat the key like a password: keep it in the client's secret store or an environment variable rather than in a config file you share.

Tools

Each tool wraps one REST endpoint and takes that endpoint's request fields (most of them), validated the same way. Options that change a call's price, such as basis and verify_sources on the calendar, stay REST-only. Tool descriptions carry the cost too, so the agent sees what a call will charge before making it.

ToolWrapsCredits
resolve_hotelTurn a hotel name (plus city) into a Google property token.
1
resolve_google_hotelFind a hotel by name and place, with each candidate's mailing address.
12
hotel_guest_reviewsGuest reviews for one property, mixed by provider.
2 per page
hotel_rate_calendarNightly prices for 1-330 nights in one call.
5
hotel_offersEvery booking site's price for one stay.
3
hotel_destination_searchList a destination's hotels with prices, ratings and filters.
3 per page
compare_ota_ratesPrice one stay on Booking.com, Hotels.com, Agoda and Expedia.
20
official_site_ratesRooms and rate plans from the hotel's own booking engine.
4
expedia_find_hotelTurn a hotel name into Expedia's property id.
1
expedia_ratesExpedia's rooms and rate plans for one stay.
8
flight_searchGoogle Flights itineraries, prices and price insights.
3
flight_next_legReturn (or next multi-city) options for a chosen outbound.
3
flight_booking_optionsWho sells a complete itinerary, for how much.
3
flight_location_searchTurn a city or airport name into the codes flight search takes.
1
flight_price_calendarCheapest fare for each date around a chosen date.
5
airbnb_searchAirbnb listings with live prices.
8
airbnb_priced_calendarDay-by-day availability with Airbnb's own quoted stay prices.
8 + 1 per priced night
vrbo_searchVrbo rentals with stay prices.
1
vrbo_quoteQuote one Vrbo rental, by property id or URL listing id.
8
credit_balanceYour plan, credits remaining and billing period.
Free

A typical hotel conversation: resolve_hotel with a name and city returns a token; hotel_rate_calendar with that token and days: 60 returns 60 nightly prices; then hotel_offers for the cheapest night returns each booking site's price. For flights: flight_search with a return date, flight_next_leg with the chosen outbound's departure_token, then flight_booking_options with the return's booking_token.

credit_balance needs a customer account

Like GET/v1/billing, it answers only for keys linked to a customer account; other keys get a tool error with status 404.

Results

A successful call returns the route's JSON twice: in structuredContent, and as text in content[0].text for clients that only read text. Per-row provenance blocks are left out to save the agent's context; call the REST endpoint when you need them for an audit.

_meta on every result gives the HTTP status of the wrapped call, the request id and, when the call was metered, the credits charged and remaining (as strings, copied from the credit headers):

tools/call result (shortened)
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [{ "type": "text", "text": "{\"token\":\"ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ\",\"requested_days\":60,\"coverage\":0.95,\"rates\":[...]}" }],
    "structuredContent": { "token": "ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ", "requested_days": 60, "coverage": 0.95, "rates": ["..."] },
    "isError": false,
    "_meta": { "http_status": 200, "credits_charged": "5", "credits_remaining": "995", "request_id": "req_..." }
  }
}

Errors

Errors come back at two levels.

Tool errors are results with isError: true, so the model can read them and fix its next call. The text is {"error": ..., "status": ...} with the wrapped route's detail and status. They cover:

  • a missing or unknown argument (the message lists the allowed ones);
  • anything the route rejects, such as a date in the past (422) or a property Google no longer lists (404);
  • a source that failed or blocked the request (502) or changed its contract (503);
  • no credits left (402, once enforcement is on) or the key's rate limit (429).

An unexpected server error is also a tool error, with a generic message and the request_id to quote to support. Tool errors are not charged.

Tool error
{
  "jsonrpc": "2.0",
  "id": 8,
  "result": {
    "content": [{ "type": "text", "text": "{\"error\": \"check_in is in the past\", \"status\": 422}" }],
    "isError": true,
    "_meta": { "http_status": 422, "request_id": "req_..." }
  }
}

Protocol errors are JSON-RPC errors, for problems with the message itself:

CodeWhen
-32700
The body is not valid JSON (HTTP 400).
-32600
Not a valid JSON-RPC 2.0 request; an unsupported MCP-Protocol-Version (HTTP 400); a browser Origin that is not allowed (HTTP 403); a body over 256 KB (HTTP 413).
-32601
Unknown method. The server implements initialize, ping, tools/list and tools/call.
-32602
Unknown tool, or params / arguments that are not objects.
-32000
Rate limit exceeded (HTTP 429 with Retry-After: 60 for a single message).

A missing or invalid key is an HTTP 401 before any JSON-RPC handling.

Limits

  • One JSON-RPC message per POST under 2025-06-18, which removed batching. 2025-03-26 clients may batch up to 10 messages.
  • Request bodies over 256 KB get 413.
  • Tool calls count against your key's rate limit through the route they wrap. Every other message (initialize, tools/list, ping), and any tool call rejected before it reaches a route, counts once.
  • A browser Origin must be scrapercompany.com (or a subdomain) or localhost; anything else gets 403, which guards against DNS rebinding. Agents and CLIs send no Origin.
  • GET and DELETE on /mcp return 405: the server never opens a stream or a session.