<?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: Robert</title>
    <description>The latest articles on DEV Community by Robert (@r0bertini).</description>
    <link>https://dev.to/r0bertini</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3982235%2Ff2bfb906-b1db-4846-8f98-3e5da8a022bf.jpeg</url>
      <title>DEV Community: Robert</title>
      <link>https://dev.to/r0bertini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/r0bertini"/>
    <language>en</language>
    <item>
      <title>Google just shipped an official "agent-ready" toolkit. Here's the one thing it can't measure.</title>
      <dc:creator>Robert</dc:creator>
      <pubDate>Mon, 29 Jun 2026 01:07:27 +0000</pubDate>
      <link>https://dev.to/r0bertini/google-just-shipped-an-official-agent-ready-toolkit-heres-the-one-thing-it-cant-measure-59o7</link>
      <guid>https://dev.to/r0bertini/google-just-shipped-an-official-agent-ready-toolkit-heres-the-one-thing-it-cant-measure-59o7</guid>
      <description>&lt;p&gt;For most of 2026, "is my website agent-ready?" was a question you answered with vibes and a blog post. As of last week, Chrome answers it with a &lt;em&gt;toolkit&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;On June 22, the Chrome team &lt;a href="https://developer.chrome.com/blog/agent-ready-toolkit" rel="noopener noreferrer"&gt;shipped the Agent-Ready Toolkit&lt;/a&gt; — a first-party set of tools for checking and fixing how your site behaves when an AI agent, not a human, is driving. It bundles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a new &lt;strong&gt;Agentic browsing&lt;/strong&gt; category in &lt;strong&gt;Lighthouse&lt;/strong&gt; (available starting from M150, currently "informational and unbenchmarked"),&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chrome DevTools for Agents&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Web Guidance&lt;/strong&gt; (including a &lt;code&gt;webmcp&lt;/code&gt; skill), and&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebMCP&lt;/strong&gt; itself as the mechanism for exposing your site's actions to agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The quiet significance isn't any single tool. It's that "agent-ready" just stopped being a think-piece and became a &lt;em&gt;measured&lt;/em&gt;, first-party concern that ships in the same browser as most of your traffic. When the platform vendor builds the ruler, the thing being measured becomes a real engineering line item.&lt;/p&gt;

&lt;p&gt;If you've read &lt;a href="https://dev.to/r0bertini/your-site-just-failed-lighthouses-new-agentic-browsing-audit-heres-how-to-fix-each-check-2l77"&gt;my earlier walkthrough of the Lighthouse Agentic Browsing checks&lt;/a&gt;, the remediation advice still holds. I don't want to re-run it here. I want to talk about the one thing this toolkit — by design — &lt;em&gt;cannot&lt;/em&gt; tell you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the toolkit measures
&lt;/h2&gt;

&lt;p&gt;The WebMCP portion of the audit, per the blog, "checks for the availability of registered WebMCP tools, forms missing declarative WebMCP, and schema validity." In plain terms it asks three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Did your page &lt;strong&gt;register&lt;/strong&gt; any tools via &lt;code&gt;navigator.modelContext&lt;/code&gt; (or declarative form annotations)?&lt;/li&gt;
&lt;li&gt;Are there forms that &lt;em&gt;should&lt;/em&gt; be exposed as tools but aren't?&lt;/li&gt;
&lt;li&gt;Are the input/output &lt;strong&gt;schemas&lt;/strong&gt; valid?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's a genuinely useful static check. It tells you whether you've done the work of &lt;em&gt;exposing&lt;/em&gt; your site's logic. Pass it and an agent that shows up has a clean, structured way to call your search, your cart, your booking form — instead of screenshotting the page and guessing where to click.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing it can't measure
&lt;/h2&gt;

&lt;p&gt;Here's the gap. Every check in that toolkit is about &lt;strong&gt;exposure&lt;/strong&gt;: have you &lt;em&gt;offered&lt;/em&gt; the tools? None of them — and none of them &lt;em&gt;can&lt;/em&gt;, because they run at audit time in your own browser — tell you whether a real agent, in production, ever &lt;strong&gt;called&lt;/strong&gt; one.&lt;/p&gt;

&lt;p&gt;Exposure and invocation are two different facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exposure&lt;/strong&gt; is a property of your code. Static. Auditable. Pass/fail. The toolkit nails it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invocation&lt;/strong&gt; is a property of the world. It's "on Tuesday at 14:03, something calling itself Gemini-in-Chrome invoked &lt;code&gt;searchProducts({query:'waterproof'})&lt;/code&gt; and got 8 results back." No static audit can know that, because it hasn't happened yet when the audit runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most of this year the honest knock on WebMCP was "no mainstream agent calls &lt;code&gt;navigator.modelContext&lt;/code&gt; anyway." That's changing — Google has &lt;a href="https://developer.chrome.com/blog/chrome-at-io26" rel="noopener noreferrer"&gt;named the first consumer&lt;/a&gt;: "Gemini in Chrome will soon support WebMCP APIs." Which means the interesting question is shifting from &lt;em&gt;"did I expose tools?"&lt;/em&gt; (the toolkit now answers this for you) to &lt;em&gt;"is anything actually using them, and what is it trying to do?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That second question is where the value is. The first agent call to your site is a signal: it tells you which intent agents reach for first, whether your schema matched what they expected, and whether the call &lt;strong&gt;succeeded or threw&lt;/strong&gt;. If you can't see it, you find out months later in an aggregate analytics wobble — long after you could have fixed the schema that made every agent call fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to close the gap (honestly)
&lt;/h2&gt;

&lt;p&gt;You don't need anything fancy. The move is to &lt;strong&gt;instrument every tool call&lt;/strong&gt; the day you register the tool, so the first real invocation isn't invisible:&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;function&lt;/span&gt; &lt;span class="nf"&gt;instrument&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;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&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;args&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;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;try&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="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;tool&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="na"&gt;ok&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;ms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;tool&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="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&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;// register the *wrapped* handler with navigator.modelContext&lt;/span&gt;
&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&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="s2"&gt;searchProducts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// ...inputSchema...&lt;/span&gt;
  &lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;searchProducts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchProducts&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;&lt;code&gt;report()&lt;/code&gt; can be a &lt;code&gt;fetch&lt;/code&gt; to your own endpoint, a log line, whatever. The point is: pass the Lighthouse audit to prove you &lt;em&gt;exposed&lt;/em&gt; the tools, and add invocation logging to learn whether agents &lt;em&gt;use&lt;/em&gt; them — because the toolkit only does the first half.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I work on &lt;a href="https://latch.tools" rel="noopener noreferrer"&gt;Latch&lt;/a&gt;, a one-line script that does both halves: it exposes your existing search/cart/forms as WebMCP tools (so you pass the new audit), and its hosted tier records which agents call which tools and whether the calls succeed — the invocation layer a static audit can't see. The free, MIT client is on &lt;a href="https://github.com/r0bertini/latch" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;; you can wire up the same logging by hand with the snippet above if you'd rather.&lt;/p&gt;

&lt;p&gt;Either way, the takeaway stands on its own: Chrome now grades you on whether you &lt;em&gt;offer&lt;/em&gt; tools to agents. Whether agents actually &lt;em&gt;take&lt;/em&gt; them is a separate fact — and right now, almost nobody is watching it. The day Gemini-in-Chrome makes its first call to your site is worth seeing happen. Make sure you can.&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>ai</category>
      <category>chrome</category>
      <category>webperf</category>
    </item>
    <item>
      <title>Gemini in Chrome is about to call WebMCP. The "no agent uses it yet" excuse just got an expiry date.</title>
      <dc:creator>Robert</dc:creator>
      <pubDate>Fri, 26 Jun 2026 01:05:22 +0000</pubDate>
      <link>https://dev.to/r0bertini/gemini-in-chrome-is-about-to-call-webmcp-the-no-agent-uses-it-yet-excuse-just-got-an-expiry-date-51be</link>
      <guid>https://dev.to/r0bertini/gemini-in-chrome-is-about-to-call-webmcp-the-no-agent-uses-it-yet-excuse-just-got-an-expiry-date-51be</guid>
      <description>&lt;p&gt;For most of 2026 the honest objection to WebMCP went like this: &lt;em&gt;"Cool API. But no mainstream agent actually calls &lt;code&gt;navigator.modelContext&lt;/code&gt;, so why ship it?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I've made that argument myself in writing — it was true, and it was the right question to ask before spending a sprint on it.&lt;/p&gt;

&lt;p&gt;Google just changed the answer. In its Google I/O 2026 round-up, the Chrome team wrote, plainly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Gemini in Chrome will soon support WebMCP APIs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And as one developer who shipped WebMCP on their own site put it: &lt;em&gt;"The sole agent consuming those tools today is Gemini in Chrome."&lt;/em&gt; So the picture for mid-2026 is: one named, mainstream, hundreds-of-millions-of-installs agent is the first real consumer — and it's coming from inside the browser most of your users already run.&lt;/p&gt;

&lt;p&gt;That doesn't make WebMCP "done." But it does turn the objection from &lt;em&gt;"no agent will ever call this"&lt;/em&gt; into &lt;em&gt;"there's now a named agent and a soon."&lt;/em&gt; That's a very different bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changed
&lt;/h2&gt;

&lt;p&gt;Nothing about the spec. WebMCP is still an origin trial (Chrome 149–156), still experimental, still opposed by WebKit, still un-called by most agents today. If you were waiting for the standard to "settle," it hasn't.&lt;/p&gt;

&lt;p&gt;What changed is the &lt;strong&gt;shape of the risk&lt;/strong&gt;. Before: you instrument your site for an audience of zero, indefinitely. Now: you instrument it for a consumer that Google has publicly committed to shipping, riding in the default browser on most of your traffic. The expected value of being ready moved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why being early is cheap (and why late is expensive)
&lt;/h2&gt;

&lt;p&gt;Here's the asymmetry that makes this an easy call once the consumer is named:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The cost to expose a tool is tiny.&lt;/strong&gt; WebMCP tools are thin wrappers over handlers you already have — your site search, your cart, your booking form. You're not building new functionality; you're describing existing functionality in a way an agent can call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost of feature-detecting is zero.&lt;/strong&gt; If &lt;code&gt;navigator.modelContext&lt;/code&gt; isn't present, your code does nothing. No agent in the browser, no behavior change, no risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The cost of being late is real.&lt;/strong&gt; When Gemini in Chrome starts driving task completion on agent-ready sites, the sites that already exposed their search/checkout/booking flows are the ones that get &lt;em&gt;completed&lt;/em&gt; instead of &lt;em&gt;abandoned&lt;/em&gt;. You don't want to discover that gap from a competitor's conversion numbers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole interaction replaces dozens of screenshot-capture-interpret-click cycles with one structured tool call. That's the entire pitch: reliability and speed for the agent, and for you, a flow that an agent can finish instead of fumble.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to ship today (the honest version)
&lt;/h2&gt;

&lt;p&gt;Don't rebuild anything. Wrap what you have, feature-detect, and lose nothing if the spec stalls:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&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="s2"&gt;search_products&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="s2"&gt;Search the catalog and return matching products.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputSchema&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="s2"&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;query&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="s2"&gt;string&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="s2"&gt;query&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;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// call the SAME search you already expose to humans&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/search?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&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;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;content&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&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;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pick the two or three actions that &lt;em&gt;are your business&lt;/em&gt; — search, add-to-cart, "book a call," "get a quote," "check availability" — and expose those first. One source of truth: the tool calls the same handler your buttons do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part nobody tells you to do: instrument it
&lt;/h2&gt;

&lt;p&gt;Here's the move that turns "soon" into something you can actually manage. Once your tools are registered, &lt;strong&gt;log every agent call&lt;/strong&gt;: which tool, what arguments, did it succeed. Because the day Gemini in Chrome (or any agent) first invokes one of your tools, you want to &lt;em&gt;see it&lt;/em&gt; — not infer it three months later from a weird analytics blip.&lt;/p&gt;

&lt;p&gt;That signal is genuinely useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It tells you which of your flows agents reach for first (so you instrument the next ones).&lt;/li&gt;
&lt;li&gt;It tells you where tool calls fail (bad schema, ambiguous descriptions, missing params) — agent UX debugging you can't do blind.&lt;/li&gt;
&lt;li&gt;It's the earliest possible read on agent-driven traffic to your site, before it's big enough to show up anywhere else.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can wire this yourself with a few &lt;code&gt;fetch&lt;/code&gt; beacons. &lt;strong&gt;Full disclosure: I work on &lt;a href="https://latch.tools" rel="noopener noreferrer"&gt;Latch&lt;/a&gt;&lt;/strong&gt; — a one-line open-source script that exposes your existing search/cart/forms as WebMCP tools, and whose paid tier records exactly this (which agent called what, and whether it worked). I'm biased, so take the plug with salt — but instrument it &lt;em&gt;somehow&lt;/em&gt;, with us or with a logging endpoint of your own. The teams that can answer "when did the first agent call our site, and what did it try?" are going to make much better decisions in the next six months than the ones guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest caveats, kept honest
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It's "&lt;strong&gt;will soon&lt;/strong&gt;," not "today." Don't promise your PM agent traffic next week.&lt;/li&gt;
&lt;li&gt;It's an &lt;strong&gt;origin trial&lt;/strong&gt;. APIs can change; register for the trial rather than assuming stability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebKit still formally opposes&lt;/strong&gt; WebMCP. Multi-engine ubiquity is not guaranteed. That's exactly why feature-detection (lose nothing if it stalls) is the right posture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the core thing has changed, and it's worth saying clearly: the strongest reason to &lt;em&gt;not&lt;/em&gt; ship WebMCP — "no agent will ever call it" — now has a name attached to its expiry. The cheap, reversible, feature-detected version costs you an afternoon. I'd take that bet.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building agent-ready sites? The vendor-neutral writeup is at &lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;latch.tools/webmcp&lt;/a&gt;, and the open-source client is &lt;a href="https://github.com/r0bertini/latch" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt; (MIT).&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>ai</category>
      <category>chrome</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Shopify's UCP makes your catalog agent-buyable. The rest of your storefront still isn't — here's where WebMCP fits.</title>
      <dc:creator>Robert</dc:creator>
      <pubDate>Mon, 22 Jun 2026 01:05:29 +0000</pubDate>
      <link>https://dev.to/r0bertini/shopifys-ucp-makes-your-catalog-agent-buyable-the-rest-of-your-storefront-still-isnt-heres-pi9</link>
      <guid>https://dev.to/r0bertini/shopifys-ucp-makes-your-catalog-agent-buyable-the-rest-of-your-storefront-still-isnt-heres-pi9</guid>
      <description>&lt;p&gt;If you run a store, the agentic-commerce wave probably arrived in your inbox this spring as a Shopify changelog, not a strategy memo. Shopify's Spring '26 release shipped &lt;strong&gt;Agentic Storefronts&lt;/strong&gt; and, with Google, the &lt;strong&gt;Universal Commerce Protocol (UCP)&lt;/strong&gt; — an open standard (backed by Amazon, Meta, Microsoft, Salesforce, Stripe, Etsy, Target, Wayfair) that lets an AI agent discover products, build a cart, and complete checkout on a shopper's behalf. If you're on Hydrogen, every storefront now exposes an MCP endpoint at &lt;code&gt;/api/mcp&lt;/code&gt; with &lt;code&gt;proxyStandardRoutes&lt;/code&gt; on by default. The old Storefront Catalog MCP folded into UCP, with the legacy endpoints maintained only through June 15.&lt;/p&gt;

&lt;p&gt;That's a genuinely big deal, and if you sell on Shopify you should make sure your catalog is flowing through it. But it's worth being precise about &lt;em&gt;what UCP actually makes agent-operable&lt;/em&gt;, because the headline ("your store is now an AI agent endpoint") quietly oversells it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What UCP covers — and where it stops
&lt;/h2&gt;

&lt;p&gt;UCP standardizes &lt;strong&gt;commerce primitives&lt;/strong&gt;: search the catalog, build a cart, create a checkout, hand off the buyer, track the order, settle payment (via AP2). Those are the operations every store shares, so it makes sense to standardize them once and let every agent speak them.&lt;/p&gt;

&lt;p&gt;The flip side of "standardized" is "only the standardized parts." UCP makes the &lt;em&gt;commodity&lt;/em&gt; surface of your store agent-operable — the parts that look the same on every Shopify store. It does &lt;strong&gt;not&lt;/strong&gt; cover the parts that make your storefront &lt;em&gt;yours&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a bundle builder or product configurator ("build your own 6-pack", "spec this bike")&lt;/li&gt;
&lt;li&gt;a gift-finder or fit quiz that narrows the catalog by answering questions&lt;/li&gt;
&lt;li&gt;"book a fitting / a consultation / a demo" scheduling&lt;/li&gt;
&lt;li&gt;subscription management, reorder, or a B2B quote / net-terms request&lt;/li&gt;
&lt;li&gt;store locator, warranty registration, returns initiation, loyalty redemption&lt;/li&gt;
&lt;li&gt;account self-service that isn't a checkout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those are "search the catalog and check out." They're bespoke interactive flows you built on top of (or beside) the catalog — and they're frequently the reason a customer chose &lt;em&gt;you&lt;/em&gt; over a generic listing. An agent driving your store through UCP can buy a SKU it already knows it wants. It cannot reliably run the quiz that helps it figure out &lt;em&gt;which&lt;/em&gt; SKU, or start the warranty claim, or request the B2B quote — because UCP doesn't describe those, and nothing else tells the agent they exist.&lt;/p&gt;

&lt;p&gt;And that's the &lt;em&gt;Shopify-on-Hydrogen&lt;/em&gt; case, where you inherit &lt;code&gt;/api/mcp&lt;/code&gt; for free. Two large groups don't:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Custom / non-Hydrogen headless storefronts.&lt;/strong&gt; "Truly headless on your own front end" means you don't get the standard routes for free — you're rebuilding the agent surface yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Everyone not on Shopify.&lt;/strong&gt; Most of the web sells, books, or onboards without Shopify's data graph underneath it at all.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For all three — the custom flows on a Shopify store, headless front ends, and non-Shopify sites — the question isn't "is my catalog in UCP." It's "can an agent operate the interactive parts of my site the same way a person can?"&lt;/p&gt;

&lt;h2&gt;
  
  
  That's the WebMCP-shaped gap
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;WebMCP&lt;/a&gt; (the &lt;code&gt;navigator.modelContext&lt;/code&gt; API, in a &lt;a href="https://developer.chrome.com/blog/web-mcp" rel="noopener noreferrer"&gt;Chrome 149 origin trial&lt;/a&gt; as of June 2026) is the complement, not the competitor, to UCP. Where UCP standardizes &lt;em&gt;commerce&lt;/em&gt; operations across stores, WebMCP lets a &lt;em&gt;single site&lt;/em&gt; declare its &lt;em&gt;own&lt;/em&gt; tools — whatever they are — so an agent in the browser can call them directly instead of guessing at your DOM.&lt;/p&gt;

&lt;p&gt;The mental model that's held up for me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;UCP is the shared commerce rails. WebMCP is the tool surface for everything your storefront does that isn't a generic commerce primitive.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They compose cleanly. The agent uses UCP to buy the thing; it uses your WebMCP tools to do the bespoke work that decides &lt;em&gt;what&lt;/em&gt; to buy and &lt;em&gt;what happens around&lt;/em&gt; the purchase. A configurator becomes a &lt;code&gt;configure_bundle&lt;/code&gt; tool. The fit quiz becomes &lt;code&gt;recommend_size&lt;/code&gt;. The B2B flow becomes &lt;code&gt;request_quote&lt;/code&gt;. Each is a thin, typed front door to a function your UI already calls:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modelContext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&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="s2"&gt;recommend_size&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="s2"&gt;Recommend a size from height, weight, and fit preference&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputSchema&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="s2"&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;heightCm&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="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;weightKg&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="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;fit&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="s2"&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;enum&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="s2"&gt;slim&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="s2"&gt;regular&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="s2"&gt;relaxed&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="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="s2"&gt;heightCm&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="s2"&gt;weightKg&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;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&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;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sizeEngine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// the same fn your quiz UI calls&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;content&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Recommended size: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things make this cheap and safe, and they're the same two that make UCP adoption sane:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feature-detected.&lt;/strong&gt; The whole surface sits behind &lt;code&gt;if ("modelContext" in navigator)&lt;/code&gt;. In every browser without the API — which today is nearly all of them — it's a no-op. Nothing breaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reuse, don't rebuild.&lt;/strong&gt; A WebMCP tool should call the exact function your existing UI calls (&lt;code&gt;sizeEngine&lt;/code&gt;, &lt;code&gt;productSearch&lt;/code&gt;, &lt;code&gt;startReturn&lt;/code&gt;). If you're writing new business logic for the agent, you've taken on the expensive version that drifts out of sync. Don't.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The honest caveat (same as for UCP)
&lt;/h2&gt;

&lt;p&gt;As of June 2026, no mainstream agent calls &lt;code&gt;navigator.modelContext&lt;/code&gt; on your page yet — not ChatGPT Agent, not Claude, not Gemini. (UCP is further along on the commerce side, because the agent and the protocol are being built by the same companies, but the general browser tool-call path isn't wired up in shipping agents either.) So this isn't "do it today or lose sales tomorrow." It's: the agentic-commerce buildout is clearly happening top-down from the platforms, the cost of exposing your custom flows as feature-detected tools is an afternoon, and the payoff lands exactly when you can't predict the date.&lt;/p&gt;

&lt;p&gt;The one thing I'd add: &lt;strong&gt;instrument it.&lt;/strong&gt; Log every tool invocation — which tool, sanitized args, success, latency — from day one. Whether an agent arrives via UCP checkout or a direct WebMCP call, you want to find out from a dashboard, not from a billing anomaly six months later. "Are agents operating my store yet, and which flows do they use?" is the only question that turns this from a guess into a managed bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;If you sell on Shopify, get your catalog into UCP — that's the commerce rails, and they're real now. But don't mistake "my catalog is agent-buyable" for "my store is agent-operable." The flows that differentiate your storefront — the configurators, quizzes, bookings, B2B, post-purchase — live outside UCP's standardized primitives, and on custom/non-Shopify sites so does everything else. That's the WebMCP-shaped half of the problem. Expose those flows as typed tools, reuse your own handlers so they can't drift, and meter them so you see the first agent that walks in.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I work on &lt;a href="https://latch.tools" rel="noopener noreferrer"&gt;Latch&lt;/a&gt;, an open-source (MIT) one-line script that does the WebMCP half of the above — it exposes your site's existing search, cart, forms, and custom flows as feature-detected &lt;code&gt;navigator.modelContext&lt;/code&gt; tools (valid schemas, reusing your own handlers), and the optional hosted tier is the meter: it shows which agents call your tools and what they do. If you just want the standard, the &lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;WebMCP guide&lt;/a&gt; is vendor-neutral and the &lt;a href="https://github.com/r0bertini/latch" rel="noopener noreferrer"&gt;code is on GitHub&lt;/a&gt;. It complements UCP rather than replacing it — happy to compare notes in the comments, especially with anyone running a headless or non-Shopify storefront.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>shopify</category>
      <category>ai</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>No agent calls WebMCP yet. Here's the honest case for shipping it today — and how to know the day that changes.</title>
      <dc:creator>Robert</dc:creator>
      <pubDate>Sat, 20 Jun 2026 01:05:39 +0000</pubDate>
      <link>https://dev.to/r0bertini/no-agent-calls-webmcp-yet-heres-the-honest-case-for-shipping-it-today-and-how-to-know-the-day-52ld</link>
      <guid>https://dev.to/r0bertini/no-agent-calls-webmcp-yet-heres-the-honest-case-for-shipping-it-today-and-how-to-know-the-day-52ld</guid>
      <description>&lt;p&gt;There's an uncomfortable fact under all the WebMCP excitement, and the skeptics are right to keep raising it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As of June 2026, none of the mainstream AI agents actually call &lt;code&gt;navigator.modelContext&lt;/code&gt; on your site.&lt;/strong&gt; Not ChatGPT Agent, not Claude, not Gemini, not Perplexity. They all still read your page by DOM-scraping or by taking screenshots and clicking pixels. Patrick Brosset's updates and &lt;a href="https://dev.to/studiomeyer_io/webmcp-reality-check-where-the-spec-actually-stands-4gh1"&gt;studiomeyer's "Reality Check"&lt;/a&gt; both lay this out plainly, and it's worth repeating because the hype usually skips it: WebMCP is a &lt;a href="https://github.com/webmachinelearning/webmcp" rel="noopener noreferrer"&gt;W3C Community Group draft&lt;/a&gt;, &lt;em&gt;not&lt;/em&gt; a standard, shipping behind a flag in Chrome and a &lt;a href="https://developer.chrome.com/blog/web-mcp" rel="noopener noreferrer"&gt;Chrome 149 origin trial&lt;/a&gt; — and the agents that would consume it haven't wired it up.&lt;/p&gt;

&lt;p&gt;So why would you add WebMCP tools to your site right now?&lt;/p&gt;

&lt;p&gt;I think there's an honest answer, and it isn't "because it's the future, trust me." Let me make the actual case — including the part most "install it now" posts skip, which is what to do so the install doesn't quietly rot.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost side is genuinely near-zero
&lt;/h2&gt;

&lt;p&gt;The reason "wait and see" feels safe is an assumption that adopting early is expensive. For WebMCP specifically, it mostly isn't — &lt;em&gt;if you do it right&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's feature-detected, so it can't break anything.&lt;/strong&gt; The entire surface lives behind &lt;code&gt;if ("modelContext" in navigator)&lt;/code&gt;. In every browser that doesn't ship the API — which today is almost all of them — your code is a no-op. Zero runtime cost, zero risk to existing users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It shouldn't add a second codebase.&lt;/strong&gt; A WebMCP tool should be a thin, typed front door to a function your UI &lt;em&gt;already&lt;/em&gt; calls. Your &lt;code&gt;search_products&lt;/code&gt; tool calls the same &lt;code&gt;productSearch()&lt;/code&gt; your search box calls. If you find yourself writing new business logic to satisfy an agent, stop — that's the expensive version, and it's the version that drifts out of sync.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There's no migration to undo.&lt;/strong&gt; Because it's additive and detected, "we were too early" has no cleanup cost. You delete a script tag.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Done this way, the real cost of shipping WebMCP today is an afternoon, not a bet-the-roadmap commitment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The benefit side is a dated option, not a promise
&lt;/h2&gt;

&lt;p&gt;What you're actually buying with that afternoon is an &lt;strong&gt;option that's worth the most precisely when it's least certain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When agents &lt;em&gt;do&lt;/em&gt; start calling typed tools — and the people building both the browsers (Google, Microsoft) and the agents are the same companies pushing this spec — the sites that already expose tools win the first wave of agent traffic with no scramble. The gap you're closing isn't "agent can read my page" (DOM scraping already half-works); it's "agent can &lt;em&gt;complete the thing I sell&lt;/em&gt; on my page reliably, in one call instead of ten guessed clicks."&lt;/p&gt;

&lt;p&gt;You don't have to believe that's six months away or eighteen. The point of an option is that you don't need to know the date. You need the cost of holding it to be low (it is) and the payoff if it hits to be high (for anything transactional, it is).&lt;/p&gt;

&lt;h2&gt;
  
  
  The part the "install now" posts skip: you won't notice when it starts mattering
&lt;/h2&gt;

&lt;p&gt;Here's the failure mode of "ship it and forget it." You add the tools, they sit behind a feature flag in browsers nobody's agent uses yet, and then... nothing tells you when that changes. Six months later an agent &lt;em&gt;does&lt;/em&gt; start calling &lt;code&gt;search_products&lt;/code&gt; — and you find out from a billing anomaly, or a support ticket, or never.&lt;/p&gt;

&lt;p&gt;If WebMCP is an option, &lt;strong&gt;you want to know the moment it goes in the money.&lt;/strong&gt; That means instrumenting your tools from day one. At minimum, log every invocation yourself:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modelContext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&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="s2"&gt;search_products&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="s2"&gt;Search the product catalog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputSchema&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="s2"&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;query&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="s2"&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;maxPrice&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="s2"&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="s2"&gt;query&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;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// 👇 the line most implementations forget&lt;/span&gt;
      &lt;span class="nf"&gt;beacon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;webmcp_tool_call&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;tool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search_products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;productSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// same fn your UI calls&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;content&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;formatResults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;beacon()&lt;/code&gt; is the difference between "we have WebMCP somewhere" and "an agent called our search tool 240 times last Tuesday and 12 of those turned into carts." The second sentence is the one that gets WebMCP a line in next quarter's budget. The first one gets it quietly deleted in a cleanup PR.&lt;/p&gt;

&lt;p&gt;Things worth capturing per call: which tool, the arguments (sanitize PII), whether &lt;code&gt;execute&lt;/code&gt; succeeded, latency, and any user-agent / client hints you can get. You're building the dashboard that answers "are agents here yet, and what do they do when they arrive?" — which is the only honest way to manage an option instead of a guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;The skeptics and the boosters are both right, and they're not actually in conflict:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skeptics:&lt;/strong&gt; no agent calls WebMCP today. True. Don't let anyone tell you the robots are already shopping your store. They aren't yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boosters:&lt;/strong&gt; ship it anyway. Also true — &lt;em&gt;because&lt;/em&gt; it's cheap, feature-detected, and additive, and because the payoff lands exactly when you can't predict the date.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The synthesis is: &lt;strong&gt;ship it early, reuse your own handlers so it can't drift, and instrument it so you see the first real agent call the day it happens&lt;/strong&gt; — not a quarter later. Adopt the option &lt;em&gt;and&lt;/em&gt; the meter, or you've adopted neither.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I work on &lt;a href="https://latch.tools" rel="noopener noreferrer"&gt;Latch&lt;/a&gt;, an open-source (MIT) one-line script that does the boring half of the above for you — it exposes your site's existing search/cart/forms as WebMCP tools (feature-detected, reusing your own handlers, valid schemas), and the optional hosted tier is exactly the "meter": it shows which agents call your tools and what they do, so you see the first agent visit instead of finding out from a billing anomaly. If you'd rather just understand the standard, the &lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;WebMCP guide&lt;/a&gt; is vendor-neutral, and the &lt;a href="https://github.com/r0bertini/latch" rel="noopener noreferrer"&gt;code is on GitHub&lt;/a&gt;. Happy to argue the trade-offs in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>ai</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Your site just failed Lighthouse's new Agentic Browsing audit — here's how to fix each check</title>
      <dc:creator>Robert</dc:creator>
      <pubDate>Fri, 19 Jun 2026 01:04:45 +0000</pubDate>
      <link>https://dev.to/r0bertini/your-site-just-failed-lighthouses-new-agentic-browsing-audit-heres-how-to-fix-each-check-2l77</link>
      <guid>https://dev.to/r0bertini/your-site-just-failed-lighthouses-new-agentic-browsing-audit-heres-how-to-fix-each-check-2l77</guid>
      <description>&lt;p&gt;If you've opened Chrome DevTools lately and run Lighthouse, you may have noticed a new category sitting under Performance, Accessibility, SEO and the rest: &lt;strong&gt;Agentic Browsing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It shipped in &lt;a href="https://www.debugbear.com/blog/lighthouse-agentic-browsing" rel="noopener noreferrer"&gt;Lighthouse 13.3&lt;/a&gt; (May 2026). It's still marked experimental, so it doesn't give you a 0–100 score — just a pass/fail per check. But "experimental" in Lighthouse has a way of becoming "default, and now your client is asking why it's red." So it's worth understanding now, while it's cheap.&lt;/p&gt;

&lt;p&gt;The category answers one question: &lt;strong&gt;can an AI agent actually understand and operate this page?&lt;/strong&gt; It does that with four checks. Here's what each one tests and exactly how to make it pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. llms.txt
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it checks:&lt;/strong&gt; whether your domain root serves an &lt;code&gt;/llms.txt&lt;/code&gt;, and — this is the part people miss — whether that file is actually useful: it flags the file if it's missing an &lt;code&gt;H1&lt;/code&gt;, is too short, or contains no links.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to pass:&lt;/strong&gt; add a plain-text (well, Markdown) file at &lt;code&gt;https://yourdomain.com/llms.txt&lt;/code&gt;. Minimum viable version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Acme Tools&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Acme sells precision hand tools. This file helps AI agents find the right pages.&lt;/span&gt;

&lt;span class="gu"&gt;## Core pages&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Product catalog&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://acme.example/products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: browse and filter all tools
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://acme.example/search&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: full-text product search
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Support&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://acme.example/support&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: returns, warranty, contact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One &lt;code&gt;H1&lt;/code&gt;, a one-line summary, real links to the pages that matter. That's the whole check. Don't dump your sitemap into it — curate the handful of entry points an agent should know about.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Accessibility tree
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it checks:&lt;/strong&gt; every interactive element has a programmatic name, roles and parent/child relationships are valid, and nothing is hidden from the a11y tree while still being interactive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to pass:&lt;/strong&gt; this is just accessibility hygiene, and it's the most important check of the four — because the accessibility tree is the &lt;em&gt;primary&lt;/em&gt; way an agent reads your page. Use real &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;/&lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; pairs instead of click-handlered &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s. Give icon-only buttons an &lt;code&gt;aria-label&lt;/code&gt;. Make sure a &lt;code&gt;&amp;lt;div role="button"&amp;gt;&lt;/code&gt; you couldn't avoid is focusable and named.&lt;/p&gt;

&lt;p&gt;If you've been putting off your a11y backlog, the agentic era just gave you a second, harder-to-ignore reason to do it: the same fixes that help screen-reader users help every agent that visits.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Cumulative Layout Shift (CLS)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it checks:&lt;/strong&gt; the same CLS you already know from Core Web Vitals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to pass:&lt;/strong&gt; nothing agent-specific here — reserve space for images and embeds (&lt;code&gt;width&lt;/code&gt;/&lt;code&gt;height&lt;/code&gt; or &lt;code&gt;aspect-ratio&lt;/code&gt;), avoid injecting content above existing content, preload fonts. Why does an &lt;em&gt;agentic&lt;/em&gt; category care about visual stability? Because agents that drive a real browser click coordinates and read snapshots; a page that reflows under them mis-clicks exactly like a human would. Stable layout = reliable automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. WebMCP
&lt;/h2&gt;

&lt;p&gt;This is the new one, and the only check that's genuinely about the agentic web rather than hygiene you should already be doing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it checks:&lt;/strong&gt; Lighthouse surfaces every &lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;WebMCP&lt;/a&gt; tool registered on the page — whether via the declarative HTML API or imperatively through &lt;code&gt;navigator.modelContext.registerTool()&lt;/code&gt; — and validates that any declared &lt;code&gt;inputSchema&lt;/code&gt; is syntactically and semantically valid. For annotated forms, it checks that the annotations match the expected schema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to pass:&lt;/strong&gt; you need to actually expose tools, and their schemas have to be valid. The imperative version:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modelContext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&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="s2"&gt;search_products&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="s2"&gt;Search the product catalog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputSchema&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="s2"&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;query&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="s2"&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;maxPrice&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="s2"&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="s2"&gt;query&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="c1"&gt;// call the SAME function your search box already calls&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxPrice&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;productSearch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxPrice&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;content&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;formatResults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things worth saying out loud, because they're where teams get this wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feature-detect.&lt;/strong&gt; Most browsers don't ship &lt;code&gt;navigator.modelContext&lt;/code&gt; yet (it's in a Chrome 149 origin trial; WebKit has &lt;a href="https://github.com/WebKit/standards-positions/issues/670" rel="noopener noreferrer"&gt;formally opposed it&lt;/a&gt;). The &lt;code&gt;if ("modelContext" in navigator)&lt;/code&gt; guard means you lose nothing if the spec stalls — it's progressive enhancement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reuse your existing handlers.&lt;/strong&gt; Your &lt;code&gt;search_products&lt;/code&gt; tool should bottom out in the exact function your search UI already calls. If a tool does something your UI can't, you've created a second source of truth that will drift — which is precisely the &lt;a href="https://github.com/webmachinelearning/webmcp/issues/91" rel="noopener noreferrer"&gt;redundancy critique&lt;/a&gt; WebKit raised. Keep tools as thin, typed front doors to behavior you already ship.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The honest prioritization
&lt;/h2&gt;

&lt;p&gt;Three of these four checks — llms.txt, accessibility, CLS — are things you should be doing regardless of whether you believe in the agentic web. Do them first; they pay off for users and search today.&lt;/p&gt;

&lt;p&gt;The fourth, WebMCP, is the real bet on where browsing is going. It's also the one with the most leverage if you sell anything: the gap between "an agent can read my page" and "an agent can complete a purchase on my page" is exactly the gap WebMCP tools fill.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I work on &lt;a href="https://latch.tools" rel="noopener noreferrer"&gt;Latch&lt;/a&gt;, an open-source (MIT) one-line script that does the WebMCP check (#4) for you — it exposes your site's existing search/cart/forms as WebMCP tools with valid schemas, feature-detected, reusing your own handlers. If you'd rather understand the standard than adopt any tool, the &lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;WebMCP guide&lt;/a&gt; is vendor-neutral. Happy to talk trade-offs in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>seo</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>WebKit opposes WebMCP. Here's what to actually build today</title>
      <dc:creator>Robert</dc:creator>
      <pubDate>Thu, 18 Jun 2026 01:05:42 +0000</pubDate>
      <link>https://dev.to/r0bertini/webkit-opposes-webmcp-heres-what-to-actually-build-today-18dn</link>
      <guid>https://dev.to/r0bertini/webkit-opposes-webmcp-heres-what-to-actually-build-today-18dn</guid>
      <description>&lt;p&gt;If you've been following the agentic-web standards fight, you've seen the headlines: Chrome shipped a &lt;a href="https://developer.chrome.com/blog/ai-webmcp-origin-trial" rel="noopener noreferrer"&gt;WebMCP origin trial in Chrome 149&lt;/a&gt;, and WebKit's standards-positions tracker landed on a one-word verdict — &lt;strong&gt;&lt;a href="https://github.com/WebKit/standards-positions/issues/670" rel="noopener noreferrer"&gt;oppose&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's tempting to read that as "Apple says no, so wait." That's the wrong takeaway. The opposition is mostly &lt;em&gt;good engineering feedback&lt;/em&gt;, and once you internalize it, it tells you exactly how to build for agents today — in a way that's safe even if the spec stalls.&lt;/p&gt;

&lt;h2&gt;
  
  
  What WebKit actually objected to
&lt;/h2&gt;

&lt;p&gt;WebKit's position cites the usual list — API design, duplication of existing platform functionality, i18n, portability, privacy, security, unclear use cases. Boilerplate-sounding, but one of those is the load-bearing critique, and it shows up most sharply in the WebMCP repo itself: &lt;strong&gt;&lt;a href="https://github.com/webmachinelearning/webmcp/issues/91" rel="noopener noreferrer"&gt;redundancy with the accessibility tree&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The argument is clean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The accessibility tree already exposes a machine-readable action space — labels, roles, states, expected inputs, validation errors, relationships. It's &lt;strong&gt;derived from the DOM&lt;/strong&gt;, so it can't desync. A separately-maintained JavaScript tool registry &lt;em&gt;can and will&lt;/em&gt; diverge from the page over time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is correct. If you hand-write a parallel description of your UI for agents, you've created a second source of truth, and second sources of truth rot. That's a real smell, and "agent-only APIs that don't help humans" is a legitimate thing to be suspicious of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the accessibility tree alone isn't enough either
&lt;/h2&gt;

&lt;p&gt;Here's the part the opposition under-weights. The a11y tree is excellent at describing &lt;strong&gt;state&lt;/strong&gt; — what's on the page, what each control is, what's required. It's much weaker at describing &lt;strong&gt;actions&lt;/strong&gt;, especially compound ones.&lt;/p&gt;

&lt;p&gt;Consider "filter products under €50, in stock, then add the top result to the cart." For a human with a screen reader that's a sequence of discrete control interactions. For an agent, inferring that whole flow from roles and labels is brittle — it has to reverse-engineer your app's intent from primitives. A tool with a typed input schema (&lt;code&gt;{ maxPrice, inStock }&lt;/code&gt;) and a single handler collapses that guesswork into one verified call.&lt;/p&gt;

&lt;p&gt;So both things are true at once:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A parallel, hand-maintained agent API is a liability.&lt;/li&gt;
&lt;li&gt;The a11y tree is lossy for multi-step &lt;em&gt;actions&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The resolution isn't "pick a side." It's &lt;strong&gt;how you implement the tools&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design that survives the critique
&lt;/h2&gt;

&lt;p&gt;The redundancy objection only bites if your tool definitions are a &lt;em&gt;second implementation&lt;/em&gt;. So don't make them one.&lt;/p&gt;

&lt;p&gt;The right posture, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build for humans first.&lt;/strong&gt; Semantic HTML, real form elements, a clean accessibility tree. This is non-negotiable and it's what everyone — users, assistive tech, search, &lt;em&gt;and&lt;/em&gt; agents — benefits from.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expose the actions, not a new app.&lt;/strong&gt; Where you register an agent tool, have its handler call &lt;strong&gt;the exact same function your UI already calls.&lt;/strong&gt; Your "Add to cart" button and your &lt;code&gt;add_to_cart&lt;/code&gt; tool should bottom out in one code path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep tools thin.&lt;/strong&gt; A tool is a typed entry point to existing behavior, not a place for new business logic. If a tool does something your UI can't, that's the divergence WebKit warned about — fix the UI instead.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do this and the "two sources of truth" problem evaporates, because there's still only one. The tool registry isn't a parallel description of the page; it's a typed front door to the handlers the page already runs. They can't desync because they're the same code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concretely
&lt;/h2&gt;

&lt;p&gt;The imperative API is just a typed wrapper over a function you already have:&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&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="s2"&gt;add_to_cart&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="s2"&gt;Add a product to the cart by id and quantity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;inputSchema&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="s2"&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;productId&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="s2"&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;quantity&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="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&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;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="s2"&gt;productId&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="c1"&gt;// same handler your "Add to cart" button calls — no second implementation&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&lt;/span&gt; &lt;span class="o"&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;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;productId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;quantity&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;content&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="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Added &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; x &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;productId&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="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;And feature-detect, because most browsers won't have it yet:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;modelContext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// register tools&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;if&lt;/code&gt; is the whole risk profile. If WebMCP ships everywhere, you're ready. If WebKit holds the line and it stalls, you've lost nothing — you added a feature-detected enhancement over handlers that already existed for your human users. This is just progressive enhancement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this leaves you
&lt;/h2&gt;

&lt;p&gt;The agentic-web tooling has already moved past "is this real" — &lt;a href="https://www.debugbear.com/blog/lighthouse-agentic-browsing" rel="noopener noreferrer"&gt;Google's Lighthouse now ships an Agentic Browsing audit category&lt;/a&gt;, and scanners will increasingly grade whether your site exposes tools. The standards politics will take a year to settle. Your move in the meantime isn't to bet the company on a spec; it's to keep one source of truth and put a typed, feature-detected front door on the handlers you already ship.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I work on &lt;a href="https://latch.tools" rel="noopener noreferrer"&gt;Latch&lt;/a&gt;, an open-source (MIT) one-line script that exposes a site's existing search/cart/forms as WebMCP tools — built around exactly this "reuse your existing handlers, feature-detect, lose nothing if the spec stalls" posture. If you'd rather understand the standard than adopt any tool, the &lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;WebMCP guide&lt;/a&gt; is vendor-neutral. Happy to talk design trade-offs in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>a11y</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Make any website agent-ready in one line (WebMCP, navigator.modelContext)</title>
      <dc:creator>Robert</dc:creator>
      <pubDate>Wed, 17 Jun 2026 01:04:56 +0000</pubDate>
      <link>https://dev.to/r0bertini/make-any-website-agent-ready-in-one-line-webmcp-navigatormodelcontext-i2b</link>
      <guid>https://dev.to/r0bertini/make-any-website-agent-ready-in-one-line-webmcp-navigatormodelcontext-i2b</guid>
      <description>&lt;p&gt;In mid-2026 a quiet fact about the "agentic web" still holds: &lt;strong&gt;none of the big agents call &lt;code&gt;navigator.modelContext&lt;/code&gt; tools directly in production yet.&lt;/strong&gt; ChatGPT Agent, Gemini, Perplexity, Claude — they still mostly DOM-scrape or take screenshots and guess where to click. That's slow, brittle, and burns tokens.&lt;/p&gt;

&lt;p&gt;WebMCP fixes the mechanism. Your site declares &lt;em&gt;tools&lt;/em&gt; — &lt;code&gt;searchProducts&lt;/code&gt;, &lt;code&gt;addToCart&lt;/code&gt;, &lt;code&gt;submitLead&lt;/code&gt; — each with a name, a JSON schema, and an &lt;code&gt;execute&lt;/code&gt; callback. An agent makes one structured call and gets JSON back, instead of clicking through your filter dropdowns. Chrome shipped the early preview in 146 (Feb 2026); Edge 147 ships it natively; &lt;strong&gt;Chrome 149 is now in an open origin trial&lt;/strong&gt; (announced at Google I/O, May 2026), with DevTools support for inspecting registered tools. Benchmarks from Chrome Labs show large token reductions vs. screenshot automation.&lt;/p&gt;

&lt;p&gt;The catch: wiring &lt;code&gt;navigator.modelContext.registerTool()&lt;/code&gt; for every search box, cart action, and form on a real site — with auth, schemas, and a polyfill so it works in browsers that don't have it yet — is real work.&lt;/p&gt;

&lt;h3&gt;
  
  
  The one-line version
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://latch.tools" rel="noopener noreferrer"&gt;Latch&lt;/a&gt; is an open-source (MIT) script that does the wiring for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://latch.tools/latch.js"&lt;/span&gt; &lt;span class="na"&gt;data-key=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_KEY"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It introspects your search, cart, and forms and registers them as WebMCP tools, with a polyfill so today's agent browsers and extensions can call them now. You keep your existing UI; agents get a structured contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why bother before agents "officially" support it
&lt;/h3&gt;

&lt;p&gt;Two reasons. First, agent browsers and extensions that &lt;em&gt;do&lt;/em&gt; read &lt;code&gt;navigator.modelContext&lt;/code&gt; already exist, and the standard is landing in stable Chrome/Edge fast — being early is cheap insurance. Second, you can't improve what you can't see: when an agent does hit your site, you want to know which one, and what it tried to do. Latch's optional hosted analytics (Latch Pro, EUR 19/mo per project) shows per-agent breakdowns and a full event feed; the OSS client is free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Guide: &lt;a href="https://latch.tools/webmcp" rel="noopener noreferrer"&gt;https://latch.tools/webmcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source: &lt;a href="https://github.com/r0bertini/latch" rel="noopener noreferrer"&gt;https://github.com/r0bertini/latch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Check your own site's agent-readiness, add a couple of tools, and watch what the agents do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The web spent 30 years optimizing for human clicks and search crawlers. The next layer is tools for agents — and it's a one-liner to get on it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I work on Latch. WebMCP itself is an open W3C Community Group standard — you can implement &lt;code&gt;navigator.modelContext&lt;/code&gt; by hand without any library; Latch just automates the wiring.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webmcp</category>
      <category>ai</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
