Build a shopping agent with the Anthropic commerce-agents blueprint

Ask about this Page
Copy for LLM
View as Markdown
In this tutorial, you will learn how to build a conversational shopping agent that answers questions about your catalog and fills a Cart. You will follow commerce-agents, the reference blueprint Anthropic publishes for building commerce agents, and implement the commercetools backend it leaves to you.

Goal

Build a service that a shopper can talk to. The shopper asks for a product in plain language, the agent searches your catalog, and the agent adds the chosen Product to a Cart in your Project. You will scaffold the backend with a plugin, run the service locally, and verify that a chat turn creates a real Cart.

The blueprint provides the agent itself: the turn loop, the tools, and the guardrails. What it leaves for you is the backend, which is the layer that turns an agent's request for a product into a commercetools API call. The plugin in this tutorial generates that layer.

The blueprint defines two agents, and the plugin can scaffold either:

  • A shopping agent serves a customer over a StorefrontBackend. It searches the catalog, compares Products, fills a Cart, and answers questions about policies. This tutorial builds one.
  • A merchant agent serves store staff over a MerchantBackend. It explains performance, maintains listings, manages Inventory, and stages price changes that apply only after someone approves them.

Prerequisites

  1. Python 3.13, which is the version the reference implementation is run with.

  2. An API Client for your Project with required scopes. Create it with every scope the agent will need, because the scopes of an API Client cannot be changed after you create it. To take payments through Checkout, add manage_sessions at the same time.
  3. An Anthropic API key.

  4. A Tax Category on every Product a shopper can buy. Without one, Cart creation fails, and the error appears when a shopper tries to buy rather than when you save the Product.
  5. At least a few published Products with a Price in the currency you plan to use.

  6. No API Extension on Carts with an unguarded custom(fields(...)) trigger condition. Such a condition cannot be evaluated against a Cart that carries no Custom Object, and it fails every Cart write in the Project rather than only the agent's. Check this before your first Cart write against a shared Project.
  7. The commercetools plugin, installed from its own marketplace. In a Claude Code session, run:

    Add the marketplace and install the pluginbash
    /plugin marketplace add commercetools/commercetools-anthropic-agents
    /plugin install commercetools-commerce-agent@commercetools-anthropic-agents
    
    This gives you the /scaffold-commercetools-agent command and a Skill called commercetools-agent-backend, which loads whenever you edit the generated backend code.

Check your catalog

The scaffolding command asks how your catalog is shaped, and the answers change the code it writes. Look at your Products before you start, so that you can answer accurately:

  • Do your Product Variants represent real choices, such as size or color, or near-duplicates? A family whose Variants are identical on every Attribute is duplicate data rather than a set of choices, and the agent should present it as a single Product.
  • Which Attributes are searchable? A search filter on an Attribute whose isSearchable is false returns zero matches without an error, so a shopper asking for a red shirt gets "no results" rather than a configuration error. Check the two or three Attributes a shopper is most likely to name.
  • Are any Product Discounts active? If so, the agent must read the discounted price rather than the list price, or it quotes the wrong number.
  • Which locales are your Product names authored under? Requesting a single locale returns null rather than a fallback when a Product has no value for that exact key, so a Product authored under en renders with no title in a storefront running en-US.

Scaffold the backend

Run the command, and describe what you want to build:

Scaffold a shopping agentbash
/scaffold-commercetools-agent a shopping agent for my-project-key

The command asks its questions in one message, prefilled from anything it can already see about your Project. Answer with what you found in the previous step. Skip a question to accept its default.

It then plays a plan back to you. Nothing is written until you approve it, so read the plan and correct anything that doesn't match your Project. On approval, the command records the decisions in your project's CLAUDE.md, generates the shared commercetools infrastructure and a StorefrontBackend subclass, and runs your linter and type checker over the result.

Configure the service

Copy the example environment file the scaffold generates, and fill in your own values:

Create your environment filebash
cp .env.example .env

The price selection variables matter more than they look:

.envbash
CTP_PROJECT_KEY=my-project-key
CTP_CLIENT_ID=
CTP_CLIENT_SECRET=
CTP_AUTH_URL=
CTP_API_URL=
CT_CURRENCY=USD
CT_COUNTRY=US
CT_LOCALE=en-US
ANTHROPIC_API_KEY=
CT_CURRENCY and CT_COUNTRY drive price selection, and CT_LOCALE drives the name. Each one governs a different part of the response, and neither raises an error when it's missing. Omit the currency or country and Products come back without a price. Omit the locale and they come back without a name. Leave all three unset and a Product Search returns nothing but an id per result. In each case the catalog looks empty or broken rather than misconfigured, which makes this worth checking first when results look wrong.

Run the service

Create a virtual environment, install the dependencies, and start the service:

Start the agent servicebash
python3.13 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
uvicorn service.main:app --port 8000

The service exposes a session endpoint and a chat endpoint. A session binds the shopper before any conversation happens, which is why no later request carries a customer id:

RoutePurpose
POST /api/sessionStarts a session. A customer id makes the shopper a member, and no id makes them a guest.
POST /api/chatSends one conversational turn, streamed back as events.
GET /api/cartReturns the Cart belonging to the session.
GET /api/productsReturns the catalog.

Test the agent

Start a session, and keep the session id it returns:

Start a sessionbash
curl -X POST http://localhost:8000/api/session

Send a turn that asks for something you know is in your catalog, passing the session id as a header:

Ask the agent for a productbash
curl -N -X POST http://localhost:8000/api/chat \
  -H "X-Session-Id: <your-session-id>" \
  -H "Content-Type: application/json" \
  -d '{"message": "I am looking for a blue shirt"}'

The response streams back as events. The agent searches your catalog and replies with the Products it found, including their prices.

Then ask it to add one to the Cart, and read the Cart back:

Read the Cartbash
curl http://localhost:8000/api/cart -H "X-Session-Id: <your-session-id>"
A Cart with the expected Line Item confirms the whole chain: the agent understood the request, your backend translated it into a commercetools call, and the write landed in your Project. You can also open the Cart in the Merchant Center to see it alongside Carts from any other client.

If the agent replies that it found nothing, check price selection and Attribute searchability before you look at the agent. Both fail silently, and both look like an empty catalog.

Add caller authentication

The scaffold doesn't include caller authentication. The agent reaches commercetools through a single API Client using client_credentials, which means the service has no idea who's talking to it beyond the session id it issued.
Before you expose the agent to real shoppers, bind the principal at session start from your own authentication, and read it off the session record afterwards. A guest maps to the anonymousId of a Cart. Don't put a guest identifier in customerId, which only accepts a registered Customer: commercetools accepts the write and leaves both fields unset, which is difficult to diagnose later.

Extend the backend

As you add methods to the generated backend, the commercetools-agent-backend Skill loads and applies the rules that keep it correct. It covers platform behaviors that are easy to get wrong because they don't raise an error. For example:
  • name(locale:) returns null rather than a fallback when a Product has no value for that exact locale. Read nameAllLocales and fall back across the locales you support.
  • A missing availability on a ProductVariant means no InventoryEntry exists for it, which isn't the same as the Product being out of stock.
  • A write that changes a Price must target the id that price selection resolved, rather than a reconstruction of which Price should apply.

Further learning

For the full set of backend rules, see the Skill source. To build an agent for store staff rather than shoppers, run the same command and ask for a merchant agent.

Treat the scaffolded code as a starting point your team reviews, tests, and owns. The defaults come from one real commercetools implementation, and the interview exists so those decisions get checked against your Project instead of inherited silently.