UCP — Universal Commerce Protocol

UCP (Universal Commerce Protocol) is the discovery-first protocol with roots in the Google and Shopify agentic-commerce work. A UCP merchant publishes a capability profile at /.well-known/ucp, and the agent reads that profile to learn what the merchant can do and how to talk to it.

Discovery and transport

UcpClient fetches the merchant’s /.well-known/ucp profile, which declares:

  • The merchant’s capabilities (search, get product, create checkout, complete checkout, …).
  • The transport for those capabilities — either plain REST or MCP (JSON-RPC). The client auto-selects the transport the profile declares, so your agent code is identical either way.
  • Payment handlers and an optional A2A (agent-to-agent) endpoint.

Introspection helpers

UcpClient exposes helpers for inspecting a discovered profile — useful for capability negotiation, key pinning, and debugging:

const ucp = new UcpClient({ domain: 'shop.example.com' });
await ucp.discover();
 
// Signing keys (for verifying merchant-signed payloads)
const keys = ucp.getSigningKeys();
const key = ucp.getSigningKey('key-2026-01'); // by key id (kid)
 
// Payment + agent routing
const handler = ucp.getPaymentHandler('stripe');
const a2a = ucp.getA2aEndpoint();
 
// Capability graph
const children = ucp.getExtensionsOf('checkout');
const lineage = ucp.getCapabilityLineage('checkout.complete');
  • getSigningKeys() / getSigningKey(kid) — the merchant’s published JWKs, looked up by key id.
  • getPaymentHandler(id) — the configuration for a named payment handler.
  • getA2aEndpoint() — the agent-to-agent endpoint, if the merchant advertises one.
  • getExtensionsOf(parentName) — capabilities that extend a given parent capability.
  • getCapabilityLineage(name) — the ancestor chain for a capability, useful for understanding inherited behavior.

When to use UCP

Use UCP whenever the merchant publishes a discovery document. It’s the most self-describing of the four protocols, so the agent needs the least up-front configuration — point it at a domain and let discovery do the rest.