Agents
Shoppers, merchants and developers act through AI agents too, so every surface of OrbSearch answers an agent as it answers a person.
An agent is a user of OrbSearch like any other. Every surface answers it with structured data that explains itself, never with meaning that lives only in markup.
Where agents connect
| Who | Connects to | Through |
|---|---|---|
| A shopper's agent | The storefront, in the browser | The search, get_facets and set_filters tools the storefront registers with WebMCP, below |
| Any agent or service | The Query API, without a key | Searches, products and URLs, each with its trace on request: Search |
| A merchant's agent | The management API, with the management key | Every change to search the panel makes, through the same actions: catalog, imports, releases, index runs. Management API |
| A coding agent | These docs, as Markdown | Each page at its path plus .md, such as /docs/quickstart.md, the overview at /docs/index.md; /docs/llms.txt lists every page with its description, /docs/llms-full.txt holds them all, and /docs/openapi.json describes both APIs |
In the shopper's browser
registerAgentTools from @orbsearch/client lets an agent in the browser search the shop, read the page's filters, and filter and sort the page the way the shopper does. Call it once the page runs, with the client the storefront uses and the router's navigate, and abort its signal when the page goes away:
const navigate = useNavigate();
useEffect(() => {
const registration = new AbortController();
registerAgentTools(search, {
locale: "de",
signal: registration.signal,
navigate: (href) => navigate(href, { preventScrollReset: true }),
}).catch(reportError);
return () => registration.abort();
}, [navigate]);| Tool | Input | What it does |
|---|---|---|
search | { "query": "grey sofa", "filters"?, "sort"?, "page"?, "facets"? } | Searches like the search box without changing the page; answers with the search response as JSON text |
get_facets | { "facets"?: ["brand"] } | Reads the listing the shopper sees, through resolve: URL, total, chosen filters and sort, the sorts on offer, each facet with its value codes, labels and counts, and the banners on the page with their slot, title, text and URL |
set_filters | { "filters"?: { "color": ["grey"] }, "sort"?: "price_asc" } | Moves the page through the router, as if the shopper chose it: chips, sort and URL change. filters replaces the selection, {} clears it |
The orders differ from page to page, so get_facets lists those the page offers and the one it starts in. A page counts only its first facets and a long list's most frequent values (Facets and filters); facets names those to read with every value, counted under the page's choices. Filters take the codes get_facets lists: value codes for a list or swatch, { "gte": 100, "lte": 300 } for a range, true for a toggle, category ids for category. A value or field the page does not offer fails with a sentence that names the ones it does, so the agent can correct itself. Where the browser offers no WebMCP, registerAgentTools does nothing.
What a tool hands the agent counts as the agent's view of it: each hit and banner it answers with, the whole search response for search and the listed products and banners for get_facets and set_filters, is reported as a view with surface: "agent" once the tool succeeds, once per answer and item, through the client's clicks and views, so the merchant's Insights tell an agent's views from a shopper's. A hit of a later page goes without its position, which the shop's page size decides. A client made with report: false reports none.