List Retailers (Messaging)
messagingmcp-list_retailers
List the retailers (or regions) the messaging corpus actually covers.
Use this before a detailed query to confirm a retailer or region is present
and how fresh the data is — and before any durability or year-on-year claim,
where a gap in capture (or a stale latest_date) otherwise reads as a change
in the retailer's behaviour. Never suggest a retailer from memory — only
reference retailers returned here. To resolve one retailer's slug, pass its
name (or a fragment) as query rather than paging the whole catalogue.
Parameters
| Name | Type | Required | Constraints | Description |
|---|---|---|---|---|
by | string | no | default: "retailer" | Grouping. 'retailer' (default) lists each retailer with its regions and latest capture date. 'region' lists each region with the retailers present. |
query | string | no | — | Case-insensitive substring to narrow the groups: matched against the retailer slug and display name (by='retailer') or the region label (by='region'). Use this to look up one retailer's slug without fetching the whole catalogue, e.g. query='zara'. |
limit | integer | no | default: 100 · 1–1000 | Max groups returned (default 100). The full corpus is ~2,800 retailers; total_groups reports the pre-limit match count so truncation is visible. |
Returns
- On success: {"result": {"by", "total_groups", "returned", "groups": [...]}} —
total_groupscounts matches beforelimit; if returned < total_groups,- narrow with
queryrather than raising the limit. - For by="retailer": each group is {retailer, retailer_name, regions,
- latest_date, count} —
retaileris the slug to pass to the promo/visual - filters,
retailer_namethe display name to match a request against. countis a raw document count across the promo + visual indices (a- volume signal — NOT a promotion count; use count_promos for that);
latest_dateis the latest capture date.- For by="region": each group is {region, retailers, latest_date}.
- On failure: {"error": {code, message}}
codeisupstream_unavailableornot_entitled- (authorization refused).
Try it
Loading interactive widget…
Code examples
- curl
- TypeScript
- Python
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": "messagingmcp-list_retailers",
"arguments": {
"by": "retailer",
"query": "Nike",
"limit": 100
}
}
}'
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "demo", version: "1.0.0" }, { capabilities: {} });
await client.connect(
new StreamableHTTPClientTransport(new URL("https://mcp.edited.com/mcp"), {
requestInit: { headers: { "x-api-key": process.env.MCP_API_KEY ?? "" } },
}),
);
const result = await client.callTool({
name: "messagingmcp-list_retailers",
arguments: {
"by": "retailer",
"query": "Nike",
"limit": 100
},
});
import os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
headers = {"x-api-key": os.environ["MCP_API_KEY"]}
async with streamablehttp_client("https://mcp.edited.com/mcp", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool(
"messagingmcp-list_retailers",
{"by": "retailer", "query": "Nike", "limit": 100},
)
Input schema
{
"type": "object",
"properties": {
"by": {
"default": "retailer",
"description": "Grouping. 'retailer' (default) lists each retailer with its regions and latest capture date. 'region' lists each region with the retailers present.",
"enum": [
"retailer",
"region"
],
"type": "string"
},
"query": {
"description": "Case-insensitive substring to narrow the groups: matched against the retailer slug and display name (by='retailer') or the region label (by='region'). Use this to look up one retailer's slug without fetching the whole catalogue, e.g. query='zara'.",
"type": "string"
},
"limit": {
"default": 100,
"description": "Max groups returned (default 100). The full corpus is ~2,800 retailers; `total_groups` reports the pre-limit match count so truncation is visible.",
"maximum": 1000,
"minimum": 1,
"type": "integer"
}
}
}
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": {
"properties": {
"by": {
"enum": [
"retailer",
"region"
],
"type": "string"
},
"total_groups": {
"description": "The count before limit.",
"type": "integer"
},
"returned": {
"description": "The count after limit.",
"type": "integer"
},
"groups": {
"description": "Retailer rows or region rows, according to by.",
"items": {
"type": "object",
"properties": {
"retailer": {
"description": "The slug to filter on.",
"type": "string"
},
"retailer_name": {
"description": "Display name to match a request against; falls back to the slug when none is recorded.",
"type": "string"
},
"regions": {
"items": {
"type": "string"
},
"type": "array"
},
"latest_date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"count": {
"type": "integer"
},
"region": {
"type": "string"
},
"retailers": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"latest_date"
],
"allOf": [
{
"anyOf": [
{
"required": [
"count",
"latest_date",
"regions",
"retailer",
"retailer_name"
]
},
{
"required": [
"latest_date",
"region",
"retailers"
]
}
]
}
],
"description": "One list_retailers(by=\"retailer\") row. / One list_retailers(by=\"region\") row: the inverted map."
},
"type": "array"
}
},
"required": [
"by",
"total_groups",
"returned",
"groups"
],
"type": "object"
},
"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"
]
}
},
"oneOf": [
{
"required": [
"result"
]
},
{
"required": [
"error"
]
}
],
"x-fastmcp-wrap-result": true
}