Skip to content

Testing & validating search ​

How to prove your catalog is actually searchable: lock down known-good results with regression cases, inspect the live index to see exactly which attributes and values are filterable, and confirm filters fire after a re-index.

You do this from two places:

  • In the app β€” Knowledge Base β†’ Products shows each catalog's indexing status and lets you connect AI tools to it.
  • Over the Product MCP β€” connect the catalog to Claude Code, Cursor, or any MCP client and call the same search tools your agent uses, so you can script exact checks.

Cheat sheet ​

Every product source you connect (a feed URL, a spreadsheet, KeyCRM, Sitniks, …) becomes one catalog, and every search runs against exactly one catalog:

  • In the app you're always looking at a single catalog's card under Knowledge Base β†’ Products.
  • Over MCP, the Server address you copy from Connect AI tools is already scoped to your account and that one catalog β€” so the search tools never ask you which catalog to use; the address decides.

In the app

Knowledge Base β†’ Products β†’ open a catalog's β‹― menu β†’ Connect AI tools. Copy the Server address (and the ready-made Claude Code / Cursor setup) for the catalog you want to test. https://app.mychatbot.app/knowledge-base

The Connect AI tools modal: the Product MCP server address plus the Claude Code and Cursor setup snippets, scoped to one catalog

The setup you copy looks like this β€” one server address, plus a one-line install for the tool you use:

bash
# Claude Code β€” run in your terminal
claude mcp add --transport http product-search "https://product.mychatbot.app/mcp/<account>/<catalog>/stream"
jsonc
// Cursor β€” add to ~/.cursor/mcp.json (or .cursor/mcp.json in your project)
{ "mcpServers": { "product-search": { "url": "https://product.mychatbot.app/mcp/<account>/<catalog>/stream" } } }

Inspect what the index knows (over MCP) ​

Once a catalog is connected, these read-only tools let you inspect what the index actually holds before and after an import. They're the same tools your agent uses, so running them yourself is the closest thing to what a shopper's message triggers.

Tool (over MCP)What it doesUse it to
get_all_categoriesLists every category in the catalogConfirm the catalog indexed at all; grab a category to drill into
get_category_attributesFor one category, lists the attributes you can filter onCheck the attributes you plan to filter on are genuinely filterable
get_category_attribute_valuesFor one attribute, shows the real values presentDiscover exact values to filter on (brand names, colours, sizes…)
get_available_filtersFor a category, returns each attribute's values with countsProve a filter is live β€” apply one and watch the counts narrow
semantic_product_searchRuns a real search (text and/or image), optionally with filtersRun the exact query a regression case checks

Check indexing status (in the app) ​

There's no status tool β€” indexing progress lives on the catalog's card.

In the app

Knowledge Base β†’ Products β†’ your catalog shows an Indexing status panel with a progress bar and a Refresh button. (KeyCRM / Sitniks catalogs show the same panel on the Integrations page.) https://app.mychatbot.app/knowledge-base

Status you seeMeaningWhat to do
Preparing / preprocessing feed…, Parsing products…, Generating embeddings…, Indexing products…Still workingKeep waiting β€” the panel auto-refreshes
Completed β€” N products / M categoriesDoneSafe to verify searches and filters
No active indexing / an errorStuck or failedRe-run it (see Confirming filters work after a re-index)

Wait for Completed before you trust any search or filter result β€” a half-built index looks exactly like a ranking or filter bug.

Validation workflow ​

StepDo thisPass signal
1. Catalog presentget_all_categoriesExpected categories appear with non-empty products
2. Attributes filterableget_category_attributes on a categoryThe attributes you plan to filter on are listed
3. Real values existget_category_attribute_values for eachThe value list is non-empty and matches your vendor data
4. Facets non-emptyget_available_filters with your attributesEach requested attribute returns values and counts
5. Filter firessemantic_product_search with a filterResults come back and applying the filter narrows the facet counts
6. Known hits holdRun your regression casesEvery expected product id lands in the top-N window

Known-hits regression pattern ​

The core idea: pin a query to the product ids that must come back for it, then check that every expected id shows up within the first N results. This catches ranking, category-selection, and merge regressions before they reach shoppers.

A case is four things:

  • Which catalog it runs against (record it, so the case always hits the right catalog).
  • The query (exactly as a shopper β€” or the bug report β€” phrased it).
  • The product ids that must appear in the results.
  • The window β€” how many top results to check.

Pick the window by query type:

Query typeWindow to checkWhy
Exact code / SKU lookup (MKRM4177-1)Just the top fewThe exact variants must be right at the top
Natural-language query ("engine for Honda Accord")A wider top 10–20Ordering is allowed to shift, but the target products must still surface

To run a case, call semantic_product_search over that catalog's MCP address with the query, read back the product ids, and confirm your expected ids are within the window. Keep the cases in a living list you re-run after any catalog change:

CatalogQueryMust returnWindow
Auto-partsMKRM4177-1the 3 exact SKU variantstop few
Auto-partsΠ”Π²ΠΈΠ³Π°Ρ‚Π΅Π»ΡŒ HONDA ACCORD3 specific engine listingstop 10

Build cases from real bugs

Every regression case should capture a real production query or a bug you fixed β€” a code lookup that returned the wrong variant, or a kitchen query that surfaced wardrobes. That way any future ranking change re-triggers the exact failure it must not reintroduce.

Only meaningful against a fully-indexed catalog

Known-hits checks only mean something when the catalog is fully built. Before you treat a miss as a ranking regression, confirm the catalog shows Completed in its Indexing status panel β€” a partial index looks exactly like a ranking bug.

Inspecting the index ​

Before you trust a filter, ask the index what it actually knows. The three inspection tools compose top-down: category β†’ its attributes β†’ the values of one attribute β†’ faceted counts.

jsonc
// 1. What attributes can I filter on in this category?
get_category_attributes({ "category_id": "<a category from get_all_categories>" })

// 2. What real values does one attribute have?
get_category_attribute_values({ "category_id": "…", "attribute_name": "brand" })

// 3. Faceted value + count breakdown
get_available_filters({ "category_id": "…", "facet_attributes": ["brand", "price"] })

Use facets to prove a filter is live

get_available_filters is the fastest confidence check: apply a filter (say a price range) and the brand counts should drop. If applying a filter changes the totals, that attribute is genuinely indexed and filterable β€” not just listed somewhere in the raw product data.

Confirming filters work after a re-index ​

Some catalogs that were first indexed a long time ago can have filters that silently return nothing even though the products are there β€” the searchable attribute data behind those filters was never built the modern way. A fresh, from-scratch re-index fixes it, because it rebuilds those searchable attributes.

Re-index, then verify:

  1. Trigger a from-scratch re-index. There's no one-click "rebuild" toggle. Either:

    • Remove the catalog and re-connect it β€” a freshly connected catalog re-indexes from scratch. Its catalog id changes, so re-point any agent tools and re-copy the MCP Server address from Connect AI tools.
    • Or contact MyChatBot support with your account and catalog, and support runs a full rebuild service-side.

    (Toggling the Products switch off/on or clicking Refresh re-validates the feed, but may not force a full from-scratch rebuild.)

  2. Wait for Completed in the Indexing status panel, then re-run the inspection tools β€” get_category_attributes β†’ get_category_attribute_values β†’ get_available_filters. Facets that were empty before should now return values and counts.

  3. Run a filtered search and confirm results come back:

    jsonc
    // A filtered search over the Product MCP
    semantic_product_search({
      "query": "wireless drill",
      "filters": [
        { "attribute": "brand", "operator": "eq",  "value": "Bosch" },
        { "attribute": "price", "operator": "lte", "value": 200 }
      ]
    })

If indexing gets stuck

If a rebuild stalls, the Indexing status panel eventually shows failed / No active indexing rather than spinning forever. Re-run it (remove & re-connect, or ask support), then resume the verification steps.

Exact-match vs range filters

Equals / one-of filters (is, is one of) work broadly. Range and comparison filters (greater than, less than, starts with) resolve reliably only inside a specific leaf category. If a range filter returns nothing on a broad or top-level category, that's expected β€” scope it to a specific leaf category instead. See Filters, attributes & params for the full operator list.

Very old catalogs

The oldest catalogs handle filters differently under the hood. A from-scratch re-index still helps, but confirm with get_category_attributes on a leaf category. If filters still misbehave, contact MyChatBot support β€” MyChatBot tunes search relevance per catalog and can adjust it for yours.

Best practices ​

Do

  • Pin a regression case the moment you fix a search bug, using the exact failing query and the ids it should return β€” and record which catalog it belongs to so it runs against the right one.
  • Keep code/SKU cases on the tight top-few window and natural-language cases on a wider top 10–20.
  • Inspect with the live tools (get_category_attributes, get_available_filters) rather than trusting the raw feed β€” an attribute can be visible in the product data yet not actually filterable.
  • Wait for Completed in the Indexing status panel before verifying, and re-run the inspection tools after every from-scratch re-index to confirm facets came back non-empty.

Don't

  • Don't assert exact result ordering for natural-language queries β€” check set membership within a window; ranking is allowed to shift.
  • Don't verify filters while the catalog is still Preparing / Parsing / Generating embeddings / Indexing β€” a half-built index reads like a filter or ranking bug.
  • Don't debug a "filter returns nothing" as a query bug before ruling out a stale or partial index β€” the fix is usually a from-scratch re-index (remove & re-connect, or ask support).
  • Don't filter with range operators on broad categories β€” scope to a specific leaf category, where range filters resolve.

Test it ​

  1. Connect a catalog to your MCP client (Knowledge Base β†’ Products β†’ β‹― β†’ Connect AI tools), then call get_all_categories and note a leaf category.
  2. Call get_category_attributes on it, then get_category_attribute_values for one attribute to grab a real value.
  3. Call get_available_filters for that attribute and record the counts.
  4. Re-call get_available_filters with a filter applied β€” the counts should narrow. If they don't change (or the facet was empty), trigger a from-scratch re-index (remove & re-connect the catalog, or ask MyChatBot support), wait for Completed in the Indexing status panel, and repeat.
  5. Add the query + expected ids (with the catalog) to your regression list so the win is permanent.

See also ​