[Pangolinfo MCP self-introspection] One call to get the full capability catalog, canonical workflows, and usage tips — no backend call, free.
Use when: an AI client first connects to pangolinfo-mcp and needs to quickly grasp "what tools exist" / "how do they chain" / "which workflow for which scene"; user asks "what can you do" / "what capabilities are there"; capability audit before SOP planning.
Don't use: for the full description of one specific tool (use tools/list — the 'summary' mode here gives one-liners only); for account balance or remaining credits (CONTRACT §9 forbids exposing account endpoints via MCP).
Returns: { version, locale, liveTools[{name, domain, oneLiner, cost}], workflows[{title, steps[], note}], tips[] }.
Pair with: ↓ AI decides which concrete tool to call next; does not consume downstream tools.
Cost: 0 points (local data, no backend round-trip).
Parameters (1)
detailstring
'summary' returns tool catalog + canonical workflows (default, token-light); 'full' also expands the full description of every tool (~8KB — use on first integration or when context budget allows).
search_amazon
[Amazon SERP scrape] Run a real Amazon keyword search and return the first-page ASIN list.
Use when: user says "search Amazon for X" / "who sells X" / "top results for keyword X" / "competitors for X"; or you need a list of ASINs for a keyword as upstream input to deeper analysis.
Don't use: for a single ASIN detail (use get_amazon_product); for category bestseller ranks (use list_bestsellers); for Google/external demand on the term (use ai_search or keyword_trends).
Returns (format='json', default): data.json[0].data.{ pageIndex, nextPage, keyword, results[{ asin, title, price, star, rating, sales, badge, rank, sponsored, image, delivery }] } — ~22 rows/page. **Pagination**: use the 'page' param (default 1, 1-based); response's 'nextPage' holds the next page number, 'nextPage=null' means last page reached.
Pair with: ↓ feed results[].asin into get_amazon_product / get_amazon_reviews for single-product deep-dive; ↓ feed the same keyword into keyword_trends to compare in-site vs external demand.
Cost: ~1 point/page, ~5s. **Only paginate when the user explicitly asks for more / Top-N (N>22) / all results** — otherwise the first page is enough.
ZIP code that must match the site country (amz_us → US zip, amz_jp → JP zip, ...). Optional; backend picks a random one from the per-country pool when omitted. Cross-country zips (e.g. amz_us + JP zip) are rejected by the backend. Examples: 10001 (NY) / 90001 (LA) / 100-0001 (Tokyo).
formatstring
Response format. Defaults to 'json' — structured search rows (asin, title, price, star, rating, sales, badge, rank, ...) ready for programmatic use. Use 'markdown' if you want the rendered SERP text instead.
pageinteger
Page number, 1-based. ~22 ASINs per page. Use response's pageIndex/nextPage to decide whether to continue: nextPage holds the next page number; nextPage=null (or absent) means last page reached. **Only paginate when the user explicitly asks for more / Top-N where N exceeds one page / all results** — otherwise the first page is enough.
get_amazon_product
[Amazon single-product detail] Scrape the full PDP for one ASIN.
Use when: user supplies a specific ASIN ("look at B0XXXXXXXX" / "check this product's price/rating/seller" / "analyse this competitor"); or as a SOP step after candidate ASINs are picked.
Don't use: for many products at once (use search_amazon or list_* series for lists); for reviews only (use get_amazon_reviews — cheaper and more focused).
Returns (format='json', default): data.json[0].data.results[0] = { asin, title, price, star, rating, brand, seller{name,id}, parentAsin, ratingDistribution[], aiReviewsSummary, bestSellersRankItems, reviews[{date,star,content,helpful,...}], productOverview[], features[], productDescription[], images[], variantDetails[], attributes[], category_id, breadCrumbs, ... } — 30+ fields (variantDetails summary included).
Pair with: ↑ asin typically comes from search_amazon / list_bestsellers / filter_niches; ↓ feed the same asin into get_amazon_reviews for more reviews (the PDP carries only ~5-10).
Cost: ~1 point/call, ~5s.
ZIP code that must match the site country (amz_us → US zip, amz_jp → JP zip, ...). Optional; backend picks a random one from the per-country pool when omitted. Cross-country zips (e.g. amz_us + JP zip) are rejected by the backend. Examples: 10001 (NY) / 90001 (LA) / 100-0001 (Tokyo).
formatstring
Response format. Defaults to 'json' — a structured payload (title, price, rating, reviews, seller, etc.) ready for programmatic use. Use 'markdown' if you want the rendered PDP text instead.
get_amazon_reviews
[Amazon review batch scrape] Page-fetch real buyer reviews for an ASIN. Filterable by star / sort / media type.
Use when: user says "look at X's negative reviews" / "mine pain points" / "analyse competitor reviews" / "do VOC" / "find user complaints for Listing copy"; or pre-launch critical-review scan; or finding improvement points for listing optimization.
Don't use: when the few reviews already in the PDP would suffice (get_amazon_product carries 5-10 reviews + aiReviewsSummary — enough for a quick read); for keyword search (use search_amazon).
Returns: data.json[0].data.results[{ reviewId, date, country, star, title, content, author, authorId, authorLink, imgs[], videos, purchased, vineVoice, helpful, attributes }] — ~10 reviews per page.
Pair with: ↑ asin typically from search_amazon / get_amazon_product / list_bestsellers; ↓ review text can be fed directly to an LLM for pain-point clustering and keyword extraction.
Cost: **10 points per page** (expensive). Start with pageCount=1 to confirm data, scale to 3-5 only when needed. Prefer filterByStar='critical' — highest signal density.
Tips: filterByStar = all_stars / five_star ... one_star / positive / critical; sortBy = recent (default) | helpful; mediaType = all_contents (default) | media_reviews_only (with photos/videos, higher credibility).
Number of review pages to fetch (~10 reviews per page). **Costs 10 points per page** — control accordingly. Defaults to 1.
filterByStarstring
Filter by star rating. For VOC pain-point mining, pass 'critical' (1-3 star reviews) to surface defects; for positive-aspect extraction, pass 'positive'.
sortBystring
Sort order: 'recent' (newest first — track current sentiment) or 'helpful' (most-upvoted first — highest impact reviews).
mediaTypestring
Review type: 'all_contents' for all, 'media_reviews_only' for reviews with photos/videos only (higher credibility).
zipcodestring
ZIP code that must match the site country (amz_us → US zip, amz_jp → JP zip, ...). Optional; backend picks a random one from the per-country pool when omitted. Cross-country zips (e.g. amz_us + JP zip) are rejected by the backend. Examples: 10001 (NY) / 90001 (LA) / 100-0001 (Tokyo).
list_bestsellers
[Amazon Best Sellers] Top-50 ranking for a category with 24h rank deltas.
Use when: user says "X category bestsellers" / "who's #1 in X" / "any new entrants climbing" / "benchmark top sellers"; setting baseline products during niche scouting; tracking category leadership in competitor radars.
Don't use: for new arrivals (use list_new_releases); for full category listings beyond top 50 (use list_category_products); when you only have a keyword (use search_categories first).
Returns: data.json[0].data.{ reftag, recsList } — recsList is a JSON-string array (parse twice); each row { id, metadataMap.{ render.zg.rank, currentSalesRank, percentageChange, twentyFourHourOldSalesRank } }.
Pair with: ↑ categorySlug from user or scene inference (e.g. 'electronics' / 'home-garden' / 'beauty'); ↓ feed id (ASIN) into get_amazon_product for single-product deep-dive.
Cost: ~1 point/call, ~5s.
Tips: categorySlug is the hyphenated English slug in amazon.com/Best-Sellers URL paths.
Parameters (4)
categorySlugstringrequired
Amazon Best Sellers category slug (lowercase, hyphenated). Examples: 'electronics', 'home-garden', 'beauty', 'toys-and-games'. Find these in the URL path on amazon.com/Best-Sellers.
sitestring
Amazon marketplace. Defaults to amz_us.
zipcodestring
ZIP code that must match the site country (amz_us → US zip, amz_jp → JP zip, ...). Optional; backend picks a random one from the per-country pool when omitted. Cross-country zips (e.g. amz_us + JP zip) are rejected by the backend. Examples: 10001 (NY) / 90001 (LA) / 100-0001 (Tokyo).
formatstring
Response format. Defaults to 'json' — structured Top-50 ranked ASIN list. Use 'markdown' for the rendered page text.
list_new_releases
[Amazon New Releases] Best-selling Top-50 ASINs that hit the market within the last 30 days for a category (backend cap; not 100).
Use when: user says "new arrivals in X" / "any breakout new products" / "newly-launched that sell well" / "trending new directions" / "new entrants to monitor"; GTM scouting for new angles; competitor radar catching new entrants.
Don't use: for evergreen winners (use list_bestsellers); for full category listings (use list_category_products); when you only have a keyword (use search_categories first).
Returns: data.json[0].data.{ reftag='zg_bsnr_g_<slug>', recsList } — recsList is a JSON-string array (parse twice); each row { id, metadataMap.{ render.zg.rank, ... } }.
Pair with: ↑ categorySlug as in list_bestsellers; ↓ feed id (ASIN) into get_amazon_product to see why it climbed (pitch, pricing, variant strategy).
Cost: ~1 point/call, ~5s.
Parameters (4)
categorySlugstringrequired
Amazon New Releases category slug (lowercase, hyphenated). Examples: 'electronics', 'home-garden'. Find these in the URL path on amazon.com/gp/new-releases.
sitestring
Amazon marketplace. Defaults to amz_us.
zipcodestring
ZIP code that must match the site country (amz_us → US zip, amz_jp → JP zip, ...). Optional; backend picks a random one from the per-country pool when omitted. Cross-country zips (e.g. amz_us + JP zip) are rejected by the backend. Examples: 10001 (NY) / 90001 (LA) / 100-0001 (Tokyo).
formatstring
Response format. Defaults to 'json' — structured ranking list. Use 'markdown' for the rendered page text.
list_seller_products
[Amazon seller storefront] List all listings under a merchant ID, paginated (24 rows/page).
Use when: user says "show me this seller's products" / "how many SKUs does store X carry" / "competitor storefront category breadth" / "what is this seller pushing" / "research a seller's catalog strategy".
Don't use: without a merchant ID (find 'sold by' link on any product PDP first); for a single product (use get_amazon_product).
Returns: data.json[0].data.{ pageIndex, maxPage, nextPage, results[{ asin, title, price, star, rating, rank, img }] } — 24 rows/page. **Every row carries rank** (its display order in the storefront, ≈ that seller's in-store popularity ranking) plus star/rating, so **this single call is enough to rank and tabulate the seller's listings — no need to re-fetch each PDP**. **Two pagination modes**: ① page locates a specific page (default 1); ② pageCount accumulates the first N pages in one call (N≤3, flat-merged into the same results). When pageCount>1, pageIndex/nextPage are blanked (pages already merged). **Category filter**: categoryId filters the seller's products by category.
Pair with: ↑ sellerId usually from get_amazon_product's seller.id field, or from amazon.com/sp?seller=... URL; categoryId extractable from the storefront URL's rh=n:<id>; ↓ feed asin into get_amazon_product to deep-dive hero products.
**Chaining pitfall — "what does this seller carry + sort by sales/rank"**: ❌ Do NOT "run get_amazon_product on every ASIN to pull each small-category BSR, then sort" — a storefront often has dozens-to-hundreds of SKUs; fanning out one PDP per ASIN hits the 2-QPS rate wall, bills N times, and blows the Fast-tier budget. ✅ Correct: **the results[] from one call (or pageCount≤3) already carry rank; sort by rank ascending for the in-store order and tabulate with star/rating**. Only when the user explicitly wants exact global small-category BSR should you run get_amazon_product on a **small head set (e.g. the top 5-10 pre-filtered by list rank)** to read bestSellersRankItems[], batched at ≤2 concurrent — never fan out across the whole store.
Cost: ~1 point/page, ~5s; pageCount=N billed by pages actually crawled (failed pages refunded).
Tips: use pageCount to grab the full multi-page SKU set in one shot (max 3 pages); use page to view one specific page; the first page is enough to glance at what the store sells. For sorting, prefer results[].rank (free, already in this response) — don't fan out PDP fetches just to sort. Amazon first-party sellerId = 'ATVPDKIKX0DER'.
Parameters (7)
sellerIdstringrequired
Amazon merchant ID (14-char alphanumeric). Examples: 'ATVPDKIKX0DER' (Amazon.com first-party) / 'A2L77EE7U53NWQ' (Amazon Warehouse). Find it in a product page's 'sold by' link or amazon.com/sp?seller=... URL.
sitestring
Amazon marketplace. Defaults to amz_us.
zipcodestring
ZIP code that must match the site country (amz_us → US zip, amz_jp → JP zip, ...). Optional; backend picks a random one from the per-country pool when omitted. Cross-country zips (e.g. amz_us + JP zip) are rejected by the backend. Examples: 10001 (NY) / 90001 (LA) / 100-0001 (Tokyo).
formatstring
Response format. Defaults to 'json' — structured seller listings. Use 'markdown' for the rendered page text.
pageinteger
Page number, 1-based. 24 rows per page. Use response's pageIndex/maxPage/nextPage to decide whether to continue: nextPage holds the next page number; nextPage=null or page>=maxPage means last page reached. **Only paginate when the user explicitly asks for more / all SKUs** — otherwise the first page is enough. NOTE: when pageCount>1 (multi-page accumulate) is set, page is ignored (the backend always accumulates from page 1).
pageCountinteger
Multi-page accumulate: passing N crawls the first N pages in one call and returns them flat-merged (e.g. 3 = all products from pages 1+2+3). Default 1 (single page, uses the `page` flow); cap 3, larger values treated as 3. Difference vs `page`: `page` locates one specific page, `pageCount` pulls the first N pages merged. **Use only when you need the full multi-page SKU set in one shot.** Billed by pages actually crawled (a failed page is refunded).
categoryIdstring
Category filter ID — filters the seller's products by category. A single leaf category ID (e.g. '7161074011'), or comma-separated multi-level categories (e.g. '172282,502394,7161073011'). Omit = all products of the seller. Extractable from the rh=n:<categoryId> part of an Amazon storefront URL.
list_category_products
[Amazon category listing] List concrete on-sale products under a Browse Node ID (paginated, 24 rows/page).
Use when: user says "what's selling in category X" / "list products in node 12345" / "show me what's in this category"; after picking a categoryId during scouting, you want to see real listings; competitor-research on category density.
Don't use: when only the top-50 winners matter (use list_bestsellers — cheaper and more signal); for category-level aggregate metrics (use filter_categories — sales/search volume/competitor density); for niche rather than full category (use filter_niches).
Returns: data.json[0].data.{ pageIndex, maxPage, nextPage, categoryName, pagination, results[{ asin, title, price, star, rating, rank, img }] } — 24 rows/page. **Pagination**: use the 'page' param (default 1, 1-based); 'nextPage' holds the next page number, 'nextPage=null' or 'page>=maxPage' means last page reached.
Pair with: ↑ nodeId from search_categories (keyword→category) or get_category_children (tree drilldown); ↓ asin into get_amazon_product; same categoryId can also feed filter_categories for aggregate metrics.
Cost: ~1 point/page, ~5s. **Only paginate when the user explicitly asks for more / all results** — otherwise the first page is enough.
Parameters (5)
nodeIdstringrequired
Amazon category Browse Node ID (numeric). Examples: '172282' (Electronics) / '2619526011' (Appliances) / '11965861' (Musical Instruments). Obtain via search_categories or get_category_children.
sitestring
Amazon marketplace. Defaults to amz_us.
zipcodestring
ZIP code that must match the site country (amz_us → US zip, amz_jp → JP zip, ...). Optional; backend picks a random one from the per-country pool when omitted. Cross-country zips (e.g. amz_us + JP zip) are rejected by the backend. Examples: 10001 (NY) / 90001 (LA) / 100-0001 (Tokyo).
formatstring
Response format. Defaults to 'json' — structured category listings. Use 'markdown' for the rendered page text.
pageinteger
Page number, 1-based. 24 rows per page. Use response's pageIndex/maxPage/nextPage to decide whether to continue: nextPage holds the next page number; nextPage=null or page>=maxPage means last page reached. **Only paginate when the user explicitly asks for more / all results** — otherwise the first page is enough.
search_categories
[Amazon category search] Match Amazon's category tree by keyword (Chinese or English) and return candidate nodes.
Use when: user gave a keyword/concept rather than a category id, and a downstream tool needs categoryId / browseNodeId (e.g. filter_niches / filter_categories / list_category_products / inferring list_bestsellers slug); when you need to know where a product concept lives in Amazon's taxonomy.
Don't use: when you already have categoryId/nodeId (use get_category_paths for breadcrumbs or a downstream filter directly); when you want to drill the subtree (use get_category_children).
Returns: data.items.data[{ browseNodeId, browseNodeIdPath, browseNodeName, browseNodeNameCn, browseNodeNamePath, browseNodeNamePathCn, parentBrowseNodeIdPath, productType, sellable, hasChild }] + pagination.
Pair with: ↓ feed browseNodeId into list_category_products / list_bestsellers (derive slug from path) / filter_niches / filter_categories; ↓ feed into get_category_children to drill further; ↓ feed into get_category_paths for breadcrumbs.
Cost: ~1 point/call, ~3s.
Parameters (2)
keywordstringrequired
Category name keyword (Chinese or English). Examples: 'headphones' / 'kitchen knives' / '无线耳机' / 'wireless earbuds'.
sitestring
Marketplace to search categories in. Defaults to 'amz_us'.
get_category_children
[Amazon category tree drilldown] List direct children from any node (or omit parent to start at the roots).
Use when: user says "show me Amazon's category tree" / "subcategories under X" / "list top-level departments" / "drill to level 3"; building a category map; deciding which level is right after search_categories returned candidates.
Don't use: when a keyword jump is faster (use search_categories); when you want products in the category, not its subcategories (use list_category_products).
Returns: data.items.data[{ browseNodeId, browseNodeIdPath, browseNodeName, browseNodeNameCn, parentBrowseNodeIdPath, productType, sellable, hasChild }] + data.items.pagination.{ total, page, size, hasNext }; omit parentBrowseNodeIdPath to fetch top-level roots; hasChild=1 means the node has further children. **Pagination**: use the 'page' param (default 1, size default 10 / max 50); 'pagination.hasNext=true' means the node has more children not yet listed.
Pair with: ↑ parentBrowseNodeIdPath either omitted (roots) or from search_categories; ↓ feed each result's browseNodeIdPath back in to drill another level, or into list_category_products / filter_categories.
Cost: ~1 point/page, ~3s. **Only paginate when a node has unusually many children (>size) and the user explicitly wants all subcategories.**
Parameters (3)
parentBrowseNodeIdPathstring
Parent node path. Either a single browseNodeId or a slash-joined path. Examples: '2619526011' (Appliances, drill from top) / '2619526011/18116197011' (Appliances > Ranges/Ovens/Cooktops, level-3 drill). Omit to fetch top-level roots.
pageinteger
Page number, 1-based.
sizeinteger
Page size.
filter_categories
[Amazon category commercial-metrics filter] Filter categories by dozens of metrics (sales, GMS, search volume, conversion, return rate, price tier, competitor density, …) — or use as a "category detail" endpoint by passing a single categoryId.
Use when: user says "find categories worth entering" / "high-sales categories" / "low return-rate categories" / "high search-volume but low competition categories" / "show me all metrics for category X"; category-level blue-ocean hunt; getting the 30+ metric snapshot of one category.
Don't use: for niche-level (use filter_niches — finer granularity); for actual products in a category (use list_category_products); for just the readable name (use get_category_paths).
Returns: data.items.data[{ id, categoryId, marketplaceId, timeRange, sampleScope, snapshotDate, unitSoldSum, glanceViewsSum, searchVolumeSum, netShippedGmsSum, buyBoxPriceAvg, buyBoxPriceTier, searchToPurchaseRatio, returnRatio, asinCount, offersPerAsin, newAsinCount, newBrandCount, avgAdSpendPerClick, unitSoldTrendDirection, unitSoldChangeRateBucket, ... trend + quantile-bucket fields }] + data.items.pagination.{ total, page, size, hasNext }. **Pagination**: use the 'page' param (default 1, 1-based, size capped at 10); 'pagination.hasNext=true' means more pages exist, 'hasNext=false' means last page.
Pair with: ↑ required timeRange ('l7d' common) + sampleScope ('all_asin') + marketplaceId (defaults US); categoryId from search_categories / get_category_children; ↓ feed high-potential categories into list_category_products / list_bestsellers for real listings.
Cost: ~1 point/page, ~5s.
Tips: size capped at 10 (backend hard limit); only paginate when the user explicitly asks for more candidate categories — single-detail or quick-filter calls are fine on page 1; long-tail filter fields (unitSoldTrendDirections / metricChangeRateBuckets / dozens more) pass through via extraFilters.
Parameters (20)
marketplaceIdstring
Amazon marketplace id. ⚠️ Backend currently supports US only; other marketplaces will fail or fall back. Use US (the default).
timeRangestringrequired
Aggregation time range (required). Examples: 'l7d' (last 7 days — verified working). The exact enum is backend-defined; 'l7d' is the safest known value.
When set, returns the full metric row for that single category (this endpoint doubles as the 'detail' endpoint). Omit to list multiple categories matching the filters. Example: '979832011'.
pageinteger
Page number, 1-based.
sizeinteger
Page size, max 10 (backend hard limit).
sortFieldstring
Sort field; any response field name is accepted (e.g. 'unitSoldSum', 'netShippedGmsSum').
Pass-through for any other upstream filter (e.g. unitSoldTrendDirections, newAsinCountLevels, metricChangeRateBuckets). Keys must match the upstream doc verbatim.
filter_niches
[Amazon niche filter] Filter Amazon Niches (a finer-grained "demand cluster" than categories) by 50+ commercial metrics, or use as a "niche detail" endpoint for one niche.
Use when: user says "find blue ocean" / "high search volume + low competition niches" / "fast-growing small markets" / "niche scouting" / "give me the deep report on this niche" / "low return-rate niches" / "niches with return rate under 10%"; the core filter step of GTM scouting SOPs; getting fee structure / brand age / new-launch trends for one niche.
Don't use: for full categories (use filter_categories); for actual products in a niche (the niche record only carries 1 referenceAsin; combine with categoryId + list_category_products); for plain keyword search (use search_amazon).
Returns: data.items.data[{ nicheId, nicheTitle, referenceAsinImageUrl, currency, searchVolumeT90, searchVolumeT360, searchVolumeGrowthT90, minimumPrice, maximumPrice, avgPrice, productCount, sponsoredProductsPercentage, primeProductsPercentage, top5ProductsClickShare, top20BrandsClickShare, brandCount, sellingPartnerCount, avgBrandAge, avgBestSellerRank, avgProductPrice, avgReviewCount, avgReviewRating, avgDetailPageQuality, newProductsLaunchedT180/T360, successfulLaunchesT90/T180/T360, returnRateT360, fee fields T365 … 100+ fields }] + data.items.pagination.{ total, page, size, hasNext }. **Pagination**: use the 'page' param (default 1, 1-based, size capped at 10 (default 3)); 'pagination.hasNext=true' means more pages exist, 'hasNext=false' means last page.
Pair with: ↑ marketplaceId required (defaults US); nicheTitle for keyword filter, nicheId for single-niche detail; ↓ feed referenceAsin into get_amazon_product to see the representative product; niche doesn't carry a categoryId directly — derive separately if needed.
Cost: ~1 point/call, ~5s.
Tips: size capped at 10 (default 3); pass long-tail filters (50+ fields) via extraFilters; classic blue-ocean combo = high searchVolumeT90Min + low top5ProductsClickShareT360Max + moderate productCountMax + positive searchVolumeGrowthT90Min + returnRateT360Max ≤ 0.10 (low-return). For return-rate filtering use returnRateT360Max (upper bound, 0-1 decimal); the response includes returnRateT360 with the actual return rate.
Parameters (23)
marketplaceIdstring
Amazon marketplace id (required). ⚠️ Backend currently supports US only; other marketplaces will fail or fall back. Use US (the default).
nicheIdstring
When set, returns the full deep report for that single niche (this endpoint doubles as the niche-detail endpoint). Omit to list multiple niches matching the filters. Example: '8140a265-768d-4679-8bc2-994cb1c96f0b' (UUID).
nicheTitlestring
Keyword match against niche titles. Examples: 'iphone 16 wallet case' / 'wireless earbuds for sports'.
pageinteger
Page number, 1-based.
sizeinteger
Page size, max 10 (backend hard limit), default 3 (small default to keep responses under AI context limits — pass size=10 explicitly when you need a wider sweep).
sortFieldstring
Sort field; any response field name is accepted (e.g. 'searchVolumeT90', 'avgProductPrice').
sortOrderstring
Sort order: 'asc' or 'desc'.
searchVolumeT90Mininteger
Min search volume over last 90 days.
searchVolumeT90Maxinteger
Max search volume over last 90 days.
searchVolumeT360Mininteger
Min search volume over last 360 days.
searchVolumeT360Maxinteger
Max search volume over last 360 days.
searchVolumeGrowthT90Minnumber
Min 90-day search-volume growth rate (decimal, 0.1 = +10%).
searchVolumeGrowthT90Maxnumber
Max 90-day search-volume growth rate.
minimumPriceMinnumber
Lower bound on the niche's minimum product price.
maximumPriceMaxnumber
Upper bound on the niche's maximum product price.
productCountMininteger
Min product count in the niche.
productCountMaxinteger
Max product count in the niche.
avgReviewCountMininteger
Min average review count.
avgReviewCountMaxinteger
Max average review count — lower means less competition.
avgReviewRatingMinnumber
Min average review rating (0-5).
top5ProductsClickShareT360Maxnumber
Max top-5-products click share over 360 days (0-1). Lower = more fragmented niche, more opportunity.
returnRateT360Maxnumber
Max return rate over 360 days (0-1).
extraFiltersobject
Pass-through for any other upstream filter (e.g. sponsoredProductsPercentageT360Min, successfulLaunchesT360Max, avgBestSellerRankMax). Keys must match the upstream doc verbatim.
get_category_paths
[Amazon category breadcrumb resolver] Batch-resolve categoryId list to full paths (e.g. 'Electronics > Headphones > Over-Ear Headphones').
Use when: a report needs readable category context (not bare IDs); user has a list of numeric IDs and wants the names; multiple categories need labels for comparison.
Don't use: for a single ID — most other tools already return browseNodeNamePath in their responses; for tree structure (use get_category_children).
Returns: data.items[{ categoryId, categoryName, categoryNameCn, browseNodeNamePaths[], browseNodeNamePathCns[] }] — one row per input ID.
Pair with: ↑ categoryIds from any prior step (filter_niches/filter_categories output, user-pasted ID list); ↓ usually presentation-only, downstream rarely depends on it.
Cost: ~1 point/call, ~2s (cheaper than N single resolutions).
Parameters (2)
categoryIdsarrayrequired
Category IDs to resolve full path for. Examples: ['2619526011'] (Appliances) / ['172282', '11965861'] (Electronics + Musical Instruments).
sitestring
Amazon marketplace. Defaults to 'amz_us' (US).
search_local_maps
[Local Maps via Google Maps] Local-business search (data source: Google Maps; use must comply with Google Terms of Service). Search local businesses at a given lat/lng — returns name, address, rating, review count, etc.
Use when: user says "Y businesses in city X" / "local retail research" / "offline channel distribution" / "coffee shops/supermarkets/wholesalers in area" / "physical-store coverage density"; offline competitor/channel research; gauging physical-supply density of a category in a region.
Don't use: for e-commerce listings (Amazon series); for global trends (use keyword_trends); for Google search results (use ai_search).
Returns: data.organicResults[{ place_id, name, about, rating, number_of_reviews, borough, street_addr, city, postal_code, ... }].
Pair with: ↑ query (business keyword) + latitude/longitude/zoom (zoom 1=world, 13=city, 21=single building); ↓ presentation-focused, downstream rarely consumes.
Cost: ~1.5 points/call, ~5s.
Tips: zoom 13 (city, default) gives you a whole neighborhood; zoom 17+ narrows to one street.
[Design Patent TRO risk control · WIPO global design / IP search] Query the WIPO design database across 12 sources (USPTO US designs, CNID China, HAGUE international registrations, …), with one-click chaining to US design-patent TRO (temporary restraining order) / litigation risk control.
Use when: user says "check trademark" / "design patent search" / "any IP risk for new product" / "X company's patent portfolio" / "WIPO search" / "USPTO query" / "what is registration DM/XXX"; pre-launch IP clearance during scouting/GTM SOPs; competitor IP-portfolio research.
Don't use: for keyword ranks / product reviews / product detail (this is an IP database, not a commerce database); for US text-trademark search (this DB focuses on design patents — text trademark coverage is limited).
Returns: data.data.{ total, hits[{ IRN, HOL[], DETAIL_DATA.structured.{indication_of_products, statement_of_novelty, ...}, IMG[], IMG_DATA[{filename,url}], DC, RD, STATUS, LCS[], DS[], PROD[], SOURCE, DETAIL_URL }] }. With enableLitigation=true each matched patent additionally carries litigationStatus(success/skipped/failed) + caseTotal + cases[{ caseId, docketNumber, caseName, court, status, dateFiled, parties[], patentNumbers[], entries[] }] (backed by US PACER litigation data — one call returns patents + lawsuits).
Pair with: ↑ source required; hol=holder name / prod=product name / irn=international registration / lcs=design classification; enableLitigation=true chains US litigation lookup (IP-risk loop, no separate tool needed); ↓ DETAIL_URL lets the user jump to WIPO's official page to verify.
Cost: ~2 points/call, ~5s; with enableLitigation=true add +12 points only when a patent is found (free if none).
⚠️ Perf contract: CNID + hol/prod MUST be paired with id/idSearch/rd/status/lcs (otherwise the backend rejects to avoid a 17M-row full scan); JPID has no HOL/PROD; USID has no STATUS; ed (expiration date) is silently ignored on all sources — filter dates via rd instead. With enableLitigation on, each page re-triggers the litigation query and billing.
Parameters (13)
sourcestringrequired
Data source (required). WIPO data is partitioned by source — cross-source queries not supported. Common: USID (US design), CNID (China design, 17M+ rows), HAGUE (Hague international), DEID, JPID.
dsstring
Designated country code (e.g. 'US', 'CN'). Optional — usually implied by `source`.
holstring
Holder name fuzzy match. Examples: 'Apple' / 'Samsung' / 'Nike'. NOTE: CNID + hol MUST be paired with id/idSearch/rd/status/lcs; JPID has no HOL column (will be ignored).
prodstring
Product name fuzzy match. CNID searches Chinese, other sources search English. Examples: '椅子' (CNID) / 'wireless headphones' (USID) / 'iphone case' (USID). CNID + prod MUST be paired with id/idSearch/rd/status/lcs; JPID has no PROD column.
irnstring
International Registration Number exact match. Examples: 'DM/000298' (HAGUE) / 'D1107730' (USID).
idstring
Full ID exact match, e.g. 'CNID.2023.123456'. Routes CNID queries to a single partition (avoids full scan).
idSearchstring
ID variant fuzzy match.
rdstring
Registration date (YYYY or YYYY-MM-DD). One of the recommended narrowing fields for CNID — routes to a year partition.
statusstring
Legal status: 'ACT' (active), 'EXP' (expired), etc. USID has no STATUS column (will be ignored).
lcsstring
Design classification (Locarno Classification code), e.g. '23-01' = fluid distribution equipment.
frominteger
Pagination offset, 0-based.
numinteger
Page size (default 10, max 100).
enableLitigationboolean
Enable Smart Risk Control Mode: after patents match, auto-query related US litigation (PACER backend) by patent number; cases are joined into each patent's `cases` field. Default false. When on, each matched patent gains litigationStatus / caseTotal / cases; +12 points charged only when a patent is found (free if none).
ai_search
[AI Search via Google SERP] Scrape publicly-available Google search results (data source: Google; use must comply with Google Terms of Service) with top AI Overview, organic results, and related searches. Two modes: overview (standard SERP) / ai_mode (immersive multi-turn conversational search).
Use when: user says "Google for me" / "external demand" / "what do people say about X" / "Reddit/Quora pain points" / "will my content be cited in AI search" / "find user complaints for keyword X"; "consumer voice" step in scouting SOPs; verifying whether a new product concept has off-Amazon demand; **see which Google Shopping ads competitors run / their ad landing pages** (the sponsered block).
Don't use: for on-Amazon search (use search_amazon); when only the trend curve matters (use keyword_trends — cheaper and tighter).
Returns: data.{ results_num, ai_overview, json.items[ { type:'ai_overview', items:[{content:[...], references:[{title,url,domain}]}] }, { type:'organic', items:[{title,url,text}] }, { type:'related_searches', items:[...] }, { type:'sponsered', items:[{type:'product', url, title_of_page}] } ], screenshot, taskId }. ⚠️ The ad block's upstream type is literally spelled 'sponsered' (missing an o — not a typo on our side; match it verbatim, do NOT look for 'sponsored') — it carries Google Shopping ad landing-page url + product titles.
Pair with: ↑ query inferred from user; in 'ai_mode' pass followups[1..5] for multi-turn; ↓ ai_overview.references[].url for authoritative external sources, organic items for content-competition analysis, sponsered[].url for competitors' paid product placements and landing pages.
Cost: ~2 points/call, ~30s (**slow** — Google AI render time).
Tips: prefer overview for single queries (cheaper); use ai_mode only when you need decomposed multi-turn investigation. Followups > 5 visibly slow down responses.
Parameters (4)
querystringrequired
Search keyword or question. Examples: 'wireless earbuds reviews' (single keyword) / 'how does noise cancellation work' (question) / 'what do people complain about Stanley Quencher' (user pain point).
modestring
Search mode: 'overview' (default) = standard Google SERP with AI Overview at the top, best for one-shot queries; 'ai_mode' = Google AI Mode immersive search (udm=50), best for complex multi-step questions with follow-ups.
followupsarray
Follow-up question list (only honored when mode='ai_mode'). Each item is a follow-up question on the previous answer. **More than 5 entries significantly degrades response time.**
screenshotboolean
Whether to return a screenshot URL of the rendered search page. Defaults to false.
keyword_trends
[Keyword Trends via Google Trends] Keyword popularity (data source: Google Trends; use must comply with Google Terms of Service). Time series + per-region heatmap + rising related queries (with 'Breakout' tags). Compare up to 5 keywords on one chart.
Use when: user says "how hot is keyword X" / "A vs B popularity" / "any seasonality" / "which states love X" / "find breakout terms" / "new-product direction" / "trend comparison" / "is X past its peak yet".
Don't use: for absolute search volume (Trends is 0-100 relative); for products/links (use search_amazon / ai_search); for a single keyword's snapshot (need ≥ 2 for meaningful comparison).
Returns: data.json.{ keywordsGeoData[{ keyword, geoMapData[{ geoCode, geoName, value[], formattedValue[], hasData[] }] }], keywordsRankData[{ keyword, rankList[{ rankedKeyword[{ query, value, formattedValue, link, hasData }] }] }], timelineData[{ time, formattedTime, value[], formattedValue[] }], geoMapData[] }, taskId, url.
Pair with: ↑ keywords from user or core terms found via search_amazon; ↓ feed Breakout/rising terms back into search_amazon to explore new opportunities, or filter_niches to see if they've crystallized into a niche.
Cost: ~1.5 points/call, ~5s.
Tips: timeRange = today 12-m (default) | today 3-m | today 5-y | all ; region = ISO country code or 'WORLD'; language affects related-query language.
Region code (ISO country, or 'WORLD' for global). Common: 'US' / 'GB' / 'DE' / 'JP' / 'CN'.
languagestring
Interface language (BCP-47), affects related-query language. Defaults to 'en-US'. Use 'zh-CN' for Chinese.
scrape_url
[Generic Amazon scrape — power-user escape hatch] Scrape pages the 5 purpose-built tools don't cover. Two input modes (pick one):
① content=bare fragment (keyword / nodeId / sellerId / ASIN) + site — backend builds a basic URL per parserName. **content mode carries NO filter/sort/pagination** — it's just the bare fragment. Best for simple pages when you only have the fragment.
② url=full Amazon link — **put ANY filter/sort/pagination into this url** (the only way, since content mode can't). Filter syntax examples: price $25-50 → '/s?k=earbuds&low-price=25&high-price=50'; sort by reviews → '&s=review-rank'; paginate → '&page=2'; category+price → '/s?i=aps&rh=n%3A172282&fs=true&low-price=25'.
Use when: a standard tool can't build the target URL — "search X but only $25-50" / "results sorted by reviews" / "category filtered by price"; or the user already has a specific Amazon link. For any filtering, use url mode.
Don't use: when a purpose-built tool fits — plain keyword search → search_amazon, single ASIN → get_amazon_product, seller → list_seller_products, category ranks → list_bestsellers/list_new_releases.
Returns (format='json'): data.json[0].data.{ ... results[] ... }, shape depends on parserName. ⚠️ If content/url doesn't match parserName, the backend returns data.{ status_code, rawHtml, url } (unparsed).
Pair with: ↓ feed asin into get_amazon_product / get_amazon_reviews.
Cost: ~1 point/call, ~5s.
⚠️ Pass exactly one of content / url (both or neither errors); filtering/pagination requires url mode; parserName must match the page type.
Parameters (6)
parserNamestringrequired
Parser deciding how the backend extracts the page AND builds the URL from content. Must match the page type: amzKeyword=keyword search (content=keyword) / amzProductOfCategory=category (content=nodeId) / amzProductOfSeller=seller storefront (content=sellerId) / amzProductDetail=single product (content=ASIN) / amzBestSellers / amzNewReleases / amzReviewV2=reviews / amzFollowSeller=follow-seller / amzVariantAsin=variant.
contentstring
Bare fragment (backend builds the URL per parserName). Pass this OR url. Examples: 'wireless earbuds' (amzKeyword) / '172282' (nodeId for amzProductOfCategory) / 'ATVPDKIKX0DER' (sellerId for amzProductOfSeller) / 'B09B8V1LZ3' (ASIN for amzProductDetail). Users/AI usually only have the fragment — prefer this.
urlstring
Full Amazon URL (https://). Pass this OR content. Use when you already have a ready link (e.g. a filtered/sorted SERP copied from the browser). Example: 'https://www.amazon.com/s?k=earbuds&rh=p_36%3A2500-5000&s=review-rank'. Must match parserName.
sitestring
Amazon site (in content mode the backend picks the domain from this). Defaults to amz_us. Optional in url mode (the URL already has the domain).
formatstring
Response format. Defaults to 'json' (structured results). Use 'markdown' for the rendered page text.
zipcodestring
ZIP code matching the site's country. Optional; backend picks one if omitted.
search_amazon_alexa
[Amazon Rufus AI conversational recommendations] Ask Amazon's AI shopping assistant Rufus in natural language, get grouped structured product recommendations + Rufus text reply + follow-up questions.
Use when: user says "ask Amazon AI X" / "Rufus recommendations" / "find products conversationally" / "products for a scene (gifting / camping / moving)" / "open-ended sourcing" / "I have no keyword, just a scenario".
Don't use: when you already have a clear keyword and want SERP (use search_amazon); category bestseller ranks (use list_bestsellers); single-ASIN detail (use get_amazon_product); Google-side AI search (use ai_search).
Returns: data.json[{ prompt, content, products[{ title, items[{ asin,url,title,cover,score,ratingsCount,price,originalPrice,describe }] }], follow_up_questions[], screenshot }] + top-level taskId / url / screenshot. Note: follow_up_questions is snake_case (passed through from backend verbatim).
Pair with: ↓ feed asin into get_amazon_product / get_amazon_reviews for deep-dive; follow_up_questions can seed the next round's prompts for multi-turn exploration.
Cost: **6 points PER PROMPT** (billed by prompts count, NOT a flat 6 per call; N prompts = N×6 points).
⚠️ **Slow tool**: **strongly prefer sending exactly 1 prompt per call**. A single prompt typically takes **60–90s** (Rufus generates the conversation live — far slower than a normal scrape); multiple prompts add up linearly and **can exceed 200s**, costing both time and points. Treat this as a long-running call: set a generous timeout, and do NOT retry or fire concurrent duplicate calls just because it didn't return instantly. For several needs, make several single-prompt calls rather than batching them.
Parameters (2)
promptsarrayrequired
Conversation prompts (zh or en). Each item is sent to Rufus independently and returns its own grouped results. **Billed per prompt: 6 points each** (N prompts = N×6 points, NOT a flat 6 per call). **Strongly prefer exactly 1 prompt per call**: this is a slow tool — 60–90s for one, and multiple add up linearly and can exceed 200s. Max 5, but multiple is both slow and costly; for several needs make several single-prompt calls. Examples: ['gifts for a 5-year-old who loves dinosaurs'] / ['camping gear under $50'].
screenshotboolean
Return the Rufus conversation screenshot URL. Defaults to false. Setting true adds backend load; only enable when you need an image proof for end users.
Plug your favorite AI client (Claude Code, Cursor, Cline, Windsurf, Codex, Hermes, OpenClaw) into Pangolinfo's Amazon scrape APIs and let the AI run keyword research, listing analysis, review mining, niche discovery, category navigation, AI search lookups, keyword-trend checks, and WIPO trademark clearance — all from natural-language instructions.
⚠️ BREAKING CHANGE in 0.7.0 — pacer_search retired, merged into wipo_search
The standalone pacer_search tool was removed. US patent-litigation (PACER) lookups
are now reached by passing enableLitigation=true to wipo_search — it finds the patent
and joins the related US litigation cases in a single call. Prompts/scripts pinning
pacer_search will get ToolNotFound; switch to wipo_search with enableLitigation.
Recommended: one-line installer (covers 7 AI clients)
The Pangolinfo Installer detects your AI client, writes the right config files, and you're done. Pass --scope=mcp to install only this MCP server (skip the Skills package).
Then wire it into your AI client — see the per-client snippets below. Point args at the file you just downloaded.
Developers: to build from source, git clone this repo and run npm install && npm run build. The produced dist/server.mjs is identical to the release asset.
The settings file lives at <vscode-user>/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json.
If you're on the standalone Cline CLI, use ~/.cline/data/settings/cline_mcp_settings.json instead.
Don't want to install anything? Point your AI client at the hosted endpoint
instead of a local server.mjs. This is the streamable HTTP transport
(MCP spec), multi-tenant — you bring your own key on every request.
Endpoint
https://mcp.pangolinfo.com/mcp
Transport
Streamable HTTP (POST + SSE)
Auth
Your pgl_xxxxxxxx key, via Bearer header or URL query
Passing your API key — two ways
1. Authorization header (recommended)
code
Authorization: Bearer pgl_xxxxxxxx
This is the preferred method: the key stays out of URLs, logs, and browser
history. The Bearer scheme is matched case-insensitively (bearer,
BEARER, Bearer all work) and extra whitespace is tolerated.
Easiest for clients that only let you paste a URL. If your key contains
URL-special characters, URL-encode it. The header (method 1) takes
precedence if both are supplied.
If your client can't set headers, fall back to the URL form:
"url": "https://mcp.pangolinfo.com/mcp?api_key=pgl_xxxxxxxx".
Notes for custom / raw HTTP integrations
If you're calling the endpoint directly (not through a standard MCP client):
POST your JSON-RPC body to /mcp.
The MCP streamable transport normally requires the request to advertise
bothapplication/json and text/event-stream in its Accept header.
This server backfills the missing media type for you, so a plain
Accept: application/json, Accept: */*, or even a missing Accept
header all work — you don't need to hand-craft it.
A 401 means the key was not found in either the header or the
query string — check that your client actually sent it (some libraries
drop the Authorization header on cross-origin redirects).
Tools (18)
See MCP-TOOLS-MAP.md for the full coordination graph (which tools chain into which).
#
Tool
Purpose
Cost (credits)
1
search_amazon
Amazon keyword search → structured product list
0.75
2
get_amazon_product
Single-ASIN listing detail (title / bullets / features / aiReviewsSummary)
0.75
3
get_amazon_reviews
Batch reviews for an ASIN (VOC mining)
0.75
4
list_bestsellers
Amazon Bestsellers by category
0.75
5
list_new_releases
Amazon New Releases by category
0.75
6
list_seller_products
Catalog of products under one seller
0.75
7
list_category_products
All products in a category leaf
0.75
8
search_categories
Search Amazon category tree by keyword
0.75
9
get_category_children
Drill down one level in the category tree
0.75
10
filter_categories
Filter category nodes by criteria
0.75
11
filter_niches
Niche discovery (size × competition × growth)
0.75
12
get_category_paths
Resolve full ancestor paths for a category node
0.75
13
search_local_maps
Google Maps local business search
0.75
14
wipo_search
WIPO global design / trademark search (IP clearance). Set enableLitigation=true to also join related US patent-litigation (PACER) cases in the same call
2 (+12 when enableLitigation finds a patent)
15
ai_search
AI Search via Google SERP (AI Overview + organic, with compliance disclaimer)
2
16
keyword_trends
Keyword Trends via Google Trends (with compliance disclaimer)
1.5
17
scrape_url
Power-user escape hatch: scrape a raw Amazon URL + parserName (non-standard pages)
0.75
18
search_amazon_alexa
Amazon Rufus AI conversational product picks (scene-based, no keyword)
6
Plus a free local call:pangolinfo_capabilities returns the full tool catalog, canonical workflows, and usage tips with no backend round-trip (0 credits). It is a self-introspection helper, not one of the 18 data tools.
Default marketplace is Amazon US (marketplaceId=ATVPDKIKX0DER, zip=90001). Override per call via tool arguments.
⏱️ Slow tools & your client's tool-call timeout
Two tools legitimately run long because they wait on live AI generation:
Tool
Typical latency
Worst case
search_amazon_alexa (Rufus)
60–90s per prompt
>200s for multiple prompts
ai_search
~30s
~60s
Most MCP clients enforce a per-tool-call timeout — often 60 seconds of silence — and abort the call if nothing comes back in time. When that happens the client reports a transport-level timeout/disconnect, and the agent mistakes it for "the tool is unavailable/broken." This is the usual reason search_amazon_alexa gets flagged as unavailable — it reliably crosses the silent 60s line.
Two things keep this from happening:
The server emits progress heartbeats. While a tool runs, the server sends a notifications/progress every 15s if your client included a progressToken in the call. Spec-compliant clients reset their idle timeout on each heartbeat, so the whole 60–90s render stays under the wire. Most modern MCP clients send a progressToken automatically — no action needed.
Raise the client timeout for clients that don't honor progress. If your client has no progressToken support or a hard cap, bump its MCP tool-call timeout to ≥120s before using search_amazon_alexa. Where to set it depends on the client (examples):
Claude Code / config-based clients: raise the MCP request/tool timeout in the client config.
Custom SDK clients: pass a larger timeout (and, ideally, a progressToken) in the callTool request options.
Also prefer exactly one prompt per search_amazon_alexa call — multiple prompts stack latency linearly and make the timeout far more likely.
Auth resolution order
The server resolves the API key with this priority:
Missing key → startup failure with an actionable error.
CLI args win over env vars — convenient when you want per-server keys without polluting the global environment.
Internationalization
Tool descriptions and error hints are available in English and Chinese. The
language is resolved in this order: --lang=zh|en → PANGOLINFO_LANG=zh|en → OS locale
($LANG starting with zh* → Chinese, otherwise English) → English when there is no
locale signal at all. So a Chinese-locale machine gets Chinese automatically; everyone
else gets English. Force a language explicitly:
Create src/tools/<verb_noun>.ts exporting a Tool object — mirror search_amazon.ts.
Import it in src/tools/index.ts and append to the tools array.
Schema is zod; .describe() every field — the AI reads those.
Never call fetch directly — use ctx.client.post(...). Auth is already injected.
Throw PangolinfoError on failure; the HTTP client already throws this for non-2xx responses.
Security & Data Handling
We take operator and user safety seriously. By design, this MCP server:
Brings your own key. Authentication is via your personal PANGOLINFO_API_KEY (issued at https://tool.pangolinfo.com/). The key is read locally from your AI client's config or environment — it is never transmitted anywhere except to https://scrapeapi.pangolinfo.com (or https://mcp.pangolinfo.com for the hosted variant) over TLS 1.2+.
No telemetry. This server does not phone home, does not collect usage analytics, and does not log your prompts. The only outbound traffic is the actual Amazon / Google / WIPO scrape API calls you explicitly invoke through tools.
No PII collection. No user account info, no email, no IP geolocation, and no prompt content is persisted by this server. Tool calls forward only the parameters you (or the AI agent) supplied.
Read-only. Every tool is a strictly read-only data lookup. None of them can write to Amazon, place orders, post reviews, modify listings, or take any side-effecting action on third-party platforms.
HTTPS-only transport. Both the stdio variant (local) and the hosted variant (https://mcp.pangolinfo.com/mcp) require HTTPS; HTTP requests are refused.
Open source. The full source is in this repository under MIT license — anyone can audit what the server sends and where.
Responsible use. Pangolinfo APIs aggregate public e-commerce data. You are responsible for using the returned data in compliance with the terms of service of the underlying platforms (Amazon, Google, etc.) and with applicable laws in your jurisdiction.
Report security issues privately to security@pangolinfo.com — please do not file public GitHub issues for vulnerabilities.