Find local US businesses: what they offer, prices from their own sites, and how to order or book.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
🔴 ACTS FOR THE USER: call it only after the user has explicitly agreed to this exact action (what, where, when, who) — never on your own judgement. For a service whose business’s card shows a `book` action with method `connected` and no `book` in its `cannot` (a door the platform refuses for this account is marked there, with the reason, at every sync). Take a `start_at` from check_availability (slots) and the platform books it for the named customer; the answer is the platform’s own status (created = on the calendar awaiting confirmation · confirmed · declined). A time the platform does not offer is an `unavailable` error and nothing is booked. Idempotent by `idempotency_key` like place_order. Get the user’s explicit yes first. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
ISO date-time with an offset, as check_availability gave it
the service, from the card
the service variation when the card lists several
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http catalog https://www.suverse.io/mcp/catalog
🔴 ACTS FOR THE USER: call it only after the user has explicitly agreed to this exact action (what, where, when, who) — never on your own judgement. For a service whose business’s card shows a `book` action with method `connected` and no `book` in its `cannot` (a door the platform refuses for this account is marked there, with the reason, at every sync). Take a `start_at` from check_availability (slots) and the platform books it for the named customer; the answer is the platform’s own status (created = on the calendar awaiting confirmation · confirmed · declined). A time the platform does not offer is an `unavailable` error and nothing is booked. Idempotent by `idempotency_key` like place_order. Get the user’s explicit yes first. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| note | any | |
| customer* | object | |
| start_at* | string | ISO date-time with an offset, as check_availability gave it |
| variant_id | any | the service variation when the card lists several |
| business_id* | string | |
| offering_id* | string | the service, from the card |
| idempotency_key | any |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"business_id",
"offering_id",
"start_at",
"customer"
],
"properties": {
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
]
},
"customer": {
"type": "object",
"properties": {
"name": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
],
"description": "the buyer’s name (required for a booking)"
},
"email": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "the buyer’s e-mail: the platform sends the checkout link and the receipt there (for a booking; NOT asked for an order on Shopify or Square, whose checkout asks the buyer)"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
],
"description": "the buyer’s telephone with country code"
}
},
"additionalProperties": false
},
"start_at": {
"type": "string",
"maxLength": 60,
"description": "ISO date-time with an offset, as check_availability gave it"
},
"variant_id": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
],
"description": "the service variation when the card lists several"
},
"business_id": {
"type": "string",
"format": "uuid"
},
"offering_id": {
"type": "string",
"format": "uuid",
"description": "the service, from the card"
},
"idempotency_key": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
}Only for a business whose card shows `live_data` (its items come from its connected Shopify or Square, not from a page read). For a product: the platform’s stock right now — `state: confirmed | refuted | unknown` (unknown = the platform does not track stock, which is not «no»). For a service on a platform with bookings: the free `slots` between `from` and `to` (default: the next 7 days), each with a `start_at` that book_slot takes as it is — on the business’s own clock with its offset (`timezone` names the zone; `start_at_utc` is the same instant). If the card’s `cannot` lists `book`, the slots are information only and the answer says so. A business without a connection answers `not_connected`. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| to | any | slots: the window’s end, ISO with an offset |
| from | any | slots: the window’s start, ISO with an offset |
| quantity | any | how many — stock is judged against it |
| variant_id | any | the variant (the card lists them when there are several) |
| business_id* | string | the business id from the card |
| offering_id |
One business the user NAMED, matched by its name near `location` (default radius 15 miles); typos, word order and punctuation are tolerated. Not in the catalogue → `name_not_found`, and up to 5 nearby businesses that carry the name's distinctive word (never presented as the business asked for). `intent`, `query`, `needed_by`, `deliver_to` shape the short card the same way as list_cards. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| name* | string | the business name as the user said it |
| query | any | the thing under the task («red roses», «ribeye»): picks the ≤ 5 items on the card |
| intent | any | what the user means to do with this business |
| location | any | a postcode, a city or "lat,lng" — orders the matches by nearness and bounds the nearby list |
| needed_by | any | when: «sunday», «tomorrow 19:00», «now», «tomorrow after 15:00» — read on the business’s own clock, three ways (on_day / open_at / slot_after) |
| deliver_to | any | where it must be brought (a postcode is best): the card says confirmed / refuted / unknown |
SYNONYM of get_card, kept for agents that already know this name. `transparency`: the SuVerse Transparency rating — how much the business publishes about itself (not the quality of its work), A–D, each item with its source page and read date. Free. One business in full, in the same shape for every trade: who it is (name, trade, address, telephone, e-mail, opening hours, time zone), everything it sells (60 offerings a page, cheapest first; `offerings_page` says how many there are and the next offset), the six actions with their links and `required_fields`, how the thing reaches the buyer (delivery, pickup, on_site, at_customer — with the published area, the fee and the order deadline), and how fresh each part of that is. `live_data` (platform, synced_at) when the shelf is the business’s own connected system: then every offering carries `source: connector` with its variants (each with `inventory`: units in stock as the platform counts them, null = unknown), and an action with method `connected` is taken through place_order / book_slot on this door. Use it when the user asks «can they deliver to me», «are they open now», «what else do they do», or when search_catalog offered a business with nothing listed and the next step is a telephone call. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| id* | string | the business id from search_catalog |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "the business id from search_catalog"
}
},
"additionalProperties": false
}`transparency`: the SuVerse Transparency rating — how much the business publishes about itself (not the quality of its work), A–D, each item with its source page and read date. Free. One business in full, in the same shape for every trade: who it is (name, trade, address, telephone, e-mail, opening hours, time zone), everything it sells (60 offerings a page, cheapest first; `offerings_page` says how many there are and the next offset), the six actions with their links and `required_fields`, how the thing reaches the buyer (delivery, pickup, on_site, at_customer — with the published area, the fee and the order deadline), and how fresh each part of that is. `live_data` (platform, synced_at) when the shelf is the business’s own connected system: then every offering carries `source: connector` with its variants (each with `inventory`: units in stock as the platform counts them, null = unknown), and an action with method `connected` is taken through place_order / book_slot on this door. Use it when the user asks «can they deliver to me», «are they open now», «what else do they do», or when search_catalog offered a business with nothing listed and the next step is a telephone call. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| id* | string | the business id from search_catalog |
| offerings_limit | integer | offerings on this page (default 60, at most 200) |
| offerings_offset | integer | 11-05: where this page of offerings starts (default 0); offerings_page.next_offset gives the next one |
Free. One offering in full, with ONE live request to the shop asking for that item’s price and stock right now (`live_check`). Call it before you quote a price to a person: a catalogue read yesterday is yesterday’s price. One business is asked at most once every ten minutes however many of its offerings you open, so walking a shop is one request and not twenty; `from_cache` and `checked_at` say which. A price list, a menu or a quote form has no single-item door to ask (`ok: false` with the reason) and the stored reading stands with its date. Hand `action_url` to the user as it is, ref=suverse included. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| id* | string | the offering id from search_catalog |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "the offering id from search_catalog"
}
},
"additionalProperties": false
}SYNONYM of get_offering, kept for agents that already know this name. A «product» is just an offering whose kind is `product`; the same id works in both. Free. One offering in full, with ONE live request to the shop asking for that item’s price and stock right now (`live_check`). Call it before you quote a price to a person: a catalogue read yesterday is yesterday’s price. One business is asked at most once every ten minutes however many of its offerings you open, so walking a shop is one request and not twenty; `from_cache` and `checked_at` say which. A price list, a menu or a quote form has no single-item door to ask (`ok: false` with the reason) and the stored reading stands with its date. Hand `action_url` to the user as it is, ref=suverse included. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| id* | string | the offering id from search_catalog |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "the offering id from search_catalog"
}
},
"additionalProperties": false
}Every business of ONE trade (`niche`: a key from list_niches, exactly) near `location`, default radius 15 miles, 20 a page. The order is fixed and is not a ranking: independent businesses, then chains, then marketplaces; inside each, by distance (a trade that comes to the customer: published service area first). `query` does NOT filter or reorder businesses: it chooses which ITEM each card shows. To find businesses that have an item, use search_catalog. Each card: id, name, distance, phone, a few items, `next` (one action), and for what you pass — `needed_by`, `max_price`, `deliver_to` — a state: hours give open_then / closed_then / unknown (never a free slot); an item price within the budget is item_price_within_budget (the total is not known until priced). `needed_by`: «today», «tomorrow 19:00», «after 15:00», an interval «tomorrow 08:00 to 17:00», a deadline «by 2026-11-20», a range «this week» — read the same way in every tool. A `niche` that is not a key returns no cards and the variants to choose from. Each card carries `transparency` {grade A–D, have, of, items ✓/✗}: how much the business publishes about itself, NOT quality. You may sort or filter by it; this order does not use it. Trades on the shelf: restaurant (2520) · medical clinic (1227) · auto repair (1111) · insurance agent (1107) · hair salon (1095) · dentist (1076) · lawyer (1037) · oil change (978) · clothing store (903) · massage (890) · accountant (881) · nail salon (782) · hvac (776) · print shop (768) · real estate agent (762) · beauty salon (757) · barber (734) · chiropractor (710) · notary (673) · gas station (663) · appliance repair (589) · grocery (562) · car dealer (560) · storage (548) · optometrist (542) · bakery (537) · bar (530) · landscaping (516) · pharmacy (505) · elder care and home care (461) · daycare (448) · body shop (446) · photographer (440) · pet grooming (433) · pizza (426) · catering (411) · cleaning (409) · event venue (402) · florist (402) · tire shop (393) · auto parts store (389) · hotel (379) · pressure washing (378) · plumber (372) · jewelry (362) · furniture (361) · electrician (355) · pool service (355) · windows and doors (330) · tree service (327) · coffee shop (325) · party rental (319) · towing (316) · roofer (313) · veterinarian (306) · tattoo studio (296) · truck tire service (294) · pest control (293) · car wash (274) · junk removal (272) · movers (271) · liquor store (268) · tutoring (262) · ev charging station (260) · urgent care (256) · window cleaning (248) · truck repair (237) · carpet cleaning (224) · travel agency (214) · painter (191) · physical therapy (190) · ice cream shop (189) · car rental (188) · parking (176) · bike repair (175) · dance studio (169) · fishing charter and boat tours (168) · fuel delivery (167) · jewelry and watch repair (164) · music lessons (160) · dry cleaner (159) · locksmith (154) · handyman (152) · med spa (152) · auto glass (151) · gym (147) · general contractor (146) · shipping and packing store (146) · wedding planner (139) · septic and well service (131) · garage door (124) · dog walking and pet sitting (108) · garden center and nursery (103) · pet boarding (103) · phone repair (101) · mattress (88) · thrift store (87) · yoga (83) · hardware store (75) · boat rental (73) · tailor (68) · bike and jet ski rental (65) · funeral home (60) · medical equipment rental (55) · golf course (53) · driving school (52) · pet store (49) · butcher and seafood market (43) · swim school (30) · meal prep (21) · cinema (20) · shooting range (20) · juice bar (19) · computer repair (18) · kids play center (18) · escape room (17) · tennis and sports courts (17) · bowling and billiards (12) · brewery (9) · kids sports and activities (9) · specialty grocery and farmers market (9) · babysitting and nanny agency (8) · motorcycle repair (8) · taxi and transfer service (8) · local business (6) · other online service (6) · martial arts (5) · shoe repair (4) · online store (3) · food truck (2) · lash and brow studio (2) · museum (2) · services (2) · sporting goods store (2) · aquarium (1) · butcher (1) · furniture store (1) · logistics software (1) · motel (1) · shoe store (1) · store (1) · transportation service (1) · travel booking site (1); known but not scanned anywhere: candle shop, confectionery, garden center, gift shop, medical apparel, party shop, toy store. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
The trades (niches) this catalogue holds near a place, by key, with how many businesses are inside the radius (default 15 miles). Without `niche`: a compact list of keys. With `niche`: that trade in full — its tags, coverage and the conditions its businesses publish. A `niche` that is not a key comes back with `variants` and why (a tag, a similar name, a meaning) — nothing is substituted: pick a key. `detail: "full"` lists every trade in full. Coverage: local businesses in a few US cities — call it and the answer says what was searched. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| niche | any | one niche key: that niche in full (tags, coverage, every condition it publishes). Another word returns `variants` with why, never a substitute |
| detail | any | compact (default without a matched niche): keys and counts; full: every niche with tags, coverage and conditions |
| location | any | a 5-digit US postcode, a city ("Tampa, FL") or "lat,lng". Optional: without it every niche is listed with its totals. |
| radius_miles | number | How far from the location counts as «here». Default 15 (the same in every tool). |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"niche": {
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
],
"description": "one niche key: that niche in full (tags, coverage, every condition it publishes). Another word returns `variants` with why, never a substitute"
},
"detail": {
"anyOf": [
{
"enum": [
"compact",
"full"
],
"type": "string"
},
{
"type": "null"
}
],
"description": "compact (default without a matched niche): keys and counts; full: every niche with tags, coverage and conditions"
},
"location": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "a 5-digit US postcode, a city (\"Tampa, FL\") or \"lat,lng\". Optional: without it every niche is listed with its totals."
},
"radius_miles": {
"type": "number",
"maximum": 250,
"minimum": 1,
"description": "How far from the location counts as «here». Default 15 (the same in every tool)."
}
},
"additionalProperties": false
}The status of an `order_id` from place_order or book_slot, asked of the platform again when it is not final (paid? confirmed? declined by the owner?). A Shopify cart link answers `unknown` — payment is on Shopify’s side and the shop does not report it here. Free. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| order_id* | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"order_id"
],
"properties": {
"order_id": {
"type": "string",
"format": "uuid"
}
},
"additionalProperties": false
}🔴 ACTS FOR THE USER: call it only after the user has explicitly agreed to this exact action (what, where, when, who) — never on your own judgement. For a business whose card shows an `order` action with method `connected`. Shopify: returns the shop’s own checkout link with these items and quantities already in the cart (`status: unknown`, `mode: cart`) — no customer data is needed or passed, the buyer gives their details and pays on Shopify, and nothing exists on the shop until they do. Square: an order with a payment link (no customer data either). WhatsApp: a message to the owner (customer phone or email). Returns `order_id`, `status`, `checkout_url` — HAND THE CHECKOUT URL TO THE USER AS IT IS: that page takes the money, SuVerse holds no card and charges nothing. Stock is checked live first on a platform that tracks it; «not in stock» is an `unavailable` error and no order or link is given. Send an `idempotency_key` of your own and keep it for a retry: the same key returns the same answer and the same link (`repeated: true`), never a second one. Lines name offerings by their card id (and `variant_id` when the card lists several). `status`: unknown (a cart link: payment is on the platform’s side) · created (the platform holds it) · pending_owner (WhatsApp) · confirmed · declined · failed. Get the user’s explicit yes before calling this. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| note | any | a note to the business, in the user’s words (not passed on a Shopify cart link) |
| lines* | array | |
| customer | any | only where the platform needs it (WhatsApp); omit for Shopify and Square |
Prices ONE cart in the shop's own public cart (Shopify or WooCommerce) to ONE ZIP, with no personal data, and orders nothing: the cart is emptied afterwards. Answers the items, delivery options with their prices, the subtotal and what stays unknown (tax and fees at checkout; the delivery date unless the cart names it — `delivery_date` asks for a day). Other platforms answer «quote not available» with the reason and the order link. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| items | any | several different items of the SAME shop in one cart (delivery and tax on the whole order); offering_id is then the first of them |
| options | any | answers to the product page’s own add-on questions; the rest are answered «no» |
| quantity | integer | default 1 |
| deliver_to* | any | where it must be brought: "33139", "Miami Beach, FL 33139", or {postcode, state, city, address_1} |
| variant_id | any | a variant id from the card when it lists several |
| offering_id* | string | the offering id from a card |
| delivery_date | any |
Delivery (`sent` · `link_given` · `expired` · `failed`) and the owner’s outcome (`declined` · `other_time` + proposal · `available` = free but NOT booked · `confirmed` = booked). `confirmed: true` only when the owner booked it. `wait_seconds` (optional, default 0 = answer now; at most 45 s are used): waits for the owner and returns as soon as the request is answered or final, otherwise the current status when the wait ends (see `wait.ended`). Waiting is not a promise of an answer, and nothing calls you back afterwards: if it is still waiting, call request_status again later (for example when the person asks). Hanging up does not cancel the request. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| request_id* | string | |
| wait_seconds | integer | seconds to wait for the owner's answer (0–60, default 0; at most 45 are used) |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"request_id"
],
"properties": {
"request_id": {
"type": "string",
"format": "uuid"
},
"wait_seconds": {
"type": "integer",
"maximum": 60,
"minimum": 0,
"description": "seconds to wait for the owner's answer (0–60, default 0; at most 45 are used)"
}
},
"additionalProperties": false
}🔴 ACTS FOR THE USER: call it only after the user has explicitly agreed to this exact action (what, where, when, who) — never on your own judgement. For a business that takes requests through SuVerse (a verified owner with Telegram, e-mail or WhatsApp). Sends what, when, how many, which branch and the person’s name and contact. Requires `idempotency_key`: retrying with the same key returns the same request. Answers: `sent` (delivered to the owner), `link_given` (WhatsApp: give `whatsapp_url` to the person — THEY send it; nothing is sent yet), or `no_channel` with the business’s other doors. After it, tell the person it is NOT a booking yet and where the answer will come (`next_steps.tell_the_person`, `next_steps.answer_goes_to`). If you can set reminders, schedule a request_status check (`next_steps.check_again_after` is a pause, not a promised reply time) — and only then say you will check; otherwise tell the person how to ask again. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| date | any | YYYY-MM-DD, the business’s local date |
| note | any | |
| time | any | HH:MM, the business’s local time |
| what* | string | what the person wants (a service, an item, a table for 4 …) |
| branch | any | which location, when the business has several |
| customer |
Search by what is wanted (an item, a dish, a service, in any language) near `location`, default radius 15 miles, when the trade is not known. Each business shows its best-fitting items first; `match.fit` says how well: exact (the thing and every asked property), likely (the thing, a property not stated), property (the thing with another quantity or colour), partial (only its main word), none. `nothing_fitting` says so when nothing does. Conditions you pass come back per business as met / violated / unknown (time: open_then / closed_then / unknown): the item's price is not the total, opening hours are not a delivery time, being near is not being served. No `location` and nothing fitting → an empty list, not unrelated businesses from anywhere. Coverage: local businesses in a few US cities — call it and the answer says what was searched. Follow the server instructions «HOW TO USE THE SUVERSE CATALOG»: results are candidates, not proof; keep reading, quoting, requesting and ordering separate; nothing is sent to an owner, booked, ordered or paid without the user’s permission.
| Argument | Type | Description |
|---|---|---|
| limit | integer | How many BUSINESS CARDS to return. Default 10. |
| query* | string | What the user wants, IN THEIR OWN WORDS AND THEIR OWN LANGUAGE: "red roses", "steakhouse", "funeral flowers", "movers 2 bedroom", "ramo de rosas", or the same question in a language not written in the Latin alphabet. Matched by MEANING as well as by words, through one multilingual model — so do NOT translate for us and do NOT list synonyms yourself. A place, a date, a budget and a delivery word may be left in (they are parsed out), but the fewer extra words the better the match. |
| detail | string | compact (default): the business, its 1–2 best offerings with prices and links, what can be done, and the date it was read — a few hundred bytes a card. full: everything, including images, the sentence each price was read from, variants, all four fulfilment modes with published areas, opening hours and per-field evidence. Ask for full only when the user has chosen a business and you need its delivery area or its hours. |
We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 11, 2026.
A very long tool description (over 4,000 characters) is hard to review and easy to hide instructions in.
Fix: Keep the description to what the tool does and when to use it; move reference material to resources or docs.
| string |
| the offering id from the card |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"business_id",
"offering_id"
],
"properties": {
"to": {
"anyOf": [
{
"type": "string",
"maxLength": 60
},
{
"type": "null"
}
],
"description": "slots: the window’s end, ISO with an offset"
},
"from": {
"anyOf": [
{
"type": "string",
"maxLength": 60
},
{
"type": "null"
}
],
"description": "slots: the window’s start, ISO with an offset"
},
"quantity": {
"anyOf": [
{
"type": "integer",
"maximum": 999,
"minimum": 1
},
{
"type": "null"
}
],
"description": "how many — stock is judged against it"
},
"variant_id": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
],
"description": "the variant (the card lists them when there are several)"
},
"business_id": {
"type": "string",
"format": "uuid",
"description": "the business id from the card"
},
"offering_id": {
"type": "string",
"format": "uuid",
"description": "the offering id from the card"
}
},
"additionalProperties": false
}| radius_miles | number | Default 15 (the same in every tool). |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 120,
"minLength": 1,
"description": "the business name as the user said it"
},
"query": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "the thing under the task («red roses», «ribeye»): picks the ≤ 5 items on the card"
},
"intent": {
"anyOf": [
{
"enum": [
"book",
"order",
"quote",
"info",
"reserve",
"request_quote",
"contact",
"call"
],
"type": "string"
},
{
"type": "null"
}
],
"description": "what the user means to do with this business"
},
"location": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "a postcode, a city or \"lat,lng\" — orders the matches by nearness and bounds the nearby list"
},
"needed_by": {
"anyOf": [
{
"type": "string",
"maxLength": 60
},
{
"type": "null"
}
],
"description": "when: «sunday», «tomorrow 19:00», «now», «tomorrow after 15:00» — read on the business’s own clock, three ways (on_day / open_at / slot_after)"
},
"deliver_to": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "where it must be brought (a postcode is best): the card says confirmed / refuted / unknown"
},
"radius_miles": {
"type": "number",
"maximum": 250,
"minimum": 1,
"description": "Default 15 (the same in every tool)."
}
},
"additionalProperties": false
}{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "the business id from search_catalog"
},
"offerings_limit": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "offerings on this page (default 60, at most 200)"
},
"offerings_offset": {
"type": "integer",
"minimum": 0,
"description": "11-05: where this page of offerings starts (default 0); offerings_page.next_offset gives the next one"
}
},
"additionalProperties": false
}| Argument | Type | Description |
|---|---|---|
| page | any | the `next_page` token of the previous answer |
| tags | any | FILTER by the niche’s own tags, as list_niches gives them («steak house», «italian», «dish»): a card without one of them is left out; the order does not change. Spelling is folded («steakhouse» = «steak house»). |
| limit | integer | cards per page. Default 10. |
| niche* | string | a niche key from list_niches, exactly (another word returns the variants to choose from, never a substitute) |
| query | any | chooses which ITEM each card shows («red roses», «balayage»); it does not filter or reorder businesses — for that, search_catalog |
| detail | any | task (default): the short card under the task; shelf: the older ≤ 1 KB shelf card |
| intent | any | what the user means to do: shapes the items shown and the ONE action in `next` (book → book / check_slot / call; order → order / quote_order / call; quote → quote_order / call; info → call) |
| location | string | a 5-digit US postcode (best), a city ("Tampa, FL") or "lat,lng". Required for local trades; ignored for online niches (software, apps, online shops — see list_niches → online_niches). |
| max_price | any | the most for ONE offering, in USD: groups the cards in_budget · budget_unknown · over_budget (nobody is left out) and picks the shown offering inside it (exact, then kind, then partial matches); fixed prices compare; a «from» price above the budget is over, under it budget_unknown |
| needed_by | any | when: «sunday» / «today» / «2026-11-08» (open that day), «tomorrow 19:00» / «now» (open at that minute), «after 15:00» / «tomorrow after 3pm» (open after then; a free slot only where the source knows slots) — on each business’s own clock; adds `time` {asked_as, day, hours, state, why} and LEAVES OUT only the cards refuted for the way the trade is done (see excluded) |
| deliver_to | any | where it must be brought (a postcode is best): adds can_deliver_to per card — confirmed when the published area names the place, refuted when the business says no, unknown otherwise |
| properties | array | facts to read off each card without filtering: property_states {key: "confirmed <value>" | "refuted" | "unknown"} |
| radius_miles | number | Default 15 (the same in every tool). |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"niche"
],
"properties": {
"page": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
],
"description": "the `next_page` token of the previous answer"
},
"tags": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"maxItems": 8
},
{
"type": "null"
}
],
"description": "FILTER by the niche’s own tags, as list_niches gives them («steak house», «italian», «dish»): a card without one of them is left out; the order does not change. Spelling is folded («steakhouse» = «steak house»)."
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "cards per page. Default 10."
},
"niche": {
"type": "string",
"maxLength": 80,
"minLength": 1,
"description": "a niche key from list_niches, exactly (another word returns the variants to choose from, never a substitute)"
},
"query": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "chooses which ITEM each card shows («red roses», «balayage»); it does not filter or reorder businesses — for that, search_catalog"
},
"detail": {
"anyOf": [
{
"enum": [
"task",
"shelf"
],
"type": "string"
},
{
"type": "null"
}
],
"description": "task (default): the short card under the task; shelf: the older ≤ 1 KB shelf card"
},
"intent": {
"anyOf": [
{
"enum": [
"book",
"order",
"quote",
"info",
"reserve",
"request_quote",
"contact",
"call"
],
"type": "string"
},
{
"type": "null"
}
],
"description": "what the user means to do: shapes the items shown and the ONE action in `next` (book → book / check_slot / call; order → order / quote_order / call; quote → quote_order / call; info → call)"
},
"location": {
"type": "string",
"maxLength": 200,
"description": "a 5-digit US postcode (best), a city (\"Tampa, FL\") or \"lat,lng\". Required for local trades; ignored for online niches (software, apps, online shops — see list_niches → online_niches)."
},
"max_price": {
"anyOf": [
{
"type": "number",
"minimum": 0
},
{
"type": "null"
}
],
"description": "the most for ONE offering, in USD: groups the cards in_budget · budget_unknown · over_budget (nobody is left out) and picks the shown offering inside it (exact, then kind, then partial matches); fixed prices compare; a «from» price above the budget is over, under it budget_unknown"
},
"needed_by": {
"anyOf": [
{
"type": "string",
"maxLength": 60
},
{
"type": "null"
}
],
"description": "when: «sunday» / «today» / «2026-11-08» (open that day), «tomorrow 19:00» / «now» (open at that minute), «after 15:00» / «tomorrow after 3pm» (open after then; a free slot only where the source knows slots) — on each business’s own clock; adds `time` {asked_as, day, hours, state, why} and LEAVES OUT only the cards refuted for the way the trade is done (see excluded)"
},
"deliver_to": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "where it must be brought (a postcode is best): adds can_deliver_to per card — confirmed when the published area names the place, refuted when the business says no, unknown otherwise"
},
"properties": {
"type": "array",
"items": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"max": {
"type": "number"
},
"min": {
"type": "number"
},
"equals": {
"type": [
"string",
"number",
"boolean"
]
}
},
"additionalProperties": false
},
"maxItems": 8,
"description": "facts to read off each card without filtering: property_states {key: \"confirmed <value>\" | \"refuted\" | \"unknown\"}"
},
"radius_miles": {
"type": "number",
"maximum": 250,
"minimum": 1,
"description": "Default 15 (the same in every tool)."
}
},
"additionalProperties": false
}| business_id* |
| string |
| idempotency_key | any | your own key for this order; reuse it on a retry |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"business_id",
"lines"
],
"properties": {
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 1000
},
{
"type": "null"
}
],
"description": "a note to the business, in the user’s words (not passed on a Shopify cart link)"
},
"lines": {
"type": "array",
"items": {
"type": "object",
"required": [
"offering_id"
],
"properties": {
"quantity": {
"type": "integer",
"maximum": 999,
"minimum": 1,
"description": "default 1"
},
"variant_id": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
]
},
"offering_id": {
"type": "string",
"format": "uuid",
"description": "from the card"
}
},
"additionalProperties": false
},
"maxItems": 20,
"minItems": 1
},
"customer": {
"anyOf": [
{
"type": "object",
"properties": {
"name": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
],
"description": "the buyer’s name (required for a booking)"
},
"email": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "the buyer’s e-mail: the platform sends the checkout link and the receipt there (for a booking; NOT asked for an order on Shopify or Square, whose checkout asks the buyer)"
},
"phone": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
],
"description": "the buyer’s telephone with country code"
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "only where the platform needs it (WhatsApp); omit for Shopify and Square"
},
"business_id": {
"type": "string",
"format": "uuid"
},
"idempotency_key": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
],
"description": "your own key for this order; reuse it on a retry"
}
},
"additionalProperties": false
}| the day the person wants it delivered ("2026-11-20"): answered as confirmed only when the shop's cart names that day, else «delivery date: unknown» |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"offering_id",
"deliver_to"
],
"properties": {
"items": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"offering_id"
],
"properties": {
"options": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"field",
"value"
],
"properties": {
"field": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"value": {
"type": "string",
"maxLength": 400
}
},
"additionalProperties": false
},
"maxItems": 10
},
{
"type": "null"
}
]
},
"quantity": {
"type": "integer",
"maximum": 99,
"minimum": 1
},
"variant_id": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
]
},
"offering_id": {
"type": "string",
"format": "uuid"
}
},
"additionalProperties": false
},
"maxItems": 20
},
{
"type": "null"
}
],
"description": "several different items of the SAME shop in one cart (delivery and tax on the whole order); offering_id is then the first of them"
},
"options": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"required": [
"field",
"value"
],
"properties": {
"field": {
"type": "string",
"maxLength": 120,
"minLength": 1,
"description": "words of the page’s own question, e.g. «card»"
},
"value": {
"type": "string",
"maxLength": 400,
"description": "the answer, e.g. «No», or the card message"
}
},
"additionalProperties": false
},
"maxItems": 10
},
{
"type": "null"
}
],
"description": "answers to the product page’s own add-on questions; the rest are answered «no»"
},
"quantity": {
"type": "integer",
"maximum": 99,
"minimum": 1,
"description": "default 1"
},
"deliver_to": {
"anyOf": [
{
"type": "string",
"maxLength": 200,
"minLength": 5
},
{
"type": "object",
"required": [
"postcode"
],
"properties": {
"city": {
"anyOf": [
{
"type": "string",
"maxLength": 80
},
{
"type": "null"
}
]
},
"state": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
],
"description": "two letters; read from the postcode when omitted"
},
"country": {
"anyOf": [
{
"type": "string",
"maxLength": 20
},
{
"type": "null"
}
],
"description": "US only for now"
},
"postcode": {
"type": "string",
"maxLength": 10,
"minLength": 5,
"description": "5-digit US postcode"
},
"address_1": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
],
"description": "street line, only for the price: some shops price by it"
}
},
"additionalProperties": false
}
],
"description": "where it must be brought: \"33139\", \"Miami Beach, FL 33139\", or {postcode, state, city, address_1}"
},
"variant_id": {
"anyOf": [
{
"type": "string",
"maxLength": 64
},
{
"type": "null"
}
],
"description": "a variant id from the card when it lists several"
},
"offering_id": {
"type": "string",
"format": "uuid",
"description": "the offering id from a card"
},
"delivery_date": {
"anyOf": [
{
"type": "string",
"maxLength": 40
},
{
"type": "null"
}
],
"description": "the day the person wants it delivered (\"2026-11-20\"): answered as confirmed only when the shop's cart names that day, else «delivery date: unknown»"
}
},
"additionalProperties": false
}| object |
| quantity | any |
| business_id* | string | the business id from the card |
| idempotency_key* | string | your own key for this request; the same key never makes a second one |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"business_id",
"what",
"customer",
"idempotency_key"
],
"properties": {
"date": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
{
"type": "null"
}
],
"description": "YYYY-MM-DD, the business’s local date"
},
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 800
},
{
"type": "null"
}
]
},
"time": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{2}:\\d{2}$"
},
{
"type": "null"
}
],
"description": "HH:MM, the business’s local time"
},
"what": {
"type": "string",
"maxLength": 200,
"minLength": 2,
"description": "what the person wants (a service, an item, a table for 4 …)"
},
"branch": {
"anyOf": [
{
"type": "string",
"maxLength": 120
},
{
"type": "null"
}
],
"description": "which location, when the business has several"
},
"customer": {
"type": "object",
"required": [
"name",
"contact"
],
"properties": {
"name": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"contact": {
"type": "string",
"maxLength": 150,
"minLength": 5,
"description": "e-mail or phone where the owner can answer"
}
},
"additionalProperties": false
},
"quantity": {
"anyOf": [
{
"type": "integer",
"maximum": 999,
"minimum": 1
},
{
"type": "null"
}
]
},
"business_id": {
"type": "string",
"format": "uuid",
"description": "the business id from the card"
},
"idempotency_key": {
"type": "string",
"maxLength": 80,
"minLength": 8,
"description": "your own key for this request; the same key never makes a second one"
}
},
"additionalProperties": false
}| location | string | Where the user is, or where it must happen. A 5-DIGIT US POSTCODE IS BEST ("33139"): it is the only form a business’s own published delivery or service area can be matched against exactly, so a postcode gets you `how: "zips"` and a city name gets you a distance. A city ("Orlando, FL") or "lat,lng" also work. OPTIONAL IN NAME ONLY — without it nothing is measured and nothing is narrowed, and the answer comes back with `needs` carrying the question to put to your user. "near me" is not a location: ask which town. |
| max_price | number | The most the user will pay for ONE offering, in USD, compared against the lowest number the business published — so "from $45" passes "under $50". An offering priced on request is NOT filtered out: it comes back `price_type: "quote_only"`, because "they quote it" is an answer. |
| needed_by | string | When it has to happen: "today", "tomorrow", "tomorrow 9am", or an ISO date-time — WITH an offset (2026-10-31T14:00:00-04:00) if you know the user’s zone, because a business whose cut-off is on the RECIPIENT’s clock can only be judged against an offset you give. |
| only_local | boolean | true = leave out marketplaces: a business whose shelf names places far from its own address (one local address, hundreds of listings in other cities and countries). Default false: a marketplace is kept, ranked lower, and its card says `marketplace: true` (the full card says why). |
| properties | array | THE OPEN LAYER AS A FILTER: facts a business publishes beyond price and availability — a capacity, a deposit, a duration, whether something is included. Three states per key: a published value that fits = confirmed; a published value that does not = refuted (left out, a fact); nothing published = unknown (KEPT, ranked lower, named in the card’s `unknown`). Ask for the user’s real conditions here instead of putting them in `query`: «for 8 people» is {key:"capacity",min:8}, «no deposit» is {key:"deposit",max:0}. |
| fulfillment | string | HOW it must reach the user, and the four are different questions: delivery = brought to the address; pickup = the user collects; on_site = the user goes there (a salon chair, a dining room); at_customer = the business travels (a mover, a plumber). Default any. A business that has not published an answer is KEPT; one that ruled it out is dropped. |
| radius_miles | number | How far the business may be, in miles. Default 15. |
| only_independent | boolean | true = leave out chains (a business whose website serves several of the places found). Default false: a chain is kept as a name, a telephone and a website — it was never read, so it has no offerings — and its card says `chain: true`. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "How many BUSINESS CARDS to return. Default 10."
},
"query": {
"type": "string",
"maxLength": 300,
"minLength": 1,
"description": "What the user wants, IN THEIR OWN WORDS AND THEIR OWN LANGUAGE: \"red roses\", \"steakhouse\", \"funeral flowers\", \"movers 2 bedroom\", \"ramo de rosas\", or the same question in a language not written in the Latin alphabet. Matched by MEANING as well as by words, through one multilingual model — so do NOT translate for us and do NOT list synonyms yourself. A place, a date, a budget and a delivery word may be left in (they are parsed out), but the fewer extra words the better the match."
},
"detail": {
"enum": [
"compact",
"full"
],
"type": "string",
"description": "compact (default): the business, its 1–2 best offerings with prices and links, what can be done, and the date it was read — a few hundred bytes a card. full: everything, including images, the sentence each price was read from, variants, all four fulfilment modes with published areas, opening hours and per-field evidence. Ask for full only when the user has chosen a business and you need its delivery area or its hours."
},
"location": {
"type": "string",
"maxLength": 200,
"description": "Where the user is, or where it must happen. A 5-DIGIT US POSTCODE IS BEST (\"33139\"): it is the only form a business’s own published delivery or service area can be matched against exactly, so a postcode gets you `how: \"zips\"` and a city name gets you a distance. A city (\"Orlando, FL\") or \"lat,lng\" also work. OPTIONAL IN NAME ONLY — without it nothing is measured and nothing is narrowed, and the answer comes back with `needs` carrying the question to put to your user. \"near me\" is not a location: ask which town."
},
"max_price": {
"type": "number",
"minimum": 0,
"description": "The most the user will pay for ONE offering, in USD, compared against the lowest number the business published — so \"from $45\" passes \"under $50\". An offering priced on request is NOT filtered out: it comes back `price_type: \"quote_only\"`, because \"they quote it\" is an answer."
},
"needed_by": {
"type": "string",
"maxLength": 60,
"description": "When it has to happen: \"today\", \"tomorrow\", \"tomorrow 9am\", or an ISO date-time — WITH an offset (2026-10-31T14:00:00-04:00) if you know the user’s zone, because a business whose cut-off is on the RECIPIENT’s clock can only be judged against an offset you give."
},
"only_local": {
"type": "boolean",
"description": "true = leave out marketplaces: a business whose shelf names places far from its own address (one local address, hundreds of listings in other cities and countries). Default false: a marketplace is kept, ranked lower, and its card says `marketplace: true` (the full card says why)."
},
"properties": {
"type": "array",
"items": {
"type": "object",
"required": [
"key"
],
"properties": {
"key": {
"type": "string",
"maxLength": 60,
"minLength": 1,
"description": "a property key this index has read — get_card lists the ones established for a niche under `established_properties`, and every card shows its own under `properties`"
},
"max": {
"type": "number",
"description": "the value must be at most this (a number); max 0 = «none»"
},
"min": {
"type": "number",
"description": "the value must be at least this (a number)"
},
"equals": {
"type": [
"string",
"number",
"boolean"
],
"description": "the value must be this, as the page wrote it («included», «yes», 8)"
},
"exists": {
"type": "boolean",
"description": "true = the business must publish this property at all"
}
},
"additionalProperties": false
},
"maxItems": 8,
"description": "THE OPEN LAYER AS A FILTER: facts a business publishes beyond price and availability — a capacity, a deposit, a duration, whether something is included. Three states per key: a published value that fits = confirmed; a published value that does not = refuted (left out, a fact); nothing published = unknown (KEPT, ranked lower, named in the card’s `unknown`). Ask for the user’s real conditions here instead of putting them in `query`: «for 8 people» is {key:\"capacity\",min:8}, «no deposit» is {key:\"deposit\",max:0}."
},
"fulfillment": {
"enum": [
"delivery",
"pickup",
"on_site",
"at_customer",
"any"
],
"type": "string",
"description": "HOW it must reach the user, and the four are different questions: delivery = brought to the address; pickup = the user collects; on_site = the user goes there (a salon chair, a dining room); at_customer = the business travels (a mover, a plumber). Default any. A business that has not published an answer is KEPT; one that ruled it out is dropped."
},
"radius_miles": {
"type": "number",
"maximum": 250,
"minimum": 1,
"description": "How far the business may be, in miles. Default 15."
},
"only_independent": {
"type": "boolean",
"description": "true = leave out chains (a business whose website serves several of the places found). Default false: a chain is kept as a name, a telephone and a website — it was never read, so it has no offerings — and its card says `chain: true`."
}
},
"additionalProperties": false
}