This repo provides an MCP server that exposes the Amadeus Hotels family of APIs as MCP tools, so MCP-capable LLM clients can search hotels and (in test/sandbox only) create bookings.
It runs as an always-on Node server using MCP’s HTTP+SSE transport (good for public deployment).
geo_lookup(OpenStreetMap Nominatim; no API key) — turn “Bowling Green, OH” into lat/lonhotels_autocomplete— Hotel Name Autocompletehotels_list_by_city— Hotel List by city (IATA city code)hotels_list_by_geocode— Hotel List by geocode (lat/lon)hotels_search_offers— Hotel Search / offers (cityCode or hotelIds), returns offers sorted cheapest-firsthotels_ratings— Hotel Ratings / sentimentshotels_book_offer_sandbox— Hotel Booking (requiresAMADEUS_ENV=test)
- Install dependencies:
cd /Users/jonk/canary-cursor
npm install- Fill in env vars:
cp .env.example .env
# edit .env and fill:
# - AMADEUS_CLIENT_ID
# - AMADEUS_CLIENT_SECRET
# - MCP_API_TOKEN- Run the MCP server:
npm run dev:mcpThe server exposes:
GET /health(no auth)GET /mcp(SSE) andPOST /messages?sessionId=...(both require auth)
Auth header:
Authorization: Bearer <MCP_API_TOKEN>
Claude Desktop works best with MCP servers launched locally over stdio.
- Build the MCP scripts:
cd /Users/jonk/canary-cursor
npm run build:mcp- Edit Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
Add:
{
"mcpServers": {
"amadeus-hotels": {
"command": "node",
"args": ["/Users/jonk/canary-cursor/dist/mcp/stdio.js"],
"env": {
"AMADEUS_CLIENT_ID": "YOUR_ID",
"AMADEUS_CLIENT_SECRET": "YOUR_SECRET",
"AMADEUS_ENV": "test"
}
}
}
}Restart Claude Desktop, then you should see the amadeus-hotels tools available.
Your deployed site (for example https://canary-cursor.vercel.app/) exposes MCP at:
https://<your-host>/mcp
Claude Desktop typically needs a local bridge to connect to remote MCP servers. Use mcp-remote in your claude_desktop_config.json and force HTTP-only (avoids SSE/EventSource issues):
curl -sS http://localhost:3000/health
curl -sS -i --max-time 1 -H "Authorization: Bearer $MCP_API_TOKEN" http://localhost:3000/mcp | head -n 20- Call
geo_lookupwithquery="Bowling Green, OH" - Call
hotels_list_by_geocodeusing the returnedlatitude/longitude - Call
hotels_search_offerswith:hotelIdsfrom the list toolcheckInDate/checkOutDatederived from “tonight” (client/LLM chooses dates)
- Pick the first offer returned (already cheapest-first)
- Call
hotels_book_offer_sandboxwithofferIdand guest details (sandbox only)
- Call
hotels_autocompletefor"Atlantis Bahamas"and"Baha Mar"to identify hotel IDs - Call
hotels_search_offerswithhotelIds=[...], dates, andcurrency="USD" - Filter offers where
price.total <= 400and compare room/board/cancellation
This MCP server is designed to be accessible on the open web. HTTP/SSE connections are long-lived, so an always-on service (Render/Fly/etc.) is recommended.
- Create a new Render Web Service from this repo
- Set:
- Build Command:
npm install && npm run build:mcp - Start Command:
node dist/mcp/server.js
- Build Command:
- Add env vars in Render:
AMADEUS_CLIENT_IDAMADEUS_CLIENT_SECRETAMADEUS_ENV(testrecommended)MCP_API_TOKEN
Your MCP endpoint will be:
GET https://<your-service>.onrender.com/mcp
The app/ directory contains a minimal Next.js app you can deploy to Vercel for documentation. The MCP server itself should remain on an always-on host (Render/Fly).
{ "mcpServers": { "amadeus-hotels-remote": { "command": "/Users/jonk/.nvm/versions/node/v22.12.0/bin/npx", "args": [ "-y", "mcp-remote@latest", "https://canary-cursor.vercel.app/mcp", "--transport", "http-only", "--header", "Authorization:${AUTH_HEADER}" ], "env": { "AUTH_HEADER": "Bearer YOUR_MCP_API_TOKEN" } } } }