Reference
URLs
| Thing | Production | Dev |
|---|---|---|
| Bridge MCP | https://agent.artos.sh/mcp | https://agent.dev.artos.sh/mcp |
| API / OAuth AS issuer | https://api.artos.sh | https://api.dev.artos.sh |
| Global catalog MCP (Direct) | https://api.artos.sh/mcp | https://api.dev.artos.sh/mcp |
| Per-store MCP (Direct) | https://api.artos.sh/s/:slug/mcp | same shape |
| OAuth token | https://api.artos.sh/ucp/oauth2/token | https://api.dev.artos.sh/ucp/oauth2/token |
| AS metadata | https://api.artos.sh/.well-known/oauth-authorization-server | same shape |
| Discovery | https://api.artos.sh/s/:slug/.well-known/ucp | same shape |
| Consent | https://my.artos.sh/oauth/consent | https://my.dev.artos.sh/oauth/consent |
| Agent profile / CIMD | profile-artos.vercel.app | same |
SDK (Path B)
@artos-commerce/ucp-client — npm install @artos-commerce/ucp-client (Node 20+; optional @mysten/sui peer for crypto).
| Export | Purpose |
|---|---|
UcpClient | Typed transport: globalSearch, callGlobalTool, callStoreTool, listAccountTools, callAccountTool, fetchStoreProfile, fetchImage, hasBuyerToken, ucpAgentHeader |
Ap2Signer | mintCheckoutMandate, mintPaymentMandate (compact ES256 JWS) |
createCheckoutHandlers | Read tools + confirmPurchase (one-call card / crypto / $0) |
resolveCryptoDeps, SuiSigner | Crypto rail — sign + submit the Sui PTB (need @mysten/sui) |
canonicalJson, verifyDetachedJws, verifyMerchantAuthorization | Byte-parity canonical JSON + AP2 verification |
toMinorUnits, normalizeSearchFilters, resolveRail, grandTotal, currencyOf, asAllowanceId, isUcpError, messageOf | Helpers |
Subpath entries: @artos-commerce/ucp-client/{ucp,ap2,checkout,sui,crypto}.
Bridge tool catalog (Path A)
Flat inputs; the bridge adds the UCP envelope. Price filters use major units (dollars).
| Tool | Input | Auth |
|---|---|---|
search_products | query?, filters?, sort?, pagination? | Platform key |
lookup_products | ids: string[] | Platform key |
view_product | store_slug, id | Platform key |
get_product_global | id, selected? | Platform key |
create_cart | store_slug, items: [{ id, quantity }] | Platform key |
update_cart | store_slug, id, items | Platform key |
view_cart | store_slug, id | Platform key |
create_checkout | store_slug, cart_id? | items?, buyer?, shipping_address? | Platform key |
update_checkout | store_slug, id, buyer?, shipping_address?, shipping_method_id?, discounts? | Platform key |
confirm_purchase | store_slug, checkout_id, payment_method?, payment_mandate_id? | Platform key (+ buyer bearer for crypto) |
get_order | store_slug, id | Platform key + orders:read |
get_agent_identity | — | None (local) |
| Buyer account tools | see Buyer account | Buyer bearer (proxied) |
fetch_image exists but is widget-only (hidden).
Bridge → raw UCP mapping (Path B)
| Bridge tool | Raw UCP tool | Endpoint |
|---|---|---|
search_products | search_catalog | /mcp (global) |
lookup_products | lookup_catalog | /mcp (global) |
get_product_global | get_product | /mcp (global) |
view_product | get_product | /s/:slug/mcp |
create_cart / update_cart / view_cart | create_cart / update_cart / get_cart | /s/:slug/mcp |
create_checkout / update_checkout | create_checkout / update_checkout | /s/:slug/mcp |
confirm_purchase | complete_checkout (+ prepare_checkout_payment for crypto) | /s/:slug/mcp |
get_order | get_order | /s/:slug/mcp |
Raw UCP differences (see Direct UCP):
args wrapped under catalog/cart/checkout; line items { item: { id }, quantity };
price filters in minor units; rails selected by inner id artos.card /
artos.crypto (not the sh.artos.* registry key).
Transport headers (Direct UCP)
Required on the UCP shopping surfaces (/mcp, /s/:slug/mcp, REST
/s/:slug/...). The buyer-account surface (/account/mcp) needs none of these —
it is bearer-scoped.
| Header | When | MCP | REST |
|---|---|---|---|
Request-Id | Every call | required | required |
UCP-Agent: profile="…" | Every shopping call | required (+ body meta["ucp-agent"].profile) | required |
Idempotency-Key | State-changing calls | use body meta["idempotency-key"] instead | required (header) |
REST paths (Direct UCP)
| Operation | Method + path |
|---|---|
| Global catalog search | POST /catalog/search |
| Per-store catalog | … /s/:slug/catalog |
| Cart | … /s/:slug/carts |
| Checkout | POST /s/:slug/checkout-sessions, …/:id (GET/PUT), …/:id/complete, …/:id/payment-intent, …/:id/cancel |
| Orders | … /s/:slug/orders |
OAuth grants
POST /ucp/oauth2/token (form-urlencoded):
| Grant | Required params |
|---|---|
authorization_code | code, code_verifier, client_id, redirect_uri |
refresh_token | refresh_token (rotated, single-use) |
client_credentials | client_id, client_secret (post or Basic) |
Scopes: purchase:complete, orders:read, offline_access.
Error signals
| Code / signal | Meaning | Fix |
|---|---|---|
invalid_api_key | Unknown/revoked platform key | Seed/rotate the platform credential |
invalid_token | Expired/invalid bearer | Refresh via OAuth (refresh_token) |
missing_request_id | No Request-Id header | Send a unique Request-Id per call |
missing_ucp_agent / invalid_ucp_agent | No/malformed UCP-Agent header | Send UCP-Agent: profile="…" |
missing_idempotency_key | State-changing REST call without the header | Send an Idempotency-Key header |
invalid_profile_url | Malformed agent profile URL | Send a valid profile URL |
insufficient_trust | Tier too low for the operation | Authenticate (token tier) |
insufficient_scope | Missing required scope | Request purchase:complete / orders:read |
payment_selection_required | Multiple rails, none chosen | Read ucp.payment_handlers, retry with payment_method |
mandate_expired | AP2 exp missing/past | Mint a fresh mandate |
mandate_scope_mismatch | Mandate merchant ≠ store | Bind the mandate to the store slug |
| UCP error envelope | Business outcome (often HTTP 200, ucp.status: error) | Read messages[] and severity |
Webhook events
See Orders → Lifecycle webhooks.
Spec & schemas
artos-api/ucp-spec — UCP schemas, services, and documentation.