@commercengine/ai exposes Commerce Engine storefront capabilities to browser AI agents through WebMCP. It works through the Storefront SDK and your existing checkout/navigation integrations rather than asking an agent to infer your UI or click DOM elements.
@commercengine/checkout only if you use Hosted Checkout and want drawer tools such as open_cart, open_checkout, or open_login.
The safety boundary
The package intentionally lets an agent prepare a purchase but never complete one.open_checkout hands control back to the shopper. Commerce Engine deliberately provides no payment or order-placement tool.
Quick start
Register from client code:site and routes should come from the same defineCommerceSeoConfig() declaration used by @commercengine/seo. That keeps crawler-visible and agent-visible URLs identical.
Registration returns
null when WebMCP is not available. That is an expected capability check, not a storefront error. In development, diagnostics prove the registration code actually ran.Capability gating
Tools appear only when the capability behind them exists.
Which adds up to a predictable tool count:
The storefront’s browser session client is used automatically by default, discovered through its
clientStorefront() or session() accessor. A storefront exposing neither registers the four catalog tools and nothing else — indistinguishable from a bug, so check the accessor name first when cart tools are missing.
Tool registration does not wait for anonymous-session bootstrap: session/cart tools can be declared immediately and return a retryable not-ready result until the session becomes usable. Set session: null when you intentionally want a catalog-only agent surface.
Add Hosted Checkout and navigation
Hosted Checkout contributes presentation only. Cart reads and mutations use the authenticated Commerce Engine Storefront SDK and return the resulting cart directly.open_cart opens the existing drawer; the drawer then refetches so it reflects any mutation the agent made through the SDK.
Cart semantics
Cart tools operate on the shopper’s real Commerce Engine cart, including anonymous shoppers.Add versus set
add_to_cartadds its quantity to the current quantity. It can take up to 10 items in one invocation.set_cart_item_quantitysets the absolute paid quantity for an existing cart line.- setting quantity to
0removes the line remove_from_cartis the explicit removal form
add_to_cart as an absolute setter. Repeating an add can create duplicate quantity.
Ordering constraints
Cart and catalog output include:minOrderQuantitymaxOrderQuantityincrementalQuantity
Promotional free items
A promotion can add units the shopper never selected. Agent-facing cart lines distinguish:
A free-only line cannot be removed or reduced, matching the Hosted Checkout UI.
Result shapes
Tools return plain values. Do not JSON-stringify them yourself; the user agent serializes the result.Two signals, doing different jobs
Claiming a tool set is not atomic — it is a sequence of awaitedregisterTool calls. Two overlapping registrations against one model context would race for the same names and one would throw InvalidStateError: Duplicate tool name. React Strict Mode makes this the ordinary case rather than an edge one: it mounts, cleans up, and mounts again back to back on every dev mount.
Registrations against one model context are therefore serialized — a second call waits for the first to settle, including any rollback.
Cancellation rejects with
CommerceWebMcpAbortError, which callers are expected to swallow — it means “you asked for this”. Without config.signal, cleanup can run before the controller exists and the stale pass stays live after its component has gone away.
Resolving CMS slugs in both directions
routes.product runs in the browser during tool execution, so a resolver that performs a CMS lookup would need that credential on the client. The portable shape is a pure function over route data the browser already has:
resolveProductRoute matters as much as product. An agent reads a CMS page slug off the page and calls get_product("knee-pain-relief-oil"); without the inbound mapping that goes straight to a catalog which has never heard of it.
The two directions have opposite fallback rules, and conflating them is the common mistake:
Returning
null from an inbound resolver fails the tool with route_not_found before any catalog request rather than passing an unmapped slug to a catalog that has never heard of it.
Cancellation is not rollback
WebMCP execution may supply anAbortSignal, and the package honors it at asynchronous boundaries. Commerce Engine SDK requests do not currently accept that signal, so once a cart request is in flight, cancellation cannot undo a server-side mutation.
If the mutation response already confirms the new cart, the package returns that truth instead of pretending the change never happened. This prevents an agent from retrying an already-applied add and duplicating quantity.
Anonymous and authenticated sessions
A shopper does not need to sign in to use cart tools. An anonymous Commerce Engine session has a user identity sufficient for cart ownership. Signing in adds customer capabilities such as orders, saved addresses, loyalty, and customer pricing. The AI package does not authenticate the shopper itself:open_loginonly opens your login UIget_session_statereports whether the current session is anonymous/logged in and whether login UI is available- no tool accepts a password or OTP
- session state does not expose who the shopper is
Navigation security
Navigation is same-origin by default. External destinations require explicit opt-in:Catalog and CMS content is untrusted
Catalog/search and optional policy/FAQ results are marked as untrusted content for the agent. Tool descriptions remain package-authored and are never interpolated from CMS output. Free-form input is bounded, tool schemas reject extra properties, and sensitive cart/customer fields are not forwarded by default.Agent tools and security
Full tool inventory, diagnostics, WebMCP availability, extension modules, and the security model.
Development diagnostics
Always wire diagnostics during development:Build tools without the DOM
UsecreateCommerceAiTools(config) when you want to inspect or test the exact tool set without browser registration:
extraModules appends custom capabilities, while modules replaces the default module list entirely. Duplicate tool names fail during composition.
Key exports
Framework setup
Registration is always client-side. The correct mount point differs by framework:React / Vite
Register from app bootstrap or a root effect.
Next.js
Use a root Client Component.
TanStack Start
Use a root client initializer.
Astro
Register on
astro:page-load and handle View Transitions.SvelteKit
Register in root
onMount.