<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Peter</title>
    <description>The latest articles on DEV Community by Peter (@ucptools).</description>
    <link>https://dev.to/ucptools</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3737432%2F036b6d50-5faf-4939-ac76-c7f56e7a6382.jpeg</url>
      <title>DEV Community: Peter</title>
      <link>https://dev.to/ucptools</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ucptools"/>
    <language>en</language>
    <item>
      <title>Valid JSON, broken discovery: the UCP checks that should fail your build</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Sun, 05 Apr 2026 08:36:11 +0000</pubDate>
      <link>https://dev.to/ucptools/valid-json-broken-discovery-the-ucp-checks-that-should-fail-your-build-4c6a</link>
      <guid>https://dev.to/ucptools/valid-json-broken-discovery-the-ucp-checks-that-should-fail-your-build-4c6a</guid>
      <description>&lt;p&gt;If your &lt;code&gt;/.well-known/ucp&lt;/code&gt; file is valid JSON but Google AI Mode or other UCP agents still cannot use it, you do not have a formatting problem.&lt;/p&gt;

&lt;p&gt;You have a discovery problem.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;In our Apr 1, 2026 scan of 28 stores, 26 were broken or missing and 2 were unreachable. That means 92% failed before richer commerce capabilities even mattered. We also found 0 fully healthy profiles. The pattern was consistent: merchants are debating payment rails and optional capability coverage while basic UCP discovery is still broken.&lt;/p&gt;

&lt;p&gt;This article covers the UCP checks that should fail your build - not warn, not get buried in a dashboard, but stop a deploy until fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovery comes before checkout
&lt;/h2&gt;

&lt;p&gt;UCP and ACP solve different problems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UCP is how Google AI Mode, Gemini, and other UCP-compatible agents discover a merchant and learn which commerce services it exposes.&lt;/li&gt;
&lt;li&gt;ACP is OpenAI and Stripe's protocol for delegated payment and ChatGPT commerce flows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the implementation order for most merchants is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make &lt;code&gt;/.well-known/ucp&lt;/code&gt; fetchable&lt;/li&gt;
&lt;li&gt;Make service endpoints callable over HTTPS&lt;/li&gt;
&lt;li&gt;Add signing keys so integrations can verify trust boundaries&lt;/li&gt;
&lt;li&gt;Then worry about payment handlers and ACP-specific checkout rails if your channel mix needs them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If step 1 fails, nothing later matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The checks that should fail your build
&lt;/h2&gt;

&lt;p&gt;These are the issues I would treat as build-breaking in CI.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;/.well-known/ucp&lt;/code&gt; is missing or not fetchable
&lt;/h3&gt;

&lt;p&gt;This is the most obvious blocker and still the most common one.&lt;/p&gt;

&lt;p&gt;From the Apr 1 scan, multiple domains scored F because of &lt;code&gt;UCP_FETCH_FAILED&lt;/code&gt;. No manifest means no discovery. An agent cannot negotiate capabilities with a merchant it cannot find.&lt;/p&gt;

&lt;p&gt;Quick repro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-i&lt;/span&gt; https://example.com/.well-known/ucp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What should fail the build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;404 or 403 response&lt;/li&gt;
&lt;li&gt;redirect loop&lt;/li&gt;
&lt;li&gt;HTML page instead of JSON&lt;/li&gt;
&lt;li&gt;timeout or TLS failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What good looks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;direct HTTPS URL&lt;/li&gt;
&lt;li&gt;200 response&lt;/li&gt;
&lt;li&gt;JSON body&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Endpoint URLs are not HTTPS
&lt;/h3&gt;

&lt;p&gt;UCP requires HTTPS for transport. If your manifest points to an &lt;code&gt;http://&lt;/code&gt; endpoint, that is not a soft warning.&lt;/p&gt;

&lt;p&gt;That is a broken integration.&lt;/p&gt;

&lt;p&gt;Example of a bad service definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dev.ucp.shopping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"spec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/specification/shopping/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/services/shopping/rest.openapi.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://store.example.com/api/ucp"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fix it by serving the endpoint over HTTPS only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://store.example.com/api/ucp"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Related validator rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Endpoint URLs have a trailing slash mismatch
&lt;/h3&gt;

&lt;p&gt;This looks minor. It is not.&lt;/p&gt;

&lt;p&gt;The UCP reference guidance says endpoint URLs should not use trailing slashes. In practice, trailing slash mismatches create annoying agent and proxy bugs, especially when paths are concatenated into checkout routes like &lt;code&gt;/checkout-sessions&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://store.example.com/api/ucp/"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Safer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://store.example.com/api/ucp"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Related validator rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UCP_ENDPOINT_TRAILING_SLASH&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should fail CI because it is the kind of issue that passes visual review and still breaks requests later.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;code&gt;ucp.version&lt;/code&gt; is missing or malformed
&lt;/h3&gt;

&lt;p&gt;UCP uses date-based versioning.&lt;/p&gt;

&lt;p&gt;Current stable version in the reference docs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2026-01-11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your file omits &lt;code&gt;ucp.version&lt;/code&gt; or uses the wrong format, agents cannot reliably interpret your profile.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Related validator rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UCP_MISSING_VERSION&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;UCP_INVALID_VERSION_FORMAT&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. The root &lt;code&gt;ucp&lt;/code&gt; object is missing
&lt;/h3&gt;

&lt;p&gt;A surprising number of machine-readable files are still structurally wrong in basic ways.&lt;/p&gt;

&lt;p&gt;If the root &lt;code&gt;ucp&lt;/code&gt; object is missing, the profile is not a UCP profile.&lt;/p&gt;

&lt;p&gt;Bad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Related validator rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UCP_MISSING_ROOT&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly the kind of issue validators should catch instantly and CI should block.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Namespace authority and schema origins do not match
&lt;/h3&gt;

&lt;p&gt;UCP uses reverse-domain namespaces for capabilities and services. The schema origin needs to line up with namespace authority.&lt;/p&gt;

&lt;p&gt;If it does not, you create ambiguity and trust problems.&lt;/p&gt;

&lt;p&gt;Related validator rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UCP_NS_ORIGIN_MISMATCH&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not just tidiness. It is part of how UCP avoids spoofing and keeps capability ownership clear.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Signing keys are missing
&lt;/h3&gt;

&lt;p&gt;This is one of the most important examples of a check teams incorrectly downgrade to a warning.&lt;/p&gt;

&lt;p&gt;In our Apr 1 scan, several C-grade profiles had a live manifest but were still missing signing keys, including allbirds.com, gymshark.com, kyliecosmetics.com, fashionnova.com, colourpop.com, brooklinen.com, and chubbiesshorts.com.&lt;/p&gt;

&lt;p&gt;Those stores are ahead of merchants with no manifest at all. But missing signing keys is still serious because UCP integrations rely on cryptographic verification for trust-sensitive flows like webhook verification.&lt;/p&gt;

&lt;p&gt;Related validator rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Minimal JWK example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"signing_keys"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"key-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"crv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"P-256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES256"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your team is deciding what fails CI and what only warns, this belongs in the fail bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should warn instead of fail
&lt;/h2&gt;

&lt;p&gt;Not every UCP issue should block a deploy.&lt;/p&gt;

&lt;p&gt;This is where teams overreact.&lt;/p&gt;

&lt;p&gt;Google's merchant guidance makes it clear that capabilities are merchant-selected. That means optional capability gaps should not automatically be treated the same way as discovery failures.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing optional capability coverage&lt;/li&gt;
&lt;li&gt;extension drift&lt;/li&gt;
&lt;li&gt;richer cart or catalog support not yet implemented&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those can be warnings.&lt;/p&gt;

&lt;p&gt;The validator should separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;discovery-critical blockers&lt;/li&gt;
&lt;li&gt;trust and endpoint correctness blockers&lt;/li&gt;
&lt;li&gt;optional capability drift&lt;/li&gt;
&lt;li&gt;non-UCP site quality hints such as Schema.org organization or return policy gaps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That severity split is the difference between a validator developers trust and a noisy checklist they ignore.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical CI workflow
&lt;/h2&gt;

&lt;p&gt;A good UCP validation job should do three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;return stable rule IDs&lt;/li&gt;
&lt;li&gt;print copy-paste repro commands&lt;/li&gt;
&lt;li&gt;emit machine-readable JSON for diffs and pull request checks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example shell step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://example.com/.well-known/ucp | jq &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_FETCH_FAILED&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_ENDPOINT_TRAILING_SLASH&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_MISSING_VERSION&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_INVALID_VERSION_FORMAT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_MISSING_ROOT&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_NS_ORIGIN_MISMATCH&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fail on &lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;warn on optional capability gaps&lt;/li&gt;
&lt;li&gt;warn on non-blocking metadata issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That keeps your build focused on what actually breaks discovery and callable commerce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where ACP fits
&lt;/h2&gt;

&lt;p&gt;ACP still matters.&lt;/p&gt;

&lt;p&gt;But only after discovery works.&lt;/p&gt;

&lt;p&gt;ACP is about delegated payment and ChatGPT-oriented commerce flows. It has its own requirements, such as checkout endpoints, product feeds, and payment handler readiness. It is a separate implementation track from hosting a correct UCP manifest for Google and other UCP agents.&lt;/p&gt;

&lt;p&gt;So if your team is debating whether to spend this sprint on Stripe delegated payment support or on fixing &lt;code&gt;/.well-known/ucp&lt;/code&gt;, the answer for most merchants is:&lt;/p&gt;

&lt;p&gt;Fix UCP discovery first.&lt;/p&gt;

&lt;p&gt;Payments headlines are louder.&lt;/p&gt;

&lt;p&gt;Discovery bugs are what actually keep you invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final takeaway
&lt;/h2&gt;

&lt;p&gt;Valid JSON is not the bar.&lt;/p&gt;

&lt;p&gt;Discoverable, trustworthy, callable UCP is the bar.&lt;/p&gt;

&lt;p&gt;The fastest way to improve merchant readiness is to stop treating discovery blockers like low-priority lint errors. If an agent cannot fetch your manifest, trust your keys, or call your endpoints over HTTPS, your store is not ready for agentic commerce.&lt;/p&gt;

&lt;p&gt;Fail those checks in CI.&lt;/p&gt;

&lt;p&gt;Everything else can come after.&lt;/p&gt;

</description>
      <category>agenticcommerce</category>
      <category>ucp</category>
      <category>ecommerce</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Valid JSON Valid UCP: 10 Checks That Should Fail Your Build</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 31 Mar 2026 16:08:40 +0000</pubDate>
      <link>https://dev.to/ucptools/valid-json-valid-ucp-10-checks-that-should-fail-your-build-d1e</link>
      <guid>https://dev.to/ucptools/valid-json-valid-ucp-10-checks-that-should-fail-your-build-d1e</guid>
      <description>&lt;p&gt;Your UCP manifest passes &lt;code&gt;JSON.parse()&lt;/code&gt;. Your linter is happy. But Google AI Mode, Gemini, and every other AI shopping agent that hits &lt;code&gt;/.well-known/ucp&lt;/code&gt; silently moves on to the next store.&lt;/p&gt;

&lt;p&gt;Why? Because &lt;strong&gt;valid JSON is not valid UCP&lt;/strong&gt;. The protocol has structural, security, and network requirements that go beyond syntax. Miss any of them, and you're invisible.&lt;/p&gt;

&lt;p&gt;This post covers the 10 checks that actually break AI agent discovery — not the optional capabilities you can safely skip. Each check includes its rule ID, what breaks, and a concrete fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Discovery Hierarchy
&lt;/h2&gt;

&lt;p&gt;When an AI agent visits your store, it follows a strict sequence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. FETCH  — Can I reach /.well-known/ucp over HTTPS?
2. PARSE  — Is the response valid UCP (not just valid JSON)?
3. VERIFY — Are endpoints reachable, schemas fetchable, keys present?
4. NEGOTIATE — Do our capabilities intersect?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fail at level 1, and nothing else matters. Fail at level 2, and the agent can't understand your profile. Levels 3 and 4 are where most subtle bugs hide.&lt;/p&gt;

&lt;p&gt;Google's own &lt;a href="https://developers.google.com/merchant/ucp" rel="noopener noreferrer"&gt;Merchant UCP guide&lt;/a&gt; says capabilities are opt-in: &lt;em&gt;"select the set of capabilities &amp;amp; extensions you want to support."&lt;/em&gt; Missing Cart or Catalog is fine. Missing a fetchable endpoint is fatal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 10 Discovery-Critical Checks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Level 1: Fetchable
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;code&gt;UCP_PROFILE_FETCH_FAILED&lt;/code&gt; — Manifest unreachable
&lt;/h4&gt;

&lt;p&gt;The single most common failure. The agent sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; https://yourstore.com/.well-known/ucp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this returns anything other than &lt;code&gt;200&lt;/code&gt; with &lt;code&gt;Content-Type: application/json&lt;/code&gt;, you're invisible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Common causes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CDN/reverse proxy strips &lt;code&gt;/.well-known/&lt;/code&gt; paths&lt;/li&gt;
&lt;li&gt;Squarespace/Wix can't serve arbitrary well-known paths natively&lt;/li&gt;
&lt;li&gt;Docker/nginx misconfiguration blocks the route&lt;/li&gt;
&lt;li&gt;SSL certificate issues (agents require valid HTTPS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Verify the path is routable in your web server config. For platforms that can't serve &lt;code&gt;/.well-known/&lt;/code&gt;, use &lt;a href="https://github.com/Shopify/ucp-proxy" rel="noopener noreferrer"&gt;Shopify's ucp-proxy&lt;/a&gt; or a Cloudflare Worker.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt; — HTTP endpoint in profile
&lt;/h4&gt;

&lt;p&gt;Every URL in your UCP profile must use HTTPS. No exceptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;BAD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://api.store.com/ucp"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GOOD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.store.com/ucp"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This applies to service endpoints, spec URLs, and schema URLs. Agents won't downgrade to HTTP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 2: Parseable
&lt;/h3&gt;

&lt;h4&gt;
  
  
  3. &lt;code&gt;UCP_MISSING_ROOT&lt;/code&gt; — No &lt;code&gt;ucp&lt;/code&gt; object
&lt;/h4&gt;

&lt;p&gt;The profile must have a root &lt;code&gt;ucp&lt;/code&gt; key. Serving raw capabilities without the wrapper object fails parsing immediately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;BAD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;looks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;right,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;isn't&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GOOD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;wrapped&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ucp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;object&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. &lt;code&gt;UCP_MISSING_VERSION&lt;/code&gt; / &lt;code&gt;UCP_INVALID_VERSION_FORMAT&lt;/code&gt; — Bad version
&lt;/h4&gt;

&lt;p&gt;UCP uses date-based versioning: &lt;code&gt;YYYY-MM-DD&lt;/code&gt;. Not semver. Not integers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;BAD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"January 2026"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GOOD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agents use the version to negotiate protocol compatibility. No version = no negotiation.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. &lt;code&gt;UCP_MISSING_SERVICES&lt;/code&gt; — No services object
&lt;/h4&gt;

&lt;p&gt;Services define your transport bindings (REST, MCP, A2A). Without them, the agent has no API to call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dev.ucp.shopping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"spec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/specification/shopping/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/services/shopping/rest.openapi.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://yourstore.com/api/ucp"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. &lt;code&gt;UCP_MISSING_CAPABILITIES&lt;/code&gt; — No capabilities array
&lt;/h4&gt;

&lt;p&gt;Capabilities tell the agent what your store supports (checkout, catalog, fulfillment). An empty or missing array means: "I support nothing."&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 3: Verifiable
&lt;/h3&gt;

&lt;h4&gt;
  
  
  7. &lt;code&gt;UCP_NS_ORIGIN_MISMATCH&lt;/code&gt; — Schema URL spoofing
&lt;/h4&gt;

&lt;p&gt;This is a security check. UCP uses reverse-domain naming (&lt;code&gt;dev.ucp.shopping.checkout&lt;/code&gt;), and the spec/schema URLs must match the namespace authority.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;BAD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;capability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;claims&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;dev.ucp.*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;schema&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;random&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;domain&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://evil.com/fake-checkout.json"&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;FAILS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GOOD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;dev.ucp.*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;schemas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;come&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ucp.dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/shopping/checkout.json"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents a store from claiming official UCP capabilities while pointing to modified schemas.&lt;/p&gt;

&lt;h4&gt;
  
  
  8. &lt;code&gt;UCP_ORPHANED_EXTENSION&lt;/code&gt; — Extension without parent
&lt;/h4&gt;

&lt;p&gt;Extensions like Fulfillment or Discount must reference a parent capability via &lt;code&gt;extends&lt;/code&gt;. If the parent isn't in your capabilities array, the extension is orphaned and gets pruned during negotiation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;BAD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fulfillment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;checkout,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;checkout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;isn't&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;listed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.fulfillment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GOOD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;parent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;capability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;present&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.fulfillment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  9. &lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt; — No webhook verification keys
&lt;/h4&gt;

&lt;p&gt;UCP requires JWK public keys for webhook signature verification. Without them, the agent can't trust your store's callbacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"signing_keys"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"key-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"crv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"P-256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"f83OJ3D2xF1Bg8vub9tLe1gH..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"x_FEzRu9m36HLN_tue659LNp..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES256"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate a key pair with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @ucptools/validator generate-keys &lt;span class="nt"&gt;--algorithm&lt;/span&gt; ES256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  10. &lt;code&gt;UCP_ENDPOINT_TRAILING_SLASH&lt;/code&gt; — Trailing slash in URL
&lt;/h4&gt;

&lt;p&gt;Small but real. Trailing slashes in endpoint URLs cause path resolution bugs when agents append checkout paths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;BAD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.store.com/ucp/"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GOOD&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.store.com/ucp"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What About Cart, Catalog, and Identity Linking?
&lt;/h2&gt;

&lt;p&gt;Cart and Catalog are &lt;strong&gt;draft&lt;/strong&gt; specs (published March 19, 2026). Identity Linking is stable. But none of them are discovery-critical.&lt;/p&gt;

&lt;p&gt;Google's guide is explicit: capabilities are opt-in. A valid UCP profile with only Checkout is fully functional for AI agent commerce. Your validator should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Error&lt;/strong&gt; on the 10 checks above — these break discovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warn&lt;/strong&gt; on Cart/Catalog schema drift — draft specs change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error&lt;/strong&gt; on Identity Linking config issues — stable spec, strict validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignore&lt;/strong&gt; missing optional capabilities — not a failure&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running These Checks in CI
&lt;/h2&gt;

&lt;p&gt;Install the validator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @ucptools/validator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validate in your build pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateProfile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ucptools/validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.well-known/ucp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UCP validation failed:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;issues&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;severity&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or validate a live domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @ucptools/validator validate &lt;span class="nt"&gt;--url&lt;/span&gt; yourstore.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each issue comes with a rule ID (like &lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt;), a JSON path (like &lt;code&gt;$.ucp.services.dev.ucp.shopping.rest.endpoint&lt;/code&gt;), and a fix hint. Designed for CI output, not just dashboards.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A GitHub Action wrapper (&lt;code&gt;ucptools/validate-action@v1&lt;/code&gt;) is coming this week — validate on every PR, fail on discovery-critical errors, post results as PR comments.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Rule ID&lt;/th&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;What Breaks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manifest unreachable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_PROFILE_FETCH_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetch&lt;/td&gt;
&lt;td&gt;Everything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP endpoint&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetch&lt;/td&gt;
&lt;td&gt;Agent refuses connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No &lt;code&gt;ucp&lt;/code&gt; root object&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_MISSING_ROOT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Parse&lt;/td&gt;
&lt;td&gt;Profile unparseable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bad version format&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_INVALID_VERSION_FORMAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Parse&lt;/td&gt;
&lt;td&gt;No negotiation possible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No services&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_MISSING_SERVICES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Parse&lt;/td&gt;
&lt;td&gt;No API to call&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No capabilities&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_MISSING_CAPABILITIES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Parse&lt;/td&gt;
&lt;td&gt;"Store supports nothing"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schema origin mismatch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_NS_ORIGIN_MISMATCH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify&lt;/td&gt;
&lt;td&gt;Security rejection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orphaned extension&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_ORPHANED_EXTENSION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify&lt;/td&gt;
&lt;td&gt;Extension silently pruned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing signing keys&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify&lt;/td&gt;
&lt;td&gt;Webhooks untrusted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trailing slash&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UCP_ENDPOINT_TRAILING_SLASH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify&lt;/td&gt;
&lt;td&gt;Path resolution bugs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Capabilities are opt-in. Discovery is not.&lt;/p&gt;




&lt;p&gt;Free validation at &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt;. npm package: &lt;a href="https://www.npmjs.com/package/@ucptools/validator" rel="noopener noreferrer"&gt;&lt;code&gt;@ucptools/validator&lt;/code&gt;&lt;/a&gt;. CLI, API, and CI integration included.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ecommerce</category>
      <category>ai</category>
      <category>ucp</category>
    </item>
    <item>
      <title>How to Check Polish Company Insolvency Programmatically (KRZ Scraper)</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 31 Mar 2026 09:24:13 +0000</pubDate>
      <link>https://dev.to/ucptools/how-to-check-polish-company-insolvency-programmatically-krz-scraper-1m9h</link>
      <guid>https://dev.to/ucptools/how-to-check-polish-company-insolvency-programmatically-krz-scraper-1m9h</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Poland's &lt;strong&gt;KRZ (Krajowy Rejestr Zadluzonych)&lt;/strong&gt; tracks all bankruptcy, restructuring, and enforcement proceedings&lt;/li&gt;
&lt;li&gt;The government has &lt;strong&gt;never released a public API&lt;/strong&gt; despite 4+ years of promises&lt;/li&gt;
&lt;li&gt;The only alternatives are &lt;strong&gt;manual web searches&lt;/strong&gt; or &lt;strong&gt;MGBI's paid subscription&lt;/strong&gt; (200-500 EUR/month)&lt;/li&gt;
&lt;li&gt;I built an &lt;a href="https://apify.com/minute_contest/krz-debtor-scraper" rel="noopener noreferrer"&gt;Apify actor&lt;/a&gt; that captures a JWT token from the portal and calls the internal REST API directly - giving you structured JSON for $0.05/entity check&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;If you work in credit risk, compliance, or debt collection in Poland, you need to check the KRZ constantly. Is this company in bankruptcy? Has restructuring been filed? Are there enforcement proceedings?&lt;/p&gt;

&lt;p&gt;The government portal at &lt;a href="https://krz.ms.gov.pl" rel="noopener noreferrer"&gt;krz.ms.gov.pl&lt;/a&gt; lets you search manually - one company at a time, through a slow AngularJS interface. There's no API, no bulk export, no way to automate it.&lt;/p&gt;

&lt;p&gt;The only commercial provider, &lt;a href="https://mgbi.pl" rel="noopener noreferrer"&gt;MGBI&lt;/a&gt;, charges 200-500 EUR/month for API access. Great for banks, overkill for everyone else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;The KRZ portal is a Single Page Application that loads Angular sub-apps in iframes. These sub-apps talk to REST APIs on the government's OpenShift backend. The APIs require a JWT token that's issued during app initialization.&lt;/p&gt;

&lt;p&gt;My actor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Launches a headless browser via Puppeteer&lt;/li&gt;
&lt;li&gt;Loads the KRZ portal and triggers the Angular sub-app&lt;/li&gt;
&lt;li&gt;Captures the JWT token from the sub-app's first API request&lt;/li&gt;
&lt;li&gt;Uses the JWT to call the REST API directly - no DOM interaction, no fragile selectors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result: structured JSON from 9 different search endpoints, covering everything the KRZ portal offers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Can Search
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Search Mode&lt;/th&gt;
&lt;th&gt;What It Finds&lt;/th&gt;
&lt;th&gt;Example Input&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;entity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Companies with proceedings&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"entityName": "Getin"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;person&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Natural persons by PESEL/NIP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"identifier": "12345678901"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;soleTrader&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sole traders (JDG)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"entityName": "Uslugi budowlane"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;signature&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;By court case signature&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"caseSignature": "WA1M/GUp/44/2023"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;announcements&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Court notices and rulings&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"entityName": "Getin", "dateFrom": "2024-01-01"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shareholders&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Partners in personal companies&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"identifier": "0000585174"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;advisors&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restructuring advisors&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"entityName": "Nowak"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;proceedingDetails&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Full case deep-dive&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{"proceedingId": "uuid-from-search"}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Step-by-Step: Check 100 Companies in 10 Minutes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a free Apify account
&lt;/h3&gt;

&lt;p&gt;Go to &lt;a href="https://apify.com" rel="noopener noreferrer"&gt;apify.com&lt;/a&gt; and sign up. You get $5 in free credits - enough for about 70 company checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Navigate to the actor
&lt;/h3&gt;

&lt;p&gt;Open the &lt;a href="https://apify.com/minute_contest/krz-debtor-scraper" rel="noopener noreferrer"&gt;KRZ Debtor Registry Scraper&lt;/a&gt; in the Apify Store.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Configure your input
&lt;/h3&gt;

&lt;p&gt;For a single company check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"searchMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"entity"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entityName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Getin Noble Bank"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxResults"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a batch check by KRS numbers, use the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApifyClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apify-client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;krsNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0000585174&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0000028860&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0000635012&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;krs&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;krsNumbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minute_contest/krz-debtor-scraper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;searchMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;entity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;krs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;maxResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;listItems&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`KRS &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;krs&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; proceedings found`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Read the results
&lt;/h3&gt;

&lt;p&gt;Each result includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entityName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GETIN RENT SPOLKA Z OGRANICZONA ODPOWIEDZIALNOSCIA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8992777278"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"krs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0000585174"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"proceedingId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"96dd6ffc-191c-41ce-bcc4-998524e4efd2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"proceedingType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"restructuring"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"court"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sad Rejonowy dla Wroclawia-Fabrycznej we Wroclawiu"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Deep-dive into a specific proceeding
&lt;/h3&gt;

&lt;p&gt;Take the &lt;code&gt;proceedingId&lt;/code&gt; from step 4 and get full details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"searchMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"proceedingDetails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"proceedingId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"96dd6ffc-191c-41ce-bcc4-998524e4efd2"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns: case signature, court, start/end dates, all participants, judge history, advisor assignments, address history, and all announcements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Volume&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;vs MGBI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 company&lt;/td&gt;
&lt;td&gt;$0.15&lt;/td&gt;
&lt;td&gt;Free trial vs 200 EUR/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100 companies&lt;/td&gt;
&lt;td&gt;$5.10&lt;/td&gt;
&lt;td&gt;30x cheaper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000 companies/month&lt;/td&gt;
&lt;td&gt;$50&lt;/td&gt;
&lt;td&gt;3-7x cheaper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10,000 companies/month&lt;/td&gt;
&lt;td&gt;$300 (GOLD tier)&lt;/td&gt;
&lt;td&gt;Comparable, no contract&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Part of the Polish Business Data Suite
&lt;/h2&gt;

&lt;p&gt;This actor is one of five covering Polish government registries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://apify.com/minute_contest/poland-krs-financial-scraper" rel="noopener noreferrer"&gt;eKRS Financial Statements&lt;/a&gt;&lt;/strong&gt; - Balance sheets and income statements from KRS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://apify.com/minute_contest/krs-fullnames-scraper" rel="noopener noreferrer"&gt;KRS Board Members&lt;/a&gt;&lt;/strong&gt; - Full (non-anonymized) director names&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://apify.com/minute_contest/knf-registry-scraper" rel="noopener noreferrer"&gt;KNF Financial Registry&lt;/a&gt;&lt;/strong&gt; - Payment institutions, credit intermediaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://apify.com/minute_contest/msig-scraper" rel="noopener noreferrer"&gt;MSiG Court Gazette&lt;/a&gt;&lt;/strong&gt; - Bankruptcy and liquidation announcements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://apify.com/minute_contest/krz-debtor-scraper" rel="noopener noreferrer"&gt;KRZ Debtor Registry&lt;/a&gt;&lt;/strong&gt; - Insolvency and restructuring proceedings (this actor)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they give you a complete Polish company intelligence workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is the company solvent?       -&amp;gt; KRZ
Any court proceedings?        -&amp;gt; MSiG
What's their financial health -&amp;gt; eKRS
Who runs the company?         -&amp;gt; KRS Board Members
Are they properly licensed?   -&amp;gt; KNF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Technical Details
&lt;/h2&gt;

&lt;p&gt;For those interested in how the reverse engineering works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Architecture discovery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The KRZ portal (&lt;code&gt;krz.ms.gov.pl&lt;/code&gt;) is an AngularJS shell that loads Angular sub-apps via iframes from OpenShift backends (&lt;code&gt;krz-rejpub-gui-krz-pub-prod.apps.ocp.prod.ms.gov.pl&lt;/code&gt;). Each module (entity search, announcements, advisors) is a separate Angular app on the same OpenShift cluster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. JWT capture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The sub-app obtains a JWT during initialization. We intercept it from the &lt;code&gt;Authorization: bearer ...&lt;/code&gt; header on the first API request using Puppeteer's request interception. The JWT is valid for about 30 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. API endpoints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;30+ REST endpoints discovered by searching the Angular bundle's compiled JavaScript for URL patterns matching &lt;code&gt;krzPubApiUrl + "..."&lt;/code&gt;. Key endpoints include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;postepowanie/wyszukaj-po-podmiocie&lt;/code&gt; - entity search&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;postepowanie/wyszukaj-po-of&lt;/code&gt; - person search&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;obwieszczenie/wyszukaj-po-podmiocie&lt;/code&gt; - announcements&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;postepowanie/szczegoly&lt;/code&gt; - proceeding details&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rdr-api/wyszukiwarka/doradcy&lt;/code&gt; - restructuring advisors (different backend)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. No DOM scraping&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After JWT capture, all data comes from direct HTTP calls. The browser is closed. This makes the actor fast (~1s per query after session setup) and resilient to UI changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The encryption keys&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The KRS board members portal (separate project) uses AES-128-CBC encryption with a static key &lt;code&gt;TopSecretApiKey1&lt;/code&gt; and a 512-character steganographic token that embeds the KRS number at specific array positions. Yes, the key is literally hardcoded in the frontend JavaScript.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://apify.com" rel="noopener noreferrer"&gt;Apify&lt;/a&gt;. Questions? Open an issue on the &lt;a href="https://apify.com/minute_contest/krz-debtor-scraper" rel="noopener noreferrer"&gt;actor page&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>api</category>
    </item>
    <item>
      <title>ClickUp + MCP: the practical setup + 5 automation patterns (Claude Desktop / ChatGPT / n8n)</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Fri, 27 Mar 2026 13:50:54 +0000</pubDate>
      <link>https://dev.to/ucptools/clickup-mcp-the-practical-setup-5-automation-patterns-claude-desktop-chatgpt-n8n-34l</link>
      <guid>https://dev.to/ucptools/clickup-mcp-the-practical-setup-5-automation-patterns-claude-desktop-chatgpt-n8n-34l</guid>
      <description>&lt;p&gt;ClickUp is one of those tools that feels like it should be perfect for AI agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tasks are structured&lt;/li&gt;
&lt;li&gt;work is already in lists/spaces&lt;/li&gt;
&lt;li&gt;there's a clear "read → decide → update" loop&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But most "AI + ClickUp" integrations I see fall into two buckets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Chat-only&lt;/strong&gt;: the model can talk about tasks but can't actually change anything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fragile automations&lt;/strong&gt;: one webhook + one action; no real planning loop.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want an agent that can inspect work, make a plan, and apply changes (create tasks, update statuses, move between lists, write docs, etc.), MCP is a good fit.&lt;/p&gt;

&lt;p&gt;This post is a developer-focused walkthrough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how to connect a ClickUp MCP server to an MCP client (Claude Desktop / ChatGPT / n8n)&lt;/li&gt;
&lt;li&gt;what auth scopes you actually need&lt;/li&gt;
&lt;li&gt;5 workflows that are worth automating&lt;/li&gt;
&lt;li&gt;common failure modes (timeouts, tool naming collisions, rate limits)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I packaged a ClickUp MCP Server on Apify, so you don't need to run a local MCP process:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://apify.com/minute_contest/clickup-mcp-server" rel="noopener noreferrer"&gt;ClickUp MCP Server on Apify&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It exposes &lt;strong&gt;20 tools&lt;/strong&gt; (not just tasks): spaces, folders, lists, views, and docs.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you need before you start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) A ClickUp personal token
&lt;/h3&gt;

&lt;p&gt;In ClickUp: &lt;strong&gt;Settings → Apps → API Token&lt;/strong&gt; (wording varies by plan/UI).&lt;/p&gt;

&lt;p&gt;Treat it like a password.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) IDs you'll use a lot
&lt;/h3&gt;

&lt;p&gt;Most of your flows will start by locating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;team_id&lt;/code&gt; (workspace)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;space_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;folder_id&lt;/code&gt; (optional)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;list_id&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good MCP setup gives the model tools to discover these, instead of hardcoding them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Option A: Use a hosted MCP server (no local Node process)
&lt;/h2&gt;

&lt;p&gt;If your MCP client supports connecting to a remote MCP endpoint (SSE), a hosted server avoids the "my local server died" class of problems.&lt;/p&gt;

&lt;p&gt;The Apify actor runs in &lt;strong&gt;Standby mode&lt;/strong&gt; (persistent server) and &lt;strong&gt;Batch mode&lt;/strong&gt; (one-shot runs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actor page:&lt;/strong&gt; &lt;a href="https://apify.com/minute_contest/clickup-mcp-server" rel="noopener noreferrer"&gt;apify.com/minute_contest/clickup-mcp-server&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; MCP client configuration differs across Claude Desktop / Cursor / ChatGPT / n8n. The principle is the same: register the server, provide auth secrets, then let the client call tools.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Option B: n8n pattern (agent-in-the-middle)
&lt;/h2&gt;

&lt;p&gt;If you're already using n8n, one solid pattern is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;n8n receives a trigger (Cron / webhook / Slack)&lt;/li&gt;
&lt;li&gt;n8n calls your LLM (planning step)&lt;/li&gt;
&lt;li&gt;the LLM calls MCP tools to read/write ClickUp&lt;/li&gt;
&lt;li&gt;n8n posts results somewhere (Slack / email)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why this works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n8n is great at deterministic orchestration&lt;/li&gt;
&lt;li&gt;the model is great at decisions and text generation&lt;/li&gt;
&lt;li&gt;MCP tools provide the side effects (ClickUp writes)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5 ClickUp workflows that are actually worth automating
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Triage new tasks into the right list + fill missing fields
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; People dump tasks into an "Inbox" list with no priority, no owner, vague title.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent loop:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read newest tasks in Inbox&lt;/li&gt;
&lt;li&gt;classify by project&lt;/li&gt;
&lt;li&gt;set priority, assignees, due date&lt;/li&gt;
&lt;li&gt;move to the correct list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MCP tools you'll use:&lt;/strong&gt; &lt;code&gt;list tasks&lt;/code&gt; → &lt;code&gt;update task&lt;/code&gt; → &lt;code&gt;move task&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Keep a "classification rubric" in a ClickUp Doc so the model can read it and stay consistent.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  2) Daily standup summary from "In Progress"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Standups become status theater.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent loop:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pull tasks in relevant lists filtered by status&lt;/li&gt;
&lt;li&gt;summarize by assignee&lt;/li&gt;
&lt;li&gt;detect blockers (stale tasks, no updates)&lt;/li&gt;
&lt;li&gt;post to Slack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MCP tools:&lt;/strong&gt; &lt;code&gt;list tasks&lt;/code&gt; + &lt;code&gt;read task details&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  3) Convert meeting notes into tasks + link to the notes doc
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Action items die in Google Docs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent loop:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;watch a "Meeting notes" doc (or paste notes)&lt;/li&gt;
&lt;li&gt;extract action items&lt;/li&gt;
&lt;li&gt;create tasks in the right list&lt;/li&gt;
&lt;li&gt;link back to the doc section&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MCP tools:&lt;/strong&gt; &lt;code&gt;create tasks&lt;/code&gt; + &lt;code&gt;create/update docs&lt;/code&gt; (if you keep notes in ClickUp Docs)&lt;/p&gt;




&lt;h3&gt;
  
  
  4) "Release checklist" generator per project
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Every release repeats the same 30 steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent loop:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read project type (web app / mobile / infra)&lt;/li&gt;
&lt;li&gt;generate a checklist as subtasks&lt;/li&gt;
&lt;li&gt;attach standard QA template&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MCP tools:&lt;/strong&gt; &lt;code&gt;create task&lt;/code&gt; + &lt;code&gt;create subtasks&lt;/code&gt; + &lt;code&gt;update description&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  5) Weekly cleanup: stale tasks + duplicate detection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; ClickUp accumulates zombie tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent loop:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find tasks with no activity in N days&lt;/li&gt;
&lt;li&gt;mark as "Needs review"&lt;/li&gt;
&lt;li&gt;detect near-duplicates (same title, same list)&lt;/li&gt;
&lt;li&gt;propose merges or close-outs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MCP tools:&lt;/strong&gt; &lt;code&gt;search/list&lt;/code&gt; + &lt;code&gt;update&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Common MCP failure modes (and how to debug fast)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Tool collisions (multiple MCP servers enabled)
&lt;/h3&gt;

&lt;p&gt;Some MCP clients have had issues where tools from one server get mis-routed when many servers are enabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debug:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;temporarily disable other MCP servers&lt;/li&gt;
&lt;li&gt;restart the client&lt;/li&gt;
&lt;li&gt;confirm the tool list shows ClickUp tools with consistent prefixes/names&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2) Timeouts on "big list" queries
&lt;/h3&gt;

&lt;p&gt;If you ask for "all tasks in a busy space", you'll hit client timeouts or API pagination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fetch by list, not entire space&lt;/li&gt;
&lt;li&gt;constrain by updated date&lt;/li&gt;
&lt;li&gt;paginate&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3) Rate limits
&lt;/h3&gt;

&lt;p&gt;ClickUp APIs will throttle you if you hammer endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;batch reads&lt;/li&gt;
&lt;li&gt;cache IDs (team/space/list)&lt;/li&gt;
&lt;li&gt;add backoff / retry in your orchestration layer (n8n or your agent runtime)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When MCP is overkill
&lt;/h2&gt;

&lt;p&gt;Honest take: if your use case is "create a task when a form is submitted", you don't need MCP. A standard automation tool is simpler.&lt;/p&gt;

&lt;p&gt;MCP becomes valuable when you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;interactive exploration&lt;/strong&gt; (agent discovers IDs, lists, docs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;multi-step edits&lt;/strong&gt; (read → decide → write)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;structured side effects&lt;/strong&gt; (no brittle UI automation)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try it / poke holes in it
&lt;/h2&gt;

&lt;p&gt;If you're building agentic workflows on top of ClickUp, I'd love to see what patterns you're using.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actor (hosted ClickUp MCP server):&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://apify.com/minute_contest/clickup-mcp-server" rel="noopener noreferrer"&gt;apify.com/minute_contest/clickup-mcp-server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want, reply with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your ClickUp structure (spaces/lists)&lt;/li&gt;
&lt;li&gt;one painful workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...and I'll suggest a minimal MCP tool-call plan.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>productivity</category>
      <category>automation</category>
    </item>
    <item>
      <title>UCP Cart, Catalog, and Identity Linking: What to Validate (and What Can Wait)</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Wed, 25 Mar 2026 07:28:47 +0000</pubDate>
      <link>https://dev.to/ucptools/ucp-cart-catalog-and-identity-linking-what-to-validate-and-what-can-wait-2ja4</link>
      <guid>https://dev.to/ucptools/ucp-cart-catalog-and-identity-linking-what-to-validate-and-what-can-wait-2ja4</guid>
      <description>&lt;p&gt;Google shipped the first major UCP update on March 19, 2026 - three new capabilities: &lt;strong&gt;Cart&lt;/strong&gt;, &lt;strong&gt;Catalog&lt;/strong&gt;, and &lt;strong&gt;Identity Linking&lt;/strong&gt;. If you're a merchant or platform developer implementing UCP, you now have more to validate.&lt;/p&gt;

&lt;p&gt;But here's the thing most guides won't tell you: &lt;strong&gt;not all three capabilities have the same stability level.&lt;/strong&gt; Cart and Catalog are draft specs. Identity Linking is stable. Treating them the same way in your validation pipeline is a mistake.&lt;/p&gt;

&lt;p&gt;This post breaks down what changed, what to validate strictly, what to treat as warnings, and provides a minimal checklist for keeping your &lt;code&gt;/.well-known/ucp&lt;/code&gt; profile working.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed on March 19
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Namespace&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cart&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dev.ucp.shopping.cart&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Draft&lt;/td&gt;
&lt;td&gt;Multi-item basket management before checkout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Catalog Search&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dev.ucp.shopping.catalog.search&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Draft&lt;/td&gt;
&lt;td&gt;Product search by keyword, category, attributes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Catalog Lookup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dev.ucp.shopping.catalog.lookup&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Draft&lt;/td&gt;
&lt;td&gt;Direct product lookup by ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Identity Linking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dev.ucp.common.identity_linking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stable&lt;/td&gt;
&lt;td&gt;OAuth 2.0 account linking via RFC 8414 discovery&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cart and Catalog are published under &lt;code&gt;ucp.dev/draft/specification/&lt;/code&gt; - note the &lt;code&gt;/draft/&lt;/code&gt; path. Identity Linking shipped in the stable spec at launch in January.&lt;/p&gt;

&lt;p&gt;This distinction matters for validation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Draft vs Stable: Why Your Validator Needs to Know
&lt;/h2&gt;

&lt;p&gt;If you hard-fail on a draft capability's schema mismatch, you'll generate noise. Draft specs change. That's the point of a draft.&lt;/p&gt;

&lt;p&gt;If you silently pass a broken &lt;code&gt;/.well-known/ucp&lt;/code&gt; endpoint, you'll miss the errors that actually prevent AI agents from discovering your store.&lt;/p&gt;

&lt;p&gt;The right approach: &lt;strong&gt;severity-aware validation.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stable capabilities  -&amp;gt; errors on failure
Draft capabilities   -&amp;gt; warnings on failure
Discovery blockers   -&amp;gt; always errors, regardless of capability status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a concrete example. Say a merchant adds Cart support but uses an outdated schema URL that doesn't match the current draft:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.cart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"spec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/draft/specification/cart/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/shopping/cart.json"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should your validator fail this? &lt;strong&gt;No - warn.&lt;/strong&gt; The schema URL might be temporarily ahead of or behind the draft. The capability is structurally valid. The merchant is doing the right thing by declaring Cart support early.&lt;/p&gt;

&lt;p&gt;But if that same profile is missing signing keys entirely? &lt;strong&gt;That's an error.&lt;/strong&gt; No agent can trust the merchant without them, draft or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cart Capability: What to Validate
&lt;/h2&gt;

&lt;p&gt;Cart (&lt;code&gt;dev.ucp.shopping.cart&lt;/code&gt;) supports four operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create Cart&lt;/strong&gt; - initialize a basket with line items&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get Cart&lt;/strong&gt; - retrieve current cart state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update Cart&lt;/strong&gt; - full replacement of cart contents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cancel Cart&lt;/strong&gt; - terminate the session&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Required Fields in Cart Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-15"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cart_abc123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"line_items"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"li_1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"item"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Blue Widget"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"29.99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"totals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"subtotal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"59.98"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"totals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"subtotal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"59.98"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validation Checklist for Cart
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Capability declared with correct namespace &lt;code&gt;dev.ucp.shopping.cart&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Version follows YYYY-MM-DD format&lt;/li&gt;
&lt;li&gt;[ ] Spec URL points to draft path (&lt;code&gt;ucp.dev/draft/specification/cart/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] If REST binding: endpoint is HTTPS, no trailing slash&lt;/li&gt;
&lt;li&gt;[ ] Cart-to-checkout conversion: if Checkout capability is also declared, verify &lt;code&gt;cart_id&lt;/code&gt; can be passed to Create Checkout&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Severity: WARN&lt;/strong&gt; on schema drift (draft spec may change)&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Severity: ERROR&lt;/strong&gt; on missing required fields (&lt;code&gt;id&lt;/code&gt;, &lt;code&gt;line_items&lt;/code&gt;, &lt;code&gt;currency&lt;/code&gt;, &lt;code&gt;totals&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cart-to-Checkout Conversion
&lt;/h3&gt;

&lt;p&gt;A key detail from the spec: when Cart is negotiated alongside Checkout, platforms convert carts to checkout sessions by passing &lt;code&gt;cart_id&lt;/code&gt; in the Create Checkout request. The spec requires idempotency - if an incomplete checkout already exists for that &lt;code&gt;cart_id&lt;/code&gt;, the business must return the existing session.&lt;/p&gt;

&lt;p&gt;This is worth testing if you support both capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Catalog Capabilities: What to Validate
&lt;/h2&gt;

&lt;p&gt;Per the official spec, Catalog is split into &lt;strong&gt;two sub-capabilities&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catalog Search&lt;/strong&gt; (&lt;code&gt;dev.ucp.shopping.catalog.search&lt;/code&gt;) - agents query by keyword, category, or attributes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catalog Lookup&lt;/strong&gt; (&lt;code&gt;dev.ucp.shopping.catalog.lookup&lt;/code&gt;) - agents fetch specific products by ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each has its own schema: &lt;code&gt;catalog_search.json&lt;/code&gt; and &lt;code&gt;catalog_lookup.json&lt;/code&gt;. The value is real-time data - agents check live inventory, current pricing, and variant availability instead of relying on static product feeds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation Checklist for Catalog
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Capabilities declared with correct namespaces (&lt;code&gt;...catalog.search&lt;/code&gt; and/or &lt;code&gt;...catalog.lookup&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Spec URL points to draft path (&lt;code&gt;ucp.dev/draft/specification/catalog/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Schemas point to correct files (&lt;code&gt;catalog_search.json&lt;/code&gt; / &lt;code&gt;catalog_lookup.json&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Endpoint responds with valid product data (not HTML error pages)&lt;/li&gt;
&lt;li&gt;[ ] Product fields include required: &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;price_range&lt;/code&gt;, &lt;code&gt;variants&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Variant price uses minor currency units + ISO 4217 currency code&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Severity: WARN&lt;/strong&gt; on schema drift&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Severity: ERROR&lt;/strong&gt; on unreachable endpoint or non-JSON response&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Identity Linking: What to Validate
&lt;/h2&gt;

&lt;p&gt;Unlike Cart and Catalog, Identity Linking is &lt;strong&gt;stable&lt;/strong&gt;. It was part of the UCP spec at launch. Validate strictly.&lt;/p&gt;

&lt;p&gt;Identity Linking uses namespace &lt;code&gt;dev.ucp.common.identity_linking&lt;/code&gt; - note the &lt;code&gt;common&lt;/code&gt; service, not &lt;code&gt;shopping&lt;/code&gt;. It's declared as a &lt;strong&gt;capability&lt;/strong&gt; in the capabilities array with a &lt;code&gt;config&lt;/code&gt; object containing &lt;code&gt;supported_mechanisms&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The mechanism uses OAuth 2.0 with RFC 8414 discovery - you declare an &lt;code&gt;issuer&lt;/code&gt; URI, and OAuth endpoints are discovered automatically via &lt;code&gt;/.well-known/oauth-authorization-server&lt;/code&gt;. You do NOT put &lt;code&gt;authorization_endpoint&lt;/code&gt; or &lt;code&gt;token_endpoint&lt;/code&gt; directly in the profile.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation Checklist for Identity Linking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Capability declared with namespace &lt;code&gt;dev.ucp.common.identity_linking&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;config.supported_mechanisms&lt;/code&gt; array has at least one entry&lt;/li&gt;
&lt;li&gt;[ ] Each mechanism has a &lt;code&gt;type&lt;/code&gt; field (currently only &lt;code&gt;"oauth2"&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] OAuth2 mechanism has an &lt;code&gt;issuer&lt;/code&gt; URI using HTTPS&lt;/li&gt;
&lt;li&gt;[ ] Issuer supports RFC 8414 discovery&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Severity: ERROR&lt;/strong&gt; on all failures (stable spec)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The 7 Rules That Actually Break Discovery
&lt;/h2&gt;

&lt;p&gt;Before worrying about Cart, Catalog, or Identity Linking, make sure the basics work. These are the validation failures that prevent AI agents from discovering your store at all:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Missing or malformed &lt;code&gt;/.well-known/ucp&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP_MISSING_ROOT&lt;/span&gt;
&lt;span class="py"&gt;Fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;Serve a valid JSON object with a "ucp" property at /.well-known/ucp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this fails, nothing else matters. The agent can't find you.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Missing or invalid version
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP_MISSING_VERSION / UCP_INVALID_VERSION_FORMAT&lt;/span&gt;
&lt;span class="py"&gt;Fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;Add "version": "2026-01-11" (YYYY-MM-DD format, not semver)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common mistake: using &lt;code&gt;"1.0"&lt;/code&gt; instead of a date string.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. HTTP endpoints (not HTTPS)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/span&gt;
&lt;span class="py"&gt;Fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;All endpoint URLs must use https://&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exceptions. HTTP endpoints are rejected by conformant agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Trailing slashes on endpoints
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP_ENDPOINT_TRAILING_SLASH&lt;/span&gt;
&lt;span class="py"&gt;Fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;https://example.com/api/ucp (not https://example.com/api/ucp/)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Subtle but real. Some web servers handle this fine. The spec says no trailing slash.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Namespace/origin mismatch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP_NS_ORIGIN_MISMATCH&lt;/span&gt;
&lt;span class="py"&gt;Fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;Schema URLs must match the namespace authority&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your capability uses the &lt;code&gt;dev.ucp.*&lt;/code&gt; namespace, schema URLs must come from &lt;code&gt;ucp.dev&lt;/code&gt;. Vendor capabilities must use their own domain. This prevents spoofing.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Orphaned extensions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP_ORPHANED_EXTENSION&lt;/span&gt;
&lt;span class="py"&gt;Fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;Every extension needs its parent capability declared&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you declare &lt;code&gt;dev.ucp.shopping.fulfillment&lt;/code&gt; (an extension of Checkout) but don't declare &lt;code&gt;dev.ucp.shopping.checkout&lt;/code&gt;, agents will prune the extension during capability negotiation. It's dead weight.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Missing signing keys
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;UCP_MISSING_SIGNING_KEYS&lt;/span&gt;
&lt;span class="py"&gt;Fix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;Add JWK public keys in the signing_keys array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"signing_keys"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"key-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"kty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"crv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"P-256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"y"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES256"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without signing keys, webhook verification fails. Agents can't trust your responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting It Together: A Severity Matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/.well-known/ucp&lt;/code&gt; serves valid JSON&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Discovery completely blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version is valid YYYY-MM-DD&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Agent can't negotiate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;All endpoints HTTPS&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Spec requirement, agents reject HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No trailing slashes&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Spec requirement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace/origin match&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Security - prevents spoofing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signing keys present&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Webhook trust broken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No orphaned extensions&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Extensions pruned, wasted config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cart schema matches draft&lt;/td&gt;
&lt;td&gt;WARN&lt;/td&gt;
&lt;td&gt;Draft spec, may change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Catalog Search/Lookup schema matches draft&lt;/td&gt;
&lt;td&gt;WARN&lt;/td&gt;
&lt;td&gt;Draft spec, may change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity Linking has valid mechanisms&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Stable spec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity Linking issuer is HTTPS&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Stable spec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cart endpoint returns valid JSON&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Unreachable = broken&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Catalog endpoint returns valid JSON&lt;/td&gt;
&lt;td&gt;ERROR&lt;/td&gt;
&lt;td&gt;Unreachable = broken&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The pattern: &lt;strong&gt;structure and reachability are always errors. Schema conformance on draft specs is a warning.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD Integration
&lt;/h2&gt;

&lt;p&gt;If you're validating UCP profiles in CI, here's what a validation-as-diff output looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx ucptools validate https://example.com/.well-known/ucp

 PASS  Structural validation
 PASS  Version format &lt;span class="o"&gt;(&lt;/span&gt;2026-01-11&lt;span class="o"&gt;)&lt;/span&gt;
 FAIL  UCP_ENDPOINT_NOT_HTTPS
       Path: &lt;span class="nv"&gt;$.&lt;/span&gt;ucp.services.dev.ucp.shopping.rest.endpoint
       Found: http://example.com/api/ucp
       Fix: Change to https://example.com/api/ucp

 FAIL  UCP_MISSING_SIGNING_KEYS
       Path: &lt;span class="nv"&gt;$.&lt;/span&gt;signing_keys
       Fix: Add at least one JWK public key &lt;span class="o"&gt;(&lt;/span&gt;Ed25519 or ES256&lt;span class="o"&gt;)&lt;/span&gt;

 WARN  Cart schema URL may not match current draft
       Path: &lt;span class="nv"&gt;$.&lt;/span&gt;ucp.capabilities[2].schema
       Spec: https://ucp.dev/draft/specification/cart/

2 errors, 1 warning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each issue has a rule ID, a JSON path, and a fix. Copy-paste friendly. Greppable. CI-ready.&lt;/p&gt;

&lt;h2&gt;
  
  
  What About Merchant Center Onboarding?
&lt;/h2&gt;

&lt;p&gt;Google is also simplifying UCP onboarding through Merchant Center, rolling out "over the coming months." One detail worth noting: only product listings with the &lt;code&gt;native_commerce&lt;/code&gt; product attribute will display the checkout button in Google's AI experiences.&lt;/p&gt;

&lt;p&gt;This is implementation-specific to Google's surfaces - it's not part of the UCP spec itself. But if you're building for Google AI Mode specifically, it's a requirement you'll need to track.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Reference: The Minimal Checklist
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before adding any new capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;/.well-known/ucp&lt;/code&gt; returns valid JSON with &lt;code&gt;Content-Type: application/json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;ucp.version&lt;/code&gt; is &lt;code&gt;"2026-01-11"&lt;/code&gt; (YYYY-MM-DD)&lt;/li&gt;
&lt;li&gt;[ ] All endpoint URLs are HTTPS, no trailing slashes&lt;/li&gt;
&lt;li&gt;[ ] Signing keys array has at least one valid JWK&lt;/li&gt;
&lt;li&gt;[ ] No namespace/origin mismatches&lt;/li&gt;
&lt;li&gt;[ ] No orphaned extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adding Cart (draft):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Namespace: &lt;code&gt;dev.ucp.shopping.cart&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Spec URL: &lt;code&gt;https://ucp.dev/draft/specification/cart/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Endpoint reachable and returns JSON&lt;/li&gt;
&lt;li&gt;[ ] If also supporting Checkout: test cart-to-checkout conversion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adding Catalog (draft):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Namespace: &lt;code&gt;dev.ucp.shopping.catalog.search&lt;/code&gt; and/or &lt;code&gt;dev.ucp.shopping.catalog.lookup&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Spec URL: &lt;code&gt;https://ucp.dev/draft/specification/catalog/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Schema: &lt;code&gt;catalog_search.json&lt;/code&gt; / &lt;code&gt;catalog_lookup.json&lt;/code&gt; (separate files)&lt;/li&gt;
&lt;li&gt;[ ] Endpoint reachable and returns JSON&lt;/li&gt;
&lt;li&gt;[ ] Product data includes required fields (id, title, description, price_range, variants)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Adding Identity Linking (stable):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Namespace: &lt;code&gt;dev.ucp.common.identity_linking&lt;/code&gt; (note: &lt;code&gt;common&lt;/code&gt;, not &lt;code&gt;shopping&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;config.supported_mechanisms&lt;/code&gt; has at least one entry&lt;/li&gt;
&lt;li&gt;[ ] OAuth2 mechanism has &lt;code&gt;issuer&lt;/code&gt; using HTTPS&lt;/li&gt;
&lt;li&gt;[ ] Issuer supports RFC 8414 discovery (&lt;code&gt;/.well-known/oauth-authorization-server&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Test the full authorization flow&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Validate Your Profile
&lt;/h2&gt;

&lt;p&gt;You can run all of these checks at &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt; - paste your profile JSON or enter your domain. It's free, no signup required.&lt;/p&gt;

&lt;p&gt;For CI integration, the &lt;a href="https://www.npmjs.com/package/ucptools" rel="noopener noreferrer"&gt;npm package&lt;/a&gt; gives you the same validation with JSON output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ucptools
ucptools validate https://your-store.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;em&gt;UCPtools is an independent community tool. UCP is an open standard developed by Google, Shopify, and partners. Cart and Catalog spec status as of March 25, 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have questions about validating the new capabilities? Drop a comment - I'm building this in public and happy to help.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ecommerce</category>
      <category>ai</category>
      <category>ucp</category>
    </item>
    <item>
      <title>Automating Airtable with AI Assistants Using MCP</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Fri, 20 Mar 2026 17:45:42 +0000</pubDate>
      <link>https://dev.to/ucptools/automating-airtable-with-ai-assistants-using-mcp-22na</link>
      <guid>https://dev.to/ucptools/automating-airtable-with-ai-assistants-using-mcp-22na</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; I built an MCP wrapper for Airtable so AI assistants can&lt;br&gt;
work with your bases using tools instead of brittle prompt-only hacks.&lt;br&gt;
If you want Claude, ChatGPT, or another MCP-compatible client to read&lt;br&gt;
records, search data, create rows, and update workflows in Airtable,&lt;br&gt;
this is a practical way to do it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Airtable MCP Server on Apify Store:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://apify.com/minute_contest/airtable-mcp-server" rel="noopener noreferrer"&gt;https://apify.com/minute_contest/airtable-mcp-server&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Airtable already sits in the middle of a lot of workflows: CRM, content&lt;br&gt;
pipelines, ops tracking, lightweight internal tools, and project&lt;br&gt;
coordination.&lt;/p&gt;

&lt;p&gt;The missing piece is often this:&lt;/p&gt;

&lt;p&gt;You want an AI assistant to work with Airtable as a system of record,&lt;br&gt;
not just talk about it.&lt;/p&gt;

&lt;p&gt;That sounds straightforward until you try it.&lt;/p&gt;

&lt;p&gt;Most AI assistant setups hit one of these problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they can summarize pasted Airtable data, but cannot act on live records&lt;/li&gt;
&lt;li&gt;they rely on custom scripts and one-off API glue&lt;/li&gt;
&lt;li&gt;they break when you need both read and write operations&lt;/li&gt;
&lt;li&gt;they are hard to reuse across clients like Claude Desktop, ChatGPT
tools, or other MCP-compatible runtimes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built &lt;strong&gt;Airtable MCP Server&lt;/strong&gt; to solve that gap.&lt;/p&gt;

&lt;p&gt;It is an MIT-licensed MCP server packaged for Apify, with&lt;br&gt;
&lt;strong&gt;15 Airtable tools&lt;/strong&gt; for reading, writing, searching, and managing&lt;br&gt;
bases. It supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standby mode&lt;/strong&gt; for a persistent MCP server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch mode&lt;/strong&gt; for one-off jobs or scripted runs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are exploring AI-agent-ready tools, this is the pattern I think&lt;br&gt;
is worth using for Airtable.&lt;/p&gt;


&lt;h2&gt;
  
  
  The problem: AI assistants need tools, not pasted spreadsheets
&lt;/h2&gt;

&lt;p&gt;A lot of Airtable + AI examples still look like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;export records&lt;/li&gt;
&lt;li&gt;paste them into a chat&lt;/li&gt;
&lt;li&gt;ask the model to analyze them&lt;/li&gt;
&lt;li&gt;manually copy results back into Airtable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That works for demos, but not for workflows.&lt;/p&gt;

&lt;p&gt;In practice, teams want things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Look up all leads that have not been contacted in 14 days and draft
follow-up actions"&lt;/li&gt;
&lt;li&gt;"Find support tickets tagged billing, summarize themes, and create a
triage table"&lt;/li&gt;
&lt;li&gt;"When I describe a new project in chat, create the corresponding
Airtable records"&lt;/li&gt;
&lt;li&gt;"Search my content calendar and tell me what is blocked, then update
statuses"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are not just reasoning tasks. They are reasoning plus data access&lt;br&gt;
plus mutation.&lt;/p&gt;

&lt;p&gt;This is where MCP helps.&lt;/p&gt;

&lt;p&gt;With MCP, the AI assistant gets a structured set of tools. Instead of&lt;br&gt;
hallucinating around your data model, it can call explicit operations&lt;br&gt;
against Airtable.&lt;/p&gt;


&lt;h2&gt;
  
  
  What this actor does
&lt;/h2&gt;

&lt;p&gt;The Apify actor wraps an Airtable MCP server and exposes Airtable&lt;br&gt;
operations through the Model Context Protocol.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apify Store link:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://apify.com/minute_contest/airtable-mcp-server" rel="noopener noreferrer"&gt;https://apify.com/minute_contest/airtable-mcp-server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At a high level, it gives an AI assistant the ability to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inspect Airtable bases and tables&lt;/li&gt;
&lt;li&gt;read records&lt;/li&gt;
&lt;li&gt;search and filter records&lt;/li&gt;
&lt;li&gt;create new records&lt;/li&gt;
&lt;li&gt;update existing records&lt;/li&gt;
&lt;li&gt;manage Airtable-backed workflows from an MCP client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I packaged it on Apify because I wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hosted execution&lt;/li&gt;
&lt;li&gt;repeatable runs&lt;/li&gt;
&lt;li&gt;a straightforward way to use persistent or one-shot server modes&lt;/li&gt;
&lt;li&gt;a cleaner path for developers who do not want to self-host everything
from scratch&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Two modes
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Standby mode
&lt;/h4&gt;

&lt;p&gt;Use this when you want a persistent MCP server that your assistant can&lt;br&gt;
connect to and keep using over time.&lt;/p&gt;

&lt;p&gt;Good for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Desktop-style workflows&lt;/li&gt;
&lt;li&gt;long-running agent sessions&lt;/li&gt;
&lt;li&gt;internal assistant setups&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  2. Batch mode
&lt;/h4&gt;

&lt;p&gt;Use this when you want to run a single task or automation step and exit.&lt;/p&gt;

&lt;p&gt;Good for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scheduled jobs&lt;/li&gt;
&lt;li&gt;testing&lt;/li&gt;
&lt;li&gt;pipeline steps&lt;/li&gt;
&lt;li&gt;one-off automations&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Real use cases
&lt;/h2&gt;

&lt;p&gt;Here are a few practical workflows where this pattern makes sense.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. AI-assisted CRM cleanup in Airtable
&lt;/h3&gt;

&lt;p&gt;A common Airtable setup is a lead table with fields like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name&lt;/li&gt;
&lt;li&gt;Company&lt;/li&gt;
&lt;li&gt;Last Contacted&lt;/li&gt;
&lt;li&gt;Status&lt;/li&gt;
&lt;li&gt;Notes&lt;/li&gt;
&lt;li&gt;Next Action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An AI assistant can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search for stale leads&lt;/li&gt;
&lt;li&gt;summarize the latest notes&lt;/li&gt;
&lt;li&gt;propose next actions&lt;/li&gt;
&lt;li&gt;update the relevant records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example prompt to an MCP-enabled assistant:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find all leads in the CRM table where Status is "Active" and&lt;br&gt;
Last Contacted is older than 14 days. Summarize the notes for each and&lt;br&gt;
update Next Action with a short follow-up recommendation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without MCP, this is a manual export-and-paste process.&lt;br&gt;
With MCP, the assistant can query the data and write the result back.&lt;/p&gt;


&lt;h3&gt;
  
  
  2. Content pipeline management
&lt;/h3&gt;

&lt;p&gt;Airtable is often used as a content calendar. Typical fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Topic&lt;/li&gt;
&lt;li&gt;Owner&lt;/li&gt;
&lt;li&gt;Status&lt;/li&gt;
&lt;li&gt;Publish Date&lt;/li&gt;
&lt;li&gt;Draft URL&lt;/li&gt;
&lt;li&gt;Notes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An AI assistant can help with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;finding blocked content items&lt;/li&gt;
&lt;li&gt;grouping them by issue&lt;/li&gt;
&lt;li&gt;updating statuses&lt;/li&gt;
&lt;li&gt;creating missing records from a planning session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Review all content records with Status set to "Blocked". Group the&lt;br&gt;
blockers into themes and update Notes with a short recommended next&lt;br&gt;
step for each record.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This works well when Airtable is the operational layer and the assistant&lt;br&gt;
is the reasoning layer.&lt;/p&gt;


&lt;h3&gt;
  
  
  3. Support triage and internal ops
&lt;/h3&gt;

&lt;p&gt;If you log support requests or internal operations issues in Airtable,&lt;br&gt;
an assistant can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search for open high-priority items&lt;/li&gt;
&lt;li&gt;identify duplicates&lt;/li&gt;
&lt;li&gt;create triage summaries&lt;/li&gt;
&lt;li&gt;update assignments or status fields&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look at open tickets from the last 7 days with category "Billing".&lt;br&gt;
Summarize repeated issues and create a new record in the weekly-review&lt;br&gt;
table with the summary.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That kind of cross-table workflow is where tool-based assistants start&lt;br&gt;
to become useful instead of just interesting.&lt;/p&gt;


&lt;h3&gt;
  
  
  4. Lightweight internal tools without building a full app
&lt;/h3&gt;

&lt;p&gt;Airtable often becomes the backend for internal workflows before anyone&lt;br&gt;
builds a dedicated UI.&lt;/p&gt;

&lt;p&gt;An MCP-enabled assistant can act as the interaction layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Create a new vendor onboarding record"&lt;/li&gt;
&lt;li&gt;"Find all overdue approvals"&lt;/li&gt;
&lt;li&gt;"Update procurement status to waiting on legal"&lt;/li&gt;
&lt;li&gt;"Show me which launches are missing assets"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a replacement for your product UI. It is a practical&lt;br&gt;
interface for operations work that already lives in Airtable.&lt;/p&gt;


&lt;h2&gt;
  
  
  How I think about the setup
&lt;/h2&gt;

&lt;p&gt;The architecture is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Airtable remains the source of truth&lt;/li&gt;
&lt;li&gt;The MCP server exposes Airtable operations as tools&lt;/li&gt;
&lt;li&gt;Your AI assistant uses those tools to read and modify data&lt;/li&gt;
&lt;li&gt;Apify hosts the MCP wrapper so you do not have to wire everything
manually&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Diagram you can add as a screenshot
&lt;/h3&gt;

&lt;p&gt;A simple diagram with four boxes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI Assistant&lt;/strong&gt; (Claude, ChatGPT, custom agent)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP Client&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Airtable MCP Server on Apify&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Airtable API / Bases&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Arrows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assistant calls MCP tools&lt;/li&gt;
&lt;li&gt;MCP server translates requests&lt;/li&gt;
&lt;li&gt;Airtable returns records&lt;/li&gt;
&lt;li&gt;assistant reasons over results and optionally writes updates back&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Example workflow: stale CRM lead follow-up
&lt;/h2&gt;

&lt;p&gt;Here is a concrete pattern.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: define the business rule
&lt;/h3&gt;

&lt;p&gt;We want to find all active leads where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Last Contacted &amp;lt; today - 14 days&lt;/li&gt;
&lt;li&gt;Status = Active&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;summarize notes&lt;/li&gt;
&lt;li&gt;write a recommended next action&lt;/li&gt;
&lt;li&gt;optionally create a task elsewhere&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 2: run the MCP server
&lt;/h3&gt;

&lt;p&gt;From Apify, configure the Airtable MCP Server with your Airtable&lt;br&gt;
credentials and choose the mode you want.&lt;/p&gt;

&lt;p&gt;For a persistent assistant setup, use &lt;strong&gt;Standby&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: call it from your MCP client
&lt;/h3&gt;

&lt;p&gt;The exact client setup depends on what you use, but the flow usually&lt;br&gt;
looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"airtable-mcp-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"baseId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"appXXXXXXXXXXXXXX"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then your assistant can issue tool calls such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"search_records"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"baseId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"appXXXXXXXXXXXXXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Leads"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Active"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tool"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"update_record"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"baseId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"appXXXXXXXXXXXXXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Leads"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"recordId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"recXXXXXXXXXXXXXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Next Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Send follow-up email focused on pricing questions"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact tool names and payload shape depend on your MCP client and&lt;br&gt;
server configuration, but this is the practical pattern:&lt;br&gt;
search, reason, update.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example: using the actor in an automation script
&lt;/h2&gt;

&lt;p&gt;If you want to trigger the Apify actor programmatically, here is a&lt;br&gt;
Node.js example using the Apify API client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApifyClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apify-client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;batch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Add your Airtable auth and server-specific config here.&lt;/span&gt;
  &lt;span class="c1"&gt;// For example:&lt;/span&gt;
  &lt;span class="c1"&gt;// airtableToken: process.env.AIRTABLE_TOKEN,&lt;/span&gt;
  &lt;span class="c1"&gt;// baseId: 'appXXXXXXXXXXXXXX',&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;minute_contest/airtable-mcp-server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Run finished:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dataset:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a simple Python version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;apify_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ApifyClient&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApifyClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;APIFY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;input_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;batch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# Add Airtable auth and config here.
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;minute_contest/airtable-mcp-server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;run_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Run finished:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dataset:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;defaultDatasetId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Screenshot idea
&lt;/h3&gt;

&lt;p&gt;Add a screenshot of the Apify actor input screen showing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mode selection&lt;/li&gt;
&lt;li&gt;Airtable token field&lt;/li&gt;
&lt;li&gt;base/table configuration&lt;/li&gt;
&lt;li&gt;run button&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why MCP is a better fit than ad hoc Airtable AI glue
&lt;/h2&gt;

&lt;p&gt;What I learned building this is that Airtable + AI gets messy fast if&lt;br&gt;
every workflow is custom.&lt;/p&gt;

&lt;p&gt;You can absolutely call the Airtable API directly. I have done that too.&lt;br&gt;
But once you want assistants to interact with Airtable across multiple&lt;br&gt;
workflows, MCP gives you a cleaner interface.&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one tool layer instead of scattered scripts&lt;/li&gt;
&lt;li&gt;reusable across multiple assistant clients&lt;/li&gt;
&lt;li&gt;better fit for agent workflows&lt;/li&gt;
&lt;li&gt;less prompt-only guessing about your data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also helps separate concerns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Airtable handles storage and structure&lt;/li&gt;
&lt;li&gt;the assistant handles reasoning&lt;/li&gt;
&lt;li&gt;MCP handles tool access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That separation is useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Honest limitations
&lt;/h2&gt;

&lt;p&gt;This is not magic, and there are a few things worth saying plainly.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Your Airtable schema still matters
&lt;/h3&gt;

&lt;p&gt;If your fields are inconsistent or overloaded, the assistant will&lt;br&gt;
struggle just like a human would.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Permissions need attention
&lt;/h3&gt;

&lt;p&gt;If you let an assistant write to production tables, think through scope&lt;br&gt;
and guardrails.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Not every workflow should be agent-driven
&lt;/h3&gt;

&lt;p&gt;If you just need one deterministic update, a direct script may be&lt;br&gt;
simpler.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. MCP adoption is still early
&lt;/h3&gt;

&lt;p&gt;Interest is rising, but the ecosystem is still settling. Different&lt;br&gt;
clients support MCP in slightly different ways, so you should expect&lt;br&gt;
some setup work.&lt;/p&gt;

&lt;p&gt;That said, if you already think in terms of AI assistants with tools,&lt;br&gt;
Airtable is a good candidate for this model.&lt;/p&gt;




&lt;h2&gt;
  
  
  When I would use this
&lt;/h2&gt;

&lt;p&gt;I would reach for Airtable MCP Server when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Airtable is already central to the workflow&lt;/li&gt;
&lt;li&gt;I want an assistant to both read and write records&lt;/li&gt;
&lt;li&gt;I need something reusable across AI clients&lt;/li&gt;
&lt;li&gt;I do not want to maintain custom Airtable glue for every use case&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would probably not use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the task is a single fixed API call&lt;/li&gt;
&lt;li&gt;there is no need for assistant reasoning&lt;/li&gt;
&lt;li&gt;the workflow is too sensitive to allow AI-triggered writes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;If you want to try it, start with one contained workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stale lead follow-up&lt;/li&gt;
&lt;li&gt;blocked content triage&lt;/li&gt;
&lt;li&gt;weekly support summary&lt;/li&gt;
&lt;li&gt;record creation from chat notes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives you a clean way to validate whether AI + Airtable tool access&lt;br&gt;
is useful in your setup.&lt;/p&gt;

&lt;p&gt;You can find the actor here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apify Store link:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://apify.com/minute_contest/airtable-mcp-server" rel="noopener noreferrer"&gt;https://apify.com/minute_contest/airtable-mcp-server&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Airtable MCP Server&lt;/strong&gt; because I wanted Airtable to be usable&lt;br&gt;
by AI assistants as an actual tool layer, not just as exported context&lt;br&gt;
pasted into a prompt.&lt;/p&gt;

&lt;p&gt;If your team keeps operational data in Airtable and you are&lt;br&gt;
experimenting with agent workflows, this is a practical starting point.&lt;br&gt;
It gives you hosted MCP access to Airtable with read/write/search&lt;br&gt;
capabilities, plus both persistent and one-shot execution modes.&lt;/p&gt;

&lt;p&gt;If you test it and hit rough edges, that is useful feedback too. This&lt;br&gt;
category is still early, and practical usage patterns matter more than&lt;br&gt;
hype.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apify Store link:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://apify.com/minute_contest/airtable-mcp-server" rel="noopener noreferrer"&gt;https://apify.com/minute_contest/airtable-mcp-server&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>airtable</category>
      <category>automation</category>
    </item>
    <item>
      <title>I Built a Validator for a Protocol That Didn't Exist 8 Weeks Ago</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Thu, 19 Mar 2026 14:06:00 +0000</pubDate>
      <link>https://dev.to/ucptools/i-built-a-validator-for-a-protocol-that-didnt-exist-8-weeks-ago-266l</link>
      <guid>https://dev.to/ucptools/i-built-a-validator-for-a-protocol-that-didnt-exist-8-weeks-ago-266l</guid>
      <description>&lt;p&gt;In January 2026, Google and Shopify announced the &lt;a href="https://ucp.dev" rel="noopener noreferrer"&gt;Universal Commerce Protocol (UCP)&lt;/a&gt; at NRF - an open standard that lets AI agents like ChatGPT, Gemini, and Copilot discover products, browse catalogs, and complete purchases on e-commerce stores.&lt;/p&gt;

&lt;p&gt;Within hours, I knew there'd be a tooling gap. Merchants would need to validate their UCP profiles. Developers would need to test their implementations. And nobody was building it yet.&lt;/p&gt;

&lt;p&gt;So I did. Here's what 8 weeks of building on an emerging standard actually looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 1: Racing the Spec
&lt;/h2&gt;

&lt;p&gt;The UCP spec was published alongside the announcement. I read the whole thing that weekend. The core concept is elegant: serve a JSON manifest at &lt;code&gt;/.well-known/ucp&lt;/code&gt; that tells AI agents what your store can do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payment_handlers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first validator was 200 lines of TypeScript. Parse JSON, check required fields, validate URLs. Ship it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson learned:&lt;/strong&gt; Perfect is the enemy of shipped. The first version had exactly one feature: paste JSON, see errors. That was enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 2: Four Levels of Validation
&lt;/h2&gt;

&lt;p&gt;The simple JSON checker wasn't enough. Merchants had profiles that &lt;em&gt;looked&lt;/em&gt; valid but failed in practice - wrong URL formats, HTTP instead of HTTPS, missing signing keys.&lt;/p&gt;

&lt;p&gt;I built a 4-level validation pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Structural&lt;/strong&gt; - Is the JSON valid? Are required fields present?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules&lt;/strong&gt; - Do namespaces match origins? Are endpoints HTTPS?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt; - Can we actually fetch the referenced schemas?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK&lt;/strong&gt; - Does it pass the official &lt;code&gt;@ucp-js/sdk&lt;/code&gt; compliance check?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each level catches errors the previous one can't. A profile can pass structural validation but fail at the network level because its schema URLs are dead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 3: First Users from Google Search
&lt;/h2&gt;

&lt;p&gt;This surprised me. Within 3 weeks of launching, Google was sending organic traffic for "ucp validator" and "ucp checker."&lt;/p&gt;

&lt;p&gt;The lesson: when you build tooling for an emerging standard before anyone else, SEO is almost free. There's no competition for keywords nobody has targeted yet.&lt;/p&gt;

&lt;p&gt;Traffic grew from 0 to ~230 sessions/week in the first month. Not viral, but consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 4: The Agent Simulator
&lt;/h2&gt;

&lt;p&gt;Validation tells you if your profile is &lt;em&gt;correct&lt;/em&gt;. But does your store actually &lt;em&gt;work&lt;/em&gt; for AI agents?&lt;/p&gt;

&lt;p&gt;I built an agent simulator that tests the full workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discovery&lt;/strong&gt; - fetch &lt;code&gt;/.well-known/ucp&lt;/code&gt; like a real agent would&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capability inspection&lt;/strong&gt; - parse capabilities and verify endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkout simulation&lt;/strong&gt; - test the checkout flow end-to-end&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This caught a whole category of bugs that static validation missed: endpoints returning HTML instead of JSON, timeouts on product APIs, CORS blocking agent requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Week 5-6: The Monetization Experiment
&lt;/h2&gt;

&lt;p&gt;Free tools get traffic. But can they generate revenue?&lt;/p&gt;

&lt;p&gt;I added a $9/month monitoring tier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weekly auto-validation of your UCP profile&lt;/li&gt;
&lt;li&gt;Email alerts when your score drops&lt;/li&gt;
&lt;li&gt;Validation history and trend tracking&lt;/li&gt;
&lt;li&gt;AI agent traffic analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The result so far:&lt;/strong&gt; 9 trial signups, 0 paid conversions. Users explore the dashboard for 5-10 minutes, find value, and... never come back.&lt;/p&gt;

&lt;p&gt;The problem isn't the product - it's the trial experience. Users get full value in one session. There's no reason to return until something breaks. And by then, they've forgotten about us.&lt;/p&gt;

&lt;p&gt;I'm currently building better retention hooks: personalized Day 2 emails showing their actual scan results, "next scan" countdowns on the dashboard, and more visible upgrade prompts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Build the monitoring first, not the validator.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The one-time validator is useful but commoditizable. Three other validators launched within weeks. The monitoring - weekly scans, alerts, history - is the defensible moat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Ship the email sequence on day one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I launched without trial nurture emails. For 3 weeks, every trial user signed up and... silence. No welcome email, no quick start guide, no reminder. By the time I fixed it, those users were gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Don't underestimate competitors building on the same trend.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Within 8 weeks, at least 3 other UCP validators appeared: UCPChecker.com (with a browser extension), Nextwaves (40+ test claims), and several WooCommerce plugins. First-mover advantage is real but temporary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers (8 Weeks In)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Weekly sessions&lt;/td&gt;
&lt;td&gt;~120&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total trial signups&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paid conversions&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monthly cost&lt;/td&gt;
&lt;td&gt;$5 (Hetzner VPS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revenue&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tools built&lt;/td&gt;
&lt;td&gt;7 (validator, simulator, generator, security scan, feed analyzer, ACP checker, schema generator)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform guides&lt;/td&gt;
&lt;td&gt;6 (Shopify, WooCommerce, Magento, BigCommerce, Wix, Squarespace)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Am I profitable? No. Am I building something people use? Yes. The gap between those two is where the real work happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The agentic commerce space is heating up. Visa launched Intelligent Commerce. Mastercard has Agent Pay. Meta is building shopping into its AI. McKinsey projects $1 trillion in AI-driven commerce by 2030.&lt;/p&gt;

&lt;p&gt;UCP is still early. Most e-commerce stores don't have a profile yet. But the ones that do will have a head start when AI agents become the primary shopping interface.&lt;/p&gt;

&lt;p&gt;If you want to check where your store stands: &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt; - free, no signup required.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm building UCPtools in public. Ask me anything in the comments.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UCPtools is an independent community tool. UCP is an open standard by Google, Shopify, and partners.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>ucp</category>
    </item>
    <item>
      <title>How to Make Your WooCommerce Store AI-Ready with UCP (2026 Guide)</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Tue, 17 Mar 2026 14:33:00 +0000</pubDate>
      <link>https://dev.to/ucptools/how-to-make-your-woocommerce-store-ai-ready-with-ucp-2026-guide-2abe</link>
      <guid>https://dev.to/ucptools/how-to-make-your-woocommerce-store-ai-ready-with-ucp-2026-guide-2abe</guid>
      <description>&lt;p&gt;AI agents are shopping for your customers. ChatGPT, Google's Gemini, and Microsoft Copilot can now browse products, compare prices, and complete purchases - if your store speaks their language.&lt;/p&gt;

&lt;p&gt;That language is &lt;strong&gt;UCP (Universal Commerce Protocol)&lt;/strong&gt;, an open standard by Google, Shopify, and 25+ retailers. And if your WooCommerce store doesn't have it, AI agents will skip you entirely.&lt;/p&gt;

&lt;p&gt;Here's how to fix that in under 10 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is UCP?
&lt;/h2&gt;

&lt;p&gt;UCP is a JSON manifest served at &lt;code&gt;/.well-known/ucp&lt;/code&gt; on your domain. It tells AI agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What your store sells&lt;/li&gt;
&lt;li&gt;How to browse products&lt;/li&gt;
&lt;li&gt;How to complete checkout&lt;/li&gt;
&lt;li&gt;Which payment methods you accept&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like &lt;code&gt;robots.txt&lt;/code&gt; but for commerce. Without it, AI agents can't interact with your store programmatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"business"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My WooCommerce Store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mystore.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/checkout/1.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payment_handlers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"supported_methods"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"card"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apple_pay"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"google_pay"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Option 1: Use a WooCommerce UCP Plugin (Easiest)
&lt;/h2&gt;

&lt;p&gt;Several plugins now handle UCP for WooCommerce:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plugin&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;th&gt;Setup Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UCP Adapter for WooCommerce&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Auto-generates &lt;code&gt;.well-known/ucp&lt;/code&gt; from your catalog&lt;/td&gt;
&lt;td&gt;~5 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;UCPReady by Zologic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full UCP manifest + monitoring&lt;/td&gt;
&lt;td&gt;~10 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI Merchant Pro&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;UCP + product feed optimization&lt;/td&gt;
&lt;td&gt;~15 min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After installing, the plugin maps your WooCommerce products, categories, and payment gateways into the UCP manifest format automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: Manual Implementation (More Control)
&lt;/h2&gt;

&lt;p&gt;If you prefer full control, create the manifest yourself:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the Manifest File
&lt;/h3&gt;

&lt;p&gt;Create a file at &lt;code&gt;/.well-known/ucp&lt;/code&gt; in your WordPress root. You can use a custom rewrite rule or a simple PHP file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In your theme's functions.php or a custom plugin&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'init'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;add_rewrite_rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'^\.well-known/ucp$'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'index.php?ucp_manifest=1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'top'&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'query_vars'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$vars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$vars&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ucp_manifest'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$vars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'template_redirect'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;get_query_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ucp_manifest'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Access-Control-Allow-Origin: *'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'version'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2026-01-11'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'business'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get_bloginfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s1"&gt;'url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'capabilities'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'checkout'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'version'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'1.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'schema'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'https://ucp.dev/schemas/checkout/1.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'endpoint'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/wp-json/wc/v3/checkout'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s1"&gt;'services'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'product_discovery'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'version'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'1.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'schema'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'https://ucp.dev/schemas/discovery/1.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s1"&gt;'endpoint'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/wp-json/wc/v3/products'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;JSON_PRETTY_PRINT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;JSON_UNESCAPED_SLASHES&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Add CORS Headers
&lt;/h3&gt;

&lt;p&gt;AI agents need to fetch your manifest from different origins. Add CORS headers to your &lt;code&gt;.htaccess&lt;/code&gt; or nginx config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="c"&gt;# .htaccess&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;IfModule&lt;/span&gt;&lt;span class="sr"&gt; mod_headers.c&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;FilesMatch&lt;/span&gt;&lt;span class="sr"&gt; "\.well-known/ucp"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Access-Control-Allow-Origin "*"
        &lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="ss"&gt;set&lt;/span&gt; Content-Type "application/json"
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;FilesMatch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;IfModule&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Validate Your Implementation
&lt;/h3&gt;

&lt;p&gt;Run your domain through a UCP validator to check for errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Using the free UCPtools validator&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://ucptools.dev/api/v1/profiles/validate-remote &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"url": "https://yourstore.com"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use the &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;web validator at ucptools.dev&lt;/a&gt; - paste your domain and get an instant A-F grade with actionable fix suggestions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Test with the AI Agent Simulator
&lt;/h2&gt;

&lt;p&gt;Validation confirms your manifest is correct, but does your store actually &lt;em&gt;work&lt;/em&gt; for AI agents? The &lt;a href="https://ucptools.dev/simulator" rel="noopener noreferrer"&gt;Agent Simulator&lt;/a&gt; tests the full workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Discovery&lt;/strong&gt; - Can agents find your UCP manifest?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browsing&lt;/strong&gt; - Can they search and view products?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkout&lt;/strong&gt; - Can they complete a purchase?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This catches issues that static validation misses, like broken API endpoints or timeout errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common WooCommerce UCP Mistakes
&lt;/h2&gt;

&lt;p&gt;From validating hundreds of WooCommerce stores, here are the top errors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Missing &lt;code&gt;version&lt;/code&gt; field&lt;/strong&gt; - Must be in &lt;code&gt;YYYY-MM-DD&lt;/code&gt; format (e.g., &lt;code&gt;2026-01-11&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP endpoints instead of HTTPS&lt;/strong&gt; - All UCP endpoints must use HTTPS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No CORS headers&lt;/strong&gt; - AI agents can't fetch your manifest cross-origin&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trailing slashes on endpoints&lt;/strong&gt; - &lt;code&gt;/wp-json/wc/v3/products/&lt;/code&gt; should be &lt;code&gt;/wp-json/wc/v3/products&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing &lt;code&gt;payment_handlers&lt;/code&gt;&lt;/strong&gt; - Even if you only support card payments, declare them&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What Happens After Setup
&lt;/h2&gt;

&lt;p&gt;Once your UCP manifest is live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ChatGPT Shopping&lt;/strong&gt; can list your products in purchase recommendations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google AI Mode&lt;/strong&gt; can include your store in shopping results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Copilot&lt;/strong&gt; can browse and compare your products&lt;/li&gt;
&lt;li&gt;Any UCP-compatible AI agent can discover and transact with your store&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Monitor Your AI Commerce Readiness
&lt;/h2&gt;

&lt;p&gt;UCP implementation isn't set-and-forget. The spec evolves, your catalog changes, and new AI agents launch constantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev/pricing" rel="noopener noreferrer"&gt;UCPtools monitoring&lt;/a&gt; ($9/mo) scans your store weekly and alerts you if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your UCP manifest breaks&lt;/li&gt;
&lt;li&gt;Your score drops&lt;/li&gt;
&lt;li&gt;New capabilities become available&lt;/li&gt;
&lt;li&gt;AI agent traffic patterns change&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Try it now:&lt;/strong&gt; Run your WooCommerce store through the &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;free validator&lt;/a&gt; and see your AI Commerce Score in 30 seconds.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UCPtools is an independent community tool. UCP is an open standard by Google, Shopify, and partners.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>woocommerce</category>
      <category>ai</category>
      <category>ecommerce</category>
      <category>ucp</category>
    </item>
    <item>
      <title>Generative Engine Optimization (GEO): How to Make Your Store Visible to AI Shopping Agents</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Thu, 12 Mar 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/ucptools/generative-engine-optimization-geo-how-to-make-your-store-visible-to-ai-shopping-agents-ki1</link>
      <guid>https://dev.to/ucptools/generative-engine-optimization-geo-how-to-make-your-store-visible-to-ai-shopping-agents-ki1</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;SEO gets you in front of humans. GEO gets you in front of AI agents that buy things.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SEO&lt;/th&gt;
&lt;th&gt;GEO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Optimized for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Search engine crawlers&lt;/td&gt;
&lt;td&gt;AI shopping agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Goal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rank in SERPs&lt;/td&gt;
&lt;td&gt;Get discovered, selected, and purchased through&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Outcome&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Human clicks through to your site&lt;/td&gt;
&lt;td&gt;AI agent completes a purchase on your store&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Key signals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keywords, backlinks, page speed&lt;/td&gt;
&lt;td&gt;Structured data depth, protocol compliance, API reliability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Metrics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rankings, CTR, organic traffic&lt;/td&gt;
&lt;td&gt;Agent discovery rate, browse rate, checkout rate, AI-attributed revenue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Timeline&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Weeks to months&lt;/td&gt;
&lt;td&gt;Data improvements: 2-4 weeks. Protocol implementation: immediate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content format&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTML pages for humans&lt;/td&gt;
&lt;td&gt;JSON-LD, product feeds, UCP profiles for machines&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The shift is already happening. 70% of consumers are using AI assistants for shopping in 2026, and 93% of AI Mode searches result in zero clicks back to merchant websites. The purchase happens inside the AI interface. If your store is not optimized for AI agents, you are invisible to a growing share of commerce.&lt;/p&gt;

&lt;p&gt;This article covers what GEO is, how it differs from SEO, the 5 pillars of GEO optimization, and a practical audit checklist you can run today.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Generative Engine Optimization?
&lt;/h2&gt;

&lt;p&gt;Generative Engine Optimization (GEO) is the practice of making your online store discoverable and actionable by AI agents. Not just appearing in AI-generated summaries, but being the store that AI agents select when a user says "buy me wireless earbuds under $80."&lt;/p&gt;

&lt;p&gt;Traditional SEO answers the question: "How do I rank higher in Google search results so humans click my link?"&lt;/p&gt;

&lt;p&gt;GEO answers a different question: "How do I make my store so well-structured, so data-rich, and so reliable that AI agents choose me over competitors when completing a purchase?"&lt;/p&gt;

&lt;p&gt;The distinction matters because the transaction flow is fundamentally different. In SEO, you rank in search results, a human clicks through, browses your site, adds items to a cart, and checks out. In GEO, an AI agent discovers your store through a protocol endpoint, reads your product data through structured APIs, creates a checkout session programmatically, submits payment, and completes the order. The human never visits your website. They never see your homepage, your product photos, or your checkout page. They said "buy me earbuds" to an AI assistant, and the assistant handled everything.&lt;/p&gt;

&lt;p&gt;This is not theoretical. Google AI Mode launched agentic shopping in early 2026. ChatGPT has shopping capabilities through ACP (Agent Commerce Protocol). Perplexity, Claude, and Copilot are all building commerce integrations. The AI agents are live, they are completing purchases, and the merchants they choose are the ones with the best structured data, the most complete product information, and the most reliable APIs.&lt;/p&gt;

&lt;p&gt;As commercetools put it in their 2026 commerce report: "The most valuable commerce capability will be supporting autonomous agent-completed transactions."&lt;/p&gt;

&lt;p&gt;GEO is how you build that capability.&lt;/p&gt;




&lt;h2&gt;
  
  
  SEO vs GEO: Key Differences
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How SEO Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You optimize your pages for search engine crawlers (keywords, meta tags, backlinks, page speed)&lt;/li&gt;
&lt;li&gt;Crawlers index your content and rank it in search engine results pages (SERPs)&lt;/li&gt;
&lt;li&gt;Humans see your listing, click through to your website&lt;/li&gt;
&lt;li&gt;Humans browse your site, add products to cart, and check out&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;SEO metrics:&lt;/strong&gt; keyword rankings, click-through rate, organic traffic, bounce rate, pages per session, conversion rate from organic search.&lt;/p&gt;

&lt;h3&gt;
  
  
  How GEO Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You optimize your store's structured data, product feeds, and protocol endpoints for AI agents&lt;/li&gt;
&lt;li&gt;AI agents discover your store through &lt;code&gt;/.well-known/ucp&lt;/code&gt;, product feeds, and Schema.org markup&lt;/li&gt;
&lt;li&gt;AI agents evaluate your product data, pricing, availability, and policies&lt;/li&gt;
&lt;li&gt;AI agents select your store, create a checkout session, submit payment, and complete the order&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;GEO metrics:&lt;/strong&gt; agent discovery rate, browse rate (agents that go past discovery to product browsing), checkout rate, AI-attributed revenue, average order value from agents, error rate, capability match rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Critical Shift
&lt;/h3&gt;

&lt;p&gt;In the SEO model, your website is the destination. Everything you build leads the human to your site, where you control the experience.&lt;/p&gt;

&lt;p&gt;In the GEO model, your data is the product. The AI agent never sends the user to your site. It reads your data, makes a decision, and completes the transaction. Your structured data, your product feed completeness, your API response times, and your protocol compliance are what determine whether you get the sale.&lt;/p&gt;

&lt;p&gt;This is why 93% of AI Mode searches result in zero clicks. The click is obsolete. The data is what matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 5 Pillars of GEO
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pillar 1: Structured Data Depth
&lt;/h3&gt;

&lt;p&gt;Schema.org Product markup is the foundation of GEO. But not the bare minimum markup that most stores ship today. AI agents need &lt;strong&gt;deep, complete markup&lt;/strong&gt; to make purchase decisions on behalf of users.&lt;/p&gt;

&lt;p&gt;Here is the difference between markup that AI agents can work with and markup they cannot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad markup (what most stores have):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Earbuds"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"offers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"79.99"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI agent sees this and knows almost nothing. What brand? What condition? Is it in stock? What is the currency? What is the return policy? Are there images? What does it weigh? The agent cannot confidently recommend this product to a user because it lacks the information needed to make a decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good markup (what AI agents need):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Product"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wireless Earbuds Pro"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Active noise cancelling wireless earbuds with 24-hour battery life"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WE-PRO-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"brand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Brand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AudioTech"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"offers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Offer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"79.99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"priceCurrency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/InStock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"itemCondition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/NewCondition"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"seller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Organization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AudioTech Store"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aggregateRating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AggregateRating"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ratingValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reviewCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2341"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/earbuds-front.jpg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/earbuds-side.jpg"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"QuantitativeValue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"unitCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GRM"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Midnight Black"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"material"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ABS Plastic + Silicone"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hasMerchantReturnPolicy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MerchantReturnPolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"returnPolicyCategory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/MerchantReturnFiniteReturnWindow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"merchantReturnDays"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This markup gives the AI agent everything it needs: product identity (SKU, brand), purchase conditions (price, currency, availability, condition), social proof (ratings, review count), physical attributes (weight, color, material), visual confirmation (multiple images), and post-purchase confidence (return policy).&lt;/p&gt;

&lt;p&gt;The depth of your structured data directly determines whether AI agents surface your products. An agent choosing between two wireless earbuds at the same price will pick the one with complete data every time, because it can make a more confident recommendation to its user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to include in every Product markup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, &lt;code&gt;sku&lt;/code&gt;, &lt;code&gt;brand&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;offers&lt;/code&gt; with &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;priceCurrency&lt;/code&gt;, &lt;code&gt;availability&lt;/code&gt;, &lt;code&gt;itemCondition&lt;/code&gt;, &lt;code&gt;seller&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aggregateRating&lt;/code&gt; with &lt;code&gt;ratingValue&lt;/code&gt; and &lt;code&gt;reviewCount&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Multiple &lt;code&gt;image&lt;/code&gt; URLs (front, side, detail shots)&lt;/li&gt;
&lt;li&gt;Physical attributes: &lt;code&gt;weight&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;material&lt;/code&gt;, &lt;code&gt;size&lt;/code&gt; where applicable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hasMerchantReturnPolicy&lt;/code&gt; with return window and conditions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gtin&lt;/code&gt;, &lt;code&gt;mpn&lt;/code&gt;, or &lt;code&gt;isbn&lt;/code&gt; for product identification&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pillar 2: Product Feed Quality
&lt;/h3&gt;

&lt;p&gt;Your product feed is the bulk data source AI agents use to evaluate your entire catalog. Incomplete feeds with missing attributes, inconsistent pricing, broken image URLs, or stale inventory data cause agents to deprioritize your store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complete attributes matter.&lt;/strong&gt; Every product in your feed should have: title, description, price, currency, availability status, condition, brand, category (Google Product Category), image URL, and unique identifier (GTIN/MPN/SKU). Products missing any of these core attributes may be excluded from agent consideration entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistent pricing.&lt;/strong&gt; The price in your feed must match the price on your product page and in your Schema.org markup. AI agents cross-reference these sources. Discrepancies signal unreliability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Valid images.&lt;/strong&gt; Every image URL must return a 200 status with an actual image. Broken images (404s, redirects to placeholder images) are a negative signal. AI agents that render product information for users need working visuals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accurate inventory.&lt;/strong&gt; If your feed says "in stock" but the checkout fails because the item is actually out of stock, the agent records a failed transaction. Repeated inventory mismatches cause agents to reduce trust in your store's data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pillar 3: Protocol Compliance
&lt;/h3&gt;

&lt;p&gt;Two agentic commerce protocols are live in 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UCP (Universal Commerce Protocol)&lt;/strong&gt; — developed by Google and Shopify with 25+ partners. Your store publishes a UCP profile at &lt;code&gt;/.well-known/ucp&lt;/code&gt; that declares your capabilities, endpoints, and signing keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACP (Agent Commerce Protocol)&lt;/strong&gt; — developed by OpenAI and Stripe. Provides a merchant listing and checkout flow through Stripe's infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Protocol compliance means your store is properly registered, your profile is valid, and your capability declarations are accurate.&lt;/p&gt;

&lt;p&gt;For UCP, this means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://yourstore.com/.well-known/ucp
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns a valid UCP profile with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correct &lt;code&gt;version&lt;/code&gt; format (YYYY-MM-DD)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;namespace&lt;/code&gt; matching your domain origin&lt;/li&gt;
&lt;li&gt;Complete &lt;code&gt;capabilities&lt;/code&gt; array with valid endpoints&lt;/li&gt;
&lt;li&gt;All endpoints using HTTPS (no trailing slashes)&lt;/li&gt;
&lt;li&gt;Valid Ed25519 or ES256 signing keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your UCP profile is missing, malformed, or declares capabilities you do not actually support, AI agents cannot transact with your store. Protocol compliance is not optional in the GEO model. It is the equivalent of having a working website in the SEO model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pillar 4: API Reliability
&lt;/h3&gt;

&lt;p&gt;AI agents deprioritize unreliable merchants. Every interaction between an agent and your store is an API call, and agents track success rates, response times, and error patterns across merchants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Response times.&lt;/strong&gt; AI agents are completing transactions in seconds. If your product API takes 3 seconds to respond, the agent may time out or move to a faster competitor. Target under 200ms for product endpoints and under 500ms for checkout operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proper error handling.&lt;/strong&gt; Return correct HTTP status codes. A &lt;code&gt;200 OK&lt;/code&gt; with an error message in the body confuses agents. A &lt;code&gt;404 Not Found&lt;/code&gt; for a product that exists confuses agents. Use &lt;code&gt;200&lt;/code&gt; for success, &lt;code&gt;400&lt;/code&gt; for bad requests, &lt;code&gt;404&lt;/code&gt; for missing resources, &lt;code&gt;429&lt;/code&gt; for rate limiting (with &lt;code&gt;Retry-After&lt;/code&gt; header), and &lt;code&gt;500&lt;/code&gt; for server errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consistent availability.&lt;/strong&gt; Downtime during peak hours means missed transactions. AI agents do not bookmark your store and come back later. They move to the next merchant. 99.9% uptime on UCP endpoints is the target.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate limiting awareness.&lt;/strong&gt; AI agents send bursts of requests during product browsing. If your rate limiter treats agent traffic like bot attacks, you are blocking customers. Whitelist known AI agent User-Agent patterns on your commerce endpoints, or set higher rate limits for these routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pillar 5: Agent-Readable Policies
&lt;/h3&gt;

&lt;p&gt;AI agents need to communicate return policies, shipping information, and privacy policies to users before completing a purchase. If these policies are buried in unstructured HTML pages, agents cannot parse them reliably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structured return policies.&lt;/strong&gt; Use &lt;code&gt;MerchantReturnPolicy&lt;/code&gt; schema markup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MerchantReturnPolicy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"returnPolicyCategory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/MerchantReturnFiniteReturnWindow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"merchantReturnDays"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"returnMethod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/ReturnByMail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"returnFees"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org/FreeReturn"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Structured shipping information.&lt;/strong&gt; Use &lt;code&gt;OfferShippingDetails&lt;/code&gt; to declare shipping rates, delivery times, and geographic coverage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OfferShippingDetails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shippingRate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MonetaryAmount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"deliveryTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ShippingDeliveryTime"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"handlingTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"QuantitativeValue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"minValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"maxValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"unitCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DAY"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"transitTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"QuantitativeValue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"minValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"maxValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"unitCode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DAY"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shippingDestination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DefinedRegion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"addressCountry"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an AI agent can read your return policy and shipping details in structured format, it can confidently tell the user "free returns within 30 days, ships in 3-5 business days" before completing the purchase. Without structured policies, the agent either guesses, escalates to the human, or picks a competitor with clearer terms.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical GEO Audit Checklist
&lt;/h2&gt;

&lt;p&gt;Here are 10 items to audit on your store today. Each one directly impacts whether AI agents discover, browse, and buy from you.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Check Schema Markup Completeness
&lt;/h3&gt;

&lt;p&gt;Run your product pages through the &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Feed Analyzer&lt;/a&gt; to see which Schema.org attributes are present and which are missing. Target 100% coverage on the core attributes listed in Pillar 1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/products/your-product | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'"@type":"Product"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Validate Your UCP Profile
&lt;/h3&gt;

&lt;p&gt;Use the &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Validator&lt;/a&gt; to check your &lt;code&gt;/.well-known/ucp&lt;/code&gt; profile for structural errors, missing fields, namespace mismatches, and endpoint issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://yourstore.com/.well-known/ucp | python &lt;span class="nt"&gt;-m&lt;/span&gt; json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this returns a 404, you do not have a UCP profile and AI agents using UCP cannot discover you.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Test ACP Readiness
&lt;/h3&gt;

&lt;p&gt;If you use Stripe, check whether your store is listed in the ACP merchant directory. ACP powers ChatGPT shopping and is growing rapidly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Audit Product Data Completeness
&lt;/h3&gt;

&lt;p&gt;Export your product feed and check the fill rate for each attribute. Calculate: how many products have brand? SKU? GTIN? Multiple images? Weight? Color? Target 95%+ fill rate on core attributes.&lt;/p&gt;

&lt;p&gt;Common gaps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing &lt;code&gt;brand&lt;/code&gt; (37% of stores)&lt;/li&gt;
&lt;li&gt;Missing &lt;code&gt;gtin&lt;/code&gt; or &lt;code&gt;mpn&lt;/code&gt; (52% of stores)&lt;/li&gt;
&lt;li&gt;Single image instead of multiple (61% of stores)&lt;/li&gt;
&lt;li&gt;Missing &lt;code&gt;weight&lt;/code&gt; and physical attributes (78% of stores)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Verify Checkout Flow with AI Agent Simulation
&lt;/h3&gt;

&lt;p&gt;Use the &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools AI Agent Simulator&lt;/a&gt; to walk through the full agent interaction flow: discovery, capability inspection, product browsing, and checkout simulation. This catches issues that static validation misses, like endpoints that return 200 but with empty responses, or checkout flows that require human-only interactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Test Response Times Under Load
&lt;/h3&gt;

&lt;p&gt;AI agents send concurrent requests. Test your UCP endpoints with a load testing tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test discovery endpoint response time&lt;/span&gt;
curl &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{time_total}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; https://yourstore.com/.well-known/ucp

&lt;span class="c"&gt;# Test product endpoint response time&lt;/span&gt;
curl &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{time_total}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; https://yourstore.com/api/products/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Target: under 200ms for product endpoints, under 500ms for checkout operations. If you are over these thresholds under load, AI agents may deprioritize your store.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Review Structured Return and Shipping Policies
&lt;/h3&gt;

&lt;p&gt;Check whether your return policy and shipping information are available as Schema.org structured data, not just as HTML pages. Search your page source for &lt;code&gt;MerchantReturnPolicy&lt;/code&gt; and &lt;code&gt;OfferShippingDetails&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Monitor AI Agent Traffic
&lt;/h3&gt;

&lt;p&gt;Check your server logs for AI agent User-Agent strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight codeowners"&gt;&lt;code&gt;&lt;span class="n"&gt;chatgpt&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gptbot&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;-&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChatGPT/OpenAI&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;gemini&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;google-extended&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;-&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Google&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Gemini&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;perplexitybot&lt;/span&gt;&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="n"&gt;-&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Perplexity&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;anthropic&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="n"&gt;-&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Claude&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;copilot&lt;/span&gt;&lt;span class="w"&gt;                         &lt;/span&gt;&lt;span class="n"&gt;-&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Copilot&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also check for requests to &lt;code&gt;/.well-known/ucp&lt;/code&gt; — this is the primary discovery endpoint. If you see traffic here, AI agents are already trying to shop on your store.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Check Capability Gaps
&lt;/h3&gt;

&lt;p&gt;Review what capabilities AI agents request versus what your store supports. If agents frequently request &lt;code&gt;fulfillment&lt;/code&gt; tracking or &lt;code&gt;discount&lt;/code&gt; application but your UCP profile does not declare these capabilities, you are losing transactions at the browse stage. UCPtools Analytics tracks these gaps automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Compare Against Competitors
&lt;/h3&gt;

&lt;p&gt;Check whether your competitors have UCP profiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://competitor.com/.well-known/ucp | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If they do and you do not, AI agents are routing commerce to them instead of you. If they do not, you have a first-mover advantage in your category.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results Timeline
&lt;/h2&gt;

&lt;p&gt;GEO improvements show results on two timescales:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Product data improvements (2-4 weeks).&lt;/strong&gt; Enriching your Schema.org markup, completing your product feed attributes, and adding structured policies takes effect as AI agents re-index your data. Most agents refresh merchant data every 1-2 weeks, so you should see changes in agent behavior within 2-4 weeks of implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protocol implementation (immediate).&lt;/strong&gt; Publishing a valid UCP profile at &lt;code&gt;/.well-known/ucp&lt;/code&gt; has an immediate effect. The moment the profile is live and valid, AI agents can discover your store on their next scan. There is no waiting period for protocol compliance. You go from invisible to discoverable the day you deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API reliability improvements (immediate to 1 week).&lt;/strong&gt; Fixing error responses, improving response times, and adjusting rate limits for AI agents shows results immediately for agents that have already discovered your store. New agents will pick up the improvements on their next visit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cumulative effect.&lt;/strong&gt; GEO is not a one-time optimization. Each improvement compounds. Better structured data leads to more agent discoveries. More discoveries with reliable APIs lead to more checkouts. More successful checkouts build agent trust, which leads to higher selection rates in future transactions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tools for GEO
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Free Tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Validator&lt;/a&gt;&lt;/strong&gt; — Validate your UCP profile for structural errors, missing fields, namespace mismatches, endpoint issues, and protocol compliance. Supports all four validation levels: structural, rules, network, and SDK validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Feed Analyzer&lt;/a&gt;&lt;/strong&gt; — Analyze your product feed and Schema.org markup for completeness. Identifies missing attributes, broken images, and data quality issues across your entire catalog.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools AI Agent Simulator&lt;/a&gt;&lt;/strong&gt; — Simulate the full AI agent interaction flow: discovery, capability inspection, product browsing, and checkout. Tests real-world functionality, not just spec compliance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paid Tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ucptools.dev/dashboard/analytics" rel="noopener noreferrer"&gt;UCPtools Analytics V2&lt;/a&gt;&lt;/strong&gt; ($9/mo) — Track the complete agentic commerce funnel: discovery, browse, checkout, payment, and order. Agent-by-agent comparison (Gemini, ChatGPT, Perplexity, Claude, Copilot), error analysis with fix suggestions, capability gap analysis, and AI-attributed revenue tracking. &lt;a href="https://ucptools.dev/dashboard/analytics?demo=true" rel="noopener noreferrer"&gt;Try the interactive demo&lt;/a&gt; with sample data.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;GEO is the future of e-commerce optimization. Not a replacement for SEO, but a parallel discipline that addresses a fundamentally different commerce channel.&lt;/p&gt;

&lt;p&gt;SEO brought your store in front of humans searching on Google. GEO brings your store in front of AI agents shopping on behalf of humans. The mechanics are different. The optimization levers are different. The metrics are different.&lt;/p&gt;

&lt;p&gt;Start with the two highest-impact actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Structured data depth.&lt;/strong&gt; Enrich your Schema.org Product markup beyond the bare minimum. Add brand, SKU, availability, ratings, images, weight, color, material, and return policies to every product. This is the single most impactful GEO optimization because it affects every AI agent across every protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Protocol compliance.&lt;/strong&gt; Publish a valid UCP profile at &lt;code&gt;/.well-known/ucp&lt;/code&gt;. This makes your store discoverable by every UCP-compatible AI agent immediately. Use the &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Validator&lt;/a&gt; to check your profile before deploying.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The merchants who invest in GEO now will capture the growing wave of AI-mediated commerce. The merchants who wait will wonder why their revenue from "direct" traffic in Google Analytics keeps growing while they cannot explain where it comes from.&lt;/p&gt;

&lt;p&gt;The AI agents are already shopping. The question is whether they are shopping on your store.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Validator&lt;/a&gt; — validate your UCP profile and product feeds (free)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ucptools.dev/dashboard/analytics?demo=true" rel="noopener noreferrer"&gt;UCPtools Analytics Demo&lt;/a&gt; — explore the agentic commerce dashboard with sample data&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ucp.dev" rel="noopener noreferrer"&gt;UCP Specification&lt;/a&gt; — the official Universal Commerce Protocol spec&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://agentcommerceprotocol.com" rel="noopener noreferrer"&gt;ACP Specification&lt;/a&gt; — the official Agent Commerce Protocol spec&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developers.google.com/merchant/ucp" rel="noopener noreferrer"&gt;Google UCP Developer Guide&lt;/a&gt; — getting started with UCP&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://schema.org/Product" rel="noopener noreferrer"&gt;Schema.org Product Markup&lt;/a&gt; — complete reference for Product structured data&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;What is your GEO readiness score? Run your store through the &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Validator&lt;/a&gt; and share your results in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclaimer: UCP is an open standard by Google and Shopify. ACP is an open standard by OpenAI and Stripe. UCPtools is an independent community tool.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>ecommerce</category>
      <category>geo</category>
      <category>ucp</category>
    </item>
    <item>
      <title>UCP vs ACP in 2026: A Technical Comparison of AI Commerce Protocols</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Thu, 05 Mar 2026 14:05:00 +0000</pubDate>
      <link>https://dev.to/ucptools/ucp-vs-acp-in-2026-a-technical-comparison-of-ai-commerce-protocols-50j7</link>
      <guid>https://dev.to/ucptools/ucp-vs-acp-in-2026-a-technical-comparison-of-ai-commerce-protocols-50j7</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Two protocols now power AI shopping. Google's UCP (Universal Commerce Protocol) and OpenAI's ACP (Agent Commerce Protocol) take fundamentally different approaches to the same problem: how do AI agents discover, browse, and buy products on behalf of users?&lt;/p&gt;

&lt;p&gt;Here is the side-by-side comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;UCP&lt;/th&gt;
&lt;th&gt;ACP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Created by&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Google + Shopify&lt;/td&gt;
&lt;td&gt;OpenAI + Stripe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Announced&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;January 2026 (NRF)&lt;/td&gt;
&lt;td&gt;February 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Decentralized (merchant-hosted)&lt;/td&gt;
&lt;td&gt;Centralized (platform-controlled)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discovery&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/.well-known/ucp&lt;/code&gt; JSON on your domain&lt;/td&gt;
&lt;td&gt;OpenAI product catalog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Payment processor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Merchant's choice (Google Pay, Stripe, Shop Pay, custom)&lt;/td&gt;
&lt;td&gt;Stripe only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transaction fees&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Payment processor fees only&lt;/td&gt;
&lt;td&gt;4% OpenAI + ~2.9% Stripe + $0.30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total cost per $100 sale&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$3.20 (Stripe)&lt;/td&gt;
&lt;td&gt;~$7.20 (OpenAI + Stripe)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Profile control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Merchant owns and hosts&lt;/td&gt;
&lt;td&gt;Platform controls listing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Protocol compatibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A2A, AP2, MCP, REST&lt;/td&gt;
&lt;td&gt;Standalone (open-sourced)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Signing/auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ed25519/ES256 JWK keys&lt;/td&gt;
&lt;td&gt;Stripe API keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Partners&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20+ (Etsy, Target, Walmart, Visa, Mastercard, Best Buy)&lt;/td&gt;
&lt;td&gt;OpenAI, Stripe, select merchants&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Availability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Global&lt;/td&gt;
&lt;td&gt;US only (expanding 2026)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Open standard&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (open-sourced)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Implementation time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hours (host JSON + endpoints)&lt;/td&gt;
&lt;td&gt;Days (apply + review process)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are a merchant deciding which to support: &lt;strong&gt;support both&lt;/strong&gt;. They target different agent ecosystems, the implementation overlap is significant, and dual-protocol merchants see up to 40% more agentic traffic than single-protocol stores.&lt;/p&gt;

&lt;p&gt;Read on for the full technical breakdown.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Two Protocols
&lt;/h2&gt;

&lt;p&gt;Two weeks apart in early 2026, two announcements reshaped how AI agents will interact with online commerce.&lt;/p&gt;

&lt;h3&gt;
  
  
  UCP: The Decentralized Standard
&lt;/h3&gt;

&lt;p&gt;Google and Shopify unveiled the Universal Commerce Protocol (UCP) at the National Retail Federation (NRF) conference in January 2026. The protocol defines how AI shopping agents discover merchants, browse product catalogs, create checkout sessions, and complete purchases through structured API interactions.&lt;/p&gt;

&lt;p&gt;UCP's core design principle is &lt;strong&gt;decentralization&lt;/strong&gt;. Merchants host their own UCP profile as a JSON file at &lt;code&gt;/.well-known/ucp&lt;/code&gt; on their domain. Any AI agent can discover it. No middleman controls who gets listed, no platform takes a cut on top of payment processing, and no review board decides which merchants are allowed.&lt;/p&gt;

&lt;p&gt;The launch partner list included over 20 companies: Etsy, Wayfair, Target, Walmart, Best Buy, Visa, Mastercard, American Express, Adyen, and more. Shopify merchants got native UCP support in their dashboards. Google AI Mode and the Gemini App began using UCP for agentic shopping immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  ACP: The Platform Approach
&lt;/h3&gt;

&lt;p&gt;OpenAI and Stripe announced the Agent Commerce Protocol (ACP) in February 2026. Where UCP is a decentralized discovery protocol, ACP is a platform-mediated commerce layer. Merchants submit product data to OpenAI, Stripe handles all payments, and ChatGPT surfaces products to users during conversations.&lt;/p&gt;

&lt;p&gt;ACP takes a different philosophical approach. Instead of asking merchants to build and host infrastructure, it provides a managed experience: submit your catalog, connect Stripe, and OpenAI handles the rest. The tradeoff is control. OpenAI decides what gets surfaced, Stripe is the only payment option, and the combined fee structure is approximately double what UCP costs.&lt;/p&gt;

&lt;p&gt;OpenAI open-sourced the ACP specification, published 8 RFCs extending the core protocol, and announced plans to expand beyond the US in 2026.&lt;/p&gt;

&lt;p&gt;Both protocols are open. Both are production-ready. And they solve the same fundamental problem differently enough that understanding the distinctions matters for every merchant entering the agentic commerce space.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Comparison
&lt;/h2&gt;

&lt;p&gt;This is where the protocols diverge most sharply.&lt;/p&gt;

&lt;h3&gt;
  
  
  UCP: Decentralized, Merchant-Hosted
&lt;/h3&gt;

&lt;p&gt;UCP follows the same architectural pattern as &lt;code&gt;robots.txt&lt;/code&gt;, &lt;code&gt;sitemap.xml&lt;/code&gt;, and &lt;code&gt;/.well-known/&lt;/code&gt; URIs. The merchant hosts the protocol artifact on their own domain. Any agent that knows where to look can discover it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent                          Merchant Domain
  |                                  |
  |  GET /.well-known/ucp            |
  |---------------------------------&amp;gt;|
  |                                  |
  |  200 OK (UCP Profile JSON)       |
  |&amp;lt;---------------------------------|
  |                                  |
  |  GET /products                   |
  |---------------------------------&amp;gt;|
  |                                  |
  |  POST /checkout-sessions         |
  |---------------------------------&amp;gt;|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The merchant controls everything: what capabilities are advertised, which services are exposed, what payment methods are accepted, and how the checkout flow works. There is no central registry to apply to. If your profile is valid and your endpoints work, any UCP-compatible agent can transact with your store.&lt;/p&gt;

&lt;p&gt;This architecture means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No gatekeepers.&lt;/strong&gt; You do not need approval to participate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No platform fees.&lt;/strong&gt; You pay only your payment processor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No vendor lock-in.&lt;/strong&gt; Switch payment providers without changing your UCP profile structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full data ownership.&lt;/strong&gt; Agent interactions hit your servers, not a third-party platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The downside is that you build and maintain the infrastructure yourself. You host the profile, implement the endpoints, handle validation, manage signing keys, and ensure uptime.&lt;/p&gt;

&lt;h3&gt;
  
  
  ACP: Centralized, Platform-Mediated
&lt;/h3&gt;

&lt;p&gt;ACP uses a hub-and-spoke model. The merchant submits product data to OpenAI (via feeds or API). OpenAI indexes the catalog, surfaces products during ChatGPT conversations, and Stripe handles payment processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User         ChatGPT/Agent         OpenAI Catalog        Merchant
  |               |                      |                   |
  | "Buy X"       |                      |                   |
  |--------------&amp;gt;|                      |                   |
  |               |  Search products     |                   |
  |               |---------------------&amp;gt;|                   |
  |               |                      |                   |
  |               |  Results             |                   |
  |               |&amp;lt;---------------------|                   |
  |               |                      |                   |
  | Show options  |                      |                   |
  |&amp;lt;--------------|                      |                   |
  |               |                      |                   |
  | "Buy this"    |                      |                   |
  |--------------&amp;gt;|  Initiate checkout   |                   |
  |               |---------------------------------------------&amp;gt;|
  |               |                      |    Stripe payment |
  |               |                      |&amp;lt;------------------|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The platform controls discovery. OpenAI decides how products are ranked, which merchants appear for which queries, and what the user experience looks like. The merchant's job is to submit accurate product data and have a working Stripe integration.&lt;/p&gt;

&lt;p&gt;This architecture means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lower implementation effort.&lt;/strong&gt; Submit data, connect Stripe, done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in distribution.&lt;/strong&gt; ChatGPT's user base is your discovery channel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed experience.&lt;/strong&gt; OpenAI handles the agent-side UX.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoffs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Platform dependency.&lt;/strong&gt; If OpenAI changes ranking algorithms, your visibility changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe-only payments.&lt;/strong&gt; No Google Pay, Shop Pay, or custom payment handlers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher fees.&lt;/strong&gt; 4% OpenAI fee on top of Stripe processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited control.&lt;/strong&gt; You do not control how your products are presented to users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither architecture is inherently better. They optimize for different priorities: UCP for control and interoperability, ACP for simplicity and built-in distribution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discovery Flow
&lt;/h2&gt;

&lt;p&gt;How an AI agent finds your store is the first — and arguably most important — difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  UCP Discovery
&lt;/h3&gt;

&lt;p&gt;UCP discovery works like DNS for commerce. The agent fetches a well-known URI on the merchant's domain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://example.com/.well-known/ucp
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is a JSON profile that describes everything the agent needs to know: what the store sells, what capabilities it supports, how to interact with its APIs, and how to verify its identity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"merchant"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example Store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"An AI-ready online store"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"spec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/specs/shopping/checkout"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/ucp/checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/checkout/v1"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent parses this profile, understands what the store can do, and then decides how to interact. The discovery is deterministic: if the profile is at the well-known URI and it is valid, the agent will find it.&lt;/p&gt;

&lt;p&gt;Key discovery properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version format:&lt;/strong&gt; YYYY-MM-DD (e.g., &lt;code&gt;2026-01-11&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Namespace governance:&lt;/strong&gt; Capability names must match the origin domain authority&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signing keys:&lt;/strong&gt; Ed25519 or ES256 JWK keys for profile authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extension chains:&lt;/strong&gt; Capabilities can extend other capabilities, enabling composable functionality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple transports:&lt;/strong&gt; REST, MCP (Model Context Protocol), A2A (Agent-to-Agent), or embedded&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ACP Discovery
&lt;/h3&gt;

&lt;p&gt;ACP discovery is catalog-based. The merchant submits product data to OpenAI through feeds or API calls. OpenAI indexes this data and makes it searchable within ChatGPT and other OpenAI-powered agents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"products"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prod_abc123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wireless Earbuds Pro"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Noise-cancelling wireless earbuds with 24h battery"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"usd"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"images"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/images/earbuds-pro.jpg"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/products/earbuds-pro"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Electronics &amp;gt; Audio &amp;gt; Headphones"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"availability"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"in_stock"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"shipping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"free_shipping"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"estimated_days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"merchant"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example Store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stripe_account_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"acct_xxx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"return_policy_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/returns"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no well-known URI. There is no file on your domain that agents fetch directly. Instead, ChatGPT queries the OpenAI catalog when a user asks about products, and the platform decides which merchants and products to surface.&lt;/p&gt;

&lt;p&gt;The merchant goes through an application and review process. OpenAI verifies the business, checks product data quality, and then activates the merchant in the catalog. This means there is a human (or automated) gating step before your products are discoverable.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Practical Difference
&lt;/h3&gt;

&lt;p&gt;With UCP, an AI agent from any vendor — Google Gemini, Perplexity, Claude, a custom enterprise agent — can discover your store by fetching a single URL. You do not need to register with each agent platform individually.&lt;/p&gt;

&lt;p&gt;With ACP, discovery is currently limited to OpenAI's ecosystem. ChatGPT and OpenAI-powered agents can find your products. Agents from other vendors cannot query the OpenAI catalog (though the open-sourced spec could change this over time).&lt;/p&gt;

&lt;p&gt;If you want to be discoverable by the broadest range of AI agents, UCP's decentralized model has a structural advantage. If you want to reach ChatGPT's user base specifically, ACP provides a direct path.&lt;/p&gt;




&lt;h2&gt;
  
  
  Checkout and Payment
&lt;/h2&gt;

&lt;p&gt;This is where the fee structures diverge and the business implications become concrete.&lt;/p&gt;

&lt;h3&gt;
  
  
  UCP Checkout
&lt;/h3&gt;

&lt;p&gt;UCP profiles declare one or more payment handlers. The merchant chooses which payment methods to support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/ucp/checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/checkout/v1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"payment_handlers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"google_pay"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"handler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/payments/google-pay"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shop_pay"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"handler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/payments/shop-pay"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stripe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"handler"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/payments/stripe"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The checkout flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Agent creates a checkout session via &lt;code&gt;POST /checkout-sessions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Agent adds line items, shipping address, preferences&lt;/li&gt;
&lt;li&gt;Agent submits payment through the merchant's declared payment handler&lt;/li&gt;
&lt;li&gt;Merchant processes payment using their chosen provider&lt;/li&gt;
&lt;li&gt;Agent receives confirmation with order ID&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Fees:&lt;/strong&gt; Only your payment processor's standard fees. If you use Stripe, that is 2.9% + $0.30 per transaction in the US. If you use Adyen, it might be lower. If you negotiate volume rates, those apply. There is no protocol-level fee.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On a $100 sale:&lt;/strong&gt; ~$3.20 total (Stripe standard).&lt;/p&gt;

&lt;h3&gt;
  
  
  ACP Checkout
&lt;/h3&gt;

&lt;p&gt;ACP routes all payments through Stripe. The checkout flow is delegated: the agent initiates the transaction, Stripe processes the payment, and OpenAI takes a 4% platform fee.&lt;/p&gt;

&lt;p&gt;The checkout flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User confirms purchase intent in ChatGPT&lt;/li&gt;
&lt;li&gt;ChatGPT creates a Stripe Checkout Session via ACP&lt;/li&gt;
&lt;li&gt;User completes payment (Stripe handles the payment UI)&lt;/li&gt;
&lt;li&gt;Stripe processes the charge and distributes funds&lt;/li&gt;
&lt;li&gt;OpenAI retains 4% as a platform fee&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Fees:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4.0% OpenAI platform fee&lt;/li&gt;
&lt;li&gt;2.9% + $0.30 Stripe processing fee&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;On a $100 sale:&lt;/strong&gt; ~$7.20 total ($4.00 OpenAI + $3.20 Stripe).&lt;/p&gt;

&lt;h3&gt;
  
  
  Fee Comparison at Scale
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Monthly GMV&lt;/th&gt;
&lt;th&gt;UCP Cost (Stripe only)&lt;/th&gt;
&lt;th&gt;ACP Cost (OpenAI + Stripe)&lt;/th&gt;
&lt;th&gt;Difference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$10,000&lt;/td&gt;
&lt;td&gt;$320&lt;/td&gt;
&lt;td&gt;$720&lt;/td&gt;
&lt;td&gt;$400/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$50,000&lt;/td&gt;
&lt;td&gt;$1,600&lt;/td&gt;
&lt;td&gt;$3,600&lt;/td&gt;
&lt;td&gt;$2,000/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$100,000&lt;/td&gt;
&lt;td&gt;$3,200&lt;/td&gt;
&lt;td&gt;$7,200&lt;/td&gt;
&lt;td&gt;$4,000/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$500,000&lt;/td&gt;
&lt;td&gt;$16,000&lt;/td&gt;
&lt;td&gt;$36,000&lt;/td&gt;
&lt;td&gt;$20,000/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$1,000,000&lt;/td&gt;
&lt;td&gt;$32,000&lt;/td&gt;
&lt;td&gt;$72,000&lt;/td&gt;
&lt;td&gt;$40,000/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At $1M monthly GMV through agentic channels, the fee difference is $40,000 per month. That is material. Even at $50K/month, the extra $2,000 adds up to $24,000 per year.&lt;/p&gt;

&lt;p&gt;Whether the ACP premium is worth it depends on the volume of transactions ChatGPT drives to your store. If ChatGPT sends you $50K/month in sales you would not otherwise get, the $2,000/month cost is a reasonable customer acquisition cost. If you would have gotten those sales anyway through UCP-compatible agents, it is an unnecessary expense.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Here is what it takes to get each protocol running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing UCP
&lt;/h3&gt;

&lt;p&gt;UCP requires three things: a valid JSON profile, working API endpoints, and proper authentication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create your UCP profile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"merchant"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example Store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"An AI-ready online store"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"logo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/logo.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"support_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"support@example.com"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"spec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/specs/shopping/checkout"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.product_catalog"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"spec"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/specs/shopping/product_catalog"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/ucp/checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/checkout/v1"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"product_catalog"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/ucp/products"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/products/v1"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"signing_keys"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"kty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OKP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"crv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ed25519"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"key-2026-01"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Host the profile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Serve this JSON at &lt;code&gt;https://yourdomain.com/.well-known/ucp&lt;/code&gt; with &lt;code&gt;Content-Type: application/json&lt;/code&gt;. On most web servers, this is a static file in a &lt;code&gt;.well-known&lt;/code&gt; directory. On Shopify, it is generated automatically. On Vercel or Netlify, you add a rewrite rule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Implement API endpoints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your profile declares endpoints. Those endpoints need to actually work. At minimum, a checkout-capable store needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /products&lt;/code&gt; — Return product catalog&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /products/:id&lt;/code&gt; — Return single product&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /checkout-sessions&lt;/code&gt; — Create a checkout session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT /checkout-sessions/:id&lt;/code&gt; — Update session (add items, set shipping)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /checkout-sessions/:id/complete&lt;/code&gt; — Process payment and complete order&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /orders/:id&lt;/code&gt; — Return order status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Validate&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @ucptools/validator validate &lt;span class="nt"&gt;-r&lt;/span&gt; yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs structural, compliance, and network validation against your live profile. Fix any errors, re-validate, and you are live.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timeline:&lt;/strong&gt; If you have an existing e-commerce backend with product and checkout APIs, adding UCP can take a few hours. Shopify merchants can deploy in under 48 hours using the native integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing ACP
&lt;/h3&gt;

&lt;p&gt;ACP requires a Stripe account, product data submission, and going through OpenAI's merchant application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Connect Stripe&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you already use Stripe, you connect your existing account. If not, you create one and integrate it with your store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Submit product data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provide your product catalog to OpenAI through their merchant portal or API. This includes product names, descriptions, prices, images, categories, availability, and shipping information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Apply and wait&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Submit your merchant application through OpenAI's portal. OpenAI reviews your business, verifies product data quality, and activates your listing in the catalog. The timeline varies — some merchants report days, others weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Monitor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once live, track performance through OpenAI's merchant dashboard. Monitor which products are being surfaced, conversion rates, and revenue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timeline:&lt;/strong&gt; The Stripe integration and product feed setup can be done in a day if you have clean product data. The review process adds an unpredictable delay.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation Effort Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;UCP&lt;/th&gt;
&lt;th&gt;ACP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Profile/data setup&lt;/td&gt;
&lt;td&gt;2-4 hours&lt;/td&gt;
&lt;td&gt;1-2 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Endpoint implementation&lt;/td&gt;
&lt;td&gt;4-8 hours (if APIs exist)&lt;/td&gt;
&lt;td&gt;N/A (Stripe handles it)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication setup&lt;/td&gt;
&lt;td&gt;1-2 hours (signing keys)&lt;/td&gt;
&lt;td&gt;30 min (Stripe keys)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;1 hour&lt;/td&gt;
&lt;td&gt;Submit and wait&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Validation/testing&lt;/td&gt;
&lt;td&gt;1-2 hours&lt;/td&gt;
&lt;td&gt;Limited pre-launch testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total (existing backend)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8-16 hours&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2-4 hours + review wait&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total (from scratch)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2-5 days&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1-2 days + review wait&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;ACP is faster to implement because the platform handles more. UCP requires more upfront work but gives you more control over the long term.&lt;/p&gt;




&lt;h2&gt;
  
  
  Protocol Compatibility
&lt;/h2&gt;

&lt;h3&gt;
  
  
  UCP: The Interoperability Play
&lt;/h3&gt;

&lt;p&gt;UCP was designed to work alongside other AI agent protocols, not replace them. A UCP profile can declare multiple service transports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;REST&lt;/strong&gt; — Standard HTTP API endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt; — Anthropic's protocol for tool use by LLMs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A (Agent-to-Agent)&lt;/strong&gt; — Google's protocol for inter-agent communication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AP2&lt;/strong&gt; — Agent Platform Protocol for platform-level integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded&lt;/strong&gt; — For agents running within the merchant's own environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A single UCP profile can expose all of these simultaneously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"services"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/api/ucp/checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://ucp.dev/schemas/checkout/v1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/mcp/checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"create_checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"add_item"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"complete_purchase"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"a2a"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/a2a/checkout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"agent_card"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/.well-known/agent.json"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means a Google Gemini agent can discover your store via &lt;code&gt;/.well-known/ucp&lt;/code&gt; and interact through A2A. A Claude-based agent can use MCP tools. A custom enterprise agent can use REST. Same store, same profile, multiple agent architectures.&lt;/p&gt;

&lt;h3&gt;
  
  
  ACP: Standalone but Open
&lt;/h3&gt;

&lt;p&gt;ACP is a standalone protocol. It does not integrate with MCP, A2A, or other agent communication standards. However, OpenAI open-sourced the specification and published 8 RFCs that extend the core protocol. These RFCs cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Capability negotiation between agent and merchant&lt;/li&gt;
&lt;li&gt;Delegated payment flows&lt;/li&gt;
&lt;li&gt;Product feed specifications&lt;/li&gt;
&lt;li&gt;Merchant verification&lt;/li&gt;
&lt;li&gt;Refund and return handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The open-sourcing means other agent platforms could adopt ACP in the future. But today, ACP is primarily an OpenAI/ChatGPT protocol. Other agent vendors have not announced ACP support.&lt;/p&gt;

&lt;h3&gt;
  
  
  What This Means for Merchants
&lt;/h3&gt;

&lt;p&gt;If you implement UCP with REST endpoints, you can later add MCP and A2A transports to the same profile without changing your core infrastructure. You write the business logic once and expose it through multiple protocols.&lt;/p&gt;

&lt;p&gt;If you implement ACP, you get access to ChatGPT's ecosystem. But if you want to support Gemini, Claude, Perplexity, or custom agents, you still need UCP (or direct integrations with each platform).&lt;/p&gt;




&lt;h2&gt;
  
  
  Ecosystem and Partners
&lt;/h2&gt;

&lt;h3&gt;
  
  
  UCP Partners (20+)
&lt;/h3&gt;

&lt;p&gt;The UCP launch coalition is broad and includes major players across retail, payments, and technology:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retailers:&lt;/strong&gt; Etsy, Wayfair, Target, Walmart, Best Buy&lt;br&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; Visa, Mastercard, American Express, Adyen&lt;br&gt;
&lt;strong&gt;Platforms:&lt;/strong&gt; Shopify (native integration), Google Merchant Center&lt;br&gt;
&lt;strong&gt;Technology:&lt;/strong&gt; Multiple e-commerce platforms announcing UCP support&lt;/p&gt;

&lt;p&gt;Shopify's native integration is particularly significant. Shopify powers millions of merchants, and built-in UCP support means those merchants can go live without writing code. The Shopify app generates the UCP profile, handles endpoint routing, and manages the checkout flow.&lt;/p&gt;
&lt;h3&gt;
  
  
  ACP Partners
&lt;/h3&gt;

&lt;p&gt;ACP's ecosystem is currently smaller but includes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; OpenAI (ChatGPT distribution)&lt;br&gt;
&lt;strong&gt;Payments:&lt;/strong&gt; Stripe (exclusive payment processor)&lt;br&gt;
&lt;strong&gt;Early merchants:&lt;/strong&gt; Etsy (notably supporting both protocols), select Shopify merchants&lt;/p&gt;

&lt;p&gt;The smaller partner list is partly because ACP launched a month after UCP. The ecosystem will grow as the review process scales. But structurally, ACP will always have a more curated partner list because the platform controls merchant admission.&lt;/p&gt;
&lt;h3&gt;
  
  
  Notable: Etsy Supports Both
&lt;/h3&gt;

&lt;p&gt;Etsy is in both the UCP and ACP partner lists. This is not a coincidence. Etsy is betting that both protocols will drive meaningful commerce and that supporting both maximizes their discoverability across all agent ecosystems. This is the dual-protocol strategy in action.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Third Player: Microsoft Copilot Checkout
&lt;/h2&gt;

&lt;p&gt;It is worth noting that Microsoft announced Copilot Checkout in early 2026 as well. While not as thoroughly documented as UCP or ACP at this stage, Microsoft is integrating shopping capabilities directly into Copilot and Bing, with its own merchant onboarding process.&lt;/p&gt;

&lt;p&gt;Microsoft's approach leans closer to ACP's platform-mediated model: merchants connect through Microsoft Merchant Center, and Copilot handles product discovery and purchase flows within its ecosystem.&lt;/p&gt;

&lt;p&gt;For merchants, this means the agentic commerce landscape is not a two-horse race. It is at least three platforms, with UCP being the only protocol that works across all of them (since any agent can fetch a &lt;code&gt;/.well-known/ucp&lt;/code&gt; profile regardless of which company built it).&lt;/p&gt;


&lt;h2&gt;
  
  
  Dual Protocol Strategy
&lt;/h2&gt;

&lt;p&gt;Supporting both UCP and ACP is not twice the work. The overlap is significant.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Support Both
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Different agent ecosystems.&lt;/strong&gt; UCP is the default for Google AI Mode, Gemini, and the growing ecosystem of independent agents. ACP is the path to ChatGPT's user base. Missing either means missing a portion of agentic traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Measurable impact.&lt;/strong&gt; Early data from merchants supporting both protocols shows up to &lt;strong&gt;40% more agentic traffic&lt;/strong&gt; compared to single-protocol stores. The audiences are largely additive — users who shop through ChatGPT are often different from those using Google AI Mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shared infrastructure.&lt;/strong&gt; Both protocols need the same underlying components: product catalog API, checkout flow, order management, payment processing. The protocol-specific layer is thin compared to the commerce infrastructure underneath.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Three-Step Implementation Guide
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Build the Commerce Layer (shared)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you already have e-commerce APIs for products, checkout, and orders, this step is done. If not, build them once and expose them through both protocols.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your E-Commerce Backend
├── Product Catalog API
├── Checkout Session API
├── Order Management API
└── Payment Processing
    ├── Stripe (works for both UCP + ACP)
    ├── Google Pay (UCP only)
    └── Shop Pay (UCP only)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Add UCP (your domain)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a UCP profile (use &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools&lt;/a&gt; or build manually)&lt;/li&gt;
&lt;li&gt;Host at &lt;code&gt;/.well-known/ucp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Map UCP service endpoints to your commerce APIs&lt;/li&gt;
&lt;li&gt;Add Ed25519 signing keys&lt;/li&gt;
&lt;li&gt;Validate with &lt;code&gt;npx @ucptools/validator validate -r yourdomain.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Add ACP (Stripe + OpenAI)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect Stripe account (you likely already have one from UCP payment setup)&lt;/li&gt;
&lt;li&gt;Export product catalog in ACP feed format&lt;/li&gt;
&lt;li&gt;Submit through OpenAI merchant portal&lt;/li&gt;
&lt;li&gt;Wait for review and activation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Total incremental effort for adding ACP after UCP: roughly 2-4 hours of setup plus the review wait. Total incremental effort for adding UCP after ACP: roughly 8-16 hours, most of which is hosting and validating the profile.&lt;/p&gt;




&lt;h2&gt;
  
  
  Validation and Monitoring
&lt;/h2&gt;

&lt;p&gt;Once you have deployed one or both protocols, you need to verify they work and track their performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validating UCP Profiles
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCPtools Validator&lt;/a&gt; runs four levels of validation against your live UCP profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Full remote validation&lt;/span&gt;
npx @ucptools/validator validate &lt;span class="nt"&gt;-r&lt;/span&gt; yourdomain.com

&lt;span class="c"&gt;# Quick structural check&lt;/span&gt;
npx @ucptools/validator validate-quick profile.json

&lt;span class="c"&gt;# Simulate agent interaction&lt;/span&gt;
npx @ucptools/validator simulate &lt;span class="nt"&gt;-r&lt;/span&gt; yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The validator checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structural validity&lt;/strong&gt; — JSON structure, required fields, version format&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UCP compliance&lt;/strong&gt; — Namespace/origin binding, extension chains, HTTPS endpoints, signing keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network verification&lt;/strong&gt; — Remote schema fetching, endpoint reachability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent simulation&lt;/strong&gt; — Runs a full discovery-browse-checkout flow like a real AI agent would&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common validation errors and what they mean:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error Code&lt;/th&gt;
&lt;th&gt;What It Means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UCP_MISSING_ROOT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No &lt;code&gt;ucp&lt;/code&gt; root object in profile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UCP_INVALID_VERSION_FORMAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Version is not YYYY-MM-DD format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UCP_NS_ORIGIN_MISMATCH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Capability namespace does not match your domain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UCP_ENDPOINT_NOT_HTTPS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Endpoint uses HTTP instead of HTTPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UCP_ENDPOINT_TRAILING_SLASH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Endpoint URL has a trailing slash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UCP_MISSING_SIGNING_KEYS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No Ed25519/ES256 keys in profile&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Checking ACP Readiness
&lt;/h3&gt;

&lt;p&gt;ACP validation is more limited since the platform controls the profile. Your checklist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stripe account active&lt;/strong&gt; — Verify your Stripe account is in good standing with payouts enabled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product data quality&lt;/strong&gt; — Check that all submitted products have complete titles, descriptions, images, accurate pricing, and correct availability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkout flow tested&lt;/strong&gt; — Run test transactions through your Stripe integration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merchant portal status&lt;/strong&gt; — Check your application status in the OpenAI merchant dashboard&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Monitoring AI Agent Traffic
&lt;/h3&gt;

&lt;p&gt;Traditional analytics tools like GA4 cannot see AI agent interactions — there is no browser, no JavaScript execution, no cookies. You need purpose-built analytics for agentic commerce.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ucptools.dev/dashboard/analytics" rel="noopener noreferrer"&gt;UCPtools Analytics V2&lt;/a&gt; tracks the full agentic commerce funnel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discovery events&lt;/strong&gt; — Which agents found your &lt;code&gt;/.well-known/ucp&lt;/code&gt; profile&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse events&lt;/strong&gt; — What products agents queried&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkout events&lt;/strong&gt; — Sessions created, items added&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment events&lt;/strong&gt; — Payment submissions and outcomes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order events&lt;/strong&gt; — Completed purchases and revenue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key metrics to watch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent conversion rate&lt;/strong&gt; — What percentage of agent discoveries result in purchases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revenue by agent&lt;/strong&gt; — Which AI agents drive the most revenue (Gemini vs. ChatGPT vs. Claude vs. Perplexity)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol split&lt;/strong&gt; — What percentage of agentic traffic comes through UCP vs. ACP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error rate&lt;/strong&gt; — Where agents fail and why (missing capabilities, endpoint errors, payment failures)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This data tells you whether your protocol implementations are working and where to invest optimization effort.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The UCP vs. ACP comparison is not really about which protocol is "better." They make different architectural tradeoffs for different use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose UCP if you value:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control over your commerce experience&lt;/li&gt;
&lt;li&gt;Interoperability with multiple AI agent platforms&lt;/li&gt;
&lt;li&gt;Lower transaction fees&lt;/li&gt;
&lt;li&gt;No platform dependency or gating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose ACP if you value:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster implementation with less infrastructure&lt;/li&gt;
&lt;li&gt;Direct access to ChatGPT's user base&lt;/li&gt;
&lt;li&gt;Managed experience with less operational overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Choose both if you value revenue.&lt;/strong&gt; The protocols are complementary, the implementation overlap is significant, and the agentic commerce market is growing fast enough that limiting yourself to one agent ecosystem is leaving money on the table.&lt;/p&gt;

&lt;p&gt;The protocol war benefits merchants. Both Google and OpenAI are competing to make their protocol easier to adopt, more feature-rich, and more widely supported. Both protocols are open. And the shared infrastructure underneath — product APIs, checkout flows, payment processing — means that supporting both is incrementally less work than building either from scratch.&lt;/p&gt;

&lt;p&gt;The AI agents are already shopping. The question is whether they can find your store.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Get started:&lt;/strong&gt; &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;Validate your UCP profile&lt;/a&gt; | &lt;a href="https://ucptools.dev/generate" rel="noopener noreferrer"&gt;Generate a UCP profile&lt;/a&gt; | &lt;a href="https://ucptools.dev/dashboard/analytics" rel="noopener noreferrer"&gt;Monitor agent traffic&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclaimer: UCP is an open standard by Google and Shopify. ACP is an open standard by OpenAI and Stripe. UCPtools is an independent community tool -- not affiliated with Google, Shopify, OpenAI, or Stripe.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>ai</category>
      <category>acp</category>
      <category>ucp</category>
    </item>
    <item>
      <title>Zero-Click Retail Is Here: What Every E-Commerce Merchant Needs to Know in 2026</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Thu, 26 Feb 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/ucptools/zero-click-retail-is-here-what-every-e-commerce-merchant-needs-to-know-in-2026-3nic</link>
      <guid>https://dev.to/ucptools/zero-click-retail-is-here-what-every-e-commerce-merchant-needs-to-know-in-2026-3nic</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;AI agents are buying products on behalf of users without ever loading your website. Google AI Mode, ChatGPT, Perplexity, and Copilot are completing full purchase flows through API calls. No browser. No clicks. No page views.&lt;/p&gt;

&lt;p&gt;Here is how fast the shift is happening:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;93% of AI Mode searches end without a click&lt;/td&gt;
&lt;td&gt;Users get answers — and now purchases — without visiting your site (&lt;a href="https://www.amsive.com/insights/seo/googles-ai-mode-93-of-queries-result-in-zero-clicks/" rel="noopener noreferrer"&gt;Amsive, 2026&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Organic CTR down 61% from AI Overviews&lt;/td&gt;
&lt;td&gt;Google is answering queries directly, collapsing the click-through funnel (&lt;a href="https://positiondigital.co.uk/seo/how-google-ai-overviews-are-impacting-seo/" rel="noopener noreferrer"&gt;Position Digital, 2026&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;70% of consumers using AI for shopping&lt;/td&gt;
&lt;td&gt;Not a niche — the mainstream is already there (&lt;a href="https://datadome.co/" rel="noopener noreferrer"&gt;DataDome, 2025-2026&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4x increase in AI bot traffic since Jan 2025&lt;/td&gt;
&lt;td&gt;AI agents are crawling and transacting at scale (&lt;a href="https://datadome.co/" rel="noopener noreferrer"&gt;DataDome&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1M+ Shopify merchants coming to UCP&lt;/td&gt;
&lt;td&gt;The protocol is not theoretical — it is rolling out across the largest e-commerce platform on earth (&lt;a href="https://www.shopify.com/" rel="noopener noreferrer"&gt;Shopify&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are an e-commerce merchant, this article explains what is happening, how AI shopping actually works at a technical level, which protocols matter, and the five things you should do right now.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Zero-Click Shift
&lt;/h2&gt;

&lt;p&gt;For twenty years, e-commerce has followed a simple model: drive traffic to your website, convert visitors into buyers. SEO, paid ads, social media, email marketing — every channel is designed to generate clicks that land on your storefront. Your analytics stack measures those clicks. Your conversion funnel starts with a page view.&lt;/p&gt;

&lt;p&gt;That model is breaking.&lt;/p&gt;

&lt;p&gt;In February 2026, Amsive published research showing that &lt;strong&gt;93% of queries in Google's AI Mode result in zero clicks&lt;/strong&gt;. The user asks a question, the AI answers it, and no one visits the source website. This is not limited to informational queries. Google AI Mode now supports agentic shopping — the AI browses products, compares options, and completes purchases directly inside the AI interface.&lt;/p&gt;

&lt;p&gt;Position Digital found that &lt;strong&gt;organic click-through rates have dropped 61%&lt;/strong&gt; on queries where AI Overviews appear. When Google provides the answer (or the product) inline, there is no reason for the user to click through. The click itself is becoming optional.&lt;/p&gt;

&lt;p&gt;This is not a temporary dip. It is structural.&lt;/p&gt;

&lt;p&gt;Google announced in February 2026 that &lt;strong&gt;AI Mode shopping now includes merchants from Etsy and Wayfair&lt;/strong&gt;, with shoppable product results appearing directly in AI conversations. Users can browse catalogs, compare prices, read reviews, and complete checkout — all without leaving the AI interface.&lt;/p&gt;

&lt;p&gt;Meanwhile, &lt;strong&gt;70% of consumers report using AI tools for shopping tasks&lt;/strong&gt; according to DataDome research. Not "considering" or "experimenting with" — actively using. And AI bot traffic has &lt;strong&gt;quadrupled since January 2025&lt;/strong&gt;, meaning the infrastructure for AI-driven commerce is scaling faster than most merchants realize.&lt;/p&gt;

&lt;p&gt;The search box used to be the front door to your store. Now it is the entire store. The AI handles discovery, browsing, selection, and purchase. Your website is the backend.&lt;/p&gt;




&lt;h2&gt;
  
  
  How AI Shopping Actually Works
&lt;/h2&gt;

&lt;p&gt;To understand why this matters, you need to understand how an AI shopping agent completes a purchase. The flow is fundamentally different from a human shopper visiting your website.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Traditional Flow (Human Shopper)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User searches "wireless earbuds under $80"
  → Clicks a Google result
    → Lands on your product page (page view)
      → Browses products (click events)
        → Adds to cart (JS event)
          → Enters payment info (form submission)
            → Completes checkout (conversion)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every step generates a page view, a cookie, a JavaScript event. Your analytics sees everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  The AI Agent Flow (Zero-Click)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User says "buy me wireless earbuds under $80"
  → AI agent queries your /.well-known/ucp endpoint (API call)
    → Agent parses your capabilities, products, payment methods (JSON)
      → Agent browses product catalog (API call)
        → Agent creates checkout session (API call)
          → Agent submits payment credentials (API call)
            → Order completed (API response)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No browser opens. No JavaScript runs. No cookies are set. No page view is recorded. The entire transaction happens through API calls between the AI agent and your store's UCP (Universal Commerce Protocol) endpoints.&lt;/p&gt;

&lt;p&gt;From the user's perspective, they said "buy me earbuds" and received a confirmation. From your GA4 dashboard's perspective, nothing happened. The sale exists in your payment processor and your order management system, but your analytics attributes it to "direct" or "other" — if it sees it at all.&lt;/p&gt;

&lt;p&gt;This is not a theoretical future. Google AI Mode is doing this today with Gemini. ChatGPT is doing this through its own protocol. Perplexity, Claude, and Copilot are all building or shipping agent commerce capabilities.&lt;/p&gt;

&lt;p&gt;The transaction happens. The revenue appears. But your traditional analytics stack is blind to how and why it happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Three Protocols
&lt;/h2&gt;

&lt;p&gt;Three competing (and partially overlapping) protocols are enabling AI agent commerce in 2026. Understanding them matters because each has different technical requirements, different ecosystems, and different merchant adoption paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  UCP — Universal Commerce Protocol
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Developed by:&lt;/strong&gt; Google and Shopify, with 25+ launch partners&lt;br&gt;
&lt;strong&gt;Powers:&lt;/strong&gt; Google AI Mode shopping, Gemini agent commerce&lt;br&gt;
&lt;strong&gt;How it works:&lt;/strong&gt; Merchants publish a JSON profile at &lt;code&gt;/.well-known/ucp&lt;/code&gt; describing their store's capabilities, products, checkout flow, and payment handlers. AI agents discover this profile, parse it, and transact through the defined API endpoints.&lt;br&gt;
&lt;strong&gt;Scale:&lt;/strong&gt; Over 1 million Shopify merchants are expected to gain UCP support as Shopify rolls out the protocol across its platform. Google's integration means any Gemini-powered surface — Search, AI Mode, Android, Google Assistant — can discover and shop UCP-enabled stores.&lt;br&gt;
&lt;strong&gt;Key detail:&lt;/strong&gt; UCP is an open specification. Any AI agent can implement it, not just Google's. The protocol is designed for a multi-agent future.&lt;/p&gt;
&lt;h3&gt;
  
  
  ACP — Agent Commerce Protocol
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Developed by:&lt;/strong&gt; OpenAI and Stripe&lt;br&gt;
&lt;strong&gt;Powers:&lt;/strong&gt; ChatGPT shopping, ChatGPT Instant Checkout&lt;br&gt;
&lt;strong&gt;How it works:&lt;/strong&gt; Merchants integrate through Stripe's payment infrastructure. AI agents use ACP endpoints to discover products and complete purchases using Stripe as the payment rail.&lt;br&gt;
&lt;strong&gt;Scale:&lt;/strong&gt; OpenAI launched ChatGPT Instant Checkout in January 2026 with a &lt;strong&gt;4% transaction fee&lt;/strong&gt; on AI-initiated purchases (&lt;a href="https://www.pymnts.com/" rel="noopener noreferrer"&gt;PYMNTS, Jan 2026&lt;/a&gt;). The initial rollout includes select merchant categories, with broader availability planned for mid-2026.&lt;br&gt;
&lt;strong&gt;Key detail:&lt;/strong&gt; ACP ties closely to Stripe's existing merchant base. If you already use Stripe, ACP adoption has a lower barrier. The 4% fee is on top of standard Stripe processing fees.&lt;/p&gt;
&lt;h3&gt;
  
  
  Microsoft Copilot Checkout
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Developed by:&lt;/strong&gt; Microsoft&lt;br&gt;
&lt;strong&gt;Powers:&lt;/strong&gt; Copilot shopping across Bing, Edge, Windows, and Microsoft 365&lt;br&gt;
&lt;strong&gt;How it works:&lt;/strong&gt; Integration through Microsoft's merchant ecosystem, including Bing Shopping and Microsoft Advertising.&lt;br&gt;
&lt;strong&gt;Scale:&lt;/strong&gt; Still in earlier stages compared to UCP and ACP, but Microsoft's distribution through Windows, Edge, and Office means it reaches a large installed base by default.&lt;br&gt;
&lt;strong&gt;Key detail:&lt;/strong&gt; Copilot's commerce capabilities are expanding with each release. Microsoft has been less public about the protocol specifics but is actively onboarding merchants.&lt;/p&gt;
&lt;h3&gt;
  
  
  Which Protocol Should You Support?
&lt;/h3&gt;

&lt;p&gt;The honest answer: probably all of them, eventually. In practice, &lt;strong&gt;UCP is the priority for most merchants&lt;/strong&gt; because Google Search is still the dominant product discovery channel, and Shopify's adoption means the tooling and infrastructure will mature fastest. ACP matters if ChatGPT is a significant discovery channel for your product category. Copilot matters for B2B and enterprise scenarios where Microsoft's ecosystem dominates.&lt;/p&gt;

&lt;p&gt;You do not need to choose one. The protocols are not mutually exclusive. A single store can serve UCP, ACP, and Copilot agents simultaneously.&lt;/p&gt;


&lt;h2&gt;
  
  
  What This Means for Merchants
&lt;/h2&gt;

&lt;p&gt;The instinctive reaction to "clicks are declining" is panic. If fewer people visit your website, revenue must be declining too. Right?&lt;/p&gt;

&lt;p&gt;Not necessarily. Here is the more nuanced picture:&lt;/p&gt;
&lt;h3&gt;
  
  
  Traffic Is Declining, but Revenue Is Shifting
&lt;/h3&gt;

&lt;p&gt;The AI agent that buys wireless earbuds from your store without generating a page view still generates revenue. The order still ships. The payment still processes. The customer still receives the product. The economic transaction is identical — it just arrives through a different channel.&lt;/p&gt;

&lt;p&gt;What is actually happening is a &lt;strong&gt;channel shift&lt;/strong&gt;, not a revenue collapse. Revenue that previously came through organic search clicks is migrating to AI agent transactions. The total addressable market is not shrinking. The distribution mechanism is changing.&lt;/p&gt;

&lt;p&gt;The merchants who will struggle are those who are only set up to receive traffic through browsers and only measure success through page views. The merchants who will thrive are those who are discoverable by AI agents and can complete transactions through protocol-level APIs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Traditional Analytics Are Blind
&lt;/h3&gt;

&lt;p&gt;This is the urgent problem. If 10% of your revenue is coming through AI agent transactions today and your GA4 dashboard shows zero AI agent activity, you are making business decisions on incomplete data. You might cut a product line that AI agents are selling well. You might change a checkout flow that breaks agent compatibility. You might think your marketing is underperforming when the missing revenue is simply arriving through a channel you cannot see.&lt;/p&gt;

&lt;p&gt;The analytics gap is not a nice-to-have issue. It is a decision-quality issue. You need tools that can track the agentic commerce funnel — discovery, browse, checkout, payment, and order — and attribute it correctly.&lt;/p&gt;
&lt;h3&gt;
  
  
  Product Data Quality Is Now Mission-Critical
&lt;/h3&gt;

&lt;p&gt;When a human shopper visits your product page, they can look at photos, read descriptions, interpret context, and make judgment calls. An AI agent cannot. It reads your structured data — product schemas, pricing fields, availability status, shipping options — and makes decisions based on that data alone.&lt;/p&gt;

&lt;p&gt;If your product titles are vague, the agent may skip your products. If your schema markup is incomplete, the agent may not understand your catalog. If your pricing data is inconsistent between your feed and your site, the agent may encounter errors at checkout.&lt;/p&gt;

&lt;p&gt;Product data quality has always mattered for SEO. In the age of AI shopping, it is the difference between being discoverable and being invisible.&lt;/p&gt;


&lt;h2&gt;
  
  
  5 Things You Should Do Right Now
&lt;/h2&gt;

&lt;p&gt;Here is the actionable checklist. These are ordered by impact and effort — the first two take minutes, the last three take days.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Validate Your UCP Profile
&lt;/h3&gt;

&lt;p&gt;If you have a UCP profile (or think you might — Shopify is rolling these out automatically), validate it. A profile with structural errors, missing required fields, or broken endpoint references means AI agents cannot transact on your store even if they discover it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to do it:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt; and run the validator. It checks four levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structural:&lt;/strong&gt; JSON format, required fields, version format&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules:&lt;/strong&gt; Namespace/origin binding, HTTPS requirements, signing keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network:&lt;/strong&gt; Remote schema verification, endpoint accessibility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK:&lt;/strong&gt; Official UCP specification compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The validator is free, requires no signup, and gives you a detailed report with specific error codes and fix suggestions. If your profile passes all four levels, agents can discover and transact on your store. If it fails, the report tells you exactly what to fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time:&lt;/strong&gt; 2 minutes&lt;br&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; Free&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Check Your ACP Readiness
&lt;/h3&gt;

&lt;p&gt;If you use Stripe, you may already be partially ACP-ready. The ACP protocol builds on Stripe's existing payment infrastructure, but there are specific requirements around product catalog exposure, checkout session handling, and agent authentication.&lt;/p&gt;

&lt;p&gt;UCPtools includes an ACP readiness checker at &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;ucptools.dev&lt;/a&gt; that evaluates your store's compatibility with the Agent Commerce Protocol. It identifies what you already have in place and what gaps remain.&lt;/p&gt;

&lt;p&gt;Even if ACP is not your immediate priority, knowing your readiness baseline is useful for planning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time:&lt;/strong&gt; 5 minutes&lt;br&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; Free&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Audit Your Product Data and Schema Markup
&lt;/h3&gt;

&lt;p&gt;AI agents rely on structured data to understand your products. This means your product feed, your schema.org markup, and your UCP product catalog need to be accurate, complete, and consistent.&lt;/p&gt;

&lt;p&gt;Run an audit focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Product titles:&lt;/strong&gt; Clear, specific, not stuffed with keywords. "Sony WH-1000XM5 Wireless Noise-Cancelling Headphones" is better than "Best Headphones SALE 2026!!!" for AI agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing data:&lt;/strong&gt; Ensure prices in your product feed match your live site. AI agents cross-reference these.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability:&lt;/strong&gt; If a product is out of stock, your structured data should say so. Agents that create checkout sessions for unavailable products generate errors and drop off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema markup:&lt;/strong&gt; Ensure &lt;code&gt;Product&lt;/code&gt;, &lt;code&gt;Offer&lt;/code&gt;, &lt;code&gt;AggregateRating&lt;/code&gt;, and &lt;code&gt;Review&lt;/code&gt; schemas are present and valid. Use Google's Rich Results Test to check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product identifiers:&lt;/strong&gt; GTINs, MPNs, and brand fields help agents match your products to user queries. Missing identifiers reduce discoverability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UCPtools includes a &lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;Feed Analyzer&lt;/a&gt; that can parse your product feed and identify issues that would cause problems for AI agents — missing fields, inconsistent pricing, broken image URLs, and more.&lt;/p&gt;

&lt;p&gt;Industry data suggests that &lt;strong&gt;product data improvements show measurable results in 2-4 weeks&lt;/strong&gt; as AI agents re-crawl and re-index your catalog. This is one of the highest-ROI investments you can make right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time:&lt;/strong&gt; 1-3 days depending on catalog size&lt;br&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; Free tools available; may need developer time for fixes&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Set Up AI Agent Analytics
&lt;/h3&gt;

&lt;p&gt;You cannot optimize what you cannot measure. Traditional analytics tools do not track AI agent transactions because AI agents do not execute JavaScript, accept cookies, or generate page views. You need purpose-built analytics that track the agentic commerce funnel.&lt;/p&gt;

&lt;p&gt;The agentic commerce funnel has five stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Discovery&lt;/strong&gt; — Agent hits &lt;code&gt;/.well-known/ucp&lt;/code&gt; to find your store&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse&lt;/strong&gt; — Agent queries your product catalog&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checkout&lt;/strong&gt; — Agent creates a checkout session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment&lt;/strong&gt; — Agent submits payment credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order&lt;/strong&gt; — Transaction completes, revenue is recorded&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each stage maps to specific API calls. Tracking middleware intercepts these calls, classifies the agent (Gemini, ChatGPT, Perplexity, Claude, Copilot), and records the funnel event.&lt;/p&gt;

&lt;p&gt;UCPtools Analytics V2 tracks the full funnel for both UCP and ACP protocols. You can explore the interactive demo at &lt;a href="https://ucptools.dev/dashboard/analytics?demo=true" rel="noopener noreferrer"&gt;ucptools.dev/dashboard/analytics?demo=true&lt;/a&gt; — it loads realistic sample data showing 2,847 events, $12,450 in agentic revenue, and per-agent conversion rates. No signup required to explore the demo.&lt;/p&gt;

&lt;p&gt;For production tracking, the &lt;a href="https://ucptools.dev/pricing" rel="noopener noreferrer"&gt;Starter plan&lt;/a&gt; at $9/mo includes full funnel analytics, agent comparison, error analysis, and capability gap reporting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time:&lt;/strong&gt; 30 minutes for middleware setup&lt;br&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; Free demo; $9/mo for production tracking&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Monitor Your AI Traffic Starting Today
&lt;/h3&gt;

&lt;p&gt;Even before you set up full funnel analytics, you can start monitoring AI agent traffic in your existing server logs. Look for these User-Agent patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;Googlebot              — Google's crawler (may include UCP discovery)&lt;/span&gt;
&lt;span class="s"&gt;Google-Extended         — Gemini/AI Mode specific&lt;/span&gt;
&lt;span class="s"&gt;GPTBot                 — OpenAI/ChatGPT&lt;/span&gt;
&lt;span class="s"&gt;ChatGPT-User           — ChatGPT browsing mode&lt;/span&gt;
&lt;span class="s"&gt;PerplexityBot          — Perplexity AI&lt;/span&gt;
&lt;span class="s"&gt;ClaudeBot / anthropic  — Anthropic's Claude&lt;/span&gt;
&lt;span class="s"&gt;CopilotBot             — Microsoft Copilot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check your access logs for requests to &lt;code&gt;/.well-known/ucp&lt;/code&gt;. If you see hits there, AI agents are already discovering your store. Check the response codes — 200 means they found a valid profile, 404 means they looked and found nothing.&lt;/p&gt;

&lt;p&gt;Also monitor requests to your product API endpoints and checkout endpoints from these user agents. Any activity there means agents are not just discovering you — they are attempting to browse and buy.&lt;/p&gt;

&lt;p&gt;You can do this with a simple log grep:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check for AI agent discovery attempts&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"well-known/ucp"&lt;/span&gt; /var/log/nginx/access.log

&lt;span class="c"&gt;# Check for specific AI agents&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"GPTBot|Google-Extended|PerplexityBot|ClaudeBot|CopilotBot"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/nginx/access.log | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see activity, you have AI agent traffic today. If you see 404s on &lt;code&gt;/.well-known/ucp&lt;/code&gt;, agents are looking for you and not finding you — which means setting up a UCP profile is an immediate revenue opportunity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time:&lt;/strong&gt; 15 minutes&lt;br&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; Free&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Zero-click retail is not the death of e-commerce. It is the transformation of e-commerce.&lt;/p&gt;

&lt;p&gt;The economic transaction has not disappeared. People still want products. They still pay money. Merchants still fulfill orders. What has changed is the intermediary. Instead of a browser rendering your product page and a human clicking "Add to Cart," an AI agent parses your product data and completes the purchase through an API call.&lt;/p&gt;

&lt;p&gt;The merchants who will win this transition are the ones who treat AI agents as a first-class sales channel — not a threat to be blocked, not a curiosity to be ignored, but a channel to be optimized with the same rigor applied to organic search, paid ads, and email.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Being discoverable&lt;/strong&gt; through UCP, ACP, and structured data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Being transactable&lt;/strong&gt; with working checkout flows that agents can complete&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Being measurable&lt;/strong&gt; with analytics that actually track the agentic funnel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Being optimized&lt;/strong&gt; by fixing errors, adding capabilities, and improving product data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 93% zero-click stat is not a death sentence. It is a signal that the channel is shifting. One million Shopify merchants are about to get UCP profiles. Google AI Mode is adding new merchant categories every month. ChatGPT Instant Checkout is rolling out with a growing merchant base.&lt;/p&gt;

&lt;p&gt;The wave is coming. The question is whether you are set up to catch it or whether AI agents will discover your store, find nothing, and move on to your competitor.&lt;/p&gt;

&lt;p&gt;Start with the five steps above. Validate your profile, check your readiness, audit your data, set up analytics, and monitor your traffic. The tools are free. The data improvements show results in weeks, not months. And the merchants who move first will have the analytics history, the optimization insights, and the agent compatibility that latecomers will spend months catching up on.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;UCP Validator&lt;/a&gt; — validate your UCP profile for free&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;AI Agent Simulator&lt;/a&gt; — test how AI agents interact with your store&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ucptools.dev/dashboard/analytics?demo=true" rel="noopener noreferrer"&gt;Analytics V2 Demo&lt;/a&gt; — explore the full agentic analytics dashboard&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ucptools.dev" rel="noopener noreferrer"&gt;Feed Analyzer&lt;/a&gt; — audit your product data for AI readiness&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ucp.dev" rel="noopener noreferrer"&gt;UCP Specification&lt;/a&gt; — the official protocol spec from Google and Shopify&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://agentcommerceprotocol.com" rel="noopener noreferrer"&gt;ACP Specification&lt;/a&gt; — the official Agent Commerce Protocol spec&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.google/products/search/" rel="noopener noreferrer"&gt;Google AI Mode Shopping Announcement&lt;/a&gt; — Google's rollout details&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;What is your experience with AI agent traffic on your store? Are you seeing hits on &lt;code&gt;/.well-known/ucp&lt;/code&gt; in your logs? Have you noticed revenue appearing in your payment processor that GA4 cannot explain? Share your observations in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclaimer: UCP is an open standard by Google and Shopify. ACP is an open standard by OpenAI and Stripe. UCPtools is an independent community tool — not affiliated with Google, Shopify, OpenAI, or Stripe.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ecommerce</category>
      <category>ai</category>
      <category>ucp</category>
      <category>seo</category>
    </item>
    <item>
      <title>Agorio v0.3: Triple-Protocol AI Agents - UCP, ACP, and MCP in One SDK</title>
      <dc:creator>Peter</dc:creator>
      <pubDate>Fri, 20 Feb 2026 14:18:47 +0000</pubDate>
      <link>https://dev.to/ucptools/agorio-v03-triple-protocol-ai-agents-ucp-acp-and-mcp-in-one-sdk-2402</link>
      <guid>https://dev.to/ucptools/agorio-v03-triple-protocol-ai-agents-ucp-acp-and-mcp-in-one-sdk-2402</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Nolpak14/agorio" rel="noopener noreferrer"&gt;Agorio v0.3&lt;/a&gt;&lt;/strong&gt; is the first commerce agent SDK that supports all three open protocols - &lt;strong&gt;UCP&lt;/strong&gt; (Google/Shopify), &lt;strong&gt;ACP&lt;/strong&gt; (OpenAI/Stripe), and &lt;strong&gt;MCP&lt;/strong&gt; (JSON-RPC) - from a single codebase. Also shipping: 4 LLM adapters (including Ollama for offline agents), a plugin system, observability, and a CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @agorio/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;191 tests. MIT license. &lt;a href="https://github.com/Nolpak14/agorio" rel="noopener noreferrer"&gt;Star the repo&lt;/a&gt; if this is useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed Since v0.1
&lt;/h2&gt;

&lt;p&gt;A few weeks ago, we &lt;a href="https://dev.to/ucptools/build-an-ai-shopping-agent-in-50-lines-of-typescript-ggd"&gt;launched Agorio&lt;/a&gt; with UCP support and a single Gemini adapter. Here's where we are now:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;v0.1&lt;/th&gt;
&lt;th&gt;v0.3&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Protocols&lt;/td&gt;
&lt;td&gt;UCP only&lt;/td&gt;
&lt;td&gt;UCP + ACP + MCP (auto-detect)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM adapters&lt;/td&gt;
&lt;td&gt;Gemini&lt;/td&gt;
&lt;td&gt;Gemini, Claude, OpenAI, Ollama&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streaming&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;runStream()&lt;/code&gt; async generator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Custom tools via &lt;code&gt;AgentPlugin&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Logging, tracing, metrics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLI&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx agorio&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mock servers&lt;/td&gt;
&lt;td&gt;1 (UCP)&lt;/td&gt;
&lt;td&gt;3 (UCP, ACP, MCP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tests&lt;/td&gt;
&lt;td&gt;37&lt;/td&gt;
&lt;td&gt;191&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let me walk through the highlights.&lt;/p&gt;




&lt;h2&gt;
  
  
  Triple-Protocol Auto-Detection
&lt;/h2&gt;

&lt;p&gt;The agentic commerce space has three protocols now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;UCP&lt;/strong&gt; - Google AI Mode (75M+ daily users), Shopify merchants&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACP&lt;/strong&gt; - ChatGPT Instant Checkout (800M+ weekly users), Stripe merchants&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; - JSON-RPC 2.0 transport for tool-based interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most SDKs force you to pick one. Agorio auto-detects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ClaudeAdapter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClaudeAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_API_KEY&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;acpOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://merchant.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MERCHANT_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Agent auto-detects UCP, ACP, or MCP - your code doesn't change&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Buy wireless headphones from shop.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;discover_merchant&lt;/code&gt; runs, Agorio tries UCP first (&lt;code&gt;/.well-known/ucp&lt;/code&gt;), checks for MCP transport support, then falls back to ACP. All 12 built-in tools route through whichever protocol the merchant speaks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Nolpak14/agorio" rel="noopener noreferrer"&gt;Star on GitHub&lt;/a&gt; - it helps other developers find this.&lt;/p&gt;




&lt;h2&gt;
  
  
  Run Agents Offline with Ollama
&lt;/h2&gt;

&lt;p&gt;No API keys? No problem. The new &lt;code&gt;OllamaAdapter&lt;/code&gt; connects to a local Ollama instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OllamaAdapter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MockMerchant&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@agorio/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;merchant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MockMerchant&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;merchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OllamaAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;llama3.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s2"&gt;`Browse products at &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;merchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;merchant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fully offline. No API costs. Same &lt;code&gt;LlmAdapter&lt;/code&gt; interface as the cloud adapters - swap one line to switch between local and cloud.&lt;/p&gt;

&lt;p&gt;All four adapters support function calling and streaming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GeminiAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GEMINI_API_KEY&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;   &lt;span class="c1"&gt;// Google&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClaudeAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_API_KEY&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;// Anthropic&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OpenAIAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OPENAI_API_KEY&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;    &lt;span class="c1"&gt;// OpenAI&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OllamaAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;llama3.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;                    &lt;span class="c1"&gt;// Local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Plugin System: Add Custom Tools
&lt;/h2&gt;

&lt;p&gt;The 12 built-in shopping tools cover discovery, search, cart, checkout, and order tracking. But what if you need something custom? Register a plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;priceAlertPlugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AgentPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;check_price_alert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Check if a product price is below the user threshold&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;max_price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;product_name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;max_price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;max_price&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Your custom logic here&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;current_price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;29.99&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClaudeAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_API_KEY&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;priceAlertPlugin&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM sees your custom tool alongside the built-in ones and can call it during the agent loop. Name conflicts with built-in tools throw at construction time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Streaming: Watch the Agent Think
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;runStream()&lt;/code&gt; to get real-time events as the agent reasons and acts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Buy me headphones&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text_delta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tool_call&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`\nCalling &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toolName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tool_result&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Got result from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toolName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;Done:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each adapter implements &lt;code&gt;chatStream()&lt;/code&gt; using its provider's native streaming API. The agent yields events as the LLM thinks and acts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Observability: Logging, Tracing, Metrics
&lt;/h2&gt;

&lt;p&gt;Production agents need visibility. Agorio v0.3 ships three observability hooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ShoppingAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ClaudeAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_API_KEY&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;

  &lt;span class="c1"&gt;// Structured logging&lt;/span&gt;
  &lt;span class="na"&gt;onLog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AgentLogEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;level&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Distributed tracing&lt;/span&gt;
  &lt;span class="na"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;startSpan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startSpan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;attributes&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// After a run, get usage metrics&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Buy headphones&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// result includes: promptTokens, completionTokens, llmCalls, toolCalls, latency&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plug in your existing OpenTelemetry setup, Datadog, or any logging backend. The interface is minimal - you bring your own implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  CLI: &lt;code&gt;npx agorio&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Explore UCP merchants and scaffold projects from the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Discover a merchant's capabilities&lt;/span&gt;
npx agorio discover shop.example.com

&lt;span class="c"&gt;# Start mock merchants for local development&lt;/span&gt;
npx agorio mock &lt;span class="nt"&gt;--port&lt;/span&gt; 3456

&lt;span class="c"&gt;# Scaffold a new agent project&lt;/span&gt;
npx agorio init my-shopping-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No global install needed. The CLI ships with the SDK.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @agorio/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/Nolpak14/agorio" rel="noopener noreferrer"&gt;github.com/Nolpak14/agorio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;a href="https://www.npmjs.com/package/@agorio/sdk" rel="noopener noreferrer"&gt;@agorio/sdk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website&lt;/strong&gt;: &lt;a href="https://agorio.dev" rel="noopener noreferrer"&gt;agorio.dev&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;191 tests. 4 adapters. 3 protocols. Plugin system. CLI. MIT license.&lt;/p&gt;

&lt;p&gt;The protocols are live, merchants are onboarding. &lt;a href="https://github.com/Nolpak14/agorio" rel="noopener noreferrer"&gt;Star the repo&lt;/a&gt; and come build with us.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Agorio is open source and not affiliated with Google, Shopify, OpenAI, or Stripe. UCP, ACP, and MCP are open standards maintained by their respective organizations.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ucp</category>
      <category>ai</category>
      <category>ecommerce</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
