mccormick.com
Audited 1 day ago· shopify
Agent-readiness across all five AI commerce surfaces.
Surfaces — click to filter
13 failing · 5 not checked · 18 shown
5 checks couldn't run on this store — each is listed below with the reason. Your score reflects only what we could verify.
Set price as a number and priceCurrency as an ISO 4217 code
Why this matters: Agents need a price with a currency to show and compare your product.
Findings (10)
Parsed Offer price and priceCurrency on Product JSON-LD across 20 sampled product pages (10 valid, 50%).
How: Parse Offer price (or AggregateOffer lowPrice) as a parseable numeric price ≥ 0; require priceCurrency to match /^[A-Z]{3}$/i.
Coverage
10/20 · 50%
- Offer is missing a numeric price or valid priceCurrencyCRITICAL× 10
Render
priceas a number andpriceCurrencyas a 3-letter ISO 4217 code.Affected (10)
- /products/stubbs-original-baked-beansmissing/invalid `price`, missing/invalid `priceCurrency`
- /products/stubbs-sticky-sweet-baked-beansmissing/invalid `price`, missing/invalid `priceCurrency`
- /products/mccormick-ghost-pepper-ranch-seasonin…missing/invalid `price`, missing/invalid `priceCurrency`
- /products/mccormick-gourmet-garlic-truffle-salt…missing/invalid `price`, missing/invalid `priceCurrency`
- /products/mccormick-rosemary-lemon-seasoning-2-…missing/invalid `price`, missing/invalid `priceCurrency`
- /products/mccormick-savory-herb-parmesan-season…missing/invalid `price`, missing/invalid `priceCurrency`
- /products/mccormick-sesame-ginger-seasoning-2-5…missing/invalid `price`, missing/invalid `priceCurrency`
- /products/mc-spicy-sicilian-seasmissing/invalid `price`, missing/invalid `priceCurrency`
- /products/frenchs-goomis-green-mustard-8-0-ozmissing/invalid `price`, missing/invalid `priceCurrency`
- /products/frenchs-minion-yellow-mustard-8-0-ozmissing/invalid `price`, missing/invalid `priceCurrency`
Enforce HTTPS sitewide and ship a Strict-Transport-Security header with max-age ≥ 6 months
Why this matters: AI agents and payment flows refuse plain HTTP; weak HSTS is treated as effectively no HSTS by trust-and-safety scanners.
Findings (1)
Confirmed the homepage is HTTPS (status 200), probed http://mccormick.com/ for redirect behaviour, and parsed the Strict-Transport-Security header (value: "max-age=7889238").
How: URL scheme + homepage status check, an http://host/ redirect probe through politeFetch, and a Strict-Transport-Security max-age parse (RFC 6797; ≥ 180-day threshold).
- HSTS max-age is below the 6-month minimumCRITICAL
/parsed max-age = 7889238s (need ≥ 15552000s = 180 days)
What we found
max-age=7889238What we expected
Strict-Transport-Security: max-age=31536000; includeSubDomainsBump
max-ageto at least 15552000 (180 days). 31536000 (1 year) is required for preload-list inclusion.
Add every required top-level key to the UCP profile
Why this matters: A profile missing one of the four required keys is treated as non-conformant — agent runtimes fall back to default behaviour and may skip the merchant.
Findings (1)
Profile is missing required key(s): signing_keys.
How: Read the profile root (or top-level ucp wrapper) and verify the presence of version, services, capabilities, and signing_keys keys.
- Required top-level key
signing_keysis missingHIGHWhat we expected
Add a top-level "signing_keys" field to the JSON document (empty array/object is fine).Set
signing_keysat the root of the JSON document.
Use a canonical Schema.org availability IRI on every Offer
Why this matters: Agents suppress out-of-stock or ambiguous items; a valid availability URL keeps you eligible.
Findings (10)
Checked Offer availability on 20 sampled product pages with an Offer (10 use a canonical Schema.org URL, 50%).
How: On each Offer, accept availability only if it matches one of the canonical Schema.org ItemAvailability IRIs (http or https, trailing slash optional).
Coverage
10/20 · 50%
- Offer
availabilityis missing or not a canonical Schema.org URLHIGH× 10Use https://schema.org/InStock (or OutOfStock / PreOrder / BackOrder).
Affected (10)
- /products/stubbs-original-baked-beansvalue: https://schema.org/InStoreOnly
- /products/stubbs-sticky-sweet-baked-beansvalue: https://schema.org/InStoreOnly
- /products/mccormick-ghost-pepper-ranch-seasonin…value: https://schema.org/InStoreOnly
- /products/mccormick-gourmet-garlic-truffle-salt…value: https://schema.org/InStoreOnly
- /products/mccormick-rosemary-lemon-seasoning-2-…value: https://schema.org/InStoreOnly
- /products/mccormick-savory-herb-parmesan-season…value: https://schema.org/InStoreOnly
- /products/mccormick-sesame-ginger-seasoning-2-5…value: https://schema.org/InStoreOnly
- /products/mc-spicy-sicilian-seasvalue: https://schema.org/InStoreOnly
- /products/frenchs-goomis-green-mustard-8-0-ozvalue: https://schema.org/InStoreOnly
- /products/frenchs-minion-yellow-mustard-8-0-ozvalue: https://schema.org/InStoreOnly
Populate gtin on every branded Product node
Why this matters: GTINs let agents match your product to the same item elsewhere; without them you lose cross-catalog matching.
Findings (8)
Checked 20 sampled product pages for a GTIN in the Product JSON-LD (12 carry a valid GTIN, 60%).
How: Extract gtin / gtin8 / gtin12 / gtin13 / gtin14 from the first Product JSON-LD node on each PDP; validate digit length.
Coverage
12/20 · 60%
- No valid GTIN on this product pageHIGH× 8
Populate gtin/gtin8/gtin12/gtin13/gtin14 with the manufacturer's barcode.
Affected (8)
- /products/ultimate-summer-grilling-variety-pack…
- /products/cholula-new-favorites-bundle-4ct
- /products/stubbs-original-baked-beans
- /products/stubbs-sticky-sweet-baked-beans
- /products/mccormick-gourmet-global-exploration-…
- /products/mccormick-gourmet-best-sellers-bundle
- /products/us-french-s-minions-monsters-limited-…
- /products/cholula-hot-sauce-variety-pack-4ct-gr…
Skipped — the runner did not surface transport metadata
Context: If your UCP profile says `no-cache`, agent runtimes re-fetch on every interaction — brittle at scale and prone to rate-limit failures.
Why this was skipped
Wanted to inspect the UCP profile's Cache-Control header, but the runner did not surface transport metadata.
How: Parse the Cache-Control header on the /.well-known/ucp response; require public, max-age ≥ 60, and no no-store/no-cache/private.
- Transport metadata not available — runner update pendingLOW
This check activates once the runner (Task I1) populates ctx.wellKnownUcp.cacheControl.
Skipped — Profile declares no signing_keys; JWK validation has no entries to evaluate.
Context: Malformed JWK entries are rejected silently by agents — signed payloads cannot be verified and the merchant loses trust signal.
Why this was skipped
Profile declares no signing_keys; JWK validation has no entries to evaluate.
How: Walk signing_keys[] and validate each entry per RFC 7517 §4.1 (kty required) + RFC 7518 §6 (kty-specific required parameters). kid is OPTIONAL per RFC 7517 §4.5 and not enforced here.
Add includeSubDomains to your Strict-Transport-Security header
Why this matters: Without includeSubDomains, an HTTP subdomain (staging, mail, …) can be used to attack the apex's cookies.
Findings (1)
Inspected the homepage Strict-Transport-Security header ("max-age=7889238") and the includeSubDomains directive is absent.
How: Parse the homepage Strict-Transport-Security header for the includeSubDomains directive (RFC 6797 §6.1.2).
- HSTS header is missing the includeSubDomains directiveMEDIUM
What we found
max-age=7889238What we expected
Strict-Transport-Security: max-age=31536000; includeSubDomainsAppend
; includeSubDomainsto your STS header once every subdomain you operate supports HTTPS.
Add an Organization (or OnlineStore) JSON-LD block to your homepage with a contactPoint
Why this matters: Organization markup with a contactPoint tells AI agents who you are and how a shopper can reach you for support.
Findings (1)
Parsed the homepage JSON-LD looking for an Organization/OnlineStore node with a contactPoint, but no Organization-class node is present.
How: Parse homepage <script type="application/ld+json"> blocks, flatten @graph, and look for an Organization/OnlineStore/Store node with a contactPoint carrying email or telephone.
- No Organization/OnlineStore JSON-LD on homepageMEDIUM
What we expected
<script type="application/ld+json">{"@context":"https://schema.org","@type":"OnlineStore","name":"Example Store","url":"https://example.com","contactPoint":[{"@type":"ContactPoint","contactType":"customer service","email":"support@example.com"}]}</script>Add an Organization (or OnlineStore) JSON-LD block in the homepage
<head>with a contactPoint.
Publish a shipping policy page and link it from your site nav/footer
Why this matters: Agents quote shipping terms to shoppers; without a reachable shipping policy they fall back to vague defaults or skip your store.
Findings (1)
Probed 4 candidate shipping-policy paths (nav-discovered + platform-conventional) and none returned a 2xx body.
How: Discover candidate URLs by scoring homepage nav/footer anchors for shipping/delivery/dispatch keywords, then append platform-conventional paths; probe each with politeFetch and pass on the first 2xx with ≥200 stripped-body chars.
- No shipping policy page reachable at any candidate URLMEDIUM
statuses: /policies/shipping-policy=404, /shipping=404, /shipping-policy=404, /pages/shipping=404
Publish a shipping policy page at
/shipping-policy(or your platform's standard slug) with ≥200 chars of body text and link it from your footer.
Skipped — No MerchantReturnPolicy node carried a `merchantReturnLink` URL, so reachability has nothing to evaluate.
Context: A broken return-link makes Option B policies invisible — agents can't render or follow the link.
Why this was skipped
No MerchantReturnPolicy node carried a merchantReturnLink URL, so reachability has nothing to evaluate.
How: Collect every unique merchantReturnLink URL across all MerchantReturnPolicy nodes; probe each once via politeFetch (failSoft). 2xx counts as reachable.
Skipped — Profile declares no capabilities; required-field checks have nothing to evaluate.
Context: Capabilities missing version/spec/schema can't be matched against agent support tables — agents skip them silently.
Why this was skipped
Profile declares no capabilities; required-field checks have nothing to evaluate.
How: For each capabilities[] entry, require non-empty string values for version, spec, and schema.
Add preload to your Strict-Transport-Security header and submit to hstspreload.org
Why this matters: HSTS preload-list inclusion is the strongest downgrade protection available — first-time visits are protected too.
Findings (1)
Inspected the homepage Strict-Transport-Security header ("max-age=7889238") and the preload directive is absent.
How: Parse the homepage Strict-Transport-Security header for the preload directive (hstspreload.org vendor extension to RFC 6797).
- HSTS header is missing the preload directiveLOW
What we found
max-age=7889238What we expected
Strict-Transport-Security: max-age=31536000; includeSubDomains; preloadAppend
; preloadafterincludeSubDomainsand submit your domain at https://hstspreload.org/.
Add an AggregateRating to Product nodes when you have real reviews
Why this matters: Review ratings are a trust signal agents use to rank and filter products.
Findings (11)
Looked for a valid aggregateRating on Product JSON-LD across 20 sampled product pages (0 valid, 0%).
How: On each Product node, parse aggregateRating (or the first element if it's an array) and require ratingValue in [0,5] AND reviewCount or ratingCount ≥ 1.
Coverage
0/20 · 0%
- Product has no valid AggregateRating (ratingValue 0-5 + reviewCount/ratingCount ≥ 1)LOW× 10
Render
aggregateRatingfrom real review totals — never fabricate.Affected (10)
- /products/mccormick-12ct-spice-rack
- /products/mccormick-18ct-spice-rack
- /products/ultimate-summer-grilling-variety-pack…
- /products/cholula-new-favorites-bundle-4ct
- /products/stubbs-original-baked-beans
- /products/stubbs-sticky-sweet-baked-beans
- /products/mccormick-ghost-pepper-ranch-seasonin…
- /products/mccormick-gourmet-garlic-truffle-salt…
- /products/mccormick-rosemary-lemon-seasoning-2-…
- /products/mccormick-savory-herb-parmesan-season…
…and 1 more
Add descriptive alt text to product images (WCAG 2.x SC 1.1.1)
Why this matters: Alt text is the only text description AI agents and screen readers have for your product imagery.
Findings (11)
Parsed <img> alt attributes across 20 sampled product pages (0 have alt text on at least 80% of images).
How: Per PDP, count <img> tags via regex; a tag 'has alt text' when its alt attribute is present AND non-empty after trim. A PDP passes when it carries no <img> at all OR ≥80% of its <img> tags have non-empty alt.
Coverage
0/20 · 0%
- Most images on this product page lack alt textLOW× 10
What we expected
<img src="/img/sneaker.webp" alt="Red leather running shoe, side view" />Populate the alt attribute on each <img> with a description of what the image shows; use alt="" only for decorative images.
Affected (10)
- /products/mccormick-12ct-spice-rack76/118 <img> tags have non-empty alt (64%)
- /products/mccormick-18ct-spice-rack76/118 <img> tags have non-empty alt (64%)
- /products/ultimate-summer-grilling-variety-pack…63/103 <img> tags have non-empty alt (61%)
- /products/cholula-new-favorites-bundle-4ct65/96 <img> tags have non-empty alt (68%)
- /products/stubbs-original-baked-beans34/61 <img> tags have non-empty alt (56%)
- /products/stubbs-sticky-sweet-baked-beans34/61 <img> tags have non-empty alt (56%)
- /products/mccormick-ghost-pepper-ranch-seasonin…45/85 <img> tags have non-empty alt (53%)
- /products/mccormick-gourmet-garlic-truffle-salt…67/88 <img> tags have non-empty alt (76%)
- /products/mccormick-rosemary-lemon-seasoning-2-…94/136 <img> tags have non-empty alt (69%)
- /products/mccormick-savory-herb-parmesan-season…94/136 <img> tags have non-empty alt (69%)
…and 1 more
Skipped — No declarative WebMCP forms found on the homepage or sampled product pages. WebMCP is an optional, experimental browser-agent capability — not in scope until advertised.
Context: If you expose WebMCP tools, browser agents call them directly instead of scraping — but a tool missing its name or description is unusable to the agent.
Why this was skipped
No declarative WebMCP forms found on the homepage or sampled product pages. WebMCP is an optional, experimental browser-agent capability — not in scope until advertised.
How: Parse the homepage and sampled PDP HTML for <form> elements carrying WebMCP attributes (toolname/tooldescription/toolautosubmit), then validate each against the 5 declarative-form rules.
Enable Apple Pay through your payment processor (informational only)
Why this matters: Apple Pay is a checkout-quality signal for human shoppers — informational only, does not affect the agent-readiness score.
Findings (1)
Scanned the homepage and 20 sampled PDPs for Apple Pay markers; none matched.
How: Substring match on known Apple Pay SDK/markup signatures (ApplePaySession, apple-pay-button, /apple-developer-merchantid-domain-association) across the homepage and every sampled PDP HTML.
- No Apple Pay markers detected on the homepage or PDPsINFO
Enable Apple Pay in your payment processor's dashboard (Stripe / Adyen / Braintree). Informational only — does not affect the score.
Enable Google Pay through your payment processor (informational only)
Why this matters: Google Pay is a checkout-quality signal for human shoppers — informational only, does not affect the agent-readiness score.
Findings (1)
Scanned the homepage and 20 sampled PDPs for Google Pay markers; none matched.
How: Substring match on known Google Pay SDK/markup signatures (pay.google.com/gp/p/js/pay.js, google.payments.api, <google-pay-button) across the homepage and every sampled PDP HTML.
- No Google Pay markers detected on the homepage or PDPsINFO
Enable Google Pay in your payment processor's dashboard (Stripe / Adyen / Braintree). Informational only — does not affect the score.