# Build a shopping agent with the Anthropic commerce-agents blueprint 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](https://github.com/anthropics/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](/merchant-center/developer-settings.md#api-clients) 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](/checkout), add `manage_sessions` at the same time. 3. An Anthropic API key. 4. A [Tax Category](/api/projects/taxCategories.md) 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](/api/projects/api-extensions.md) 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. [Claude Code](https://docs.claude.com/en/docs/claude-code/overview), which runs the scaffolding command. 8. The commercetools plugin, installed from its own marketplace. In a Claude Code session, run: ```bash title="Add the marketplace and install the plugin" /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: ```bash title="Scaffold a shopping agent" /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: ```bash title="Create your environment file" cp .env.example .env ``` The price selection variables matter more than they look: ```bash title=".env" 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: ```bash title="Start the agent service" 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: | Route | Purpose | | --- | --- | | `POST /api/session` | Starts a session. A customer id makes the shopper a member, and no id makes them a guest. | | `POST /api/chat` | Sends one conversational turn, streamed back as events. | | `GET /api/cart` | Returns the Cart belonging to the session. | | `GET /api/products` | Returns the catalog. | ## Test the agent Start a session, and keep the session id it returns: ```bash title="Start a session" 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: ```bash title="Ask the agent for a product" curl -N -X POST http://localhost:8000/api/chat -H "X-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: ```bash title="Read the Cart" curl http://localhost:8000/api/cart -H "X-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](/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](https://github.com/commercetools/commercetools-anthropic-agents/tree/main/plugins/commercetools-commerce-agent/skills/commercetools-agent-backend). 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. ## Related pages - [Area overview page with navigation](/tutorials.md) - [Previous page: Subscribe to Messages on AWS EventBridge](/tutorials/subscriptions-eventbridge.md) - [Next page: Add Custom Fields](/tutorials/custom-types.md) - [Search documentation and API specs](/search.md)