cross_selling MCP Tool
The cross_selling tool recommends products that go well with a given anchor product. The merchant’s campaign defines what counts as a match; reach for similar_products when the shopper wants more like the anchor itself. Pass the anchor’s catalog product_id; leave campaigns empty to use the merchant’s default cross-selling campaigns, or pass numeric campaign IDs to restrict the candidate set. This tool answers under any authenticated credential, including the site’s read-only token.
Request (CrossSellingRequest)
Section titled “Request (CrossSellingRequest)”| Field | Type | Description |
|---|---|---|
product_id |
string |
Required. Catalog product_id of the anchor product to find matching items for. |
campaigns |
array of string |
Campaign IDs (numeric strings) to use instead of the merchant’s is_default campaigns. Leave empty to use the defaults. When non-empty, the list acts as a candidate set; the most-specific match per request is picked based on the anchor product’s category path. |
sensitivity_columns |
array of string, or null |
Column names each result must match the anchor product on — e.g. ["brand"] keeps results to the anchor’s own brand. Name only the column; the matching criterion is taken from the anchor product. This replaces the merchant’s configured sensitivity for this request: omit the field to keep it, or pass an empty list to drop it entirely. Only columns reported by list_relevant_columns may be named; columns that cannot be matched against the anchor are rejected, as is the column the campaign defines its category shift on — matching the anchor there would cancel the cross-sell. |
columns |
array of string, or null |
Catalog columns to materialize into every result’s attributes. Leave unset to receive the default preset. |
limit |
number (uint32) or null |
Upper bound on the number of results returned. When omitted the merchant’s campaign limit applies. When set, the effective limit is min(limit, max(campaign_k)). |
additional_filter |
McpStaticFilter or null |
Free-form boolean filter tree applied in addition to the campaign’s static filters. Shrinks the underlying candidate set before ranking, so use it for hard constraints (e.g. “only in-stock”). For refinement within the same ranking use dynamic_filters instead. |
dynamic_filters |
array of McpDynamicFilterSelection, or null |
Facet selections echoed back from a previous response’s dynamic_filters, narrowing the facet result set without changing the underlying ranked candidate set. |
group_variants |
boolean or null |
Whether variants of the same product are collapsed into a single result. Leave unset to use the merchant’s configured default; set true to force grouping on or false to force it off. |
session_id |
string or null |
Optional session identifier (UUID). Omit on the first call; on follow-up calls for the same anchor, pass a stable UUID. |
Response (CrossSellingResponse)
Section titled “Response (CrossSellingResponse)”| Field | Type | Description |
|---|---|---|
results |
array of McpItem |
The ranked complementary products for the anchor. Always present. |
dynamic_filters |
array of McpDynamicFilter |
The facets available for refining this result set. Always present. |
stream |
array of McpStreamItem, or null |
Always absent: anchor-based recommendations produce no stream. |
Sensitivity and the campaign’s category shift
Section titled “Sensitivity and the campaign’s category shift”sensitivity_columns works as it does for similar_products, with one extra restriction: the column a cross-selling campaign defines its category shift on cannot be named. Requiring results to match the anchor on that column would cancel the shift that makes the recommendation a cross-sell in the first place, so such a request is rejected.