UCP Checker
Developer Quickstart

Build an AI Shopping Agent

Step-by-step guide to building your first shopping agent on UCP, using the tool names and request shapes from the spec (v2026-08-25). Copy-paste code, real test targets from 19,337+ verified stores, and error patterns from production. Get to a working agent in under 30 minutes. Want the shortcut? Connect the UCP Checker MCP server and skip to shopping — see the API & MCP docs.

Proven in Production

Thousands of real agent sessions have run on this stack

LLM-driven agent sessions run through UCP Playground against real verified stores, across several model providers and store platforms. As of September 2026.

The Mental Model

What you're actually building

A UCP shopping agent is four things glued together: a profile fetcher, an MCP client, a tool-call dispatcher, and (optionally) an LLM to pick which tools to call. That's it. Every step below is one of those layers.

1
Fetch the store's UCP profile from /.well-known/ucp. This tells you which protocol versions and capabilities the store supports, and where its endpoints are.
2
Read the capabilities (e.g. dev.ucp.shopping.catalog.search, dev.ucp.shopping.checkout) and the services entry for dev.ucp.shopping. Decide whether this store supports the flow you want to run.
3
Connect an MCP client to the endpoint declared for the mcp transport. List the tools, then call them — every call carries meta["ucp-agent"], the URL of your platform's own UCP profile.
4
Compose the tool calls into a flow: search_catalog → get_product → create_cart → create_checkout → complete_checkout. Optionally wire an LLM to pick steps automatically.
Before You Start

What you need

  • A language runtime with an MCP client library. Official MCP SDKs exist for Python, TypeScript and several other languages. Any language works — MCP is JSON-RPC, ~100 lines to roll your own.
  • An HTTP client (curl, requests, fetch, whatever). You'll use it to fetch the store's profile before MCP takes over.
  • A platform profile URL. UCP requires every request to name your platform's profile (a JSON document you host, same shape as a store's /.well-known/ucp). The store fetches it to agree a protocol version and capabilities with you. See Platform Profile in the spec.
  • A test store from the UCP directory. We list 6 ready-to-use targets below — all verified, all with deep capability declarations, across platforms.
  • Optional: any LLM with tool calling if you want the agent to pick which tools to call. You can also hard-code the flow for deterministic testing.
Step 1

Pick a target store

Start with a store that already has deep UCP coverage so your agent has real tools to call. The 6 stores below are top of the directory by capability depth — pick any one as your first target.

Tip: Start with a store whose profile declares dev.ucp.shopping.catalog.search and an mcp transport — catalog reads are the easiest first call. Open a store's status page to see exactly what it declares, or browse the full directory to pick your own target.

Step 2

Fetch the store's profile

Every UCP store publishes a JSON profile at /.well-known/ucp. Fetch it first — it tells you which protocol versions and capabilities the store supports and which transports you can use.

# curl
curl https://store.example/.well-known/ucp | jq .ucp.services
# Python
import httpx
STORE = "https://store.example"  # any store from the directory
profile = httpx.get(f"{STORE}/.well-known/ucp").json()
print(profile["ucp"]["version"])
print("capabilities:", list(profile["ucp"].get("capabilities", {}).keys()))
// TypeScript
const STORE = "https://store.example"; // any store from the directory
const profile = await (await fetch(`${STORE}/.well-known/ucp`)).json();
console.log(profile.ucp.version);
console.log("capabilities:", Object.keys(profile.ucp.capabilities ?? {}));

You want two things from the profile: the services map (to find the MCP endpoint URL) and the capabilities map (to know what you can call, keyed by names like dev.ucp.shopping.catalog.search). See the full field reference on the /.well-known/ucp developer guide.

Step 3

Find the MCP endpoint

The spec is exact about this: the MCP endpoint is services["dev.ucp.shopping"] → the entry whose transport is mcp → its endpoint. Stores can also declare rest, a2a and embedded transports for the same service.

# Python — find the MCP endpoint from a parsed profile
def find_mcp_endpoint(profile):
    for entry in profile["ucp"].get("services", {}).get("dev.ucp.shopping", []):
        if entry.get("transport") == "mcp":
            return entry["endpoint"]
    raise ValueError("No MCP transport declared for dev.ucp.shopping")

endpoint = find_mcp_endpoint(profile)
print(f"MCP endpoint: {endpoint}")

Heads up: use the endpoint the profile declares — the spec says the endpoint MUST come from the store's profile, not from a guessed path. If a store declares no mcp transport, check its REST entry or pick another store.

Step 4

Connect an MCP client and list tools

MCP is JSON-RPC over HTTP. You can use an official MCP SDK or hand-roll the calls you need: initialize, tools/list and tools/call.

Or let UCP Checker do steps 1–4: connect https://ucpchecker.com/mcp to your client and call list-stores, search-catalog and check-domain to resolve a verified store — then transact against that store's own endpoint. Parameters and limits in the docs.

# Python — minimal MCP client, no SDK
import httpx

def mcp_call(endpoint, method, params=None):
    res = httpx.post(endpoint, json={
        "jsonrpc": "2.0",
        "id": 1,
        "method": method,
        "params": params or {},
    }, headers={
        "Content-Type": "application/json",
        "Accept": "application/json, text/event-stream",
    })
    return res.json()

mcp_call(endpoint, "initialize", {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": {"name": "my-agent", "version": "0.1"},
})
tools = mcp_call(endpoint, "tools/list")["result"]["tools"]
for tool in tools:
    print(f"- {tool['name']}: {tool['description'][:80]}")

The UCP tool names are fixed by the spec: search_catalog, lookup_catalog and get_product for catalog; create_cart, get_cart, update_cart, cancel_cart for cart; create_checkout, get_checkout, update_checkout, complete_checkout, cancel_checkout for checkout; and get_order. A store exposes the ones for the capabilities it declares. If tools/list returns an empty array or an error, the store declares MCP but hasn't wired it up — validate the store to confirm.

Step 5

Execute your first tool call

Call search_catalog with a query and a buyer context. Two argument blocks: meta (required on every UCP call — it names your platform profile) and catalog (the search itself). Context values are hints for relevance and localisation, not binding data.

# Python — search the catalog
PLATFORM_PROFILE = "https://agent.example/.well-known/ucp"  # your platform profile

result = mcp_call(endpoint, "tools/call", {
    "name": "search_catalog",
    "arguments": {
        "meta": {
            "ucp-agent": {"profile": PLATFORM_PROFILE},
        },
        "catalog": {
            "query": "running shoes",
            "context": {
                "address_country": "US",
                "currency": "USD",
                "language": "en",
            },
            "pagination": {"limit": 10},
        },
    },
})

# UCP payloads come back in result.structuredContent
for p in result["result"]["structuredContent"].get("products", []):
    print(p["id"], p["title"], p.get("price_range", {}).get("min"))

If you get real product results back — titles, prices (in minor units, e.g. 12000 = $120.00), variant IDs — you have a working UCP shopping agent. Everything past this point (create_cart, create_checkout, complete_checkout) is the same tool-call pattern with the same meta block. Full request and response shapes are in the spec's Catalog MCP binding.

Step 6

Handle the common failure modes

Real stores fail in predictable ways. Here's the taxonomy and how to recover.

HTTP 404 on /.well-known/ucp
The domain has no public UCP profile. Run a live check to confirm, then pick a different target from the directory.
JSON-RPC -32001: invalid_profile_url, profile_unreachable, profile_malformed or version_unsupported
The store couldn't negotiate with you. Check that meta["ucp-agent"].profile is present, publicly reachable and valid, and that it declares a protocol version the store supports (compare with the store's ucp.version). The error's data.continue_url, when present, is where to hand the buyer off instead.
Result with ucp.status: "error" and capabilities_incompatible
Negotiation worked but you and the store share no capabilities. This is a business outcome, not a transport error — declare the capabilities you need (e.g. dev.ucp.shopping.catalog.search) in your platform profile.
JSON-RPC -32000 (HTTP 401 / 403)
The operation needs authentication or you lack permission. Catalog reads are often open; carts, checkout and orders may not be. For buyer-account flows the spec defines Identity Linking (dev.ucp.common.identity_linking) — check whether the store declares it.
JSON-RPC -32000 (HTTP 429)
Rate limited. Honour Retry-After when the store sends it and back off — don't retry in a tight loop.
JSON-RPC -32602
Invalid params. Check the inputSchema each tool returns from tools/list against your arguments — UCP puts operation fields under a named block (catalog, cart, checkout) next to meta.
Empty tools array
The store declares MCP in its profile but hasn't wired up the tool handlers. Skip this store — it's a profile-level declaration, not a functional endpoint.
Empty products or missing items
Not an error in UCP — "nothing found" comes back as a normal result, sometimes with messages explaining why. Try a broader query, drop filters, and follow pagination rather than assuming one call returns everything.
Ship Your Agent

Where to go next

Watch your agent run against real stores, and let UCP Checker find the stores for you.

Test Harness

UCP Playground

Run an agent against a verified store and watch every search_catalog → create_cart → create_checkout step with full tool-call visibility. Replay any session and compare models on the same store.

Open Playground
Store Discovery

UCP Checker MCP

Connect https://ucpchecker.com/mcp to your client and resolve verified stores by what they declare — then transact against each store's own endpoint. Every store's profile is checked daily.

API & MCP docs

Frequently Asked Questions

What language should I build my agent in?
Any language with an MCP client library — official MCP SDKs cover Python, TypeScript and several others. The protocol is just JSON-RPC over HTTP — you can roll your own client in any language in under 100 lines if you prefer. Start with whatever your team already uses; the language choice doesn't constrain the agent architecture.
Do I need an API key to call a UCP store?
It depends on the store and the operation. Every UCP request must carry meta["ucp-agent"] with your platform profile URL. Many stores serve catalog reads (search_catalog, lookup_catalog, get_product) without further credentials; carts, checkout and orders may require authentication, and buyer-account flows use Identity Linking. The store's profile at /.well-known/ucp is always public.
How do I test without making real purchases?
Two options. First: UCP Playground runs agents against real stores in a controlled environment — you can watch every tool call and replay sessions without submitting orders. Second: stop your own agent before complete_checkout. That is the call that places the order; search, cart and checkout creation before it do not.
Which AI models can call UCP tools?
Any model that supports tool calling, driven through an MCP client. UCP defines the tools, not the model. You can also make the MCP calls from a plain script with no LLM in the loop — the tools behave identically whether a model or a hand-coded script drives them, which is useful for deterministic test suites.
What's the minimum viable agent?
Fetch the store's /.well-known/ucp profile, read the MCP endpoint from services["dev.ucp.shopping"], call tools/list, then call search_catalog with a query and your meta["ucp-agent"] profile. That's roughly 50 lines of Python. Cart and checkout use the same tool-call pattern — they need the store to declare those capabilities and (often) authentication.
How do I handle stores that reject my agent?
Check the error layer first. A JSON-RPC -32001 means negotiation failed — your meta["ucp-agent"] profile is missing, unreachable, malformed or on a version the store doesn't support. -32000 means authentication, permission or rate limiting. A normal result with ucp.status: "error" is a business outcome such as capabilities_incompatible; read its messages. When in doubt, run a live check on the store to see what it declares.
Weekly UCP Report

Get the agentic commerce digest every Monday

Real adoption data, ecosystem trends, new spec versions, and the stores that broke or recovered this week. Read by founders and engineers building the next generation of commerce.

Free forever No spam Unsubscribe anytime

View a sample report →

Weekly UCP Report
Issue #54 · Oct 12, 2026
+664
new verified stores
Verified rate
Latest spec
Cart capability