<?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>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>
