We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/lev-corrupted/travel-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""Amadeus API client wrapper for flight and hotel search."""
import os
from typing import Any, Dict, List, Optional
from amadeus import Client, ResponseError
from dotenv import load_dotenv
load_dotenv()
class AmadeusClient:
"""Client for interacting with Amadeus Travel APIs."""
def __init__(self) -> None:
"""Initialize the Amadeus client with credentials from environment variables."""
self.client_id = os.getenv("AMADEUS_CLIENT_ID")
self.client_secret = os.getenv("AMADEUS_CLIENT_SECRET")
self.env = os.getenv("AMADEUS_ENV", "test")
if not self.client_id or not self.client_secret:
raise ValueError(
"AMADEUS_CLIENT_ID and AMADEUS_CLIENT_SECRET must be set in environment"
)
self.client = Client(
client_id=self.client_id,
client_secret=self.client_secret,
hostname="test" if self.env == "test" else "production",
)
def search_flights(
self,
origin: str,
destination: str,
departure_date: str,
return_date: Optional[str] = None,
adults: int = 1,
max_results: int = 10,
) -> Dict[str, Any]:
"""
Search for flight offers.
Args:
origin: Origin airport IATA code (e.g., 'JFK')
destination: Destination airport IATA code (e.g., 'LAX')
departure_date: Departure date in YYYY-MM-DD format
return_date: Return date in YYYY-MM-DD format (optional for one-way)
adults: Number of adult passengers
max_results: Maximum number of results to return
Returns:
Dictionary containing flight offers
Raises:
ResponseError: If the API request fails
"""
try:
params = {
"originLocationCode": origin.upper(),
"destinationLocationCode": destination.upper(),
"departureDate": departure_date,
"adults": adults,
"max": max_results,
}
if return_date:
params["returnDate"] = return_date
response = self.client.shopping.flight_offers_search.get(**params)
return {
"success": True,
"data": response.data,
"meta": getattr(response, "meta", {}),
}
except ResponseError as error:
return {
"success": False,
"error": str(error),
"details": getattr(error, "description", "Unknown error"),
}
def search_hotels(
self,
city_code: str,
check_in_date: str,
check_out_date: str,
adults: int = 1,
radius: int = 5,
radius_unit: str = "KM",
) -> Dict[str, Any]:
"""
Search for hotels by city.
Args:
city_code: City IATA code (e.g., 'NYC', 'PAR')
check_in_date: Check-in date in YYYY-MM-DD format
check_out_date: Check-out date in YYYY-MM-DD format
adults: Number of adults
radius: Search radius
radius_unit: Unit for radius ('KM' or 'MILE')
Returns:
Dictionary containing hotel offers
Raises:
ResponseError: If the API request fails
"""
try:
response = self.client.reference_data.locations.hotels.by_city.get(
cityCode=city_code.upper()
)
if not response.data:
return {
"success": True,
"data": [],
"message": f"No hotels found in {city_code}",
}
# Get hotel IDs from the response
hotel_ids = [hotel["hotelId"] for hotel in response.data[:20]] # Limit to 20 hotels
# Get hotel offers
if hotel_ids:
offers_response = self.client.shopping.hotel_offers_search.get(
hotelIds=",".join(hotel_ids),
checkInDate=check_in_date,
checkOutDate=check_out_date,
adults=adults,
)
return {
"success": True,
"data": offers_response.data,
"meta": getattr(offers_response, "meta", {}),
}
return {
"success": True,
"data": [],
"message": "No hotel offers available",
}
except ResponseError as error:
return {
"success": False,
"error": str(error),
"details": getattr(error, "description", "Unknown error"),
}
def search_airport_by_city(self, city_name: str) -> Dict[str, Any]:
"""
Search for airports by city name.
Args:
city_name: Name of the city
Returns:
Dictionary containing airport information
Raises:
ResponseError: If the API request fails
"""
try:
response = self.client.reference_data.locations.get(
keyword=city_name,
subType="AIRPORT,CITY",
)
return {
"success": True,
"data": response.data,
}
except ResponseError as error:
return {
"success": False,
"error": str(error),
"details": getattr(error, "description", "Unknown error"),
}
def get_cheapest_date_for_route(
self,
origin: str,
destination: str,
) -> Dict[str, Any]:
"""
Get the cheapest flight dates for a route.
Args:
origin: Origin airport IATA code
destination: Destination airport IATA code
Returns:
Dictionary containing cheapest dates information
Raises:
ResponseError: If the API request fails
"""
try:
response = self.client.shopping.flight_dates.get(
origin=origin.upper(),
destination=destination.upper(),
)
return {
"success": True,
"data": response.data,
}
except ResponseError as error:
return {
"success": False,
"error": str(error),
"details": getattr(error, "description", "Unknown error"),
}