analyzeListingPhotos
Analyze Airbnb listing photos to assess property quality, identify key features, and evaluate visual presentation for informed booking decisions.
Instructions
Analyze photos from an Airbnb listing
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Airbnb listing ID |
Implementation Reference
- photoTools.ts:56-71 (handler)Handler logic for 'analyzeListingPhotos' tool: extracts photos using extractListingPhotos, formats analysis prompt, and returns structured response with success status, photo count, prompt, and URLs.if (toolName === 'analyzeListingPhotos') { return { content: [ { type: 'text', text: JSON.stringify({ success: photos.extractionSuccess, photoCount: photos.photoCount, analysisPrompt: formatPhotosForAnalysis(photos), photoUrls: photos.photoUrls, }), }, ], isError: !photos.extractionSuccess, }; }
- photoTools.ts:15-26 (schema)Input schema definition for the 'analyzeListingPhotos' tool, requiring Airbnb listing ID.{ name: 'analyzeListingPhotos', description: 'Analyze photos from an Airbnb listing', inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Airbnb listing ID' }, }, required: ['id'], }, }, ];
- index.ts:666-670 (registration)Tool dispatch registration in the main CallToolRequestSchema handler switch statement, routing 'analyzeListingPhotos' to handlePhotoAnalysisTool.case "getListingPhotos": case "analyzeListingPhotos": { result = await handlePhotoAnalysisTool(request.params.name, request.params.arguments); break; }
- photoAnalyzer.ts:4-42 (helper)Helper function to scrape and extract photo URLs from an Airbnb listing page using fetch and cheerio.export async function extractListingPhotos(listingId: string) { try { const url = `https://www.airbnb.com/rooms/${listingId}`; const response = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' }, }); if (!response.ok) throw new Error(`HTTP ${response.status}`); const html = await response.text(); const $ = cheerio.load(html); const photoUrls: string[] = []; $('img[src*="airbnb"]').each((_: any, el: any) => { const src = $(el).attr('src'); const alt = $(el).attr('alt'); if (src && alt?.includes('photo') && photoUrls.length < 50) { if (!photoUrls.includes(src)) photoUrls.push(src); } }); return { listingId, photoUrls, photoCount: photoUrls.length, extractionSuccess: photoUrls.length > 0, timestamp: new Date().toISOString(), }; } catch (error) { return { listingId, photoUrls: [], photoCount: 0, extractionSuccess: false, error: (error instanceof Error ? error.message : 'Unknown error'), timestamp: new Date().toISOString(), }; } }
- photoAnalyzer.ts:44-47 (helper)Helper function to format extracted photos into a string prompt for analysis.export function formatPhotosForAnalysis(photos: any) { const photoList = photos.photoUrls.map((url: string, i: number) => `Photo ${i + 1}: ${url}`).join('\n'); return `Listing ${photos.listingId}\n${photoList}`; }