Skip to main content
Glama

airbnb_listing_details

Retrieve comprehensive Airbnb property details including availability, pricing, and direct booking links for specific listings using listing ID and travel dates.

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 main handler function that implements the tool logic: parses parameters, builds and validates the listing URL against robots.txt, fetches the HTML page, extracts JSON data from the #data-deferred-state-0 script tag using Cheerio, filters and processes relevant sections (location, policies, highlights, description, amenities), and returns the structured details as JSON text content.
    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 complete Tool definition object for 'airbnb_listing_details', including name, description, and inputSchema specifying required 'id' and optional parameters for 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:661-663 (registration)
    Registration of the tool list for discovery via ListToolsRequestSchema handler, where AIRBNB_TOOLS array includes the airbnb_listing_details tool.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: AIRBNB_TOOLS,
    }));
  • index.ts:695-698 (registration)
    Dispatch/registration in the CallToolRequestSchema switch statement that routes calls to the specific handler function for airbnb_listing_details.
    case "airbnb_listing_details": {
      result = await handleAirbnbListingDetails(request.params.arguments);
      break;
    }
  • The AIRBNB_TOOLS constant array that collects and exports the tool definitions for registration.
    const AIRBNB_TOOLS = [
      AIRBNB_SEARCH_TOOL,
      AIRBNB_LISTING_DETAILS_TOOL,
    ] as const;

Tool Definition Quality

Score is being calculated. Check back soon.

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/openbnb-org/mcp-server-airbnb'

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