Skip to main content
Glama
ampcome-mcps

Airbnb Search & Listings

by ampcome-mcps

airbnb_listing_details

Retrieve comprehensive property details for specific Airbnb listings, including availability, pricing, and direct booking links for informed accommodation decisions.

Instructions

Get detailed information about a specific Airbnb listing. Provide direct links to the user

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesThe Airbnb listing ID
checkinNoCheck-in date (YYYY-MM-DD)
checkoutNoCheck-out date (YYYY-MM-DD)
adultsNoNumber of adults
childrenNoNumber of children
infantsNoNumber of infants
petsNoNumber of pets
ignoreRobotsTextNoIgnore robots.txt rules for this request

Implementation Reference

  • The handler function that implements the core logic for fetching and parsing detailed information about an Airbnb listing using the provided ID and optional dates/guest parameters. It respects robots.txt, scrapes the page, extracts structured data from a script tag, filters relevant sections, and returns JSON-formatted details.
    async function handleAirbnbListingDetails(params: any) {
      const {
        id,
        checkin,
        checkout,
        adults = 1,
        children = 0,
        infants = 0,
        pets = 0,
        ignoreRobotsText = false,
      } = params;
    
      // Build listing URL
      const listingUrl = new URL(`${BASE_URL}/rooms/${id}`);
      
      // Add query parameters
      if (checkin) listingUrl.searchParams.append("check_in", checkin);
      if (checkout) listingUrl.searchParams.append("check_out", checkout);
      
      // Add guests
      const adults_int = parseInt(adults.toString());
      const children_int = parseInt(children.toString());
      const infants_int = parseInt(infants.toString());
      const pets_int = parseInt(pets.toString());
      
      const totalGuests = adults_int + children_int;
      if (totalGuests > 0) {
        listingUrl.searchParams.append("adults", adults_int.toString());
        listingUrl.searchParams.append("children", children_int.toString());
        listingUrl.searchParams.append("infants", infants_int.toString());
        listingUrl.searchParams.append("pets", pets_int.toString());
      }
    
      // Check if path is allowed by robots.txt
      const path = listingUrl.pathname + listingUrl.search;
      if (!ignoreRobotsText && !isPathAllowed(path)) {
        log('warn', 'Listing details blocked by robots.txt', { path, url: listingUrl.toString() });
        return {
          content: [{
            type: "text",
            text: JSON.stringify({
              error: robotsErrorMessage,
              url: listingUrl.toString(),
              suggestion: "Consider enabling 'ignore_robots_txt' in extension settings if needed for testing"
            }, null, 2)
          }],
          isError: true
        };
      }
    
      const allowSectionSchema: Record<string, any> = {
        "LOCATION_DEFAULT": {
          lat: true,
          lng: true,
          subtitle: true,
          title: true
        },
        "POLICIES_DEFAULT": {
          title: true,
          houseRulesSections: {
            title: true,
            items : {
              title: true
            }
          }
        },
        "HIGHLIGHTS_DEFAULT": {
          highlights: {
            title: true
          }
        },
        "DESCRIPTION_DEFAULT": {
          htmlDescription: {
            htmlText: true
          }
        },
        "AMENITIES_DEFAULT": {
          title: true,
          seeAllAmenitiesGroups: {
            title: true,
            amenities: {
              title: true
            }
          }
        },
        //"AVAILABLITY_CALENDAR_DEFAULT": true,
      };
    
      try {
        log('info', 'Fetching listing details', { id, checkin, checkout, adults, children });
        
        const response = await fetchWithUserAgent(listingUrl.toString());
        const html = await response.text();
        const $ = cheerio.load(html);
        
        let details = {};
        
        try {
          const scriptElement = $("#data-deferred-state-0").first();
          if (scriptElement.length === 0) {
            throw new Error("Could not find data script element - page structure may have changed");
          }
          
          const scriptContent = $(scriptElement).text();
          if (!scriptContent) {
            throw new Error("Data script element is empty");
          }
          
          const clientData = JSON.parse(scriptContent).niobeClientData[0][1];
          const sections = clientData.data.presentation.stayProductDetailPage.sections.sections;
          sections.forEach((section: any) => cleanObject(section));
          
          details = sections
            .filter((section: any) => allowSectionSchema.hasOwnProperty(section.sectionId))
            .map((section: any) => {
              return {
                id: section.sectionId,
                ...flattenArraysInObject(pickBySchema(section.section, allowSectionSchema[section.sectionId]))
              }
            });
            
          log('info', 'Listing details fetched successfully', { 
            id, 
            sectionsFound: Array.isArray(details) ? details.length : 0 
          });
        } catch (parseError) {
          log('error', 'Failed to parse listing details', {
            error: parseError instanceof Error ? parseError.message : String(parseError),
            id,
            url: listingUrl.toString()
          });
          
          return {
            content: [{
              type: "text",
              text: JSON.stringify({
                error: "Failed to parse listing details from Airbnb. The page structure may have changed.",
                details: parseError instanceof Error ? parseError.message : String(parseError),
                listingUrl: listingUrl.toString()
              }, null, 2)
            }],
            isError: true
          };
        }
    
        return {
          content: [{
            type: "text",
            text: JSON.stringify({
              listingUrl: listingUrl.toString(),
              details: details
            }, null, 2)
          }],
          isError: false
        };
      } catch (error) {
        log('error', 'Listing details request failed', {
          error: error instanceof Error ? error.message : String(error),
          id,
          url: listingUrl.toString()
        });
        
        return {
          content: [{
            type: "text",
            text: JSON.stringify({
              error: error instanceof Error ? error.message : String(error),
              listingUrl: listingUrl.toString(),
              timestamp: new Date().toISOString()
            }, null, 2)
          }],
          isError: true
        };
      }
    }
  • The Tool definition including name, description, and inputSchema for validating parameters like listing ID, dates, and guest counts.
    const AIRBNB_LISTING_DETAILS_TOOL: Tool = {
      name: "airbnb_listing_details",
      description: "Get detailed information about a specific Airbnb listing. Provide direct links to the user",
      inputSchema: {
        type: "object",
        properties: {
          id: {
            type: "string",
            description: "The Airbnb listing ID"
          },
          checkin: {
            type: "string",
            description: "Check-in date (YYYY-MM-DD)"
          },
          checkout: {
            type: "string",
            description: "Check-out date (YYYY-MM-DD)"
          },
          adults: {
            type: "number",
            description: "Number of adults"
          },
          children: {
            type: "number",
            description: "Number of children"
          },
          infants: {
            type: "number",
            description: "Number of infants"
          },
          pets: {
            type: "number",
            description: "Number of pets"
          },
          ignoreRobotsText: {
            type: "boolean",
            description: "Ignore robots.txt rules for this request"
          }
        },
        required: ["id"]
      }
    };
  • index.ts:138-141 (registration)
    Registration of the tool in the AIRBNB_TOOLS array, which is returned by the ListTools handler.
    const AIRBNB_TOOLS = [
      AIRBNB_SEARCH_TOOL,
      AIRBNB_LISTING_DETAILS_TOOL,
    ] as const;
  • index.ts:661-663 (registration)
    MCP server handler for ListToolsRequestSchema that exposes the registered tools including airbnb_listing_details.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: AIRBNB_TOOLS,
    }));
  • index.ts:695-697 (registration)
    Dispatch case in the CallToolRequestSchema handler that routes calls to the airbnb_listing_details handler function.
    case "airbnb_listing_details": {
      result = await handleAirbnbListingDetails(request.params.arguments);
      break;
Install Server

Other Tools

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/ampcome-mcps/airbnb-mcp'

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