The catalogue tool server: what it may expose, what it must never return
In short
A catalogue tool server is a read-only interface an AI agent may call to search your published products, read one in detail, check availability and quote published policy. Its definition is its boundary: nothing it returns may be a cost, a per-location stock figure, an unpublished record, or anything keyed to a customer. Wrapping an admin API is how that boundary is usually crossed.
Key takeaways
- Tools are model-chosen calls; resources are client-fetched documents. Commerce needs both, for different things.
- The surface is read-only. Nothing an agent calls here should change state on your side.
- Availability is a state with a timestamp, not a per-location count. The count is competitive information.
- Wrapping an internal admin API is the single most common way cost and stock leak outward.
- Project responses from an allow-list schema. A pass-through serializer will eventually ship a field nobody reviewed.
A catalogue tool server is a read-only interface that lets an AI agent ask questions about your products: find candidates, read one in detail, check whether it can be had, and quote the terms attached to it. In agentic commerce that is usually an MCP server over a product catalogue. What defines it is not the protocol but the boundary — published catalogue, published price, coarse availability, published policy, nothing else.
Everything outside that line is commercially sensitive, legally sensitive, or wrong to serve anonymously. The boundary is not enforced by MCP or any other protocol. It is enforced by what your handlers put in a response, which is why the interesting part of building one is subtraction.
Tools and resources are two different objects, and commerce needs both
A tool is a call the model decides to make, with arguments it chooses. A commerce surface usually needs 4: search products by description and filters, fetch 1 product by identifier, check availability for a destination, and read the policy governing a category. Tool names and descriptions are prompt surface — the model picks between them by reading them, so a vague description produces a wrong call.
A resource is a document your client fetches and hands to the model without the model choosing anything: a size guide, a category taxonomy, a returns document. Stable, cacheable, addressable. Every tool call costs a round trip inside a live conversation; a resource is one nobody pays for twice.
The read boundary, drawn as a field list
| Field | May it be returned? | Reasoning |
|---|---|---|
| Published title, description, structured attributes | Yes | Already public on the product page |
| Published identifiers — your SKU, GTIN, MPN | Yes | The agent needs a key it can quote back at checkout |
| Published price for the requested market | Yes | The same figure a shopper would be shown |
| Availability as a coarse state plus a timestamp | Yes | Enough to decide, not enough to infer your inventory |
| Cost, landed cost, margin | Never | Commercially fatal, and no agent has a use for it |
| On-hand quantity per location | Never | Reveals the inventory position of every site you run |
| Draft, staged, embargoed or archived records | Never | Unpublished means unpublished, whoever is asking |
| Supplier names and purchase terms | Never | Somebody else's commercial data, not yours to serve |
| Anything keyed to a customer identifier | Never | The caller is anonymous; there is no customer in scope |
Wrapping the admin API is how the boundary gets crossed
The fast way to ship a tool server is a thin layer over the internal API your back office already uses. It is also the reliable way to leak: that API was written under 1 assumption — the caller is staff — and its serializers were built to be generous. The new caller is anonymous internet, and nobody re-read the serializer.
- Define the response schema first, as an allow-list of fields, and construct every response from it. No handler should ever return an internal record object directly.
- Give the tool server its own read credentials, scoped to published data only, so 1 serializer mistake is not enough to become an incident by itself.
- Add a contract test that fails the build when a response contains a key absent from the schema. That is the check which catches the field a colleague adds upstream 6 months later.
- Diff a captured set of real responses against the schema in staging before the surface goes live, and read the diff by hand once.
Three fields that get exposed without anyone deciding to
- Cost, riding along inside the product payload because the admin serializer has always included it and no test asserts its absence.
- Per-location quantity, because availability was implemented by returning the inventory rows rather than computing a state from them — a warehouse data problem before it is an AI one, of the kind described in AI in logistics operations.
- Unpublished rows, because the internal endpoint never filtered on publication state and the storefront did that filtering in the front end. That is also one of the mechanisms behind an assistant recommending products you stopped selling.
The protocol does not draw the boundary. Your response objects do, 1 field at a time, and a pass-through serializer draws no boundary at all.
What the boundary does not settle
It says nothing about whether an agent should be reading you live at all rather than from a published file — that turns on freshness tolerance, and is settled in a published feed or a live tool call. It says nothing about writes either: a catalogue tool server changes no state, and whether a purchase completes inside the agent or hands back to you is a separate decision with its own consequences.
It also cannot rescue attributes that were never modelled. If size, voltage and material live in a free-text blob, no allow-list makes them comparable — that choice is attribute columns versus an attribute table. Building the surface is AI agents and automation work, part of agentic commerce in our retail and e-commerce practice.
Frequently asked questions
Short answers to the follow-ups this page tends to raise.
Can we expose our existing product API to AI agents instead of building a tool server?
Reuse the data path, not the interface. An internal product API returns fields that only make sense to staff, applies filters your front end was expected to add, and assumes an authenticated caller. A tool server is a separate projection over the same data, with its own schema, its own credentials and its own tests — thin, but not absent.
Should a catalogue tool server return exact stock quantities?
No. Return a state — in stock, low, out, backordered with a date — plus the time it was computed. An agent only ever needs to know whether to proceed, while an exact per-location count exposes your inventory position to anyone who asks politely, including competitors running the same agent.
Can an agent look up a customer's order through a catalogue tool server?
Not through this one. Anything keyed to a customer identifier belongs to an authenticated surface with its own authorisation, its own logging and its own consent story. Mixing anonymous catalogue reads and account reads into one server is how a tool that was safe on Monday returns somebody else's order on Friday.
- agentic commerce
- MCP
- product data
- security
The work behind this page
Builds from our portfolio that this page draws on.
StowPilot
An AI warehouse slotting and pick-path platform that re-slots SKUs by velocity, plans pick waves, and routes pickers on the shortest path — cutting walk distance per pick.
LogisticsAI Lease Management
AI-powered commercial real estate lease management for multi-brand operators — automates lease data extraction, obligation tracking, and portfolio intelligence.
Real EstateRead next
- The commerce manifest: the file an agent reads before anything elseA machine-readable declaration of what your store can do, served at a fixed path. It is not marketing, it carries no prices, and 3 serving conditions decide whether an agent can read it at all.definition
- The assistant keeps recommending products you stopped sellingA shopping assistant naming products you withdrew is rarely hallucination. It is a stale index, a missing lifecycle field, an unenforced tool call or a tool returning unpublished rows.diagnostic
- The agentic checkout session: a cart your server ownsA server-side basket the merchant owns and an AI agent only renders. Every create, update or complete call returns the merchant's full current state — the property that makes agent buying safe to allow.definition
- Agents fetch your manifest and still skip your storeA file that loads in your browser can be unreachable, unparseable or disqualifying to an agent. Three verdicts, and the ordered checks that tell them apart.diagnostic
- The agent confirmed the order and the charge failed afterwardsAn order exists, the shopper was told it is placed, and no money moved. The cause is almost never the card: it is one of the 4 constraints on the delegated token refusing the charge.diagnostic
- The agent shows one total and your checkout session returns anotherThe shopper saw one number and your server charged another. Replay the call sequence: the agent is nearly always displaying a response that a later call replaced.diagnostic
Working on something in this space?
Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.
Start the conversation