Skip to main content

Search Retailers (Market)

mdmcp-search_retailers

Find retailers to use in filter queries. Search by name, slug, region, or description.

A slug you already hold is a valid query and returns that retailer as exact — worth knowing because slugs are not always the name: dvf is Diane Von Furstenberg (US), groceriesatasda-uk is Asda (UK).

Use the returned retailers[].slug value when building retailer filters, copied exactly — the filter matches it verbatim, case included.

One retailer per country: Zara (ES) and Zara (UK) are separate retailers with separate data, so a bare Zara is exact on EVERY country it trades in. Picking one is your job — choose on region, pass country_code, or name the country in the query (Zara (ES)).

Every hit carries match: exact (query equals its name or slug, ignoring case, accents, punctuation and spacing; a separator between two digits is kept, so 3-6 months is not 36 months; a region/code suffix on the name is ignored), lexical (text search ranked it: a typo, a partial, or the name plus or minus a word), or semantic_only (only the vector arm returned it: a nearest neighbour, not a match — verify or discard). Nothing beats semantic_only = not found. No hit is evidence of data behind the name. Rules: market_data_docs(topic="lookup_matching").

Run get_retailer_coverage on the slugs you pick before reporting numbers from the query tools — that, not match, answers whether data exists.

Try queries like

"Zara", "UK retailers", "fast fashion", "Amazon", "dvf".

Parameters​

NameTypeRequiredConstraintsDescription
querystring | string[]yes—Single query string or list of query strings for batch search.
search_limitintegernodefault: 10 · 1–50Maximum number of results to return (default 10, max 50). Raise it when validating or comparing many entities in one call so the list is not clipped at the default 10.
country_codestringno—Optional country code to filter by region (e.g., "UK", "US", "ES"). EDITED codes are ISO 3166-1 alpha-2 with two exceptions: the United Kingdom is "UK" (not ISO "GB"; "GB" is accepted and mapped to "UK") and "EU" covers EU-wide retailers. Case-insensitive.

Returns​

  • A RetailerSearchResult — retailers plus search_limit /
  • at_search_limit. A batch request returns one result per query, in the
  • same order as the queries.

Try it​

Loading interactive widget…

Code examples​

curl -s https://mcp.edited.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-06-18" \
-H "x-api-key: $MCP_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "mdmcp-search_retailers",
"arguments": {
"query": "Nike",
"search_limit": 10,
"country_code": "UK"
}
}
}'

Example response​

The payload — what you read from result.structuredContent.result. A refusal arrives on the sibling error key instead, with isError still false — see Concepts → Response shape.

{
"retailers": [
{
"name": "Zara (UK)",
"slug": "zara",
"region": {
"id": 561,
"iso_code": "UK",
"name": "United Kingdom"
},
"is_deprecated": false,
"visible": true,
"tier": {
"id": 6,
"name": "Mass",
"slug": "mass"
},
"match": "exact"
},
{
"name": "Zara Home (UK)",
"slug": "zarahome-uk",
"region": {
"id": 561,
"iso_code": "UK",
"name": "United Kingdom"
},
"is_deprecated": false,
"visible": true,
"tier": {
"id": 6,
"name": "Mass",
"slug": "mass"
},
"match": "lexical"
},
{
"name": "La Senza (UK)",
"slug": "lasenza-uk",
"region": {
"id": 561,
"iso_code": "UK",
"name": "United Kingdom"
},
"is_deprecated": false,
"visible": true,
"tier": {
"id": 6,
"name": "Mass",
"slug": "mass"
},
"match": "semantic_only"
}
],
"search_limit": 3,
"at_search_limit": true
}

Input schema​

{
"type": "object",
"properties": {
"query": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"maxItems": 10,
"type": "array"
}
]
},
"search_limit": {
"default": 10,
"description": "Maximum number of results to return (default 10, max 50). Raise it when validating or comparing many entities in one call so the list is not clipped at the default 10.",
"maximum": 50,
"minimum": 1,
"type": "integer"
},
"country_code": {
"type": "string"
}
},
"required": [
"query"
]
}

Output schema​

Describes both branches of the envelope — result on success, error on a refusal. Validate against this rather than pattern-matching the prose above; see Concepts → Response shape.

{
"type": "object",
"properties": {
"result": {
"anyOf": [
{
"description": "Retailer hits, the applied ``search_limit``, and whether the search filled it.",
"properties": {
"retailers": {
"items": {
"properties": {
"name": {
"type": "string"
},
"slug": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"region": {
"anyOf": [
{
"properties": {
"id": {
"type": "integer"
},
"iso_code": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"iso_code",
"name"
],
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"is_deprecated": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Constant (`false` or absent; ingest filters on it), not an availability signal — use `get_retailer_coverage` for that."
},
"visible": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Constant (`true`; ingest filters on it), not an availability signal."
},
"tier": {
"anyOf": [
{
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
}
},
"required": [
"id",
"name",
"slug"
],
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"match": {
"description": "What matched, not how well. Not a score. See the tool description.",
"enum": [
"exact",
"lexical",
"semantic_only"
],
"type": "string"
}
},
"required": [
"name",
"slug",
"match"
],
"type": "object"
},
"type": "array"
},
"search_limit": {
"minimum": 1,
"type": "integer"
},
"at_search_limit": {
"description": "True if the search filled search_limit. Retailer search is hybrid (lexical + semantic) and the vector arm has no similarity floor, so a full list does NOT mean more matches exist — low-relevance neighbours pad it out, and they are the rows reporting `match: semantic_only`. Raise search_limit (max 50) only if a retailer you expected is missing. `retailers` can be shorter than search_limit while this is true, if a matched record could not be returned (momentarily unavailable, or malformed).",
"type": "boolean"
}
},
"required": [
"retailers",
"search_limit",
"at_search_limit"
],
"type": "object"
},
{
"items": {
"description": "Retailer hits, the applied ``search_limit``, and whether the search filled it.",
"properties": {
"retailers": {
"items": {
"properties": {
"name": {
"type": "string"
},
"slug": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"region": {
"anyOf": [
{
"properties": {
"id": {
"type": "integer"
},
"iso_code": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"iso_code",
"name"
],
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"is_deprecated": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Constant (`false` or absent; ingest filters on it), not an availability signal — use `get_retailer_coverage` for that."
},
"visible": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"description": "Constant (`true`; ingest filters on it), not an availability signal."
},
"tier": {
"anyOf": [
{
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
}
},
"required": [
"id",
"name",
"slug"
],
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"match": {
"description": "What matched, not how well. Not a score. See the tool description.",
"enum": [
"exact",
"lexical",
"semantic_only"
],
"type": "string"
}
},
"required": [
"name",
"slug",
"match"
],
"type": "object"
},
"type": "array"
},
"search_limit": {
"minimum": 1,
"type": "integer"
},
"at_search_limit": {
"description": "True if the search filled search_limit. Retailer search is hybrid (lexical + semantic) and the vector arm has no similarity floor, so a full list does NOT mean more matches exist — low-relevance neighbours pad it out, and they are the rows reporting `match: semantic_only`. Raise search_limit (max 50) only if a retailer you expected is missing. `retailers` can be shorter than search_limit while this is true, if a matched record could not be returned (momentarily unavailable, or malformed).",
"type": "boolean"
}
},
"required": [
"retailers",
"search_limit",
"at_search_limit"
],
"type": "object"
},
"type": "array"
}
]
},
"error": {
"type": "object",
"description": "Present instead of `result` when the call was rejected. Branch on `code`; never string-match `message`.",
"properties": {
"code": {
"type": "string",
"enum": [
"invalid_input",
"not_entitled",
"upstream_unavailable",
"internal"
]
},
"message": {
"type": "string"
},
"field": {
"type": "string",
"description": "Offending parameter, when the failure is attributable to one."
},
"details": {
"type": "object",
"additionalProperties": true
}
},
"required": [
"code",
"message"
]
}
},
"x-fastmcp-wrap-result": true,
"oneOf": [
{
"required": [
"result"
]
},
{
"required": [
"error"
]
}
]
}