Skip to main content
Glama

check_warehouse_stock

Check product availability at specific Costco warehouses using item numbers or URLs and ZIP codes to find nearby locations.

Instructions

Check in-warehouse availability of a product at a specific Costco location

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
item_numberNoCostco item number
urlNoProduct URL (alternative to item_number)
zip_codeNoZIP code to find nearby warehouses

Implementation Reference

  • The handleCheckWarehouseStock function implements the tool logic. It navigates to a Costco product page, optionally sets a ZIP code location, scrapes warehouse availability information from the page, and returns stock status with details about which warehouses have the item in stock.
    async function handleCheckWarehouseStock(
      itemNumber?: string,
      url?: string,
      zipCode?: string
    ) {
      if (!itemNumber && !url) {
        return err("Provide either item_number or url");
      }
    
      return withPage(async (page: Page) => {
        const productUrl = url ?? `https://www.costco.com/p.${itemNumber}.product.html`;
    
        await page.goto(productUrl, {
          waitUntil: "domcontentloaded",
          timeout: 30000,
        });
        await page.waitForTimeout(2000);
    
        // Try to set location if zip code provided
        if (zipCode) {
          try {
            const locationBtn = await page.$(
              '[class*="warehouse-picker"], [automation-id="warehouse-picker-btn"], button[aria-label*="warehouse" i]'
            );
            if (locationBtn) {
              await locationBtn.click();
              await page.waitForTimeout(1000);
    
              const zipInput = await page.waitForSelector(
                'input[placeholder*="ZIP" i], input[name*="zip" i]',
                { timeout: 5000 }
              );
              await zipInput.fill(zipCode);
              await zipInput.press("Enter");
              await page.waitForTimeout(2000);
            }
          } catch {
            // Continue without location update
          }
        }
    
        const stockInfo = await page.evaluate(() => {
          // Check for warehouse availability section
          const warehouseSection = document.querySelector(
            '[class*="warehouse-availability"], [automation-id="warehouse-availability"], [class*="in-warehouse"]'
          );
    
          if (!warehouseSection) {
            // Check if item is online-only
            const onlineOnly = document.querySelector(
              '[class*="online-only"], [automation-id="online-only"]'
            );
    
            const availabilityText =
              document.querySelector('[class*="availability"], [automation-id*="availability"]')
                ?.textContent?.trim()?.slice(0, 300) ?? "";
    
            return {
              available: false,
              onlineOnly: !!onlineOnly,
              details: availabilityText || "Warehouse availability information not found on this page.",
              warehouses: [],
            };
          }
    
          const isAvailable =
            !warehouseSection.textContent?.toLowerCase().includes("not available") &&
            !warehouseSection.textContent?.toLowerCase().includes("out of stock");
    
          const warehouseEls = Array.from(
            document.querySelectorAll('[class*="warehouse-name"], [automation-id="warehouse-name"]')
          );
          const warehouses = warehouseEls
            .map((el) => el.textContent?.trim() ?? "")
            .filter(Boolean)
            .slice(0, 5);
    
          return {
            available: isAvailable,
            onlineOnly: false,
            details: warehouseSection.textContent?.trim()?.slice(0, 300) ?? "",
            warehouses,
          };
        });
    
        const lines = [
          `**Warehouse Stock Check — Item #${itemNumber ?? "from URL"}**\n`,
        ];
    
        if (stockInfo.onlineOnly) {
          lines.push("Status: Online-only item — not available in warehouses");
        } else {
          lines.push(
            `Status: ${stockInfo.available ? "Available in warehouse" : "Not available in warehouse"}`
          );
        }
    
        if (zipCode) lines.push(`ZIP: ${zipCode}`);
    
        if (stockInfo.warehouses.length > 0) {
          lines.push(`\nWarehouses with stock:`);
          stockInfo.warehouses.forEach((w) => lines.push(`  - ${w}`));
        }
    
        if (stockInfo.details) {
          lines.push(`\nDetails: ${stockInfo.details}`);
        }
    
        lines.push(`\nURL: ${page.url()}`);
    
        return ok(lines.join("\n"));
      });
    }
  • src/index.ts:257-276 (registration)
    Tool registration (schema definition) for 'check_warehouse_stock'. Defines the tool name, description, and inputSchema with properties for item_number, url, and zip_code parameters.
      name: "check_warehouse_stock",
      description: "Check in-warehouse availability of a product at a specific Costco location",
      inputSchema: {
        type: "object",
        properties: {
          item_number: {
            type: "string",
            description: "Costco item number",
          },
          url: {
            type: "string",
            description: "Product URL (alternative to item_number)",
          },
          zip_code: {
            type: "string",
            description: "ZIP code to find nearby warehouses",
          },
        },
      },
    },
  • src/index.ts:353-358 (registration)
    Handler dispatch in the CallToolRequestSchema switch statement. Routes incoming 'check_warehouse_stock' tool calls to the handleCheckWarehouseStock function with extracted arguments.
    case "check_warehouse_stock":
      return await handleCheckWarehouseStock(
        a.item_number as string | undefined,
        a.url as string | undefined,
        a.zip_code as string | undefined
      );

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/markswendsen-code/mcp-costco'

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