File size: 13,526 Bytes
afe5a30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
from mcp.server.fastmcp import FastMCP
from datetime import datetime
import random
import urllib.parse

# Initialize FastMCP server for Hotels
mcp = FastMCP("HotelsAgent")

# Destination-specific real hotels
DESTINATION_HOTELS = {
    "dubai": [
        {"name": "Burj Al Arab Jumeirah", "stars": 5, "base_price": 1500, "rating": 4.8},
        {"name": "Atlantis The Palm", "stars": 5, "base_price": 450, "rating": 4.6},
        {"name": "Armani Hotel Dubai", "stars": 5, "base_price": 600, "rating": 4.7},
        {"name": "Jumeirah Beach Hotel", "stars": 5, "base_price": 400, "rating": 4.5},
        {"name": "One&Only The Palm", "stars": 5, "base_price": 800, "rating": 4.8},
        {"name": "Address Downtown Dubai", "stars": 5, "base_price": 350, "rating": 4.6},
    ],
    "paris": [
        {"name": "The Ritz Paris", "stars": 5, "base_price": 1200, "rating": 4.9},
        {"name": "Four Seasons Hotel George V Paris", "stars": 5, "base_price": 1100, "rating": 4.8},
        {"name": "Le Meurice Paris", "stars": 5, "base_price": 900, "rating": 4.7},
        {"name": "Shangri-La Hotel Paris", "stars": 5, "base_price": 800, "rating": 4.7},
        {"name": "Hotel Plaza Athenee Paris", "stars": 5, "base_price": 950, "rating": 4.8},
    ],
    "tokyo": [
        {"name": "The Peninsula Tokyo", "stars": 5, "base_price": 700, "rating": 4.8},
        {"name": "Aman Tokyo", "stars": 5, "base_price": 1000, "rating": 4.9},
        {"name": "Park Hyatt Tokyo", "stars": 5, "base_price": 600, "rating": 4.7},
        {"name": "The Ritz-Carlton Tokyo", "stars": 5, "base_price": 650, "rating": 4.7},
        {"name": "Mandarin Oriental Tokyo", "stars": 5, "base_price": 700, "rating": 4.8},
    ],
    "london": [
        {"name": "The Savoy London", "stars": 5, "base_price": 700, "rating": 4.7},
        {"name": "Claridge's London", "stars": 5, "base_price": 800, "rating": 4.8},
        {"name": "The Ritz London", "stars": 5, "base_price": 750, "rating": 4.7},
        {"name": "Four Seasons Hotel London at Park Lane", "stars": 5, "base_price": 650, "rating": 4.6},
    ],
    "rome": [
        {"name": "Hotel Hassler Roma", "stars": 5, "base_price": 600, "rating": 4.7},
        {"name": "Hotel de Russie Rome", "stars": 5, "base_price": 550, "rating": 4.6},
        {"name": "St. Regis Rome", "stars": 5, "base_price": 500, "rating": 4.5},
        {"name": "Rome Cavalieri Waldorf Astoria", "stars": 5, "base_price": 450, "rating": 4.6},
    ],
    "bali": [
        {"name": "Four Seasons Resort Bali at Sayan", "stars": 5, "base_price": 800, "rating": 4.9},
        {"name": "The Mulia Bali", "stars": 5, "base_price": 500, "rating": 4.7},
        {"name": "Ayana Resort and Spa Bali", "stars": 5, "base_price": 400, "rating": 4.6},
        {"name": "St. Regis Bali Resort", "stars": 5, "base_price": 600, "rating": 4.8},
        {"name": "The Legian Bali", "stars": 5, "base_price": 350, "rating": 4.5},
    ],
    "new york": [
        {"name": "The Plaza Hotel New York", "stars": 5, "base_price": 800, "rating": 4.6},
        {"name": "The St. Regis New York", "stars": 5, "base_price": 900, "rating": 4.7},
        {"name": "Mandarin Oriental New York", "stars": 5, "base_price": 750, "rating": 4.7},
        {"name": "Four Seasons Hotel New York Downtown", "stars": 5, "base_price": 850, "rating": 4.6},
    ],
    "maldives": [
        {"name": "Soneva Fushi Maldives", "stars": 5, "base_price": 1800, "rating": 4.9},
        {"name": "One&Only Reethi Rah Maldives", "stars": 5, "base_price": 1500, "rating": 4.8},
        {"name": "Anantara Kihavah Maldives Villas", "stars": 5, "base_price": 1200, "rating": 4.8},
        {"name": "Waldorf Astoria Maldives Ithaafushi", "stars": 5, "base_price": 2000, "rating": 4.9},
    ],
    "santorini": [
        {"name": "Grace Hotel Santorini", "stars": 5, "base_price": 800, "rating": 4.8},
        {"name": "Canaves Oia Santorini", "stars": 5, "base_price": 700, "rating": 4.7},
        {"name": "Andronis Luxury Suites", "stars": 5, "base_price": 900, "rating": 4.9},
        {"name": "Mystique Santorini", "stars": 5, "base_price": 650, "rating": 4.6},
    ],
    "barcelona": [
        {"name": "Hotel Arts Barcelona", "stars": 5, "base_price": 450, "rating": 4.6},
        {"name": "W Barcelona", "stars": 5, "base_price": 400, "rating": 4.5},
        {"name": "Mandarin Oriental Barcelona", "stars": 5, "base_price": 550, "rating": 4.7},
        {"name": "Majestic Hotel & Spa Barcelona", "stars": 5, "base_price": 350, "rating": 4.5},
    ],
    "amsterdam": [
        {"name": "Waldorf Astoria Amsterdam", "stars": 5, "base_price": 600, "rating": 4.7},
        {"name": "Conservatorium Hotel Amsterdam", "stars": 5, "base_price": 500, "rating": 4.6},
        {"name": "The Dylan Amsterdam", "stars": 5, "base_price": 450, "rating": 4.6},
        {"name": "InterContinental Amstel Amsterdam", "stars": 5, "base_price": 550, "rating": 4.7},
    ],
    "sydney": [
        {"name": "Park Hyatt Sydney", "stars": 5, "base_price": 650, "rating": 4.8},
        {"name": "Four Seasons Hotel Sydney", "stars": 5, "base_price": 550, "rating": 4.6},
        {"name": "Shangri-La Hotel Sydney", "stars": 5, "base_price": 450, "rating": 4.5},
        {"name": "The Langham Sydney", "stars": 5, "base_price": 400, "rating": 4.5},
    ],
    "singapore": [
        {"name": "Marina Bay Sands Singapore", "stars": 5, "base_price": 500, "rating": 4.6},
        {"name": "Raffles Hotel Singapore", "stars": 5, "base_price": 800, "rating": 4.8},
        {"name": "The Fullerton Hotel Singapore", "stars": 5, "base_price": 400, "rating": 4.6},
        {"name": "Capella Singapore", "stars": 5, "base_price": 700, "rating": 4.8},
    ],
    "bangkok": [
        {"name": "Mandarin Oriental Bangkok", "stars": 5, "base_price": 400, "rating": 4.8},
        {"name": "The Peninsula Bangkok", "stars": 5, "base_price": 350, "rating": 4.7},
        {"name": "Shangri-La Hotel Bangkok", "stars": 5, "base_price": 250, "rating": 4.5},
        {"name": "Four Seasons Hotel Bangkok", "stars": 5, "base_price": 450, "rating": 4.7},
    ],
    "bucharest": [
        {"name": "JW Marriott Bucharest Grand Hotel", "stars": 5, "base_price": 180, "rating": 4.6},
        {"name": "InterContinental Bucharest", "stars": 5, "base_price": 150, "rating": 4.5},
        {"name": "Radisson Blu Hotel Bucharest", "stars": 5, "base_price": 120, "rating": 4.4},
        {"name": "Sheraton Bucharest Hotel", "stars": 5, "base_price": 140, "rating": 4.5},
        {"name": "Hilton Garden Inn Bucharest", "stars": 4, "base_price": 90, "rating": 4.4},
    ],
    "cairo": [
        {"name": "Four Seasons Hotel Cairo at The First Residence", "stars": 5, "base_price": 350, "rating": 4.7},
        {"name": "Marriott Mena House Cairo", "stars": 5, "base_price": 300, "rating": 4.6},
        {"name": "The Nile Ritz-Carlton Cairo", "stars": 5, "base_price": 280, "rating": 4.5},
        {"name": "Kempinski Nile Hotel Cairo", "stars": 5, "base_price": 250, "rating": 4.5},
    ],
    "marrakech": [
        {"name": "Royal Mansour Marrakech", "stars": 5, "base_price": 1200, "rating": 4.9},
        {"name": "La Mamounia Marrakech", "stars": 5, "base_price": 700, "rating": 4.8},
        {"name": "Four Seasons Resort Marrakech", "stars": 5, "base_price": 600, "rating": 4.7},
        {"name": "Mandarin Oriental Marrakech", "stars": 5, "base_price": 550, "rating": 4.7},
    ],
    "istanbul": [
        {"name": "Four Seasons Hotel Istanbul at Sultanahmet", "stars": 5, "base_price": 450, "rating": 4.8},
        {"name": "Ciragan Palace Kempinski Istanbul", "stars": 5, "base_price": 500, "rating": 4.7},
        {"name": "The St. Regis Istanbul", "stars": 5, "base_price": 400, "rating": 4.6},
        {"name": "Raffles Istanbul", "stars": 5, "base_price": 380, "rating": 4.6},
    ],
}

# Generic luxury hotel chains for unknown destinations
GENERIC_HOTELS = [
    {"chain": "JW Marriott", "stars": 5, "base_price": 300, "rating": 4.6},
    {"chain": "Hilton", "stars": 5, "base_price": 250, "rating": 4.5},
    {"chain": "InterContinental", "stars": 5, "base_price": 280, "rating": 4.5},
    {"chain": "Hyatt Regency", "stars": 5, "base_price": 260, "rating": 4.5},
    {"chain": "Sheraton", "stars": 5, "base_price": 220, "rating": 4.4},
    {"chain": "Radisson Blu", "stars": 4, "base_price": 180, "rating": 4.4},
]

def get_hotels_for_destination(location: str, stars: int):
    """Get hotels for a specific destination."""
    location_lower = location.lower().split(",")[0].strip()
    
    # Check for known destinations
    for key in DESTINATION_HOTELS:
        if key in location_lower:
            hotels = DESTINATION_HOTELS[key]
            # Filter by stars if needed
            if stars < 5:
                return [h for h in hotels if h.get("stars", 5) <= stars + 1]
            return hotels
    
    # For unknown destinations, generate hotels with the destination name
    location_clean = location.split(",")[0].strip()
    return [
        {"name": f"{h['chain']} {location_clean}", "stars": h["stars"], "base_price": h["base_price"], "rating": h["rating"]}
        for h in GENERIC_HOTELS
    ]

@mcp.tool()
def search_hotels(location: str, check_in: str, check_out: str, stars: int = 4) -> str:
    """Search for hotels in a specific location. Returns a list of hotel options with booking links."""
    
    try:
        d1 = datetime.strptime(check_in, "%Y-%m-%d")
        d2 = datetime.strptime(check_out, "%Y-%m-%d")
        nights = (d2 - d1).days
        check_in_fmt = d1.strftime("%B %d")
        check_out_fmt = d2.strftime("%B %d, %Y")
        if nights < 1:
            return "Error: Check-out must be after check-in."
    except ValueError:
        return "Error: Dates must be in YYYY-MM-DD format."
    
    # Clean location for URLs
    location_clean = location.split(",")[0].strip()
    location_encoded = urllib.parse.quote(location)  # Full location for search
    
    results = []
    results.append(f"🏨 **Hotels in {location}**")
    results.append(f"📅 {check_in_fmt} - {check_out_fmt} ({nights} night{'s' if nights > 1 else ''})")
    results.append("")
    results.append("---")
    
    # Get destination-specific hotels
    available_hotels = get_hotels_for_destination(location, stars)
    selected_hotels = random.sample(available_hotels, min(4, len(available_hotels)))
    
    for i, hotel in enumerate(selected_hotels, 1):
        # Calculate price with some variation
        price_var = random.uniform(0.9, 1.15)
        price_per_night = int(hotel["base_price"] * price_var)
        total_price = price_per_night * nights
        
        # Get rating with small variation
        rating = round(min(5.0, hotel["rating"] + random.uniform(-0.1, 0.1)), 1)
        reviews = random.randint(1000, 8000)
        
        star_emoji = "⭐" * hotel.get("stars", 5)
        
        # Build WORKING booking URLs
        # Booking.com - search for hotel name + location
        hotel_search = urllib.parse.quote(f"{hotel['name']}")
        booking_url = f"https://www.booking.com/searchresults.html?ss={hotel_search}&checkin={check_in}&checkout={check_out}&group_adults=2&no_rooms=1"
        
        # Hotels.com - search by destination (more reliable than hotel name)
        hotels_url = f"https://www.hotels.com/Hotel-Search?destination={location_encoded}&startDate={check_in}&endDate={check_out}&rooms=1&adults=2&sort=RECOMMENDED"
        
        # Google Hotels - most reliable for finding specific hotels
        google_url = f"https://www.google.com/travel/hotels/{location_encoded}?q={hotel_search}&dates={check_in}%20to%20{check_out}"
        
        # Amenities
        if hotel.get("stars", 5) >= 5:
            amenities = ["🏊 Pool", "🧖 Spa", "🍽️ Restaurant", "🏋️ Gym", "🛎️ Concierge"]
        else:
            amenities = ["📶 WiFi", "☕ Breakfast", "🏋️ Gym", "🅿️ Parking"]
        
        results.append("")
        results.append(f"### 🏨 Option {i}: {hotel['name']}")
        results.append(f"{star_emoji}{rating}/5 ({reviews:,} reviews)")
        results.append(f"💰 **${price_per_night}/night** → **${total_price:,} total** for {nights} nights")
        results.append(f"✨ {' • '.join(amenities)}")
        results.append(f"🔗 [Booking.com]({booking_url}) | [Google Hotels]({google_url})")
        results.append("")
    
    results.append("---")
    results.append("")
    # General search link for more options
    results.append(f"🔍 **See all hotels:** [Search {location_clean} on Booking.com](https://www.booking.com/searchresults.html?ss={location_encoded}&checkin={check_in}&checkout={check_out}&group_adults=2)")
    
    return "\n".join(results)

@mcp.tool()
def get_hotel_details(hotel_name: str) -> str:
    """Get detailed information about a specific hotel."""
    rating = round(random.uniform(4.3, 4.9), 1)
    reviews = random.randint(1000, 5000)
    
    return f"""🏨 **{hotel_name}**

📍 **Location:** Prime city center location
⭐ **Rating:** {rating}/5.0 ({reviews:,} guest reviews)

**Premium Amenities:**
• 🏊 Infinity rooftop pool with city views
• 🧖 Full-service spa & wellness center
• 🍽️ Award-winning restaurants & bars
• 🏋️ State-of-the-art fitness center
• 📶 Complimentary high-speed WiFi
• 🛎️ 24-hour concierge service
• 🚗 Valet parking available
• 🛏️ Premium bedding & pillow menu

**Check-in:** 3:00 PM | **Check-out:** 12:00 PM"""

if __name__ == "__main__":
    mcp.run()