Skip to main content
Glama

product_scout

Find and rank current TikTok Shop / social-commerce product opportunities using evidence rather than opinion. Use it to answer questions like 'what skincare products are breaking out in the US under $40', 'show me products with strong reviews but low competition', or 'what is worth testing in this niche right now'. Returns products ranked by a deterministic 9-component engine (demand, momentum, creator_adoption, competition, saturation, review_strength, price_attractiveness, creator_concentration, freshness), each carrying an opportunity status (emerging | promising | crowded | mature | cooling | insufficient_data), a qualification record (what passed, failed and is unknown), a confidence band, evidence-cited why_now[], risks[], insufficient_signals[] and history_coverage. Status comes from a qualification gate, never from the score: emerging needs measured sold-count growth across 3+ dated observations spanning 7+ days plus an independent signal (review growth or creator adoption over time); mature means established demand without verified growth; insufficient_data means trajectory cannot be verified yet, however high the score. verification_summary.outcome is NO_VERIFIED_OPPORTUNITIES whenever no returned product passed the gate - say so plainly instead of presenting the list as opportunities, and use verification_summary.by_status to explain whether the category or the filters were the limit. Amazon competition is never measured (AMAZON_COMPETITION_UNVERIFIED); never describe a product as unsaturated on Amazon. The ranking is deterministic and contains no model output - read qualification, why_now, risks and components to explain to the user WHY something ranked where it did, and never present the score on its own. Provider-reported fields live under provider_reported.* and are null when TikTok did not expose them; null means unknown, never zero, and sold counts are never multiplied by price to imply revenue. There is no revenue or GMV field. To validate a single product in depth once you have a shortlist, call analyze_product - product_scout ranks a field of candidates, analyze_product interrogates one. Not for generic video search (use search_videos), creator analysis (use analyze_account), or any guaranteed-sales claim. Cost: 5 credits. Requires the shop_intelligence entitlement.

Input Schema

NameRequiredDescriptionDefault
sortNoOrder the results: verified_first is the default when omitted, listing verified emerging products first and measured-growth products next, then unverified candidates and established comparisons interleaved so neither dominates, buyer-satisfaction risks last. Also: opportunity (same grouping, needs history), rating (highest rated), sold (most cumulative sold), reviews (most reviewed), discount, price_asc, price_desc, momentum, creator_adoption. An unsupported name is rejected, never replaced. History-backed sorts are refused up front when history is unavailable rather than silently falling back.
limitNoMax products to return. Default 20, hard cap 20. This is a ceiling, not a target — fewer rows means the provider had fewer matching products, never that results were withheld.
nicheNoNiche or category to search (e.g. 'Beauty & Skincare', 'Fitness & Wellness'). At least one of niche or query is required.
queryNoFree-text product keywords (e.g. 'wireless earbuds'). Widens the search corpus. May be combined with niche.
marketNo2-letter ISO region code (US, GB, BR, ...) or 'GLOBAL'. Defaults to US. Only regions ScrapeCreators covers for TikTok Shop return usable data.
categoryNoStrict category-breadcrumb filter applied to returned rows (case-insensitive substring). Rows whose category is unknown are dropped when this is set. Distinct from niche, which is a search hint rather than a gate.
max_soldNoMaximum provider-reported cumulative sold count. Strict: unknown is dropped.
min_soldNoMinimum provider-reported cumulative sold count. This is a lifetime total, not a sales rate. Strict: unknown is dropped.
price_maxNoMaximum price in the market currency.
price_minNoMinimum price in the market currency.
max_ratingNoMaximum average rating 0-5. Pair with min_rating to isolate a mid-tier band rather than only top-rated listings. Strict: unknown rating is dropped.
min_ratingNoMinimum average rating 0-5. Strict: rows with unknown rating are dropped.
max_reviewsNoMaximum provider-reported review count - the usual way to find products before they are saturated with social proof. Strict: rows whose review count could not be retrieved are dropped rather than assumed to be zero.
min_reviewsNoMinimum provider-reported review count. Review counts are fetched per candidate, so this filter reflects real provider data. Strict: rows whose review count could not be retrieved are dropped rather than assumed to be zero.
max_discountNoMaximum discount percentage 0-100. Strict: unknown is dropped.
min_discountNoMinimum discount percentage 0-100 off the listed original price. Strict: unknown is dropped.
min_momentumNoMinimum momentum component 0-100. Momentum needs stored history; when the history layer has not seen these products yet the request is refused up front with executed:false rather than charged and returned empty.
max_saturationNoMaximum saturation component 0-100. Saturation needs video-to-product linkage that the current pipeline does not extract, so this is accepted for forward compatibility and reported as unsupported rather than silently applied.
max_competitionNoMaximum competition tolerated, 0-100, expressed intuitively (lower = less competition accepted).
opportunity_stageNoComma-separated stages to keep: emerging, promising, crowded, mature, cooling, insufficient_data. Use 'emerging,promising' for the usual 'find breakout products' request. An empty result reports verification_summary.by_status so you can tell a weak category from a restrictive filter; when nothing in the scan could be classified, the empty result is not charged.
min_creator_adoptionNoMinimum creator-adoption component 0-100 (distinct creators per day with confirmed showcase links). Needs stored history; cold-start products report insufficient_data for this component.

Output Schema

NameRequiredDescriptionDefault
nicheNo
queryNo
regionNo
successYes
executedNoPresent and false when the request needed stored history that is unavailable. Nothing was charged; drop the history-backed filter or sort and retry.
provenanceNo
generated_atNoISO timestamp
opportunitiesNo
query_contextNoThe filters actually applied, echoed back.
source_coverageNoWhat the engine managed to read: shop search, product hydration, history depth, counts.
credits_remainingNo
recommended_chainNoSuggested next calls, chosen from what this result actually contained. SUGGESTIONS ONLY - present them and let the user pick. Do not call them automatically; each one costs the user credits.
degradation_reasonsNoWhy coverage was partial, when it was. Surface these rather than presenting a degraded result as complete.
verification_summaryNoScan-level verdict. outcome is VERIFIED_OPPORTUNITIES or NO_VERIFIED_OPPORTUNITIES; by_status counts every classified product before stage filters and the limit; explanation says whether the category or the filters were the limit. Lead with this when outcome is NO_VERIFIED_OPPORTUNITIES.
skipped_intelligence_filtersNoFilters that could not be enforced for this request.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedInput schema / properties / sort / description
      Previous value: -"Order the results: verified_first is the default when omitted, listing products that passed the qualification gate first, then unverified candidates and established comparisons interleaved so neither dominates, buyer-satisfaction risks last. Also: opportunity (same grouping, needs history), rating (highest rated), sold (most cumulative sold), reviews (most reviewed), discount, price_asc, price_desc, momentum, creator_adoption. An unsupported name is rejected, never replaced. History-backed sorts are refused up front when history is unavailable rather than silently falling back."New value: +"Order the results: verified_first is the default when omitted, listing verified emerging products first and measured-growth products next, then unverified candidates and established comparisons interleaved so neither dominates, buyer-satisfaction risks last. Also: opportunity (same grouping, needs history), rating (highest rated), sold (most cumulative sold), reviews (most reviewed), discount, price_asc, price_desc, momentum, creator_adoption. An unsupported name is rejected, never replaced. History-backed sorts are refused up front when history is unavailable rather than silently falling back."
    • changedOutput schema / properties / opportunities / items / properties / result_role / description
      Previous value: -"What the row is in this answer. Only verified_opportunity passed the qualification gate; established_comparison rows are context, unverified_candidate rows lack the dated evidence to be called opportunities."New value: +"What the row is in this answer. Only verified_emerging passed the qualification gate. measured_growth has measured sales growth but did not pass it, so never call it verified. established_comparison rows are context; unverified_candidate rows lack the dated evidence to be called opportunities."
    • changedOutput schema / properties / opportunities / items / properties / result_role / enum
      Previous value: -[
      -  "verified_opportunity",
      -  "unverified_candidate",
      -  "established_comparison",
      -  "quality_risk"
      -]New value: +[
      +  "verified_emerging",
      +  "measured_growth",
      +  "unverified_candidate",
      +  "established_comparison",
      +  "quality_risk"
      +]
  2. Changed5 schema fields changed
    • changedInput schema / properties / sort / description
      Previous value: -"Order the results: opportunity (final score), rating (highest rated), sold (most cumulative sold), reviews (most reviewed), discount, price_asc, price_desc, momentum, creator_adoption. An unsupported name is rejected, never replaced. History-backed sorts are refused up front when history is unavailable rather than silently falling back."New value: +"Order the results: verified_first is the default when omitted, listing products that passed the qualification gate first, then unverified candidates and established comparisons interleaved so neither dominates, buyer-satisfaction risks last. Also: opportunity (same grouping, needs history), rating (highest rated), sold (most cumulative sold), reviews (most reviewed), discount, price_asc, price_desc, momentum, creator_adoption. An unsupported name is rejected, never replaced. History-backed sorts are refused up front when history is unavailable rather than silently falling back."
    • changedOutput schema / properties / opportunities / items / properties / qualification / description
      Previous value: -"The gate behind the status. qualified_emerging is true only when every emerging requirement passed. momentum.state is measured_growth | measured_flat | measured_slowdown | unknown; creator_evidence.state VIDEO_LINKAGE_UNVERIFIED and competition.state COMPETITION_UNVERIFIED mean not assessed, never \"none\". Quote failed[] and unknowns[] when explaining why a product is not an opportunity."New value: +"The gate behind the status. qualified_emerging is true only when every emerging requirement passed. momentum.state is measured_growth | measured_flat | measured_slowdown | unknown; creator_evidence.state is adoption_over_time | recent_posting_increase (measured growth among videos carrying the provider affiliate marker for this exact product) | recent_linked_videos | observed_not_over_time (activity, not growth) | VIDEO_LINKAGE_UNVERIFIED; VIDEO_LINKAGE_UNVERIFIED and competition.state COMPETITION_UNVERIFIED mean not assessed, never \"none\". evidence_ledger[] separates fact, computed, hypothesis and missing claims, each with source, observed_at and sample_size; never present a hypothesis or a missing item as a finding. Quote failed[] and unknowns[] when explaining why a product is not an opportunity."
    • addedOutput schema / properties / opportunities / items / properties / qualification / properties / evidence_ledger
      Added value: +{
      +  "items": {
      +    "properties": {
      +      "claim": {
      +        "type": "string"
      +      },
      +      "kind": {
      +        "enum": [
      +          "fact",
      +          "computed",
      +          "hypothesis",
      +          "missing"
      +        ],
      +        "type": "string"
      +      },
      +      "observed_at": {
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "sample_size": {
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "source": {
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / opportunities / items / properties / result_role
      Added value: +{
      +  "description": "What the row is in this answer. Only verified_opportunity passed the qualification gate; established_comparison rows are context, unverified_candidate rows lack the dated evidence to be called opportunities.",
      +  "enum": [
      +    "verified_opportunity",
      +    "unverified_candidate",
      +    "established_comparison",
      +    "quality_risk"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / properties / opportunities / items / properties / why_shown / description
      Previous value: -"Why the row is in the list (it matched the search). Being listed is not a recommendation."New value: +"Why the row is in the list (it matched the search) and its role. Being listed is not a recommendation."
  3. Changed6 schema fields changed
    • changedInput schema / properties / opportunity_stage / description
      Previous value: -"Comma-separated stages to keep: emerging, promising, crowded, mature, cooling. Use 'emerging,promising' for the usual 'find breakout products' request."New value: +"Comma-separated stages to keep: emerging, promising, crowded, mature, cooling, insufficient_data. Use 'emerging,promising' for the usual 'find breakout products' request. An empty result reports verification_summary.by_status so you can tell a weak category from a restrictive filter; when nothing in the scan could be classified, the empty result is not charged."
    • changedOutput schema / properties / opportunities / items / properties / opportunity / properties / score / description
      Previous value: -"0-100 composite. Null when status is insufficient_data."New value: +"0-100 composite of present-state quality. Null when too few components resolved. Never decides the status."
    • addedOutput schema / properties / opportunities / items / properties / opportunity / properties / status / description
      Added value: +"Decided by the qualification gate. early_read is retired and no longer emitted."
    • addedOutput schema / properties / opportunities / items / properties / qualification
      Added value: +{
      +  "description": "The gate behind the status. qualified_emerging is true only when every emerging requirement passed. momentum.state is measured_growth | measured_flat | measured_slowdown | unknown; creator_evidence.state VIDEO_LINKAGE_UNVERIFIED and competition.state COMPETITION_UNVERIFIED mean not assessed, never \"none\". Quote failed[] and unknowns[] when explaining why a product is not an opportunity.",
      +  "properties": {
      +    "amazon_competition": {
      +      "type": "object"
      +    },
      +    "competition": {
      +      "type": "object"
      +    },
      +    "creator_evidence": {
      +      "type": "object"
      +    },
      +    "demand": {
      +      "type": "object"
      +    },
      +    "failed": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "momentum": {
      +      "type": "object"
      +    },
      +    "passed": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "qualified_emerging": {
      +      "type": "boolean"
      +    },
      +    "status": {
      +      "type": "string"
      +    },
      +    "summary": {
      +      "type": "string"
      +    },
      +    "supporting_signals": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "unknowns": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedOutput schema / properties / opportunities / items / properties / why_shown
      Added value: +{
      +  "description": "Why the row is in the list (it matched the search). Being listed is not a recommendation.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / verification_summary
      Added value: +{
      +  "description": "Scan-level verdict. outcome is VERIFIED_OPPORTUNITIES or NO_VERIFIED_OPPORTUNITIES; by_status counts every classified product before stage filters and the limit; explanation says whether the category or the filters were the limit. Lead with this when outcome is NO_VERIFIED_OPPORTUNITIES.",
      +  "properties": {
      +    "amazon_competition": {
      +      "type": "object"
      +    },
      +    "by_status": {
      +      "type": "object"
      +    },
      +    "candidates_classified": {
      +      "type": "integer"
      +    },
      +    "explanation": {
      +      "type": "string"
      +    },
      +    "outcome": {
      +      "enum": [
      +        "VERIFIED_OPPORTUNITIES",
      +        "NO_VERIFIED_OPPORTUNITIES"
      +      ],
      +      "type": "string"
      +    },
      +    "returned": {
      +      "type": "integer"
      +    },
      +    "returned_verified_emerging": {
      +      "type": "integer"
      +    },
      +    "thresholds": {
      +      "type": "object"
      +    },
      +    "verified_emerging": {
      +      "type": "integer"
      +    }
      +  },
      +  "type": "object"
      +}
  4. Changed1 schema field changed
    • changedInput schema / properties / sort / description
      Previous value: -"Order the results: momentum, creator_adoption, price_asc, price_desc, reviews, rating, sold, discount, opportunity. History-backed sorts are refused up front when history is unavailable rather than silently falling back."New value: +"Order the results: opportunity (final score), rating (highest rated), sold (most cumulative sold), reviews (most reviewed), discount, price_asc, price_desc, momentum, creator_adoption. An unsupported name is rejected, never replaced. History-backed sorts are refused up front when history is unavailable rather than silently falling back."
  5. Changed1 schema field changed
    • changedInput schema / properties / limit / description
      Previous value: -"Max products to return. Default 10, hard cap 20."New value: +"Max products to return. Default 20, hard cap 20. This is a ceiling, not a target — fewer rows means the provider had fewer matching products, never that results were withheld."
  6. Added

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Far exceeds the annotations (which only say readOnly=false, openWorld=true, idempotent=false, destructive=false). It discloses that status comes from a qualification gate rather than the score, defines what each status requires, explains the NO_VERIFIED_OPPORTUNITIES outcome and how to report it, warns that Amazon competition is never measured, notes provider_reported.* nulls mean unknown not zero, and states there is no revenue/GMV field. This is unusually rich behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and routing are front-loaded, and nearly every sentence carries a non-obvious rule (gate semantics, null-means-unknown, no-revenue caveat). It is a dense single block rather than a structured list, which hurts scannability for a 350-word description, but almost nothing is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 21-parameter, zero-required, complex ranking tool with an output schema present, the description supplies everything an agent needs to invoke and interpret it: entry conditions, filter semantics, gate-based status rules, empty-result handling, and the no-revenue/no-Amazon caveats. Return-value explanation is appropriately delegated to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents every one of the 21 parameters in depth (sort modes, strict-filter drop behavior, cold-start refusal). The description adds interpretation rules about scores/statuses but little per-parameter meaning beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+domain: 'Find and rank current TikTok Shop / social-commerce product opportunities using evidence rather than opinion,' and immediately distinguishes itself from analyze_product, search_videos, and analyze_account by name. An agent can tell what this tool does and what it is not without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete triggering questions ('what skincare products are breaking out in the US under $40'), an explicit sibling hand-off rule ('product_scout ranks a field of candidates, analyze_product interrogates one'), negative guidance ('Not for generic video search... creator analysis... guaranteed-sales claims'), plus cost (5 credits) and the shop_intelligence entitlement prerequisite.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.