Skip to content

Quickstart ​

Add CommerceAI to your product with your coding agent (Claude Code, Cursor, Codex, or similar). You do two things: create an API key and export it in your terminal. Your coding agent reads your project, writes the integration, verifies it, and reports back.

1. Create an API key ​

  1. Open the CommerceAI console and sign in with Google. New accounts receive 1,000 free credits. See Credits.
  2. Go to API Keys, click Create key, and give the key a name. Copy the key now: it is shown only once.

Each account can have up to 5 active keys. Keys do not expire; a key works until you delete it. Anyone with the key can spend your credits. If a key leaks, delete it in API Keys and create a new one.

2. Export the key in your own terminal ​

bash
export COMMERCEAI_API_KEY="<YOUR_API_KEY>"

Run this in the terminal where your coding agent runs, or put it in your project's .env file if the project already loads one and the file is in .gitignore. Do not paste the key into the agent chat. The agent reads it from the environment.

3. Give this prompt to your coding agent ​

Open your project in the coding agent and paste the prompt below.

text
Integrate the CommerceAI shopping agent into this project.

Work inside the project I have open: use its existing language, package manager, framework, and error-handling conventions. Do not scaffold a new demo app unless the project is empty. Install only the dependencies the integration needs.

## About CommerceAI

- CommerceAI exposes one MCP tool, `shopping.agent`, over MCP Streamable HTTP at `https://commerceai.ai/mcp/`. Keep the trailing slash. There is no REST API and no OAuth.
- Auth: send `Authorization: Bearer <key>` on every request. The key is in the `COMMERCEAI_API_KEY` environment variable.
- The tool searches the US product catalog, compares products it already returned, and answers questions about a returned product. The `query` text selects the capability; there is no mode parameter.
- The server is stateless. The caller stores `conversation_id` and the `item_id` values from `answer_items`, and sends them back as `conversation_id` and `selected_item_ids` to continue a conversation or refer to products already shown.
- Each result has two parts. `content[0].text` is for a model: self-contained text where each product appears in place as one line with its `item_id`, name, price, rating, merchant, and link, each comparison appears in place as a Markdown table, and the `conversation_id` is on the last line. `structuredContent` is for code: the same answer as `answer_text` with inline markers, plus the products, comparison tables, `outcome`, and `usage` as structured data.
- A call usually takes 20 to 40 seconds and can take up to about 2 minutes.
- A completed shopping turn is charged for input tokens (325 credits per 1M), output tokens (650 credits per 1M), and tool calls (6 credits each; about 5 per turn), rounded up to a whole credit per turn. 1 credit = $0.001. With about 5 tool calls, a turn costs around 30 credits plus token usage; `usage.credits_used` reports the exact amount. Refused requests and errors cost 0. Listing tools costs 0.

## Step 1: decide how to integrate, then tell me before writing code

Read the project and pick one:

A. The project already has an LLM agent with tool calling (for example OpenAI Agents SDK, Claude Agent SDK, LangChain, LlamaIndex, Vercel AI SDK, or a hand-written tool loop). Register the CommerceAI MCP server as a tool source through the framework's own MCP support, so the model decides when to call `shopping.agent`.

B. The project has no LLM agent, or calls the shopping capability from fixed application logic (a search box, a product-finder page, a backend endpoint). Write a small client module with the official MCP SDK for this language (Python: `mcp`; TypeScript: `@modelcontextprotocol/sdk`) that calls `shopping.agent` directly.

Tell me which one you chose, why, and which files you plan to change. If neither fits, say so and stop.

## Step 2: build it

Both options:
- Timeouts: set both the HTTP request timeout and the MCP session or tool-call timeout to at least 130 seconds. MCP client and framework defaults are often shorter; find the actual setting in the installed SDK version.
- In code, read the result from `structuredContent`.
- Branch on `structuredContent.outcome`: `SUCCESS` (products found), `NEEDS_CLARIFICATION` (the agent asks the shopper a question; send the reply as the next `query` with the same `conversation_id`), `NO_RESULTS` (nothing matched; suggest loosening the request), `UNSUPPORTED` (out of scope; show `answer_text`, do not retry). These are normal results, not errors.
- On `isError: true`, branch on `structuredContent.error.code`. Retry only when `error.retryable` is true, wait at least `error.details.retry_after_seconds` when present, stop after 3 attempts, and send a new `request_id` (or none) on each retry. A missing or invalid key fails earlier with HTTP 401.
- Store `conversation_id` and the latest `answer_items[].item_id` values per end user or per chat session, in the project's existing session or state store. Send `selected_item_ids` only together with the `conversation_id` they came from, at most 10. Treat `item_id` as an opaque string: do not parse or build it.
- `answer_text` is Markdown that can contain `<item_mini_card item_id="..." />` and `<item_comparison_table table_ref_id="..." />` markers on their own lines. Replace each marker with a product card from `answer_items` or a table from `item_comparison_table`, or remove the markers if the output is text only.
- Show `purchase_url` for each product. The shopper buys on the merchant's page.
- The response contains only these fields; use them as documented:
  - Top level: `request_id`, `conversation_id`, `outcome`, `answer_text`, `answer_items`, `item_comparison_table` (only when the agent built a comparison), `usage` (`credits_used`, `billing_status`).
  - Each item in `answer_items`: `item_id`, `rank`, `name`, `brand`, `description`, `image_url`, `images`, `price`, `price_formatted`, `price_min`, `price_max`, `currency`, `rating`, `rating_count`, `purchase_url`, `item_source`, `availability`, `rcmd_reason`, `key_selling_point`, `key_attributes`. Any of them can be empty.

Option A only:
- Give the model `content[0].text`. Each product line carries its `item_id` and the last line is the `conversation_id`, so the model can answer from it and send `conversation_id` and `selected_item_ids` on follow-ups like "compare the first two". Do not give the model `answer_text`; its markers are for your UI code.
- If the product renders cards, render them in the UI from `structuredContent.answer_items` and `structuredContent.item_comparison_table`. The framework usually exposes only the text to the model; find where it keeps the raw tool result and pass `structuredContent` to the UI from there.
- Make sure the framework keeps tool results in the conversation history across turns, so the model still sees earlier `item_id` values when the shopper refers back to them.

Do not build: carts, orders, checkout, coupons or vouchers, store account sign-in, markets other than US, or image input. The service refuses or rejects these.

Tests: do not call the live service from unit tests or CI. Each call costs credits. Save the response from the smoke test in Step 3 as a fixture with the key and any user data removed, and mock the MCP call in tests.

## Ground rules

- The published docs are the source of truth. Read these before writing code, and copy field names, error codes, and limits exactly:
  - https://commerceai.ai/docs/reference/shopping-agent
  - https://commerceai.ai/docs/reference/outcomes
  - https://commerceai.ai/docs/reference/errors
  - https://commerceai.ai/docs/guide/conversations
  - https://commerceai.ai/docs/guide/rate-limits
- The API key is a secret. Read it only from `COMMERCEAI_API_KEY`. Never hardcode, print, log, or commit it. Check presence only, for example `test -n "$COMMERCEAI_API_KEY"`. If it is missing, tell me to create a key in the CommerceAI console and export it in my own terminal. Never ask me to paste it into this chat. If the key is ever exposed, tell me to delete it in the console and create a new one.

## Step 3: verify, then report

1. Free check: connect, run `initialize` and `tools/list`, and confirm `shopping.agent` is listed. Print only the HTTP status or the tool names. HTTP 401 means the key is missing, invalid, or deleted.
2. Tell me that one real call costs around 30 credits plus token usage, then make one `shopping.agent` call through the code you wrote, for example `{"query": "wireless earbuds under $50 with long battery life"}`. Print only the response shape: `outcome`, number of `answer_items`, whether `conversation_id` is set, and `usage.credits_used`. If it fails, print `error.code` and `error.request_id`, then follow the error table in the docs.
3. Run the project's own lint, type-check, and test commands.
4. Report: the integration option you chose, files changed, commands run, and one example invocation.

What your coding agent does ​

StepWhat happensCredits
PlanReads your project and tells you whether it will register CommerceAI as a tool in your existing LLM agent, or call it directly from your code0
BuildInstalls the MCP SDK if needed, writes the integration, sets timeouts, stores conversation state, renders products0
Free checkConnects and lists tools to confirm the key works0
Smoke testMakes one real shopping call and saves the response as a test fixtureAbout 30 plus token usage, reported in usage.credits_used
ReportLists the files changed, the commands run, and an example invocation0

A successful call ​

A shopping call returns two parts. The example below is shortened and illustrative, including its credits_used: 34 value; the actual charge depends on token and tool call usage. See Agent Capabilities for every field.

content[0].text, for the model:

text
These neutral daily trainers are lightweight and currently listed below $120. Choose the gender-specific version and confirm your size before buying.

**Best all-around daily trainer**
NITRO foam provides a smooth, cushioned ride for everyday mileage and varied distances; this listing is the men's version.

[pr_mig9IoxC] Puma Mens Velocity Nitro 3 Running Shoes · $59.95 · 4.5/5 · amazon · https://www.amazon.com/...

**Fastest, lightest-feeling option**
...

[pr_4JGR9jAt] ...

conversation_id: e79b7b6c42c348a3b5098150824bb2c2

structuredContent, for your code:

json
{
  "request_id": "23fd41b5-6e25-4ce8-9125-bfcb80d1ecfc",
  "conversation_id": "e79b7b6c42c348a3b5098150824bb2c2",
  "outcome": "SUCCESS",
  "answer_text": "These neutral daily trainers are lightweight and currently listed below $120. ...\n\n<item_mini_card item_id=\"pr_mig9IoxC\" />\n\n...",
  "answer_items": [
    {
      "item_id": "pr_mig9IoxC",
      "rank": 1,
      "name": "Puma Mens Velocity Nitro 3 Running Shoes",
      "brand": "Puma",
      "description": "Highlights Puma's flagship running shoe featuring NITRO foam cushioning ...",
      "image_url": "https://...",
      "images": ["https://...", "https://..."],
      "price": 59.95,
      "price_formatted": "$59.95",
      "price_min": 59.95,
      "price_max": 59.95,
      "currency": "USD",
      "rating": 4.5,
      "rating_count": 0,
      "purchase_url": "https://www.amazon.com/...",
      "item_source": "amazon",
      "availability": "in_stock",
      "rcmd_reason": ["Cushioned Comfort: NITRO foam and a higher stack deliver smooth cushioning."],
      "key_selling_point": [{"tag": "Material", "value": "Nitro foam cushioning"}],
      "key_attributes": [{"tag": "Item Weight", "value": "2.43 Pounds"}]
    }
  ],
  "usage": {
    "credits_used": 34,
    "billing_status": "PENDING"
  }
}

When the agent compares products, structuredContent also has item_comparison_table, and content[0].text shows the table in place as a Markdown table whose first column is item_id.

Connect without a coding agent ​

Python ​

Install the official MCP SDK: pip install mcp.

python
import asyncio
import os

from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

URL = "https://commerceai.ai/mcp/"
HEADERS = {"Authorization": f"Bearer {os.environ['COMMERCEAI_API_KEY']}"}


async def main() -> None:
    async with streamablehttp_client(URL, headers=HEADERS, timeout=130) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "shopping.agent",
                {"query": "wireless earbuds under $50 with long battery life"},
            )
            data = result.structuredContent
            if result.isError:
                print(data["error"]["code"], data["error"]["message"])
                return
            print("outcome:", data["outcome"])
            print(data["answer_text"])
            for item in data["answer_items"]:
                print(item["name"], item.get("price_formatted"), item.get("purchase_url"))
            print("credits used:", data["usage"]["credits_used"])


asyncio.run(main())

Cursor ​

Add this to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project).

json
{
  "mcpServers": {
    "commerceai": {
      "url": "https://commerceai.ai/mcp/",
      "headers": {
        "Authorization": "Bearer <YOUR_API_KEY>"
      }
    }
  }
}

Claude Desktop ​

Claude Desktop reaches remote MCP servers through the mcp-remote bridge. Add this to claude_desktop_config.json, then restart Claude Desktop.

json
{
  "mcpServers": {
    "commerceai": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://commerceai.ai/mcp/",
        "--header",
        "Authorization: Bearer ${COMMERCEAI_API_KEY}"
      ],
      "env": {
        "COMMERCEAI_API_KEY": "<YOUR_API_KEY>"
      }
    }
  }
}

Next ​

  • Conversations: follow-up questions and comparing products you already showed.
  • Outcomes: how to tell the kinds of results apart and render them.
  • Errors & Retries: what to retry and what to surface to the user.