Skip to main content
Glama
dumyCq

Jinko Hotel Booking MCP Server

by dumyCq
formatters.ts6.29 kB
/** * Formatting functions for hotel data */ import { Hotel, HotelDetail, HotelSummary } from "./types.js"; /** * Format hotel to a summary object for search results * @param hotel Hotel object to format * @returns Formatted hotel summary object with images and lowest rate info */ export function formatHotelToSummaryObject(hotel: Hotel): HotelSummary { // Get up to 3 images (main photo first) const images: string[] = []; // Add main photo if exists if (hotel.main_photo) { images.push(hotel.main_photo); } // Add up to 2 more photos from images array if (hotel.images && hotel.images.length > 0) { const additionalImages = hotel.images .filter((img: any) => img.path !== hotel.main_photo) // Exclude main photo if already added .slice(0, images.length === 0 ? 3 : (3 - images.length)) .map((img: any) => img.path); images.push(...additionalImages); } // Find the room with the lowest rate let lowestRateRoom = { room_id: "", room_name: "", rate_id: "", price: `${hotel.min_price?.value || "N/A"} ${hotel.min_price?.currency || "USD"}`, is_refundable: false, payment_type: "Pay Now" }; if (hotel.rooms && hotel.rooms.length > 0) { // Sort rooms by min_price to find the cheapest const sortedRooms = [...hotel.rooms].sort((a, b) => { const priceA = a.min_price ? Number(a.min_price.value) : Infinity; const priceB = b.min_price ? Number(b.min_price.value) : Infinity; return priceA - priceB; }); const cheapestRoom = sortedRooms[0]; if (cheapestRoom && cheapestRoom.lowest_rate) { // Find the associated rate const rate = cheapestRoom.rates?.find((r: any) => r.rate_id === cheapestRoom.lowest_rate.rate_id); // Extract meal plan from rate if available let mealPlan: string | undefined; let paymentType = "Pay Now"; if (rate?.opaque) { try { const rateData = JSON.parse(rate.opaque); mealPlan = rateData.meal_plan?.description; paymentType = rateData.pricing?.pricing_type === "pay_later" ? "Pay Later" : "Pay Now"; } catch (e) { // Ignore parsing errors } } lowestRateRoom = { room_id: cheapestRoom.room_id, room_name: cheapestRoom.room_name, rate_id: cheapestRoom.lowest_rate.rate_id, price: `${cheapestRoom.min_price?.value || "N/A"} ${cheapestRoom.min_price?.currency || "USD"}`, is_refundable: rate?.is_refundable || false, payment_type: paymentType, }; } } return { id: hotel.id, name: hotel.name, ranking: `${hotel.star_rating || "N/A"} stars`, location: hotel.address || "Unknown location", price: `From ${hotel.min_price?.value || "N/A"} ${hotel.min_price?.currency || "USD"}`, images, lowest_rate: lowestRateRoom }; } /** * Format hotel to a detail object with complete room and rate information * @param hotel Hotel object to format * @returns Formatted hotel detail object */ export function formatHotelToDetailObject(hotel: Hotel): HotelDetail { if (!hotel) { return { id: "unknown", name: "Unknown Hotel", ranking: "N/A", location: "N/A", facilities: [], images: [], rooms: [] }; } // Get all hotel images const images = hotel.images ? hotel.images.map((img: any) => img.path) : []; // If main photo exists and not already in images, add it to the beginning if (hotel.main_photo && !images.includes(hotel.main_photo)) { images.unshift(hotel.main_photo); } // Format facilities const facilities = hotel.amenities.filter((amenity: any) => !amenity.name.includes("Unknown Facility") ).map((amenity: any) => amenity.name); // Get check-in/check-out times let checkIn: string | undefined; let checkOut: string | undefined; if (hotel.policies) { const checkInPolicy = hotel.policies.find((p: any) => p.type === 'check_in'); const checkOutPolicy = hotel.policies.find((p: any) => p.type === 'check_out'); checkIn = checkInPolicy?.description?.[0]; checkOut = checkOutPolicy?.description?.[0]; } // Format rooms with all rates const rooms = hotel.rooms ? hotel.rooms.map((room: any) => { // Get room images const roomImages = room.images ? room.images.map((img: any) => img.path) : []; // Get room amenities const roomAmenities = room.amenities ? room.amenities .filter((a: any) => !a.name.includes("Unknown")) .map((a: any) => a.name) : []; // Format all rates for the room const rates = room.rates ? room.rates.map((rate: any) => { // Extract meal plan if available let mealPlan: string | undefined; let paymentType = rate.description || "Pay Now"; try { if (rate.opaque) { const rateData = JSON.parse(rate.opaque); mealPlan = rateData.meal_plan?.description; // Determine payment type from opaque data if available if (rateData.pricing && rateData.pricing.pricing_type) { paymentType = rateData.pricing.pricing_type === "pay_later" ? "Pay Later" : "Pay Now"; } } } catch (e) { // Ignore parsing errors } return { rate_id: rate.rate_id, description: rate.description || "", price: `${rate.selling_price?.value || "N/A"} ${rate.selling_price?.currency || "USD"}`, is_refundable: rate.is_refundable || false, cancellation_policy: rate.policies?.find((p: any) => p.type === 'cancellation')?.description, meal_plan: mealPlan, payment_type: paymentType }; }) : []; return { room_id: room.room_id, room_name: room.room_name, description: room.description, images: roomImages, amenities: roomAmenities, max_occupancy: room.max_occupancy == null ? undefined : room.max_occupancy, rates }; }) : []; // Return structured hotel detail object return { id: hotel.id, name: hotel.name, ranking: `${hotel.star_rating || "N/A"} stars`, location: hotel.address || "Unknown location", description: hotel.description, facilities, images, check_in: checkIn, check_out: checkOut, rooms }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dumyCq/jinko-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server