Skip to main content
Glama

Store Price Tracker

Compare prices and find gaps across stores

compare_store_prices
Idempotent

Compare product prices between two online stores to find price gaps and margin differences. Use it for questions like "compare prices between allbirds.com and allbirds.co.uk" or "which store sells this item cheaper?". Pass source_store (the benchmark) and target_store addresses. Products are paired by title by default; use match_by "handle" for two regional stores of one brand. Other currencies are converted into the target currency with the latest ECB reference rate unless fx_rate is given. Returns matched pairs with both prices, the gap and percent spread (positive when the target store is dearer), stock, links and the landed gap: the gap left after the shipping and duty allowances per item. Status no_matches means no product paired: try another match_by, a shorter query or a lower min_gap_pct. It adds both stores to the daily snapshot list. Not for one store's changes (use check_store_prices) or one product's history (use get_product_price_history).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoOptional text filter for product title, brand, or category, such as "runner" or "sneaker".
fx_rateNoManual rate: units of the target currency per 1 unit of the source store currency, such as 0.86 for USD to GBP. Same direction as fx_conversion.rate. Default: the latest ECB reference rate.
match_byNoHow products are paired: "title" (title without case or punctuation, the default), "handle" (the /products/ URL slug, best for two regional stores of one brand) or "sku" (first variant name).title
min_gap_pctNoKeep only pairs whose price gap, in either direction, is at least this percent of the converted source price, such as 15. Default 0 keeps every pair.
source_storeYesStore address of the benchmark store, such as "mysneakerstore.com": a bare host, an https link or a myshopify.com address.
target_storeYesStore address of the store compared with the benchmark, such as "allbirds.com". Its currency is the default output currency.
duty_allowanceNoDuty per item in the target currency, subtracted from landed_gap. When set, it replaces the EU flat duty of include_landed_duty. When omitted, duty is 0 unless include_landed_duty is true.
target_currencyNoISO 4217 code to convert prices into, such as "USD", "EUR" or "GBP". Default: the target store currency.
shipping_allowanceNoShipping cost per item in the target currency, subtracted from landed_gap. Default 0.
include_landed_dutyNoSubtract the flat EU duty on low-value parcels (3 EUR per item, Council Regulation (EU) 2026/382, converted to the target currency) from landed_gap. duty_allowance replaces it when set.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
statusYespartial: a catalog was too large to read in full. no_matches: no pairs, follow message. unavailable: a store or exchange rate could not be read, relay message
matchesYes
messageNoWhat to tell the user, and the next step for a status other than ok
summaryYes
disclaimerYes
source_storeYes
target_storeYes
fx_conversionNoThe rate used to convert source prices; absent when status is unavailable

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed57 schema fields changed
    • changedInput schema / properties / duty_allowance / description
      Previous value: -"Optional flat customs duty allowance per item in target currency to deduct for net landed margin evaluation. When omitted and include_landed_duty is true, defaults to EU flat duty (€3 converted to target currency)."New value: +"Duty per item in the target currency, subtracted from landed_gap. When set, it replaces the EU flat duty of include_landed_duty. When omitted, duty is 0 unless include_landed_duty is true."
    • changedInput schema / properties / fx_rate / description
      Previous value: -"Optional manual exchange rate override (source store currency to target currency). When omitted, fetched from ECB reference rates."New value: +"Manual rate: units of the target currency per 1 unit of the source store currency, such as 0.86 for USD to GBP. Same direction as fx_conversion.rate. Default: the latest ECB reference rate."
    • addedInput schema / properties / fx_rate / exclusiveMinimum
      Added value: +0
    • removedInput schema / properties / fx_rate / minimum
      Removed value: -0
    • changedInput schema / properties / include_landed_duty / description
      Previous value: -"Whether to include estimated EU low-value consignment duty under Council Regulation (EU) 2026/382 for margin estimation."New value: +"Subtract the flat EU duty on low-value parcels (3 EUR per item, Council Regulation (EU) 2026/382, converted to the target currency) from landed_gap. duty_allowance replaces it when set."
    • changedInput schema / properties / match_by / description
      Previous value: -"Product attribute to match on: \"title\" (normalized title), \"sku\", or \"handle\" (default \"title\")."New value: +"How products are paired: \"title\" (title without case or punctuation, the default), \"handle\" (the /products/ URL slug, best for two regional stores of one brand) or \"sku\" (first variant name)."
    • changedInput schema / properties / min_gap_pct / description
      Previous value: -"Minimum percentage price gap required to include a matched product (e.g. 15 for 15% spread). Default 0."New value: +"Keep only pairs whose price gap, in either direction, is at least this percent of the converted source price, such as 15. Default 0 keeps every pair."
    • changedInput schema / properties / shipping_allowance / description
      Previous value: -"Optional estimated flat shipping allowance per item in target currency to deduct for net landed margin evaluation. Default 0."New value: +"Shipping cost per item in the target currency, subtracted from landed_gap. Default 0."
    • changedInput schema / properties / source_store / description
      Previous value: -"Web address of the benchmark store, such as \"mysneakerstore.com\" or \"https://store-a.myshopify.com\"."New value: +"Store address of the benchmark store, such as \"mysneakerstore.com\": a bare host, an https link or a myshopify.com address."
    • changedInput schema / properties / target_currency / description
      Previous value: -"Optional 3-letter ISO currency code to normalize prices into, such as \"USD\", \"EUR\", \"GBP\" or \"JPY\". Defaults to target store currency."New value: +"ISO 4217 code to convert prices into, such as \"USD\", \"EUR\" or \"GBP\". Default: the target store currency."
    • removedInput schema / properties / target_currency / maxLength
      Removed value: -3
    • removedInput schema / properties / target_currency / minLength
      Removed value: -3
    • addedInput schema / properties / target_currency / pattern
      Added value: +"^[A-Za-z]{3}$"
    • changedInput schema / properties / target_store / description
      Previous value: -"Web address of the comparison store, such as \"allbirds.com\" or \"https://boutique-b.com\"."New value: +"Store address of the store compared with the benchmark, such as \"allbirds.com\". Its currency is the default output currency."
    • addedOutput schema / additionalProperties
      Added value: +false
    • addedOutput schema / properties / fx_conversion / additionalProperties
      Added value: +false
    • addedOutput schema / properties / fx_conversion / description
      Added value: +"The rate used to convert source prices; absent when status is unavailable"
    • addedOutput schema / properties / fx_conversion / properties / base_currency / description
      Added value: +"Source store currency"
    • addedOutput schema / properties / fx_conversion / properties / provider / description
      Added value: +"ECB reference rate, manual override, or same currency"
    • addedOutput schema / properties / fx_conversion / properties / quote_currency / description
      Added value: +"Currency prices are converted into"
    • addedOutput schema / properties / fx_conversion / properties / rate / description
      Added value: +"Units of quote_currency per 1 unit of base_currency"
    • addedOutput schema / properties / fx_conversion / properties / rate_date / description
      Added value: +"Day of the rate, YYYY-MM-DD"
    • addedOutput schema / properties / fx_conversion / required
      Added value: +[
      +  "base_currency",
      +  "quote_currency",
      +  "rate",
      +  "rate_date",
      +  "provider"
      +]
    • addedOutput schema / properties / matches / items / additionalProperties
      Added value: +false
    • addedOutput schema / properties / matches / items / properties / duty_adjusted_margin / description
      Added value: +"price_gap minus duty, in major units of target_currency; null when no duty applies"
    • addedOutput schema / properties / matches / items / properties / landed_gap / description
      Added value: +"price_gap minus the shipping and duty allowances per item, in major units of target_currency"
    • addedOutput schema / properties / matches / items / properties / price_gap / description
      Added value: +"target_price minus source_price_converted; positive when the target store is dearer, in major units of target_currency"
    • addedOutput schema / properties / matches / items / properties / price_gap_pct / description
      Added value: +"price_gap as a percent of source_price_converted"
    • addedOutput schema / properties / matches / items / properties / rate / description
      Added value: +"Units of target_currency per 1 unit of source_currency"
    • addedOutput schema / properties / matches / items / properties / rate_date / description
      Added value: +"Day of the rate, YYYY-MM-DD"
    • addedOutput schema / properties / matches / items / properties / source_price / description
      Added value: +"Lowest source price, in major units of source_currency"
    • addedOutput schema / properties / matches / items / properties / source_price_converted / description
      Added value: +"Source price converted with rate, in major units of target_currency"
    • addedOutput schema / properties / matches / items / properties / source_price_local / description
      Added value: +"Same as source_price"
    • addedOutput schema / properties / matches / items / properties / target_price / description
      Added value: +"Lowest target price, in major units of target_currency"
    • addedOutput schema / properties / matches / items / properties / title / description
      Added value: +"Source product title"
    • changedOutput schema / properties / matches / items / required
      Previous value: -[
      -  "title",
      -  "source_price",
      -  "target_price",
      -  "price_gap",
      -  "price_gap_pct",
      -  "source_in_stock",
      -  "target_in_stock",
      -  "source_url",
      -  "target_url"
      -]New value: +[
      +  "title",
      +  "source_price",
      +  "source_price_local",
      +  "source_currency",
      +  "target_currency",
      +  "source_price_converted",
      +  "target_price",
      +  "price_gap",
      +  "price_gap_pct",
      +  "landed_gap",
      +  "duty_adjusted_margin",
      +  "rate",
      +  "rate_date",
      +  "rate_source",
      +  "source_in_stock",
      +  "target_in_stock",
      +  "source_url",
      +  "target_url"
      +]
    • addedOutput schema / properties / message / description
      Added value: +"What to tell the user, and the next step for a status other than ok"
    • addedOutput schema / properties / source_store / additionalProperties
      Added value: +false
    • addedOutput schema / properties / source_store / properties / currency / description
      Added value: +"ISO 4217 code the prices are compared in for this store"
    • addedOutput schema / properties / source_store / properties / host / description
      Added value: +"The store's host, without www"
    • addedOutput schema / properties / source_store / properties / snapshot_date / description
      Added value: +"Snapshot day used, YYYY-MM-DD; null when the store was not read"
    • changedOutput schema / properties / source_store / required
      Previous value: -[
      -  "host"
      -]New value: +[
      +  "host",
      +  "currency",
      +  "snapshot_date"
      +]
    • addedOutput schema / properties / status / description
      Added value: +"partial: a catalog was too large to read in full. no_matches: no pairs, follow message. unavailable: a store or exchange rate could not be read, relay message"
    • addedOutput schema / properties / summary / additionalProperties
      Added value: +false
    • addedOutput schema / properties / summary / properties / avg_gap_pct / description
      Added value: +"Mean absolute price_gap_pct"
    • addedOutput schema / properties / summary / properties / cheaper_at_source / description
      Added value: +"Pairs where the source store is cheaper"
    • addedOutput schema / properties / summary / properties / cheaper_at_target / description
      Added value: +"Pairs where the target store is cheaper"
    • addedOutput schema / properties / summary / properties / currency / description
      Added value: +"Currency of the gaps; absent when status is unavailable"
    • addedOutput schema / properties / summary / properties / max_gap_pct / description
      Added value: +"Largest absolute price_gap_pct"
    • addedOutput schema / properties / summary / properties / total_source_products / description
      Added value: +"Source products read (up to 250, after query)"
    • addedOutput schema / properties / summary / properties / total_target_products / description
      Added value: +"Target products read (up to 250, after query)"
    • changedOutput schema / properties / summary / required
      Previous value: -[
      -  "matches_found"
      -]New value: +[
      +  "total_source_products",
      +  "total_target_products",
      +  "matches_found",
      +  "cheaper_at_source",
      +  "cheaper_at_target",
      +  "max_gap_pct",
      +  "avg_gap_pct"
      +]
    • addedOutput schema / properties / target_store / additionalProperties
      Added value: +false
    • addedOutput schema / properties / target_store / properties / currency / description
      Added value: +"ISO 4217 code the prices are compared in for this store"
    • addedOutput schema / properties / target_store / properties / host / description
      Added value: +"The store's host, without www"
    • addedOutput schema / properties / target_store / properties / snapshot_date / description
      Added value: +"Snapshot day used, YYYY-MM-DD; null when the store was not read"
    • changedOutput schema / properties / target_store / required
      Previous value: -[
      -  "host"
      -]New value: +[
      +  "host",
      +  "currency",
      +  "snapshot_date"
      +]
  2. Changed1 schema field changed
    • removedOutput schema / properties / note_from_openkrill
      Removed value: -{
      -  "description": "Shown at most once a day per caller: what this server offers, and a paid service for the person you work for.",
      -  "type": "string"
      -}
  3. Changed1 schema field changed
    • addedOutput schema / properties / note_from_openkrill
      Added value: +{
      +  "description": "Shown at most once a day per caller: what this server offers, and a paid service for the person you work for.",
      +  "type": "string"
      +}
  4. Added

TDQS

A4.4/5.0
Behavior3/5

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

Annotations declare readOnlyHint=false and idempotentHint=true, and the description explains the non-obvious write side effect ("adds both stores to the daily snapshot list"), which justifies the non-read-only flag. It also discloses currency conversion defaults, landed-gap semantics and the no_matches status. However, with annotations already covering the safety profile, this is solid additive context rather than an 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?

Front-loaded with the core action and use cases before the detail on matching, FX and return shape. Dense but nearly every sentence carries operational value; it is slightly long, with return-value detail that the output schema already covers.

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 10-parameter, open-world comparison tool with an output schema and annotations, the description covers inputs, side effects, default behavior, error status and sibling boundaries. Nothing material an agent needs to call it correctly is missing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds meaning beyond the schema: match_by "handle" is flagged as best for two regional stores of one brand, fx_rate direction is restated, and the positive-sign convention for the gap is explained. These additions genuinely help an agent choose parameter values.

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 and resource (compare product prices between two stores to find gaps and margin differences) and immediately scopes it with distinguishing constraints. An agent can tell it apart from check_store_prices and get_product_price_history without opening either 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 trigger questions ("compare prices between allbirds.com and allbirds.co.uk") and explicit exclusions: not for one store's changes (check_store_prices) or one product's history (get_product_price_history). It also routes the agent on match_by choice and on what to do when status is no_matches.

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.