Hi, I’ve been trying to add shop metafields to my agents.md.liquid file but only the agents ones are rendering despite the docs saying that request and shop should work. I had a full report drafted below:
Area: Online Store › Themes › agents.md.liquid template
Docs referenced: agents.md.liquid — “the template exposes an agents object alongside the standard global Liquid objects (such as request and shop).”
Summary
The agents.md.liquid template exposes the base shop global object as documented, but shop.metafields.<namespace>.<key> resolves to empty — even when the metafield has a definition and Storefront API read access. The dedicated agents object and request hydrate correctly, and on a live (non-password) store shop.name renders, so the base shop object is present; only the metafields association appears not to be loaded by this template’s rendering pipeline (which behaves like the robots.txt.liquid class of templates).
Environment
- Online Store 2.0 theme, file
templates/agents.md.liquid - Metafield: merchant-owned, non-reserved namespace, with a definition, type
single_line_text_field, Storefront API access enabled (PUBLIC_READ) - Tested via the live
/agents.mdroute (page typeagents_md, served by the active theme — confirmed inserver-timing: ... pageType;desc="agents_md")
Steps to reproduce
-
In Settings › Custom data › Shop, create a metafield definition: namespace/key
custom.agents_render_test, type single-line text, Storefront API access ON. Set its value toRENDER-OK. -
Add
templates/agents.md.liquidwith:SHOPNAME={{ shop.name }}MF_VALUE={{ shop.metafields.custom.agents_render_test.value }}MF_OBJ={{ shop.metafields.custom.agents_render_test }}AGENTS_STORE={{ agents.store_name }}AGENTS_MCP={{ agents.mcp_endpoint_url }}REQHOST={{ request.host }} -
Save (this busts the
AgentsMdControllerpage cache) and requestGET /agents.md.
Expected
MF_VALUE renders RENDER-OK (and MF_OBJ renders the metafield), consistent with shop being exposed and the metafield having a storefront-readable definition.
Actual
SHOPNAME=DylanDevelopment ← base shop object present (live store)
MF_VALUE= ← EMPTY
MF_OBJ= ← EMPTY
AGENTS_STORE=DylanDevelopment ← agents object works
AGENTS_MCP=https://<shop>/api/ucp/mcp ← agents object works
REQHOST=<shop>.myshopify.com ← request works
shop.metafields.* is empty while every other global resolves. We ruled out the usual suspects:
- Metafield type / definition: failed with a properly typed, defined metafield.
- Access controls: failed with Storefront API
PUBLIC_READenabled. (We also confirmed separately that for a non-reserved merchant-owned namespace,access.adminmust bePUBLIC_READ_WRITEor omitted — neither changes the Liquid result.) - Caching:
/agents.mdiscf-cache-status: DYNAMIC; saving the template busts the Shopifypage_cache:...:AgentsMdControlleretag. A fresh render still shows empty. - Password wall: ruled out —
request.hostand the fullagentsobject render, so the request context is live, not a degraded password render. (On a password-protected store the baseshopobject is additionally suppressed, butshop.metafieldsis empty on both live and password stores.)
The same gap was reproduced independently on two stores.
Impact / the ask
Apps that want to populate a store’s /agents.md (and /llms.txt//llms-full.txt) with brand-specific, always-current content currently have only two options: (a) ask the merchant to paste the full generated file into the template by hand, which then goes stale, or (b) obtain a write_themes exemption to upsert the file via the Theme Files API.
If agents.md.liquid hydrated shop.metafields (the base shop object is already exposed, so this looks like a small gap rather than a design decision), an app could write its content to a shop metafield and have the template stay in sync with a tiny merchant-pasted connector — no theme-write scope required. That’s a materially better integration story for the whole ecosystem of agentic-commerce apps building on agents.md.
Question for Shopify: Is shop.metafields intentionally excluded from the agents.md.liquid rendering context, or is this a gap? If intentional, could the docs state it explicitly (right now they list shop as available without noting the metafields exclusion)? If a gap, please consider hydrating storefront-readable metafields in this template.