Skip to content

Search tools reference ​

The Product (commerce) MCP server exposes 10 read-only tools your AI sales agent uses to search, filter, and fetch a merchant's catalog. Inside MyChatBot these run automatically whenever the agent answers a product question β€” you don't call them by hand. You can also point an external MCP client (Claude Code, Cursor, or any MCP host) at the same tools to build your own sales agent on top of your catalog.

This page is the cheat sheet: every tool, what it does, what it accepts, and β€” crucially β€” which filter operators actually work. Reach for it whenever you're writing a search prompt or debugging why a filter didn't apply.

All 10 tools live behind one MCP server URL, scoped to a single account + product integration:

https://product.mychatbot.app/mcp/{account_id}/{integration_id}/stream

In the app β€” get the connect command

You don't assemble the URL by hand. Open Knowledge Base (https://app.mychatbot.app/knowledge-base) or Agents β†’ Connectors (https://app.mychatbot.app/agents/connectors), find your product integration card, and choose Connect AI tools. MyChatBot fills in the correct account + integration and hands you a copy-paste setup command for Claude Code plus a Cursor config. See Product (commerce) MCP for the full walkthrough.

The Connect AI tools panel on a product integration card, showing the copy-paste MCP setup command

Cheat sheet ​

All 10 tools at a glance ​

ToolWhat it doesKey inputsFilter operators
semantic_product_searchNatural-language + visual catalog search, ranked by meaningquery and/or image_url; optional limit=20, filters[]eq, in reliably β€” ranges/prefix are best-effort ΒΉ
filter_category_productsDeterministic browse + filtering inside one known categorycategory_id; optional filters[], limit=100eq, gt, gte, lt, lte, in
get_all_categoriesReturns the full category treeβ€”β€”
get_product_detailsFull record for one productproduct_idβ€”
get_product_variantsA product's sizes / colors / other variantsproduct_idβ€”
find_similar_products"More like this" / cross-sell from a productproduct_id; optional limit=10β€”
get_category_attributesWhich attributes a category hascategory_idβ€”
get_category_attribute_valuesAn attribute's type + its common valuescategory_id, attribute_nameβ€”
get_available_filtersFacet values + product counts per value (for faceted UIs)category_id; optional filters[], facet_attributes[]eq, gt, gte, lt, lte, in
get_products_by_idsExact batch fetch by known IDsproduct_ids[]β€”

semantic_product_search has no required input β€” pass at least a query or an image_url.

ΒΉ semantic_product_search reliably honors only eq and in. Range and prefix operators are best-effort and can silently do nothing β€” see Which operators actually work below.

Which operators actually work ​

Only three tools accept filters[] at all, and what each one actually does with a given operator differs. This table is the authoritative answer β€” trust it over any operator list you see advertised:

ToolReliably honorsBest-effort / unreliable
semantic_product_searcheq, ingt, gte, lt, lte, startswith, endswith, ne β€” may silently return nothing; don't rely on them for correctness
filter_category_productseq, gt, gte, lt, lte, inβ€” (no ne, startswith, endswith)
get_available_filterseq, gt, gte, lt, lte, inβ€” (no ne, startswith, endswith)

There is no "prefix-ops" tool and no "eq/in-only" tool

It's tempting to split the tools into "supports startswith/endswith" vs "only eq/in" β€” neither category exists. semantic_product_search advertises prefix and range operators but in practice reliably resolves only eq/in; ranges and prefixes are best-effort and can quietly match nothing. Meanwhile filter_category_products and get_available_filters give you dependable range operators (gt/gte/lt/lte) β€” but they never support startswith/endswith. If you need reliable prefix matching, no tool guarantees it: use in with an explicit value set, or fetch candidates and filter on your side. MyChatBot tunes how filters resolve for each catalog β€” contact support if you need different behavior for yours.

Which tool for which job ​

JobTool
Natural-language / conversational lookup ("gift for dry skin")semantic_product_search
Visual search ("find this dress")semantic_product_search with image_url
Rank by meaning but constrain by eq/in attributessemantic_product_search with filters[]
Free-text query + reliable price / numeric rangeTwo-step: semantic_product_search β†’ filter_category_products (see below)
Deterministic browse + range filtering inside one known categoryfilter_category_products
List the catalog's category treeget_all_categories
Full record for one product (agent already has the ID)get_product_details
Sizes / colors / other variants of a productget_product_variants
"More like this" / cross-sell from a productfind_similar_products
Discover what attributes a category hasget_category_attributes
Discover a specific attribute's type + common valuesget_category_attribute_values
Build a faceted UI / count how many products per valueget_available_filters
Exact batch lookup by known IDs (e.g. SKUs already resolved)get_products_by_ids

Defaults ​

InputApplies toDefault
limitsemantic_product_search20 (max 60)
limitfilter_category_products100
limitfind_similar_products10
enable_rerankingsemantic_product_searchtrue
truncate_descriptionsemantic_product_searchtrue

Passing filters ​

Every entry in filters[] (for semantic_product_search, filter_category_products, and get_available_filters) has three parts:

json
{ "attribute": "price", "operator": "gte", "value": 500 }
  • attribute β€” the attribute name to constrain on (e.g. price, vendor, stickers).
  • operator β€” eq, ne, gt, gte, lt, lte, in, startswith, endswith. Effective behavior differs by tool (see Which operators actually work above): semantic_product_search reliably honors only eq and in; filter_category_products and get_available_filters honor eq, gt, gte, lt, lte, in.
  • value β€” a scalar for most operators; a list when the operator is in.

Multiple filters are AND-composed β€” every filter must match. In semantic_product_search they apply across the whole ranked search.

Why semantic_product_search range/prefix filters are unreliable

A price range or prefix filter passed to semantic_product_search may silently match nothing. Ranges (gt/gte/lt/lte) and prefixes (startswith/endswith/ne) are best-effort there. For dependable numeric/range filtering, use filter_category_products against a known category_id. MyChatBot tunes how filters resolve for each catalog β€” contact support if the behavior isn't what you need.

Example tool calls ​

These show how to drive the tools over MCP. Each is a tools/call with a tool name and its arguments.

Semantic search with an attribute filter ​

Rank by meaning, but only among products carrying a specific sticker:

json
{
  "name": "semantic_product_search",
  "arguments": {
    "query": "gift for dry skin",
    "limit": 20,
    "filters": [
      { "attribute": "stickers", "operator": "eq", "value": "ΠŸΠΎΠ΄Π°Ρ€ΡƒΠ½ΠΎΠΊ" }
    ]
  }
}

stickers is a string-list attribute, so an eq matches any single element in the list. This is the sweet spot for semantic_product_search filters: eq/in on a string attribute.

Free-text query with a reliable price filter (two-step) ​

There is no single tool that combines a free-text query with a dependable numeric/price range. semantic_product_search is the only tool that takes a query, but its range filters are best-effort; filter_category_products gives reliable ranges but requires a category_id and accepts no query. Bridge them: use the free-text search to resolve a category, then apply the price range there.

json
// Step 1 β€” resolve a category from the free-text query.
// semantic_product_search returns suggested categories alongside products.
{
  "name": "semantic_product_search",
  "arguments": { "query": "waterproof hiking boots", "limit": 20 }
}
// -> pick a category_id from the returned categories, e.g. "boots-hiking"

// Step 2 β€” apply the reliable price range inside that category.
{
  "name": "filter_category_products",
  "arguments": {
    "category_id": "boots-hiking",
    "filters": [
      { "attribute": "price", "operator": "gte", "value": 80 },
      { "attribute": "price", "operator": "lte", "value": 200 }
    ],
    "limit": 100
  }
}

Single-call fallback

If you must do it in one call, semantic_product_search with price range filters is acceptable only as best-effort. Don't depend on it when the price bound matters β€” prefer the two-step pattern.

json
{
  "name": "semantic_product_search",
  "arguments": {
    "image_url": "https://example.com/customer-photo.jpg",
    "limit": 10
  }
}

Multi-value in filter ​

json
{
  "name": "semantic_product_search",
  "arguments": {
    "query": "running shoes",
    "filters": [
      { "attribute": "brand", "operator": "in", "value": ["Nike", "Adidas", "Asics"] }
    ]
  }
}

Deterministic category browse with a price range ​

json
{
  "name": "filter_category_products",
  "arguments": {
    "category_id": "shoes-running",
    "filters": [
      { "attribute": "price", "operator": "gte", "value": 50 },
      { "attribute": "price", "operator": "lte", "value": 150 }
    ],
    "limit": 100
  }
}

Introspect a category before filtering ​

json
{ "name": "get_category_attributes",        "arguments": { "category_id": "shoes-running" } }
{ "name": "get_category_attribute_values",  "arguments": { "category_id": "shoes-running", "attribute_name": "brand" } }
{ "name": "get_available_filters",          "arguments": { "category_id": "shoes-running", "facet_attributes": ["brand", "color"] } }

Exact batch fetch by ID ​

json
{
  "name": "get_products_by_ids",
  "arguments": { "product_ids": ["SKU-1001", "SKU-1002", "SKU-1003"] }
}

Best practices ​

Do

  • Start conversational queries with semantic_product_search; it understands the meaning of the query and reranks the best matches to the top.
  • Keep semantic_product_search filters to eq/in on string attributes β€” that's the reliable path.
  • Discover valid attribute names/values with get_category_attributes and get_category_attribute_values before sending filters β€” don't guess attribute names.
  • Use filter_category_products when the category is known and you need predictable range-based filtering (gt/gte/lt/lte) rather than ranked recall.
  • For free-text + price, run the two-step pattern: semantic_product_search to resolve a category_id, then filter_category_products for the range.
  • Use get_products_by_ids (or get_product_details) when the agent already resolved exact IDs β€” skip ranking entirely.
  • Keep enable_reranking=true for natural-language queries; it materially improves ordering.

Don't

  • Don't rely on gt/gte/lt/lte/startswith/endswith/ne inside semantic_product_search filters for correctness β€” route range filtering through filter_category_products.
  • Don't expect startswith/endswith to work reliably on any tool β€” use in with an explicit value set instead.
  • Don't request a limit above 60 for semantic_product_search.
  • Don't send filters to tools that don't accept them (find_similar_products, get_product_details, get_all_categories, etc.).

Reranking is auto-skipped for code / URL queries

Even with enable_reranking=true, reranking is automatically skipped when the query looks like a SKU/barcode or a URL β€” MyChatBot tunes exactly when it kicks in. For exact SKU-style lookups, prefer get_products_by_ids, or set enable_reranking=false.

truncate_description trims payloads

truncate_description defaults to true, so semantic_product_search results carry shortened descriptions. Set it to false only when the agent needs the full text. Very long descriptions are shortened when indexed regardless.

Test it ​

  • Call get_all_categories, pick a category_id, then chain get_category_attributes β†’ get_category_attribute_values to confirm which attributes and values are actually filterable for that catalog.
  • Run a known-good query through semantic_product_search and assert the expected product IDs appear.
  • To verify a price range actually applied, compare semantic_product_search (best-effort) against the two-step filter_category_products result β€” divergence means the semantic-search range filter didn't apply, so use the two-step pattern.
  • If an attribute filter silently returns nothing, the integration's searchable attributes may be out of date. Re-index by removing and re-adding the product integration, or ask support to run a full re-index.

See also ​