Skip to main content

Agent profiles and UCP negotiation

In the Universal Commerce Protocol (UCP), a platform profile is a JSON document that describes the protocol version and capabilities the platform supports.

When your agents call UCP-shaped MCP tools, Shopify acts as the business in the negotiation. Shopify uses your profile to learn what your agent declares, intersect it with what the shop supports, and settle on a single negotiated set for the session.

This page explains this flow at a high level, and points to hosted agent profile fixtures you can reference from meta.ucp-agent.profile to use and test UCP.

For more detail, see the UCP specification.


Negotiation for UCP involves two profiles:

  • Business profile: Published by the merchant or platform operating the commerce API, typically at /.well-known/ucp on the business origin. On Shopify, this exists at the merchant storefront ({shop}.myshopify.com/.well-known/ucp). It describes that party’s protocol version, services, capabilities, payment handlers, and signing keys.
  • Platform profile: Published at an HTTPS URL you host, it describes your agent’s declared protocol version and capabilities. You include this URL on every relevant request so the business can fetch, potentially cache, and negotiate.

Negotiation is server-selects. The business computes the intersection of its capabilities with the platform’s and chooses the active set, including which extension capabilities apply (for example, fulfillment or discount layered on checkout). Extensions that depend on a parent capability are pruned if that parent does not end up in the intersection.

Negotiation follows this sequence:

  1. Your request includes the platform profile URL (see Usage).
  2. Shopify (the business) fetches and validates the profile.
  3. Protocol version alignment is checked against what the shop supports.
  4. Capability intersection runs; matching capability names, compatible capability versions, then dependency pruning for extensions.
  5. Responses include negotiated UCP metadata (including active capabilities) where applicable.

If the profile cannot be loaded, is invalid, or yields no compatible capabilities, you get an error path instead of a successful negotiation. See Invalid profiles for more details.


Include the agent profile URI in the meta.ucp-agent.profile field of your MCP request:

{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 1,
"params": {
"name": "create_checkout",
"arguments": {
"meta": {
"ucp-agent": {
"profile": "https://shopify.dev/ucp/agent-profiles/2026-04-08/valid-with-capabilities.json"
}
},
"input": {
"lines": []
}
}
}
}

This profile triggers UCP discovery: profile fetch, validation, version negotiation, and caching.


These fixtures are profiles Shopify can load and negotiate against successfully for different UCP versions.

A platform (an agent) declares checkout with multiple extensions, then the business intersects with its own capabilities. Matching ones are kept, orphaned extensions are pruned.

The examples below will result in a full capability set negotiated successfully. You can use them to test that capability intersection works end-to-end, where agent and business agree on a complete set.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/valid-with-capabilities.json

Which contains the following:

{
"ucp": {
"version": "2026-04-08",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/overview",
"transport": "rest",
"schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json",
"endpoint": "https://business.example.com/ucp/v1"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-04-08"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
],
"dev.ucp.shopping.buyer_consent": [
{
"version": "2026-04-08",
"extends": "dev.ucp.shopping.checkout"
}
],
"dev.ucp.shopping.discount": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
],
"dev.ucp.shopping.cart": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/cart",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/cart.json"
}
],
"dev.ucp.shopping.order": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/order",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/order.json"
}
],
"dev.ucp.shopping.catalog.search": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/catalog/search",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_search.json"
}
],
"dev.ucp.shopping.catalog.lookup": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/catalog/lookup",
"schema": "https://ucp.dev/2026-04-08/schemas/shopping/catalog_lookup.json"
}
],
"dev.shopify.catalog": [
{
"version": "2026-04-08",
"spec": "https://shopify.dev/docs/agents/catalog/storefront-catalog",
"schema": "https://shopify.dev/ucp/schemas/2026-04-08/shopify_catalog.json",
"extends": ["dev.ucp.shopping.catalog.lookup", "dev.ucp.shopping.catalog.search"]
}
],
"dev.shopify.catalog.global": [
{
"version": "2026-04-08",
"spec": "https://shopify.dev/docs/agents/catalog/global-catalog",
"schema": "https://shopify.dev/ucp/schemas/2026-04-08/shopify_catalog_global.json",
"extends": ["dev.ucp.shopping.catalog.lookup", "dev.ucp.shopping.catalog.search"]
}
]
},
"payment_handlers": {}
}
}

Anchor to Only checkout capabilitiesOnly checkout capabilities

A platform (an agent) declares only the checkout capability, with no extensions (for example fulfillment, discount, or buyer consent). The business intersects and returns checkout alone. Negotiation succeeds, but tools won't include fulfillment or discount input fields in their schemas.

The examples below exercise that minimal path. You can use them to test an agent that only needs basic checkout without shipping or discount support.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/checkout-only.json

Which contains the following:

{
"ucp": {
"version": "2026-04-08",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/overview",
"transport": "rest",
"schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json",
"endpoint": "https://business.example.com/ucp/v1"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-04-08"
}
]
},
"payment_handlers": {}
}
}

These fixtures demonstrate profiles that will result in negotiation failures.

A platform declares a valid UCP profile with the correct version but no capabilities. The business has nothing to intersect with, so negotiation cannot succeed.

The examples below surface that scenario. You can use them to test what happens when an agent connects without declaring any capabilities.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/empty-capabilities.json

Which contains the following:

{
"ucp": {
"version": "2026-04-08",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/overview",
"transport": "rest",
"schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json",
"endpoint": "https://business.example.com/ucp/v1"
}
]
},
"capabilities": {},
"payment_handlers": {}
}
}

The profile is valid JSON but omits the ucp.version field. The business cannot determine which protocol version the agent targets, so version negotiation fails before capability intersection.

The examples below let you verify that agents without a declared protocol version are rejected early.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/missing-ucp-version.json

Which contains the following:

{
"ucp": {
"services": {
"dev.ucp.shopping": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/overview",
"transport": "rest",
"schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json",
"endpoint": "https://business.example.com/ucp/v1"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-04-08"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
],
"dev.ucp.shopping.buyer_consent": [
{
"version": "2026-04-08",
"extends": "dev.ucp.shopping.checkout"
}
],
"dev.ucp.shopping.discount": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
]
},
"payment_handlers": {}
}
}

The profile declares a ucp.version the business does not support. Version negotiation fails immediately and capability intersection is not attempted.

The examples below let you test that unknown protocol versions are rejected before any capability processing begins.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/unsupported-ucp-version.json

Which contains the following:

{
"ucp": {
"version": "2026-01-11",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-01-11",
"spec": "https://ucp.dev/2026-01-11/specification/overview",
"transport": "rest",
"schema": "https://ucp.dev/2026-01-11/services/shopping/rest.openapi.json",
"endpoint": "https://business.example.com/ucp/v1"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-04-08"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
],
"dev.ucp.shopping.buyer_consent": [
{
"version": "2026-04-08",
"extends": "dev.ucp.shopping.checkout"
}
],
"dev.ucp.shopping.discount": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
]
},
"payment_handlers": {}
}
}

Anchor to Capability version mismatchCapability version mismatch

The platform declares multiple capabilities, but one uses a version the business does not support. Intersection keeps the matching capabilities and drops the mismatched one so you get partial negotiation: compatible capabilities succeed and the rest are excluded.

The examples below let you test partial intersection instead of an all-or-nothing failure.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/capability-version-mismatch.json

Which contains the following:

{
"ucp": {
"version": "2026-04-08",
"services": {
"dev.ucp.shopping": [
{
"version": "2026-04-08",
"spec": "https://ucp.dev/2026-04-08/specification/overview",
"transport": "rest",
"schema": "https://ucp.dev/2026-04-08/services/shopping/rest.openapi.json",
"endpoint": "https://business.example.com/ucp/v1"
}
]
},
"capabilities": {
"dev.ucp.shopping.checkout": [
{
"version": "2026-04-08"
}
],
"dev.ucp.shopping.fulfillment": [
{
"version": "2099-01-23",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
],
"dev.ucp.shopping.buyer_consent": [
{
"version": "2026-04-08",
"extends": "dev.ucp.shopping.checkout"
}],
"dev.ucp.shopping.discount": [
{
"version": "2026-04-08",
"extends": ["dev.ucp.shopping.checkout", "dev.ucp.shopping.cart"]
}
]
},
"payment_handlers": {}
}
}

The profile is valid JSON but exceeds the maximum allowed payload size. The business rejects it before parsing. Expect a profile_too_large error: no version negotiation or capability intersection runs.

The examples below let you test the size limit guard and reject oversized profiles early.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/too-large.json

The payload is not valid JSON, so the profile cannot be parsed. Use these examples to test parse error handling and resilience.

Copy the following link into the meta.ucp-agent.profile field of your MCP request:

https://shopify.dev/ucp/agent-profiles/2026-04-08/malformed.json

Was this page helpful?