Verify
Point an agent at us and see for yourself.
Evaluating a commerce layer should not require a sales call or a signup. This is a verification path an agent can run unattended, in three lanes, with the expected result stated for every call. Lanes 1 and 2 need nothing from us at all.
Start with no credentials
The open tier answers immediately. Paste this and you have a live capability profile — no key, no account.
curl https://commerce.mcp.pivota.cc/.well-known/ucpcurl -sX POST https://mcp.pivota.cc/mcp \
-H "content-type: application/json" \
-H "accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Lane 1
Commerce index
The open tier. No signup, no key, no coordination — if your agent can make an HTTP request it can finish this lane.
GET /.well-known/ucp
Expect: 200 with a ucp object listing six capabilities: catalog.search, catalog.lookup, checkout, identity_linking, fulfillment, and the vendor extension cc.pivota.insights.
tools/list on mcp.pivota.cc
Expect: Exactly four tools: search_catalog, get_product, get_alternatives, get_intel. A different count means you are on a different door.
search_catalog
Expect: Around ten products carrying product_id, brand, title, price as {amount, currency}, and availability. Budget 3–7s on a cold query; an identical repeat returns from cache in roughly 100ms.
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
"name":"search_catalog",
"arguments":{"query":"niacinamide serum"}}}Lane 2
Decision layer
Search is a commodity. The reason to route through Pivota is that we hold grounded claims about products and can compare them.
get_intel
Expect: A review-grounded block: whether the product is reviewed, what it is best for, and why. Claims are attached to evidence rather than generated on demand.
get_alternatives
Expect: An anchor plus alternatives, each carrying a price relationship to the anchor and a grade. This is substitution logic a search index cannot give you.
recommend_products
Expect: A reasoned shortlist from a need in the buyer's own words rather than a product name. Runs a model — allow up to 30s on a cold call, and keep it off your critical path. A budget is enforced only when sent as a number nested at constraints.price_max; a top-level price_max or a prose budget is not enforced.
{"name":"get_intel","arguments":{"product_id":"sig_..."}}
{"name":"get_alternatives","arguments":{"product_id":"sig_...","limit":5}}Lane 3
Checkout routing
Every call in this lane was executed against production with a third-party agent key. Response shapes below are what we observed, not what our internal docs claim.
initialize, then tools/list
Expect: 200 on both. This door is stateless: no session header is returned and none is required on later calls. tools/list returns fourteen tools.
get_product
Expect: The two things checkout needs: a merchant_id, and variants[] carrying real upstream variant ids. Keep both.
create_checkout_session
Expect: status: ready_for_payment and a server-locked quote. Totals are in minor units on this response — a $33.00 order reads {subtotal: 2500, shipping: 800, total: 3300}. The total is authoritative; an agent cannot set it.
create_payment_link
Expect: An order_id, status: awaiting_payment, and a hosted checkout_url carrying a 30-minute token. Supply a complete shipping address — name, address line 1, city, postal code and country together.
Read the order back over REST. Use this endpoint for order state rather than the MCP tool — see the limits below.
curl https://api.pivota.cc/agent/v2/orders/<order_id> \
-H "Authorization: Bearer YOUR_API_KEY"Results that look like failures but are not
An unattended agent will hit several of these. Each one is correct behaviour, so check here before filing anything.
401 on commerce.mcp.pivota.cc
Correct. That door requires a key; only mcp.pivota.cc is open.
USER_AUTH_REQUIRED
Correct. An agent key identifies your platform, not the person spending money. Checkout needs a buyer identity.
Refusal on a multi-variant product
Deliberate. We refuse rather than guess a size or shade, because guessing prices a different cart than the buyer chose. Pass variant_id from get_product.
Refusal on a multi-seller cart
Deliberate. Up to 50 line items across 25 products, but one seller per checkout. The refusal message tells you how to split it.
Result arrives as a JSON string in content[0].text
Expected on the keyed door. Tool results there are a JSON document inside the text member rather than structuredContent — parse content[0].text.
Prices differ between doors
Expected. The UCP dialect returns ISO minor units; the native door returns major. Do not divide by 100 yourself — currencies have different exponents.
What we are still finishing
Stated here rather than discovered by your agent. We would rather be useful than impressive.
Catalog coverage is deepest in beauty and personal care. Off-vertical queries sometimes return empty sets and sometimes confident but irrelevant results, often without price fields — judge coverage by relevance, never by result count. If your evaluation needs a specific category, tell us early: that is a data lead time rather than a code change.
get_order, request_after_sales and cancel_checkout_session appear in tools/list but are not yet wired through. The capability is live over REST: read order state with GET /agent/v2/orders/{order_id}.
create_payment_link and recommend_products work on the native door and are absent from the UCP dialect. Variant selection is likewise native-only today.
get_alternatives can return fewer alternatives than the requested limit, and an alternative's currency field is currently null — read the anchor's currency until we populate it.
Completing a payment on the hosted page is a coordinated step. Ask us for a sandbox pack and we will confirm the demo merchant is on test payment credentials before you drive that leg.
Checkout needs a buyer identity. That is one exchange.
An agent key identifies your platform. Spending money needs a verified buyer, and we would rather you register your own issuer and mint tokens for your own users than have us hand you credentials you would replace later.