Grocery ordering

This guide describes a sample integration for a grocery ordering experience using the Universal Commerce Protocol (UCP). Both the Model Context Protocol (MCP) and REST are supported transport bindings, but MCP is recommended to better align with the Connected Apps' mission.

In this scenario, a user has found a recipe online (not detailed in this guide) and wants to purchase the required ingredients:

  • 4 tbsp salted butter
  • 3 cloves garlic
  • 1 yellow onion
  • 28 oz can whole peeled tomatoes
  • 8 oz pasta

Transports

This section describes the key differences between the two transport bindings.

Model Context Protocol (MCP)

The MCP transport enables AI agents to interact with your capabilities using structured tool calling over JSON-RPC 2.0:

  • Wire protocol: operates over JSON-RPC 2.0 (stdio, SSE, or Stream).
  • Request envelope: requests call tools/call where params.name identifies the tool (for example, search_locations, search_catalog, create_cart, update_cart, get_cart, lookup_locations, cancel_cart). Metadata (such as ucp-agent and idempotency-key) is passed in params.arguments.meta, while capability parameters are wrapped in a capability-specific container object (location, catalog, or cart).
  • Response envelope: responses return a JSON-RPC 2.0 result with payloads encapsulated in result.structuredContent, containing top-level ucp capability metadata alongside capability response fields.

REST

The REST transport uses standard HTTP/1.1+ and RESTful resource patterns:

  • Wire protocol and security: requests and responses use Content-Type: application/json served over HTTPS (minimum TLS 1.3).
  • Methods and paths: standard HTTP verbs map directly to capabilities:
    • POST /locations/search — Search locations and stored addresses.
    • POST /locations/lookup — Lookup locations by identifier.
    • POST /catalog/search — Search products and availability.
    • POST /carts — Create a cart session.
    • PUT /carts/{id} — Update a cart session.
    • GET /carts/{id} — Fetch a cart session.
    • POST /carts/{id}/cancel — Cancel a cart session.
  • Headers: metadata is passed through standard HTTP headers:
    • Host: Target server hostname, for example, business.example.com.
    • UCP-Agent: Platform profile URI in RFC 8941 Dictionary Structured Field syntax, for example, profile="https://platform.example/profiles/grocery-agent.json".
    • Idempotency-Key: UUID string for state-modifying operations (such as cart cancellation) for safe retries.
    • Request-Id: Optional request identifier for end-to-end tracing.
  • Payloads and responses: request and response bodies contain the raw capability JSON schema directly without JSON-RPC envelopes or tool wrapper containers. Successful responses return standard HTTP status codes (200 OK, 201 Created).

Flow overview

The following table outlines the sequence of calls between the Google Agent and your server:

Step Operation User action and description Response
1 search_locations Search for store locations and saved user delivery addresses Returns store locations, saved delivery addresses, and info messages to signal to the Agent to do location disambiguation
2 search_catalog Location-aware search for products Returns matching products, prices, and variants using queries and location hints passed in the request
3 create_cart Create a cart with selected variants Returns cart details and a continue_url for checkout
4 update_cart Update cart to replace a chosen product with a variant Returns cart details and a continue_url for checkout
5 get_cart Fetch a previously created cart to resume a session Returns cart details and a continue_url for checkout
6 lookup_locations Lookup store locations and buyer delivery addresses by identifier whenever the cart UI has to be rendered to the user (to display the user-selected address in the UI) Returns resolved store locations and buyer delivery addresses
7 cancel_cart Cancel a cart session when the user starts over or abandons the order Returns the cart state before deletion

By default, delivery is the assumed fulfillment method. Users may change to pickup by explicit prompt.

The user flows cover three scenarios based on fulfillment intent (delivery versus pickup) and the user's stored delivery addresses and store pickup locations in your system:

  • Scenario A: delivery, one or more delivery addresses
  • Scenario B: delivery, no delivery addresses
  • Scenario C: pickup, no store addresses

Before searching the catalog or creating a cart, the agent performs location discovery using search_locations. This step resolves both physical store locations and user delivery addresses stored in the user's profile on the your app to use in subsequent UCP operations (such as localized catalog search and cart management).

Request

MCP

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_locations",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "location": {}
    }
  }
}

REST

POST /locations/search HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab01
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{}

Scenario A: Delivery, one or more delivery addresses

In this scenario, the user wants grocery delivery, and their linked account has one or more delivery addresses saved in your system along with any number of store locations (which aren't used in the delivery user flow).

  1. The agent calls search_locations.
  2. Your UCP server returns the user's stored store location in the locations list as well as the user's stored delivery addresses in the buyer_address_locations list.
  3. In the case of multiple delivery addresses, the model treats the first address in the list ('addr_user_home_01') as the selected or preferred address. You should return addresses in order of user preference. If no preference mechanism exists, you should return addresses from most recently used to least recently used.
  4. Subsequent Catalog and Cart operation requests pass the delivery address ID as a hint in context.buyer_address_location.
  5. The user may change their delivery address lower in the funnel triggering a cart rebuild for the new location with possible item updates for the inventory available at that location.

Response

You return the store location and the user's saved delivery addresses. To optimize performance, cap the list to a maximum of 10 entries.

MCP

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.common.location.search": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [
        {
          "id": "loc_valley_grocers_chicago_clark",
          "name": "Valley Grocers - Lincoln Park",
          "address": {
            "street_address": "2200 N Clark St",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60614"
          }
        }
      ],
      "buyer_address_locations": [
        {
          "id": "addr_user_home_01",
          "name": "Home",
          "address": {
            "street_address": "2200 N Clark St, Apt 4B",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60614"
          }
        },
        {
          "id": "addr_user_work_02",
          "name": "Work",
          "address": {
            "street_address": "100 S State St, Floor 12",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60603"
          }
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.common.location.search": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [
    {
      "id": "loc_valley_grocers_chicago_clark",
      "name": "Valley Grocers - Lincoln Park",
      "address": {
        "street_address": "2200 N Clark St",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60614"
      }
    }
  ],
  "buyer_address_locations": [
    {
      "id": "addr_user_home_01",
      "name": "Home",
      "address": {
        "street_address": "2200 N Clark St, Apt 4B",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60614"
      }
    },
    {
      "id": "addr_user_work_02",
      "name": "Work",
      "address": {
        "street_address": "100 S State St, Floor 12",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60603"
      }
    }
  ]
}

Response (delivery-only partners)

For partners that only support delivery, they must return the pickup_not_supported info message in search_locations (Note: Follow the exact wording of the message shown below):

MCP

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.common.location.search": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [],
      "messages": [
        {
          "type": "info",
          "code": "pickup_not_supported",
          "content": "In store pickup is not supported. Only delivery is available."
        }
      ],
      "buyer_address_locations": [
        {
          "id": "addr_user_home_01",
          "name": "Home",
          "address": {
            "street_address": "2200 N Clark St, Apt 4B",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60614"
          }
        },
        {
          "id": "addr_user_work_02",
          "name": "Work",
          "address": {
            "street_address": "100 S State St, Floor 12",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60603"
          }
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.common.location.search": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [],
  "messages": [
    {
      "type": "info",
      "code": "pickup_not_supported",
      "content": "In store pickup is not supported. Only delivery is available."
    }
  ],
  "buyer_address_locations": [
    {
      "id": "addr_user_home_01",
      "name": "Home",
      "address": {
        "street_address": "2200 N Clark St, Apt 4B",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60614"
      }
    },
    {
      "id": "addr_user_work_02",
      "name": "Work",
      "address": {
        "street_address": "100 S State St, Floor 12",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60603"
      }
    }
  ]
}

Scenario B: Delivery, no delivery addresses

In this scenario, the user wants delivery, but their linked account has 0 delivery addresses saved in your system (and any number of pickup store locations). The model prompts the user for a postal code which is then used in as a hint in subsequent catalog and cart operations. Final delivery address resolution is done during checkout on your app or website.

  1. The agent calls search_locations.
  2. You return the user's saved pickup store locations, an empty buyer_address_locations list, and an info message signaling that no delivery addresses are stored on the account.
  3. The agent prompts the user to enter their postal code.
  4. The user provides their postal code (for example, 60614).
  5. On subsequent catalog and cart operation requests the agent passes the postal code as a hint in context.postal_code. The full delivery address is entered later during checkout on your web checkout flow (continue_url).

Response

MCP

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.common.location.search": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [
        {
          "id": "loc_valley_grocers_chicago_clark",
          "name": "Valley Grocers - Lincoln Park",
          "address": {
            "street_address": "2200 N Clark St",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60614"
          }
        }
      ],
      "buyer_address_locations": [],
      "messages": [
        {
          "type": "info",
          "code": "no_delivery_addresses_stored",
          "content": "No delivery addresses stored on the linked account."
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.common.location.search": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [
    {
      "id": "loc_valley_grocers_chicago_clark",
      "name": "Valley Grocers - Lincoln Park",
      "address": {
        "street_address": "2200 N Clark St",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60614"
      }
    }
  ],
  "buyer_address_locations": [],
  "messages": [
    {
      "type": "info",
      "code": "no_delivery_addresses_stored",
      "content": "No delivery addresses stored on the linked account."
    }
  ]
}

User interaction:

  • Agent prompt: the agent asks: "What is your delivery postal code?"
  • User response: the user responds with 60614.
  • Agent action: the agent then passes 60614 in the context.postal_code location hint for catalog search and subsequent cart operations.
  • Fulfillment: delivery address resolution occurs at checkout on your app or website.

Response (saved delivery address required)

If you require the user to have a saved delivery address on their linked account before proceeding with a delivery journey (instead of falling back to a postal code hint), you can return the following recoverable error response to search_locations.

MCP

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "status": "error",
        "capabilities": {
          "dev.ucp.common.location.search": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [],
      "messages": [
        {
          "type": "error",
          "code": "buyer_address_locations_required",
          "content": "The partner you are trying to connect with this tool doesn't have any saved delivery address for the linked account. Inform the user they must first add a delivery address for their linked account on partner's app/website, then continue the journey here.",
          "severity": "recoverable"
        }
      ],
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "status": "error",
    "capabilities": {
      "dev.ucp.common.location.search": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [],
  "messages": [
    {
      "type": "error",
      "code": "buyer_address_locations_required",
      "content": "The partner you are trying to connect with this tool doesn't have any saved delivery address for the linked account. Inform the user they must first add a delivery address for their linked account on partner's app/website, then continue the journey here.",
      "severity": "recoverable"
    }
  ]
}

Scenario C: Pickup, no store locations

In this scenario, the user expresses intent for order pickup, but has 0 pickup store locations saved in your system.

  1. The agent calls search_locations.
  2. You return an empty list for locations and buyer_address_locations along with an info message signaling no saved pickup store locations.
  3. The agent prompts the user to enter their postal code.
  4. The user provides their postal code (for example, 60614).
  5. The agent issues a second search_locations call specifying serves.address.postal_code.
  6. You return a list of candidate store locations that realistically serve that postal code.
  7. In the case of multiple store locations, the model treats the first store location in the list as the selected or preferred store. You should return store locations in order of user preference. If no preference mechanism exists, you should return store locations from most recently used to least recently used.
  8. Subsequent Catalog and Cart operations requests include the store's ID in context.location as a hint (per PR 642).

Response 1

MCP

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.common.location.search": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [],
      "buyer_address_locations": [],
      "messages": [
        {
          "type": "info",
          "code": "no_pickup_locations_stored",
          "content": "No stored pickup store locations found for the linked account."
        },
        {
          "type": "info",
          "code": "no_delivery_addresses_stored",
          "content": "No delivery addresses stored on the linked account."
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.common.location.search": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [],
  "buyer_address_locations": [],
  "messages": [
    {
      "type": "info",
      "code": "no_pickup_locations_stored",
      "content": "No stored pickup store locations found for the linked account."
    },
    {
      "type": "info",
      "code": "no_delivery_addresses_stored",
      "content": "No delivery addresses stored on the linked account."
    }
  ]
}

User interaction:

  • Agent prompt: the agent asks: "Provide your postal code to find nearby pickup stores."
  • User response: the user responds with 60614.

Request 2 (search nearby stores by postal code)

MCP

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "search_locations",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "location": {
        "serves": {
          "address": {
            "postal_code": "60614"
          }
        }
      }
    }
  }
}

REST

POST /locations/search HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab02
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "serves": {
    "address": {
      "postal_code": "60614"
    }
  }
}

Response 2

MCP

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.common.location.search": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [
        {
          "id": "loc_valley_grocers_chicago_clark",
          "name": "Valley Grocers - Lincoln Park",
          "address": {
            "street_address": "2200 N Clark St",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60614"
          }
        },
        {
          "id": "loc_valley_grocers_chicago_halsted",
          "name": "Valley Grocers - Lakeview",
          "address": {
            "street_address": "3200 N Halsted St",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60657"
          }
        }
      ],
      "buyer_address_locations": [],
      "messages": [
        {
          "type": "info",
          "code": "no_delivery_addresses_stored",
          "content": "No delivery addresses stored on the linked account."
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.common.location.search": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [
    {
      "id": "loc_valley_grocers_chicago_clark",
      "name": "Valley Grocers - Lincoln Park",
      "address": {
        "street_address": "2200 N Clark St",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60614"
      }
    },
    {
      "id": "loc_valley_grocers_chicago_halsted",
      "name": "Valley Grocers - Lakeview",
      "address": {
        "street_address": "3200 N Halsted St",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60657"
      }
    }
  ],
  "buyer_address_locations": [],
  "messages": [
    {
      "type": "info",
      "code": "no_delivery_addresses_stored",
      "content": "No delivery addresses stored on the linked account."
    }
  ]
}

User selection:

  • User selection: the user selects Valley Grocers - Lincoln Park (loc_valley_grocers_chicago_clark).
  • Agent action: the agent then proceeds to catalog search, passing "location": "loc_valley_grocers_chicago_clark" in context.

The agent searches the merchant's catalog for the ingredients. The agent makes one search_catalog call per ingredient. For localized availability and store-specific pricing, the agent includes the location hint resolved in Step 1 within the request's context object.

The following examples show the request and response for searching for "salted butter". The agent repeats this process for the other ingredients: garlic, yellow onion, whole peeled tomatoes, and pasta.

  • Operation / tool: search_catalog
  • Capability: dev.ucp.shopping.catalog.search (extended with dev.ucp.shopping.fulfillment filters)
  • Transport specs: MCP specification and REST specification.

Scenario A: Delivery with buyer address location hint

In a delivery journey where the user has one or more stored delivery addresses on file, the agent passes the stored buyer address location identifier (for example, "buyer_address_location": "addr_user_home_01") in the context object to retrieve catalog items and prices available for delivery to that address.

Request (butter - stored delivery address)

MCP

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "search_catalog",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "catalog": {
        "query": "salted butter",
        "context": {
          "buyer_address_location": "addr_user_home_01"
        }
      }
    }
  }
}

REST

POST /catalog/search HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab03
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "query": "salted butter",
  "context": {
    "buyer_address_location": "addr_user_home_01"
  }
}

Scenario B: Delivery with postal code location hint

In a delivery journey where the user has no saved delivery addresses on file (Scenario B), the agent passes the user-provided delivery postal code (for example, "postal_code": "60614") in the context object to retrieve catalog items and prices available for delivery to that area.

Request (butter - postal code delivery)

MCP

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "search_catalog",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "catalog": {
        "query": "salted butter",
        "context": {
          "postal_code": "60614"
        }
      }
    }
  }
}

REST

POST /catalog/search HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab04
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "query": "salted butter",
  "context": {
    "postal_code": "60614"
  }
}

Scenario C: Pickup with store location hint

In a pickup journey, the agent passes the selected store location identifier (for example, "location": "loc_valley_grocers_chicago_clark") in the context object to filter catalog results and verify in-store pickup inventory at that specific store.

Request (butter - pickup)

MCP

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "search_catalog",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "catalog": {
        "query": "salted butter",
        "context": {
          "location": "loc_valley_grocers_chicago_clark"
        }
      }
    }
  }
}

REST

POST /catalog/search HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab05
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "query": "salted butter",
  "context": {
    "location": "loc_valley_grocers_chicago_clark"
  }
}

Response (butter)

In all scenarios the response returns the best match for "salted butter", with prices, availability for delivery or pickup based on the provided location context, and size variants.

MCP

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.shopping.catalog.search": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "products": [
        {
          "id": "prod_butter_valley_dairy",
          "title": "Valley Dairy Salted Butter",
          "description": {
            "plain": "Premium salted butter sticks."
          },
          "price_range": {
            "min": {
              "amount": 299,
              "currency": "USD"
            },
            "max": {
              "amount": 499,
              "currency": "USD"
            }
          },
          "variants": [
            {
              "id": "var_butter_valley_dairy_8oz",
              "title": "Valley Dairy Salted Butter (8 oz)",
              "description": {
                "plain": "Valley Dairy Salted Butter (8 oz) pack."
              },
              "price": {
                "amount": 299,
                "currency": "USD"
              },
              "availability": {
                "status": "in_stock"
              }
            },
            {
              "id": "var_butter_valley_dairy_16oz",
              "title": "Valley Dairy Salted Butter (16 oz)",
              "description": {
                "plain": "Valley Dairy Salted Butter (16 oz) pack."
              },
              "price": {
                "amount": 499,
                "currency": "USD"
              },
              "availability": {
                "status": "in_stock"
              }
            }
          ]
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.shopping.catalog.search": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "products": [
    {
      "id": "prod_butter_valley_dairy",
      "title": "Valley Dairy Salted Butter",
      "description": {
        "plain": "Premium salted butter sticks."
      },
      "price_range": {
        "min": {
          "amount": 299,
          "currency": "USD"
        },
        "max": {
          "amount": 499,
          "currency": "USD"
        }
      },
      "variants": [
        {
          "id": "var_butter_valley_dairy_8oz",
          "title": "Valley Dairy Salted Butter (8 oz)",
          "description": {
            "plain": "Valley Dairy Salted Butter (8 oz) pack."
          },
          "price": {
            "amount": 299,
            "currency": "USD"
          },
          "availability": {
            "status": "in_stock"
          }
        },
        {
          "id": "var_butter_valley_dairy_16oz",
          "title": "Valley Dairy Salted Butter (16 oz)",
          "description": {
            "plain": "Valley Dairy Salted Butter (16 oz) pack."
          },
          "price": {
            "amount": 499,
            "currency": "USD"
          },
          "availability": {
            "status": "in_stock"
          }
        }
      ]
    }
  ]
}

Create cart

The user signals an intention to move forward with the purchase so the agent compiles the items and creates a cart.

The following example illustrates creating a cart using a delivery postal code location hint ("context": { "postal_code": "60614"}).

Request

MCP

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "create_cart",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "cart": {
        "context": {
          "postal_code": "60614"
        },
        "line_items": [
          {
            "item": {
              "id": "var_butter_valley_dairy_8oz"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_garlic_3pk"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_onion_yellow_single"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_tomatoes_bella_vista_28oz"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_pasta_roma_spaghetti_16oz"
            },
            "quantity": 1
          }
        ]
      }
    }
  }
}

REST

POST /carts HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab06
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "context": {
    "postal_code": "60614"
  },
  "line_items": [
    {
      "item": {
        "id": "var_butter_valley_dairy_8oz"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_garlic_3pk"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_onion_yellow_single"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_tomatoes_bella_vista_28oz"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_pasta_roma_spaghetti_16oz"
      },
      "quantity": 1
    }
  ]
}

Response

You successfully create the cart for delivery, returning estimated totals and a continue_url that clicks through to your checkout flow to complete the order (including final delivery address, time window selection, and payment).

MCP

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.shopping.cart": [
            { "version": "2026-08-25" }
          ]
        }
      },
      "id": "cart_chicago_grocery_98765",
      "line_items": [
        {
          "id": "li_butter_01",
          "item": {
            "id": "var_butter_valley_dairy_8oz",
            "title": "Valley Dairy Salted Butter (8 oz)",
            "price": 299,
            "image_url": "https://business.example.com/images/var_butter_valley_dairy_8oz.png"
          },
          "quantity": 1,
          "totals": [
            { "type": "subtotal", "display_text": "Subtotal", "amount": 299 }
          ]
        },
        {
          "id": "li_garlic_01",
          "item": {
            "id": "var_garlic_3pk",
            "title": "Garlic (3-Pack)",
            "price": 249,
            "image_url": "https://business.example.com/images/var_garlic_3pk.png"
          },
          "quantity": 1,
          "totals": [
            { "type": "subtotal", "display_text": "Subtotal", "amount": 249 }
          ]
        },
        {
          "id": "li_onion_01",
          "item": {
            "id": "var_onion_yellow_single",
            "title": "Yellow Onion (Single)",
            "price": 79,
            "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
          },
          "quantity": 1,
          "totals": [
            { "type": "subtotal", "display_text": "Subtotal", "amount": 79 }
          ]
        },
        {
          "id": "li_tomatoes_01",
          "item": {
            "id": "var_tomatoes_bella_vista_28oz",
            "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
            "price": 299,
            "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
          },
          "quantity": 1,
          "totals": [
            { "type": "subtotal", "display_text": "Subtotal", "amount": 299 }
          ]
        },
        {
          "id": "li_pasta_01",
          "item": {
            "id": "var_pasta_roma_spaghetti_16oz",
            "title": "Roma Organics Spaghetti (16 oz)",
            "price": 179,
            "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
          },
          "quantity": 1,
          "totals": [
            { "type": "subtotal", "display_text": "Subtotal", "amount": 179 }
          ]
        }
      ],
      "currency": "USD",
      "totals": [
        { "type": "subtotal", "display_text": "Subtotal", "amount": 1105 },
        { "type": "total", "display_text": "Total", "amount": 1105 }
      ],
      "continue_url": "https://business.example.com/cart/"
    }
  }
}

REST

HTTP/1.1 201 Created
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.shopping.cart": [
        { "version": "2026-08-25" }
      ]
    }
  },
  "id": "cart_chicago_grocery_98765",
  "line_items": [
    {
      "id": "li_butter_01",
      "item": {
        "id": "var_butter_valley_dairy_8oz",
        "title": "Valley Dairy Salted Butter (8 oz)",
        "price": 299,
        "image_url": "https://business.example.com/images/var_butter_valley_dairy_8oz.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "display_text": "Subtotal", "amount": 299 }
      ]
    },
    {
      "id": "li_garlic_01",
      "item": {
        "id": "var_garlic_3pk",
        "title": "Garlic (3-Pack)",
        "price": 249,
        "image_url": "https://business.example.com/images/var_garlic_3pk.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "display_text": "Subtotal", "amount": 249 }
      ]
    },
    {
      "id": "li_onion_01",
      "item": {
        "id": "var_onion_yellow_single",
        "title": "Yellow Onion (Single)",
        "price": 79,
        "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "display_text": "Subtotal", "amount": 79 }
      ]
    },
    {
      "id": "li_tomatoes_01",
      "item": {
        "id": "var_tomatoes_bella_vista_28oz",
        "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
        "price": 299,
        "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "display_text": "Subtotal", "amount": 299 }
      ]
    },
    {
      "id": "li_pasta_01",
      "item": {
        "id": "var_pasta_roma_spaghetti_16oz",
        "title": "Roma Organics Spaghetti (16 oz)",
        "price": 179,
        "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
      },
      "quantity": 1,
      "totals": [
        { "type": "subtotal", "display_text": "Subtotal", "amount": 179 }
      ]
    }
  ],
  "currency": "USD",
  "totals": [
    { "type": "subtotal", "display_text": "Subtotal", "amount": 1105 },
    { "type": "total", "display_text": "Total", "amount": 1105 }
  ],
  "continue_url": "https://business.example.com/cart/"
}

Update cart

The user decides they want the 16 oz butter instead of the 8 oz. The agent updates the cart to replace the 8 oz butter with the 16 oz butter. It makes an update_cart call with the cart ID, retaining the appropriate location context, removing the 8 oz butter line item and adding the 16 oz butter line item. update_cart is a full refresh.

The following example illustrates updating a cart for store pickup using a store location identifier hint ("cart": { "context": { "location": "loc_valley_grocers_chicago_clark" }, ... }).

Request

MCP

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "update_cart",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "id": "cart_chicago_grocery_98765",
      "cart": {
        "context": {
          "location": "loc_valley_grocers_chicago_clark"
        },
        "line_items": [
          {
            "item": {
              "id": "var_butter_valley_dairy_16oz"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_garlic_3pk"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_onion_yellow_single"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_tomatoes_bella_vista_28oz"
            },
            "quantity": 1
          },
          {
            "item": {
              "id": "var_pasta_roma_spaghetti_16oz"
            },
            "quantity": 1
          }
        ]
      }
    }
  }
}

REST

PUT /carts/cart_chicago_grocery_98765 HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab07
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "line_items": [
    {
      "item": {
        "id": "var_butter_valley_dairy_16oz"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_garlic_3pk"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_onion_yellow_single"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_tomatoes_bella_vista_28oz"
      },
      "quantity": 1
    },
    {
      "item": {
        "id": "var_pasta_roma_spaghetti_16oz"
      },
      "quantity": 1
    }
  ],
  "context": {
    "location": "loc_valley_grocers_chicago_clark"
  }
}

Response

The response returns the updated cart state. The totals are updated accordingly.

MCP

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.shopping.cart": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "id": "cart_chicago_grocery_98765",
      "line_items": [
        {
          "id": "li_garlic_01",
          "item": {
            "id": "var_garlic_3pk",
            "title": "Garlic (3-Pack)",
            "price": 249,
            "image_url": "https://business.example.com/images/var_garlic_3pk.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 249
            }
          ]
        },
        {
          "id": "li_onion_01",
          "item": {
            "id": "var_onion_yellow_single",
            "title": "Yellow Onion (Single)",
            "price": 79,
            "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 79
            }
          ]
        },
        {
          "id": "li_tomatoes_01",
          "item": {
            "id": "var_tomatoes_bella_vista_28oz",
            "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
            "price": 299,
            "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 299
            }
          ]
        },
        {
          "id": "li_pasta_01",
          "item": {
            "id": "var_pasta_roma_spaghetti_16oz",
            "title": "Roma Organics Spaghetti (16 oz)",
            "price": 179,
            "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 179
            }
          ]
        },
        {
          "id": "li_butter_02",
          "item": {
            "id": "var_butter_valley_dairy_16oz",
            "title": "Valley Dairy Salted Butter (16 oz)",
            "price": 499,
            "image_url": "https://business.example.com/images/var_butter_valley_dairy_16oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 499
            }
          ]
        }
      ],
      "currency": "USD",
      "totals": [
        {
          "type": "subtotal",
          "display_text": "Subtotal",
          "amount": 1305
        },
        {
          "type": "total",
          "display_text": "Total",
          "amount": 1305
        }
      ],
      "continue_url": "https://business.example.com/cart/"
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.shopping.cart": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "id": "cart_chicago_grocery_98765",
  "line_items": [
    {
      "id": "li_garlic_01",
      "item": {
        "id": "var_garlic_3pk",
        "title": "Garlic (3-Pack)",
        "price": 249,
        "image_url": "https://business.example.com/images/var_garlic_3pk.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 249
        }
      ]
    },
    {
      "id": "li_onion_01",
      "item": {
        "id": "var_onion_yellow_single",
        "title": "Yellow Onion (Single)",
        "price": 79,
        "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 79
        }
      ]
    },
    {
      "id": "li_tomatoes_01",
      "item": {
        "id": "var_tomatoes_bella_vista_28oz",
        "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
        "price": 299,
        "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 299
        }
      ]
    },
    {
      "id": "li_pasta_01",
      "item": {
        "id": "var_pasta_roma_spaghetti_16oz",
        "title": "Roma Organics Spaghetti (16 oz)",
        "price": 179,
        "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 179
        }
      ]
    },
    {
      "id": "li_butter_02",
      "item": {
        "id": "var_butter_valley_dairy_16oz",
        "title": "Valley Dairy Salted Butter (16 oz)",
        "price": 499,
        "image_url": "https://business.example.com/images/var_butter_valley_dairy_16oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 499
        }
      ]
    }
  ],
  "currency": "USD",
  "totals": [
    {
      "type": "subtotal",
      "display_text": "Subtotal",
      "amount": 1305
    },
    {
      "type": "total",
      "display_text": "Total",
      "amount": 1305
    }
  ],
  "continue_url": "https://business.example.com/cart/"
}

Get cart

get_cart is used to fetch a previously created cart, such as if the user were to start a new session and want to continue building their previous cart.

The following example illustrates retrieving the cart session using the cart ID from the previous update operation ("id": "cart_chicago_grocery_98765").

Request

MCP

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "get_cart",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "id": "cart_chicago_grocery_98765"
    }
  }
}

REST

GET /carts/cart_chicago_grocery_98765 HTTP/1.1
Host: business.example.com
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab08
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

Response

You return the current state of the requested cart session.

MCP

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.shopping.cart": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "id": "cart_chicago_grocery_98765",
      "line_items": [
        {
          "id": "li_garlic_01",
          "item": {
            "id": "var_garlic_3pk",
            "title": "Garlic (3-Pack)",
            "price": 249,
            "image_url": "https://business.example.com/images/var_garlic_3pk.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 249
            }
          ]
        },
        {
          "id": "li_onion_01",
          "item": {
            "id": "var_onion_yellow_single",
            "title": "Yellow Onion (Single)",
            "price": 79,
            "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 79
            }
          ]
        },
        {
          "id": "li_tomatoes_01",
          "item": {
            "id": "var_tomatoes_bella_vista_28oz",
            "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
            "price": 299,
            "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 299
            }
          ]
        },
        {
          "id": "li_pasta_01",
          "item": {
            "id": "var_pasta_roma_spaghetti_16oz",
            "title": "Roma Organics Spaghetti (16 oz)",
            "price": 179,
            "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 179
            }
          ]
        },
        {
          "id": "li_butter_02",
          "item": {
            "id": "var_butter_valley_dairy_16oz",
            "title": "Valley Dairy Salted Butter (16 oz)",
            "price": 499,
            "image_url": "https://business.example.com/images/var_butter_valley_dairy_16oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 499
            }
          ]
        }
      ],
      "currency": "USD",
      "totals": [
        {
          "type": "subtotal",
          "display_text": "Subtotal",
          "amount": 1305
        },
        {
          "type": "total",
          "display_text": "Total",
          "amount": 1305
        }
      ],
      "continue_url": "https://business.example.com/cart/"
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.shopping.cart": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "id": "cart_chicago_grocery_98765",
  "line_items": [
    {
      "id": "li_garlic_01",
      "item": {
        "id": "var_garlic_3pk",
        "title": "Garlic (3-Pack)",
        "price": 249,
        "image_url": "https://business.example.com/images/var_garlic_3pk.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 249
        }
      ]
    },
    {
      "id": "li_onion_01",
      "item": {
        "id": "var_onion_yellow_single",
        "title": "Yellow Onion (Single)",
        "price": 79,
        "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 79
        }
      ]
    },
    {
      "id": "li_tomatoes_01",
      "item": {
        "id": "var_tomatoes_bella_vista_28oz",
        "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
        "price": 299,
        "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 299
        }
      ]
    },
    {
      "id": "li_pasta_01",
      "item": {
        "id": "var_pasta_roma_spaghetti_16oz",
        "title": "Roma Organics Spaghetti (16 oz)",
        "price": 179,
        "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 179
        }
      ]
    },
    {
      "id": "li_butter_02",
      "item": {
        "id": "var_butter_valley_dairy_16oz",
        "title": "Valley Dairy Salted Butter (16 oz)",
        "price": 499,
        "image_url": "https://business.example.com/images/var_butter_valley_dairy_16oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 499
        }
      ]
    }
  ],
  "currency": "USD",
  "totals": [
    {
      "type": "subtotal",
      "display_text": "Subtotal",
      "amount": 1305
    },
    {
      "type": "total",
      "display_text": "Total",
      "amount": 1305
    }
  ],
  "continue_url": "https://business.example.com/cart/"
}

Lookup locations

The UCP backend does not cache location details, only location identifiers received from you. Consequently, lookup_locations is called whenever the cart UI has to be rendered to the user (unless the location hint is a postal_code) to get the user's delivery address or store pickup location to be shown in the UI. Both store locations and buyer locations can be included in the ids array in the request, and the response should include the appropriate locations or buyer_address_locations array.

Store locations

The following example illustrates looking up a store pickup location by its identifier ("ids": ["loc_valley_grocers_chicago_clark"]).

Request

MCP

{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "lookup_locations",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "location": {
        "ids": [
          "loc_valley_grocers_chicago_clark"
        ]
      }
    }
  }
}

REST

POST /locations/lookup HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab09
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "ids": [
    "loc_valley_grocers_chicago_clark"
  ]
}

Response

You return the resolved store location details in the locations array, including the required inputs correlation metadata.

MCP

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.common.location.lookup": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [
        {
          "id": "loc_valley_grocers_chicago_clark",
          "inputs": [
            {
              "id": "loc_valley_grocers_chicago_clark"
            }
          ],
          "name": "Valley Grocers - Lincoln Park",
          "address": {
            "street_address": "2200 N Clark St",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60614"
          }
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.common.location.lookup": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [
    {
      "id": "loc_valley_grocers_chicago_clark",
      "inputs": [
        {
          "id": "loc_valley_grocers_chicago_clark"
        }
      ],
      "name": "Valley Grocers - Lincoln Park",
      "address": {
        "street_address": "2200 N Clark St",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60614"
      }
    }
  ]
}

Buyer address locations

The following example illustrates looking up a saved buyer delivery address by its identifier ("ids": ["addr_user_home_01"]).

Request

MCP

{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "lookup_locations",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        }
      },
      "location": {
        "ids": [
          "addr_user_home_01"
        ]
      }
    }
  }
}

REST

POST /locations/lookup HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab10
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"

{
  "ids": [
    "addr_user_home_01"
  ]
}

Response

You return the resolved buyer delivery address in the buyer_address_locations array.

MCP

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.common.location.lookup": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "locations": [],
      "buyer_address_locations": [
        {
          "id": "addr_user_home_01",
          "inputs": [
            {
              "id": "addr_user_home_01"
            }
          ],
          "name": "Home",
          "address": {
            "street_address": "2200 N Clark St, Apt 4B",
            "address_locality": "Chicago",
            "address_region": "IL",
            "address_country": "US",
            "postal_code": "60614"
          }
        }
      ]
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.common.location.lookup": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "locations": [],
  "buyer_address_locations": [
    {
      "id": "addr_user_home_01",
      "inputs": [
        {
          "id": "addr_user_home_01"
        }
      ],
      "name": "Home",
      "address": {
        "street_address": "2200 N Clark St, Apt 4B",
        "address_locality": "Chicago",
        "address_region": "IL",
        "address_country": "US",
        "postal_code": "60614"
      }
    }
  ]
}

Cancel cart

cancel_cart is called if the user expresses an intent to start over with a different recipe or otherwise wants to clear their entire cart. Invoking cancel_cart must trigger business logic on your side to immediately terminate or invalidate the cart session so that the cart ID is no longer available. If you keep one persistent cart ID per user on your side then you must create new cart IDs on create_cart operations and maintain mappings between those Google-created cart ids and the user's single, persistent cart_id for the lifetime of those carts.

The following example illustrates canceling the existing cart session using its cart ID ("id": "cart_chicago_grocery_98765").

Request

MCP

{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "cancel_cart",
    "arguments": {
      "meta": {
        "ucp-agent": {
          "profile": "https://platform.example/profiles/grocery-agent.json"
        },
        "idempotency-key": "660e8400-e29b-41d4-a716-446655440001"
      },
      "id": "cart_chicago_grocery_98765"
    }
  }
}

REST

POST /carts/cart_chicago_grocery_98765/cancel HTTP/1.1
Host: business.example.com
Content-Type: application/json
Request-Id: 8ef9b0c2-78d1-4e4b-91c2-3e2ef0d3ab11
UCP-Agent: profile="https://platform.example/profiles/grocery-agent.json"
Idempotency-Key: 660e8400-e29b-41d4-a716-446655440001

{}

Response

You cancel the cart session and return the cart state before deletion.

MCP

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "structuredContent": {
      "ucp": {
        "version": "2026-08-25",
        "capabilities": {
          "dev.ucp.shopping.cart": [
            {
              "version": "2026-08-25"
            }
          ]
        }
      },
      "id": "cart_chicago_grocery_98765",
      "line_items": [
        {
          "id": "li_garlic_01",
          "item": {
            "id": "var_garlic_3pk",
            "title": "Garlic (3-Pack)",
            "price": 249,
            "image_url": "https://business.example.com/images/var_garlic_3pk.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 249
            }
          ]
        },
        {
          "id": "li_onion_01",
          "item": {
            "id": "var_onion_yellow_single",
            "title": "Yellow Onion (Single)",
            "price": 79,
            "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 79
            }
          ]
        },
        {
          "id": "li_tomatoes_01",
          "item": {
            "id": "var_tomatoes_bella_vista_28oz",
            "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
            "price": 299,
            "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 299
            }
          ]
        },
        {
          "id": "li_pasta_01",
          "item": {
            "id": "var_pasta_roma_spaghetti_16oz",
            "title": "Roma Organics Spaghetti (16 oz)",
            "price": 179,
            "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 179
            }
          ]
        },
        {
          "id": "li_butter_02",
          "item": {
            "id": "var_butter_valley_dairy_16oz",
            "title": "Valley Dairy Salted Butter (16 oz)",
            "price": 499,
            "image_url": "https://business.example.com/images/var_butter_valley_dairy_16oz.png"
          },
          "quantity": 1,
          "totals": [
            {
              "type": "subtotal",
              "amount": 499
            }
          ]
        }
      ],
      "currency": "USD",
      "totals": [
        {
          "type": "subtotal",
          "display_text": "Subtotal",
          "amount": 1305
        },
        {
          "type": "total",
          "display_text": "Total",
          "amount": 1305
        }
      ],
      "continue_url": "https://business.example.com/cart/"
    }
  }
}

REST

HTTP/1.1 200 OK
Content-Type: application/json

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.ucp.shopping.cart": [
        {
          "version": "2026-08-25"
        }
      ]
    }
  },
  "id": "cart_chicago_grocery_98765",
  "line_items": [
    {
      "id": "li_garlic_01",
      "item": {
        "id": "var_garlic_3pk",
        "title": "Garlic (3-Pack)",
        "price": 249,
        "image_url": "https://business.example.com/images/var_garlic_3pk.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 249
        }
      ]
    },
    {
      "id": "li_onion_01",
      "item": {
        "id": "var_onion_yellow_single",
        "title": "Yellow Onion (Single)",
        "price": 79,
        "image_url": "https://business.example.com/images/var_onion_yellow_single.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 79
        }
      ]
    },
    {
      "id": "li_tomatoes_01",
      "item": {
        "id": "var_tomatoes_bella_vista_28oz",
        "title": "Bella Vista Organic Whole Peeled Tomatoes (28 oz Can)",
        "price": 299,
        "image_url": "https://business.example.com/images/var_tomatoes_bella_vista_28oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 299
        }
      ]
    },
    {
      "id": "li_pasta_01",
      "item": {
        "id": "var_pasta_roma_spaghetti_16oz",
        "title": "Roma Organics Spaghetti (16 oz)",
        "price": 179,
        "image_url": "https://business.example.com/images/var_pasta_roma_spaghetti_16oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 179
        }
      ]
    },
    {
      "id": "li_butter_02",
      "item": {
        "id": "var_butter_valley_dairy_16oz",
        "title": "Valley Dairy Salted Butter (16 oz)",
        "price": 499,
        "image_url": "https://business.example.com/images/var_butter_valley_dairy_16oz.png"
      },
      "quantity": 1,
      "totals": [
        {
          "type": "subtotal",
          "amount": 499
        }
      ]
    }
  ],
  "currency": "USD",
  "totals": [
    {
      "type": "subtotal",
      "display_text": "Subtotal",
      "amount": 1305
    },
    {
      "type": "total",
      "display_text": "Total",
      "amount": 1305
    }
  ],
  "continue_url": "https://business.example.com/cart/"
}

Profile and discovery

Information about profile and discovery negotiation, including vendor extension definitions, is under development.

Error handling

Errors are handled as described in UCP Error Handling and UCP Business Outcome Errors. The Business Outcome errors linked here are documented under the Checkout capability, but the concept is universal in UCP.

Required UCP scopes

These scopes are required to enable UCP capabilities.

  • dev.ucp.shopping.cart:manage
  • dev.ucp.shopping.catalog.search:read
  • dev.ucp.shopping.catalog.lookup:read
  • dev.ucp.common.location.lookup:read
  • dev.ucp.common.location.search:read
  • dev.ucp.shopping.order:manage
  • dev.ucp.shopping.checkout:manage