{"ok":true,"site":{"host":"luoaini1213.github.io","url":"https://luoaini1213.github.io/counterask-webmcp/","type":"live","desc":"A menswear storefront whose WebMCP tools return a question when answering would be a guess.","tools":[{"name":"search_products","kind":"answer","impl":"imperative","description":"Search 9,901 menswear products. Pass the shopper's request in their own words: the store reads budgets (\"under $40\", \"between 20 and 30 dollars\"), refusals (\"not leather\", \"no laces\", \"nothing from Nike\"), orderings (\"cheapest\", \"best rated\"), stated attributes (\"long sleeve\", \"waterproof\") and attributes waved through (\"any material is fine\") out of the sentence itself, and never asks about anything already said. Anything you already know from the conversation can also be passed structured; structured input wins over the parse. Returns one of two shapes. status \"answer\": ranked products, plus \"differentiators\" naming the attributes that still separate them, so you can summarise rather than list. status \"need_more_evidence\": one clarifying question, because ranking now would be a coin flip between near-identical items and one attribute would settle it — put it to the shopper, then call answer_question. Either way, \"understood\" echoes exactly how the request was read; check it if a result looks off. When fewer than four products match, \"relax\" says which requirement to lift and how many that leaves.","title":"Search the store","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"The request, in the shopper's words. A whole sentence is fine."},"attributes":{"type":"object","description":"Attributes the shopper requires. Keys are facets — material, closure, sleeve, fit, care, origin, sole, occasion, pocket, waterproof, color, kind — values are arrays of attribute values. Surface wording is accepted (\"waterproof\" for \"water resistant\", \"wallets\" for the category leaf); call list_attributes for the exact vocabulary and counts.","additionalProperties":{"type":"array","items":{"type":"string"}}},"exclude":{"type":"object","description":"Attributes the shopper refuses. Keys are facets — material, closure, sleeve, fit, care, origin, sole, occasion, pocket, waterproof, color, kind — values are arrays of attribute values. Surface wording is accepted (\"waterproof\" for \"water resistant\", \"wallets\" for the category leaf); call list_attributes for the exact vocabulary and counts.","additionalProperties":{"type":"array","items":{"type":"string"}}},"budget_max":{"type":"number","minimum":0,"description":"Ceiling in dollars. Products with no listed price are kept, ranked after priced ones."},"budget_min":{"type":"number","minimum":0,"description":"Floor in dollars."},"no_preference":{"type":"array","items":{"type":"string","enum":["material","closure","sleeve","fit","care","origin","sole","occasion","pocket","waterproof","color","kind"]},"description":"Facets the shopper said they do not mind. The store will not ask about these."},"sort":{"type":"string","enum":["relevance","price_asc","price_desc","rating","popular"],"description":"Order of the answer. Default relevance."}},"required":["query"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"refine_search","kind":"act","impl":"imperative","description":"Add one requirement or one refusal to the current search without starting over. Use it when the shopper adds a fact mid-conversation — \"actually, leather\", \"not the zip one\". Returns the same two shapes as search_products, and may come back with a question.","title":"Add a requirement or a refusal","inputSchema":{"type":"object","properties":{"facet":{"type":"string","enum":["material","closure","sleeve","fit","care","origin","sole","occasion","pocket","waterproof","color","kind"],"description":"Which attribute."},"values":{"type":"array","items":{"type":"string"},"description":"Accepted (or, with mode \"exclude\", refused) values. Surface wording is accepted."},"mode":{"type":"string","enum":["require","exclude"],"description":"Default \"require\"."}},"required":["facet","values"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"parse_only","kind":"act","impl":"imperative","description":"A dry run: how the store would read the shopper's words — what it takes as a requirement, a refusal, a budget, an ordering, a facet waved through, and what it ignores — with which pass claimed which words, in order. Nothing is searched or changed. Use it to check a reading before acting on it, or to show the shopper what was heard.","title":"See how the store would read a sentence","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"The request, verbatim."}},"required":["query"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"revise_search","kind":"act","impl":"imperative","description":"The shopper changed their mind. Drop one or more things they had said — an attribute value (\"leather\"), a facet name (\"material\", which also forgets a no-preference), a refused word, \"budget\" or \"sort\" — and keep the rest, including the cart. Pass drop_all to take the whole request back. The result says what was dropped and what was not found, so you can tell the shopper it heard them.","title":"Take something back","inputSchema":{"type":"object","properties":{"drop":{"type":"array","items":{"type":"string"},"description":"Values, facet names, refused words, \"budget\" or \"sort\"."},"drop_all":{"type":"boolean","description":"Take the whole request back; the cart is kept."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"list_attributes","kind":"answer","impl":"imperative","description":"The attribute vocabulary this catalog actually carries, per facet, with how many products record each value. Use it to map a shopper's wording onto values the other tools accept, and to tell the shopper what is and is not on offer.","title":"The catalog's attribute vocabulary","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"show_products","kind":"act","impl":"imperative","description":"Replace the visible product grid with a specific set of ids, in your order. Use it after applying judgement the store cannot — reading images, weighing what the shopper said three messages ago — so the person sees what you picked rather than a chat transcript.","title":"Curate the grid","inputSchema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"},"description":"Product ids from a previous result, in the order to display."}},"required":["ids"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"explain_ranking","kind":"act","impl":"imperative","description":"Why a given product sits where it does: which words matched, whether it matches the whole request, the demand signal, and the stopping-policy state. Deterministic, so the same answer every time — quote it to the shopper if they ask why.","title":"Why a product ranks where it does","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"A product id from the current results."}},"required":["id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"add_to_cart","kind":"act","impl":"imperative","description":"Put a product from the current results in the cart. Returns the cart with line totals. Placing the order is not a tool you can call: the checkout form on the page is a declarative WebMCP tool without auto-submit, so you may fill it in, and only the shopper can press \"Place order\".","title":"Add to the cart","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"A product id from the current results."},"quantity":{"type":"integer","minimum":1,"maximum":99,"description":"Default 1. At most 99 of a product in the cart, including previous additions."}},"required":["id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"remove_from_cart","kind":"act","impl":"imperative","description":"Take a product out of the cart. Returns the cart.","title":"Remove from the cart","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"A product id in the cart."}},"required":["id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"view_cart","kind":"act","impl":"imperative","description":"What is in the cart, with line totals and the order total.","title":"The cart","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"reset_search","kind":"act","impl":"imperative","description":"Clear the query, every requirement, refusal and budget, and the question budget. The cart is kept.","title":"Start over","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/counterask-webmcp/"},{"name":"checkout","kind":"transact","impl":"declarative","description":"Place the order for everything in the cart. Fill in the shopper's name and delivery address. This form is deliberately not auto-submitted: after it is filled, the shopper reviews it and presses Place order themselves.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Full name"},"address":{"type":"string","description":"Delivery address"}},"required":["name","address"]},"__source":"spec","__declarative":true,"page":"/counterask-webmcp/"}],"category":"Commerce","apiSurface":"spec","toolCount":12}}