<?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: Nilam Bora</title>
    <description>The latest articles on DEV Community by Nilam Bora (@nilambuilds).</description>
    <link>https://dev.to/nilambuilds</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3892838%2Fd6265034-ff2a-4993-8e9b-56a1b807927b.jpg</url>
      <title>DEV Community: Nilam Bora</title>
      <link>https://dev.to/nilambuilds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nilambuilds"/>
    <language>en</language>
    <item>
      <title>Your Website Has a New User — And It's Not Human. A Hands-On Guide to WebMCP</title>
      <dc:creator>Nilam Bora</dc:creator>
      <pubDate>Sat, 23 May 2026 15:41:38 +0000</pubDate>
      <link>https://dev.to/nilambuilds/your-website-has-a-new-user-and-its-not-human-a-hands-on-guide-to-webmcp-1e73</link>
      <guid>https://dev.to/nilambuilds/your-website-has-a-new-user-and-its-not-human-a-hands-on-guide-to-webmcp-1e73</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-io-writing-2026-05-19"&gt;Google I/O Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Web Just Got a New Kind of Visitor
&lt;/h2&gt;

&lt;p&gt;Here's a question nobody was asking five years ago: &lt;em&gt;what happens when the primary user of your website isn't a person?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At Google I/O 2026, sitting in my home office watching the Chrome session, I got my answer — and it wasn't what I expected. While everyone was buzzing about Gemini 3.5 and Antigravity 2.0, the Chrome team quietly dropped what I think is the most consequential announcement for web developers: &lt;strong&gt;WebMCP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;WebMCP (Web Model Context Protocol) is a proposed W3C standard that lets websites expose JavaScript functions as structured tools that AI agents can call directly — no scraping, no DOM simulation, no brittle Puppeteer scripts. Just a clean, typed API living right inside the browser tab.&lt;/p&gt;

&lt;p&gt;I've spent the last few days building with it. This isn't a summary of the keynote. This is what I learned when I actually opened &lt;code&gt;chrome://flags&lt;/code&gt; and started writing code.&lt;/p&gt;




&lt;h2&gt;
  
  
  What WebMCP Actually Is (In 60 Seconds)
&lt;/h2&gt;

&lt;p&gt;If you've worked with &lt;a href="https://modelcontextprotocol.io/" rel="noopener noreferrer"&gt;MCP (Model Context Protocol)&lt;/a&gt;, you know the concept: give AI agents structured tools to call instead of making them guess what to click on a screen.&lt;/p&gt;

&lt;p&gt;WebMCP takes that idea and moves it &lt;strong&gt;into the browser&lt;/strong&gt;. Instead of running a separate Node.js or Python server, you register tools directly on your webpage using a new browser API: &lt;code&gt;navigator.modelContext&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the fundamental mental model shift:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Traditional MCP&lt;/th&gt;
&lt;th&gt;WebMCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runs on&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your backend server&lt;/td&gt;
&lt;td&gt;The browser tab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API keys, OAuth tokens&lt;/td&gt;
&lt;td&gt;User's existing session &amp;amp; cookies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sees&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your database, internal APIs&lt;/td&gt;
&lt;td&gt;The page's JavaScript context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Headless automation&lt;/td&gt;
&lt;td&gt;Human-in-the-loop workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Infrastructure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;New server required&lt;/td&gt;
&lt;td&gt;Zero additional infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They're complementary, not competing. MCP is for your backend. WebMCP is for your frontend. But if you're a web developer who's been wondering "how do I make my site work with AI agents?" — WebMCP is the answer Google just handed you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up: 5 Minutes to Your First WebMCP Tool
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chrome 149+&lt;/strong&gt; (currently in Canary/Dev channel, or behind a flag in stable)&lt;/li&gt;
&lt;li&gt;A basic web page&lt;/li&gt;
&lt;li&gt;That's it. No npm packages. No build tools. No server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Enable the Flag
&lt;/h3&gt;

&lt;p&gt;For local development, navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chrome://flags/#enable-webmcp-testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set it to &lt;strong&gt;Enabled&lt;/strong&gt;, then relaunch Chrome.&lt;/p&gt;

&lt;p&gt;For production deployment, you'll want to register for the &lt;strong&gt;origin trial&lt;/strong&gt; at &lt;code&gt;developer.chrome.com/origintrials&lt;/code&gt; — search for "WebMCP", register your origin, and include the token as a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag in your page's &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Open the WebMCP DevTools Pane
&lt;/h3&gt;

&lt;p&gt;Chrome DevTools now has a dedicated &lt;strong&gt;WebMCP pane&lt;/strong&gt; under the &lt;strong&gt;Application&lt;/strong&gt; tab. This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Available Tools&lt;/strong&gt;: Every tool registered on the page, with invocation counters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invoked Tools Log&lt;/strong&gt;: Chronological record of agent-tool interactions with input/output inspection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Test&lt;/strong&gt;: Execute any tool directly, bypassing agent logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema Validation&lt;/strong&gt;: Catches malformed JSON schemas before agents hit them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alternatively, you can also install the &lt;strong&gt;Model Context Tool Inspector&lt;/strong&gt; extension from the Chrome Web Store for a more visual workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Register Your First Tool
&lt;/h3&gt;

&lt;p&gt;Create an &lt;code&gt;index.html&lt;/code&gt; file:&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="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;WebMCP Demo&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;🛠️ My Agent-Ready Page&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"output"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// Check if the API is available&lt;/span&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="s1"&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="s1"&gt;get_weather&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Returns the current weather for a given city. Use this when the user asks about weather conditions.&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="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The city name, e.g. "Tokyo" or "San Francisco"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;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="s1"&gt;celsius&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fahrenheit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
              &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Temperature unit preference&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;city&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;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;units&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;celsius&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// In a real app, this would call your existing API&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mockData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tokyo&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;temp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Partly Cloudy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;san francisco&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;temp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Foggy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;london&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;temp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Overcast&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;};&lt;/span&gt;

          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mockData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;
          &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`No weather data for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;city&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;units&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fahrenheit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
            &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
            &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;temp&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="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;°&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;units&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fahrenheit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;F&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;'&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="na"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✅ WebMCP tool registered: get_weather&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WebMCP not available. Enable chrome://flags/#enable-webmcp-testing&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open this in Chrome 149 with the flag enabled. Open DevTools console. You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ WebMCP tool registered: get_weather
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations — your page is now &lt;strong&gt;agent-ready&lt;/strong&gt;. Any AI agent that supports WebMCP (like Gemini in Chrome) can discover and call this tool instead of trying to scrape your page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Going Deeper: The Declarative Approach
&lt;/h2&gt;

&lt;p&gt;The imperative JavaScript API gives you full control, but WebMCP also offers a declarative approach for common form-based workflows. This is where it gets really elegant.&lt;/p&gt;

&lt;p&gt;Instead of writing JavaScript, you add attributes directly to your HTML forms:&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;form&lt;/span&gt; &lt;span class="na"&gt;toolname=&lt;/span&gt;&lt;span class="s"&gt;"search_products"&lt;/span&gt; 
      &lt;span class="na"&gt;tooldescription=&lt;/span&gt;&lt;span class="s"&gt;"Search the product catalog by name, category, or price range"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"query"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"query"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"query"&lt;/span&gt; 
         &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"What are you looking for?"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"category"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Category&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"category"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"category"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;All Categories&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"electronics"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Electronics&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"books"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Books&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"clothing"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Clothing&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"max_price"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Max Price ($)&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"max_price"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"max_price"&lt;/span&gt; &lt;span class="na"&gt;min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;step=&lt;/span&gt;&lt;span class="s"&gt;"0.01"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser &lt;strong&gt;automatically generates the JSON schema&lt;/strong&gt; from your form structure — input types, names, required fields, select options, min/max constraints. The agent gets a typed tool contract without you writing a single line of schema code.&lt;/p&gt;

&lt;p&gt;This is honestly brilliant. If you have an existing website with forms, you can make it agent-accessible by adding two HTML attributes. That's it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building Something Real: A Task Manager with 3 WebMCP Tools
&lt;/h2&gt;

&lt;p&gt;Let me walk through something more practical. I built a simple task manager that exposes three tools to AI agents:&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="c1"&gt;// Tool 1: Add a task&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="s1"&gt;add_task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Creates a new task in the task list. Returns the created task with its ID.&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="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The task title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;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="s1"&gt;low&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;urgent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Priority level&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;due_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Due date in YYYY-MM-DD format (optional)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&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;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;priority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;due_date&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;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;due_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;due_date&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;completed&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;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Update the UI&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;success&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="nx"&gt;task&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;// Tool 2: List tasks with filters&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="s1"&gt;list_tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Returns all tasks, optionally filtered by completion status or priority.&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="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;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="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Filter by status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="na"&gt;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="s1"&gt;low&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;urgent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Filter by priority&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;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;priority&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;priority&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;priority&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;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;filtered&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;// Tool 3: Complete a task&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="s1"&gt;complete_task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Marks a specific task as completed by its ID.&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="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The UUID of the task to complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;task_id&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;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;task_id&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;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;task&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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Update the UI in real-time&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;success&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="nx"&gt;task&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;What's happening here is subtle but important: when an AI agent calls &lt;code&gt;add_task&lt;/code&gt;, the UI updates in real-time because &lt;code&gt;renderTasks()&lt;/code&gt; runs inside the user's browser. The user watches their task list populate while the agent works. &lt;strong&gt;The agent and the human share the same view.&lt;/strong&gt; This is fundamentally different from a headless MCP server processing requests in the background.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing Your Tools (Without an Agent)
&lt;/h2&gt;

&lt;p&gt;You don't need a full AI agent to test your WebMCP implementation. Use the programmatic API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// List all registered tools&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&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;getTools&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Registered tools:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&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="c1"&gt;// Execute a tool manually&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="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;executeTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;add_task&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Write WebMCP article&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;urgent&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Result:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use the &lt;strong&gt;Model Context Tool Inspector&lt;/strong&gt; extension — it gives you a visual panel to browse tools, fill in parameters, and hit "Execute". During development, this was my most-used tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Security Model: What You Need to Know
&lt;/h2&gt;

&lt;p&gt;WebMCP isn't a free-for-all. The security considerations are thoughtful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Same-Origin Policy&lt;/strong&gt;: Tools are strictly isolated by origin. Cross-origin tools cannot be accessed, enumerated, or invoked — even from iframes. Third-party widgets can't interfere with your app's tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CSP Integration&lt;/strong&gt;: WebMCP respects Content Security Policy headers. If your CSP blocks inline scripts, tool registration via inline &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags won't work (use external scripts instead).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTPS Required&lt;/strong&gt;: Tools can only be registered on secure origins. No HTTP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Human-in-the-Loop&lt;/strong&gt;: This is the big one. The spec provides a &lt;code&gt;requestUserInteraction()&lt;/code&gt; API for sensitive or destructive actions (payments, deletions, data exports). When invoked, the &lt;strong&gt;browser&lt;/strong&gt; — not your website — renders a native consent dialog. Your site cannot suppress, restyle, or auto-click it. It's a mandatory choke-point.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;requestUserInteraction&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// For dangerous operations, require explicit user consent&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;requestUserInteraction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Delete all &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; items? This cannot be undone.`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;});&lt;/span&gt;
     &lt;span class="c1"&gt;// Only reaches here if user approved&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deleteItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agent Traceability&lt;/strong&gt;: When an agent invokes a tool that makes HTTP requests, Chrome automatically adds a &lt;code&gt;Sec-WebMCP-Agent: 1&lt;/code&gt; header. On the server side, form submissions set &lt;code&gt;SubmitEvent.agentInvoked = true&lt;/code&gt;. This means you can detect agent traffic, set up agent-specific rate limits, and build audit logs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Permission-First Design&lt;/strong&gt;: Nothing is exposed by default. You must explicitly call &lt;code&gt;registerTool()&lt;/code&gt; to make anything available. It follows a least-privilege model and supports &lt;code&gt;Permissions Policy&lt;/code&gt; headers for fine-grained access control.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a sane, web-platform-native security model. It doesn't invent new trust boundaries — it inherits the browser's existing ones and adds agent-specific layers on top.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Think Is Underrated About WebMCP
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Zero-Auth for Agents
&lt;/h3&gt;

&lt;p&gt;This is the killer feature that nobody's talking about enough. &lt;/p&gt;

&lt;p&gt;With traditional MCP, you need to solve authentication for the AI agent separately — API keys, OAuth flows, token management. With WebMCP, &lt;strong&gt;the agent inherits the user's existing session&lt;/strong&gt;. If the user is logged into your app, the agent can act on their behalf, within the same session, using the same cookies.&lt;/p&gt;

&lt;p&gt;No new auth infrastructure. No token management. No security review for a new API surface. The user's login &lt;em&gt;is&lt;/em&gt; the auth.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Progressive Enhancement
&lt;/h3&gt;

&lt;p&gt;WebMCP follows the web platform's best tradition: your site works fine without it. The &lt;code&gt;if ('modelContext' in navigator)&lt;/code&gt; check means you can ship WebMCP tools today — users on older browsers simply don't see them. No polyfills, no graceful degradation code. It's additive.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Declarative API Lowers the Bar Massively
&lt;/h3&gt;

&lt;p&gt;Not every web developer wants to write JSON Schema by hand. The &lt;code&gt;&amp;lt;form toolname="..." tooldescription="..."&amp;gt;&lt;/code&gt; approach means a WordPress theme developer, a Shopify store owner, or a junior dev on their first project can make their site agent-ready. This is how you get ecosystem adoption.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Still Missing (Honest Take)
&lt;/h2&gt;

&lt;p&gt;No technology ships perfect. Here's what I noticed during my hands-on time:&lt;/p&gt;

&lt;h3&gt;
  
  
  Tool Discovery is Unclear
&lt;/h3&gt;

&lt;p&gt;How does an agent find &lt;em&gt;which&lt;/em&gt; websites have WebMCP tools? There's no registry, no manifest file, no equivalent of &lt;code&gt;robots.txt&lt;/code&gt; for agents. Right now, the agent has to navigate to your page first, and then discover tools. That's fine for "help me on this website" flows, but limits proactive agent discovery.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Inter-Tool Dependencies
&lt;/h3&gt;

&lt;p&gt;What if &lt;code&gt;complete_task&lt;/code&gt; should only be callable after &lt;code&gt;list_tasks&lt;/code&gt; returns results? There's no way to express tool ordering or dependencies in the schema. Agents have to figure this out from descriptions alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging Could Go Further
&lt;/h3&gt;

&lt;p&gt;The DevTools WebMCP pane is solid for basic inspection, but there's no integration with the Performance timeline yet. You can't profile tool execution latency alongside your app's rendering pipeline. For a spec aiming at production adoption, this will need to come.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Origin Trial Boundary
&lt;/h3&gt;

&lt;p&gt;This is experimental. Chrome 149 only. The spec lives in the &lt;strong&gt;W3C Web Machine Learning Community Group&lt;/strong&gt; (repo: &lt;a href="https://github.com/webmachinelearning/webmcp" rel="noopener noreferrer"&gt;github.com/webmachinelearning/webmcp&lt;/a&gt;) — which is a Community Group Report, &lt;em&gt;not&lt;/em&gt; a formal W3C Standard or even on the Standards Track yet. No Firefox, no Safari. If you're building production features on this today, you're building on sand. If you're prototyping and providing feedback to shape the spec — you're in exactly the right place.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who Should Care About This Today
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If you are...&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A web developer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prototype one tool. Get familiar with &lt;code&gt;registerTool()&lt;/code&gt;. Ship behind a feature flag.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;An e-commerce dev&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The declarative form API is built for you. &lt;code&gt;&amp;lt;form toolname="search_products"&amp;gt;&lt;/code&gt; is a one-line upgrade.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A framework author&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Start thinking about WebMCP primitives. React/Vue/Svelte components that auto-register tools will be huge.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A product manager&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Know that your website will have two interfaces soon: one for humans, one for agents. Plan accordingly.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;WebMCP isn't just a Chrome API. It's a signal about where the web is heading.&lt;/p&gt;

&lt;p&gt;For 30 years, the web has been a visual medium — we write HTML for human eyes, style it with CSS for human aesthetics, and add JavaScript for human interactions. WebMCP introduces a parallel interface layer: the same page, the same code, but now also speaking machine.&lt;/p&gt;

&lt;p&gt;The websites that embrace this won't just be "AI-friendly" — they'll be the ones that AI agents actually recommend, prefer, and route users toward. Because an agent that can reliably call &lt;code&gt;book_flight({ from: 'SFO', to: 'NRT', date: '2026-07-01' })&lt;/code&gt; will always choose that over scraping a booking page and hoping the DOM hasn't changed.&lt;/p&gt;

&lt;p&gt;The question isn't whether the web will become agent-ready. It's whether your website will be ready when the agents arrive.&lt;/p&gt;

&lt;p&gt;Start with &lt;code&gt;navigator.modelContext.registerTool()&lt;/code&gt;. Start today.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Nilam — a developer who builds things and occasionally writes about them. If you found this useful, the 💜 reaction helps this article reach more developers. Got questions about WebMCP? Drop them in the comments — I'll answer everything I can from my hands-on experience.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleiochallenge</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>The Anatomy of a Self-Improving AI Agent — How Hermes Agent's Closed Learning Loop Actually Works</title>
      <dc:creator>Nilam Bora</dc:creator>
      <pubDate>Sat, 23 May 2026 15:00:23 +0000</pubDate>
      <link>https://dev.to/nilambuilds/the-anatomy-of-a-self-improving-ai-agent-how-hermes-agents-closed-learning-loop-actually-works-4jk7</link>
      <guid>https://dev.to/nilambuilds/the-anatomy-of-a-self-improving-ai-agent-how-hermes-agents-closed-learning-loop-actually-works-4jk7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;: Write About Hermes Agent&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every AI agent framework solves the same problem: how to make an LLM use tools. Hermes Agent asks a different question entirely — &lt;em&gt;how do you make an LLM that used a tool today use it better tomorrow?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That question sounds simple. The engineering required to answer it is not.&lt;/p&gt;

&lt;p&gt;I've spent the past few weeks dissecting Hermes Agent's architecture, reading through its source code, studying the GEPA evolution pipeline, and mapping how its three-layer memory system actually works under the hood. What I found isn't just another agentic wrapper around API calls — it's a genuinely novel approach to building AI systems that compound in capability over time.&lt;/p&gt;

&lt;p&gt;This article is a technical deep dive. No "getting started" tutorial, no surface-level overview. We're going straight into the internals — the Closed Learning Loop, the SKILL.md format, the progressive disclosure system that keeps token costs sane, and the DSPy + GEPA pipeline that lets Hermes evolve its own skills without a single GPU.&lt;/p&gt;

&lt;p&gt;Let's crack it open.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Goldfish Problem: Why Most Agent Frameworks Start From Zero Every Time
&lt;/h2&gt;

&lt;p&gt;Here's a thought experiment. You ask an AI agent to scrape a website, parse the data, and save it to a CSV. It takes 12 tool calls, hits two errors, retries with different selectors, and eventually succeeds.&lt;/p&gt;

&lt;p&gt;Tomorrow, you ask it to scrape a different website.&lt;/p&gt;

&lt;p&gt;It starts from scratch. Same errors. Same retries. Same 12 tool calls. It learned nothing from yesterday.&lt;/p&gt;

&lt;p&gt;This is what I call the &lt;strong&gt;Goldfish Problem&lt;/strong&gt; — and it plagues every major agentic framework:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Mental Model&lt;/th&gt;
&lt;th&gt;Learns From Past Tasks?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LangChain / LangGraph&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Graph-based state machine&lt;/td&gt;
&lt;td&gt;❌ No — state resets per workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Role-based multi-agent teams&lt;/td&gt;
&lt;td&gt;❌ No — crews are stateless&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AutoGen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Conversational multi-agent dialogue&lt;/td&gt;
&lt;td&gt;❌ No — conversation history only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hermes Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Persistent self-improving runtime&lt;/td&gt;
&lt;td&gt;✅ Yes — Closed Learning Loop&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;LangGraph gives you surgical control over state machines. CrewAI lets you prototype multi-agent teams fast. AutoGen enables agent-to-agent dialogue. These are good tools for their intended use cases.&lt;/p&gt;

&lt;p&gt;But none of them treat &lt;strong&gt;past execution as training data for future execution&lt;/strong&gt;. They orchestrate. They don't learn.&lt;/p&gt;

&lt;p&gt;Hermes Agent does both.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Closed Learning Loop — Execute, Evaluate, Extract, Retrieve
&lt;/h2&gt;

&lt;p&gt;The core innovation in Hermes Agent is a four-phase cycle that Nous Research calls the &lt;strong&gt;Closed Learning Loop&lt;/strong&gt;. Here's how it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────┐
│                                                  │
│   ┌──────────┐    ┌──────────┐    ┌──────────┐  │
│   │          │    │          │    │          │   │
│   │ EXECUTE  │───▶│ EVALUATE │───▶│ EXTRACT  │  │
│   │          │    │          │    │          │   │
│   └──────────┘    └──────────┘    └──────────┘  │
│        ▲                               │         │
│        │          ┌──────────┐         │         │
│        │          │          │         │         │
│        └──────────│ RETRIEVE │◀────────┘         │
│                   │          │                    │
│                   └──────────┘                    │
│                                                  │
└──────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 1: Execute
&lt;/h3&gt;

&lt;p&gt;The agent performs a task using its available tools — web search, browser automation, terminal commands, file operations, code execution. Standard agentic behavior. Nothing unusual here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Evaluate
&lt;/h3&gt;

&lt;p&gt;After the task completes, the agent doesn't just move on. It &lt;strong&gt;reviews its own execution trace&lt;/strong&gt; — every tool call, every reasoning step, every error and recovery. It asks: &lt;em&gt;What worked? What failed? What took more steps than necessary?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the critical divergence from other frameworks. Most agents treat completion as the end. Hermes treats it as the beginning of learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Extract
&lt;/h3&gt;

&lt;p&gt;If the agent identifies a reusable pattern — a sequence of tool calls that solved a class of problems, an error-handling strategy that recovered gracefully, a workflow that could be templated — it &lt;strong&gt;codifies that pattern into a Skill&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Skills are written as Markdown files (&lt;code&gt;SKILL.md&lt;/code&gt;) with structured YAML frontmatter. They're human-readable, version-controllable, and composable. More on this in the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: Retrieve
&lt;/h3&gt;

&lt;p&gt;The next time the agent encounters a similar task, it searches its skill library before acting. If a relevant skill exists, it loads the skill's instructions and follows the proven workflow — skipping the trial-and-error phase entirely.&lt;/p&gt;

&lt;p&gt;Then the cycle repeats. The skill gets refined. Edge cases get covered. The agent gets measurably faster and more reliable at recurring tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The neuroscience parallel is striking.&lt;/strong&gt; This is essentially how human procedural memory works. You don't consciously think through every step of riding a bike — your brain retrieves a compressed motor program built from hundreds of past attempts. Hermes does the same thing with tool-calling sequences.&lt;/p&gt;

&lt;p&gt;And critically, this is architecturally different from the three common approaches to "giving agents memory":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RAG&lt;/strong&gt; retrieves &lt;em&gt;information&lt;/em&gt;. Hermes retrieves &lt;em&gt;procedures&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fine-tuning&lt;/strong&gt; bakes knowledge into weights. Hermes stores it in editable text files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt caching&lt;/strong&gt; saves tokens. Hermes saves &lt;em&gt;entire workflows&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  SKILL.md — The Anatomy of an Agent's Procedural Memory
&lt;/h2&gt;

&lt;p&gt;This is where Hermes Agent gets genuinely interesting from an engineering perspective. Let's look at what a Skill actually is.&lt;/p&gt;

&lt;p&gt;Every skill lives in &lt;code&gt;~/.hermes/skills/&lt;/code&gt; as a directory containing a &lt;code&gt;SKILL.md&lt;/code&gt; file. Here's a realistic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;web-scraping-with-retry&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="s"&gt;Scrapes web pages using browser automation with intelligent retry&lt;/span&gt;
  &lt;span class="s"&gt;logic, selector fallbacks, and anti-detection measures.&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.2.0&lt;/span&gt;
&lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hermes-agent (auto-generated)&lt;/span&gt;
&lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MIT&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;web-scraping&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;browser&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;automation&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;retry&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;related_skills&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;data-parsing-csv&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;browser-stealth-config&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;linux&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;macos&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;min_tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;browser&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;trigger_conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;requests&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;web&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;scraping"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;involves&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;extracting&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;websites"&lt;/span&gt;
  &lt;span class="na"&gt;success_rate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.94&lt;/span&gt;
  &lt;span class="na"&gt;total_executions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;47&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;# Web Scraping with Retry&lt;/span&gt;

&lt;span class="c1"&gt;## Overview&lt;/span&gt;
&lt;span class="s"&gt;This skill handles web scraping tasks with built-in resilience.&lt;/span&gt;
&lt;span class="s"&gt;It was originally created after a session where naive scraping&lt;/span&gt;
&lt;span class="s"&gt;failed due to dynamic content loading and rate limiting.&lt;/span&gt;

&lt;span class="c1"&gt;## Procedure&lt;/span&gt;

&lt;span class="c1"&gt;### Step 1: Assess the Target&lt;/span&gt;
&lt;span class="s"&gt;Before scraping, check for&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;robots.txt restrictions&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Dynamic rendering (SPA vs server-rendered)&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Rate limiting headers (X-RateLimit-*)&lt;/span&gt;

&lt;span class="c1"&gt;### Step 2: Choose Strategy&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;**Static HTML**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use `fetch_url` tool directly&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;**Dynamic/SPA**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use `browser_navigate` + wait for selectors&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;**Rate-limited**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add 2-5 second delays between requests&lt;/span&gt;

&lt;span class="c1"&gt;### Step 3: Implement Fallback Selectors&lt;/span&gt;
&lt;span class="na"&gt;Always prepare 3 levels of selectors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;1. Semantic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;data-testid="product-price"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;span class="na"&gt;2. Structural&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="s"&gt;.product-card &amp;gt; .price-container &amp;gt; span`&lt;/span&gt;
&lt;span class="na"&gt;3. XPath fallback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="s"&gt;//div[contains(@class,"price")]`&lt;/span&gt;

&lt;span class="c1"&gt;### Step 4: Error Recovery&lt;/span&gt;
&lt;span class="na"&gt;If a selector fails&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Wait 3 seconds and retry (content may still be loading)&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Try next fallback selector&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;If all selectors fail, capture a screenshot and report&lt;/span&gt;

&lt;span class="c1"&gt;## Anti-Patterns to Avoid&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Never scrape without checking robots.txt first&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Never use fixed sleep() — use element-wait conditions&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Never store raw HTML when structured data is available&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what's happening here. This isn't a prompt template. It isn't a function signature. It's a &lt;strong&gt;structured decision-making guide&lt;/strong&gt; that encodes &lt;em&gt;judgment&lt;/em&gt; — when to use which strategy, what to watch out for, how to recover from specific failure modes.&lt;/p&gt;

&lt;p&gt;The agent wrote this itself, after 47 executions of scraping tasks, refining the procedure each time. The &lt;code&gt;success_rate: 0.94&lt;/code&gt; in the metadata isn't a fabrication — it's tracked from actual execution outcomes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Progressive Disclosure: How Hermes Keeps Token Costs Sane
&lt;/h3&gt;

&lt;p&gt;Here's the engineering problem: if you have 200 skills, you can't load all of them into the context window. That would burn tens of thousands of tokens before the agent even starts working.&lt;/p&gt;

&lt;p&gt;Hermes solves this with a three-level &lt;strong&gt;progressive disclosure&lt;/strong&gt; system:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 0 — The Index (Always Loaded)&lt;/strong&gt;&lt;br&gt;
The agent sees only skill names and one-line descriptions. This is a compact lookup table that costs maybe 500 tokens for dozens of skills:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Available Skills:
- web-scraping-with-retry: Scrapes web pages with retry logic and fallbacks
- data-parsing-csv: Parses messy CSV/TSV data into clean structured formats
- git-pr-review: Reviews pull requests for code quality and security issues
- email-digest-summary: Summarizes email threads into actionable bullet points
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Level 1 — Full Skill (Loaded On Demand)&lt;/strong&gt;&lt;br&gt;
When the agent decides a skill is relevant to the current task, it loads the full &lt;code&gt;SKILL.md&lt;/code&gt; content. Now it has the complete procedure, anti-patterns, and decision logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level 2 — Deep References (Rare)&lt;/strong&gt;&lt;br&gt;
Some skills include a &lt;code&gt;references/&lt;/code&gt; subdirectory with example scripts, configuration templates, or API documentation. These are loaded only when the agent needs specific implementation details — like a regex pattern for parsing dates, or a template for a specific API's authentication flow.&lt;/p&gt;

&lt;p&gt;This three-tier system means the token cost scales with &lt;em&gt;relevance&lt;/em&gt;, not with library size. An agent with 500 skills pays roughly the same base cost as one with 50 — only the skills actually needed get loaded.&lt;/p&gt;
&lt;h3&gt;
  
  
  When Does the Agent Create a New Skill?
&lt;/h3&gt;

&lt;p&gt;Not every task becomes a skill. Hermes uses specific triggers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Complexity threshold&lt;/strong&gt;: The task required 5+ tool calls to complete&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error recovery&lt;/strong&gt;: The agent hit errors and successfully recovered — that recovery pattern is worth saving&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Novelty detection&lt;/strong&gt;: The task doesn't match any existing skill in the library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User confirmation&lt;/strong&gt;: In some configurations, the agent asks the user before creating a skill&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The threshold is intentionally high. You don't want a skill for "read a file" — that's trivial. You want skills for multi-step procedures where the agent's learned judgment actually saves time.&lt;/p&gt;


&lt;h2&gt;
  
  
  Self-Evolution: How DSPy + GEPA Optimize Skills Without a GPU
&lt;/h2&gt;

&lt;p&gt;Manual skill creation through the Closed Learning Loop is powerful. But Nous Research pushed further with an automated evolution pipeline called &lt;strong&gt;GEPA&lt;/strong&gt; — &lt;strong&gt;Genetic-Pareto Prompt Evolution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is where Hermes Agent stops being "just" an agent framework and starts looking like an AI research platform.&lt;/p&gt;
&lt;h3&gt;
  
  
  The GEPA Pipeline (5 Stages)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Execution Trace Collection&lt;/strong&gt;&lt;br&gt;
GEPA reads the agent's SQLite database of past sessions. It doesn't just look at pass/fail outcomes — it analyzes the &lt;em&gt;full reasoning trace&lt;/em&gt;: every tool call, every decision branch, every error message and recovery attempt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2: Reflective Failure Analysis&lt;/strong&gt;&lt;br&gt;
An LLM examines failed traces and generates what Nous calls "Actionable Side Information" — a diagnosis of &lt;em&gt;why&lt;/em&gt; the skill failed. Not "it didn't work," but "the CSS selector assumed a class name that changed between page loads" or "the retry logic didn't account for 429 rate-limit responses."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 3: Targeted Mutation&lt;/strong&gt;&lt;br&gt;
Based on the failure analysis, GEPA proposes specific text edits to the &lt;code&gt;SKILL.md&lt;/code&gt; file. These aren't random perturbations — they're targeted fixes and improvements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  ### Step 4: Error Recovery
  If a selector fails:
  - Wait 3 seconds and retry
&lt;span class="gi"&gt;+ - Check for 429 status code — if present, back off exponentially
+   (5s, 15s, 45s) before retrying
&lt;/span&gt;  - Try next fallback selector
  - If all selectors fail, capture a screenshot and report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stage 4: Multi-Candidate Evaluation&lt;/strong&gt;&lt;br&gt;
GEPA generates multiple mutated variants of the skill and evaluates each against a test suite — either synthetic test cases or replayed real-world scenarios. It uses &lt;strong&gt;Pareto optimization&lt;/strong&gt; across multiple dimensions (success rate, token efficiency, execution speed) rather than optimizing a single metric.&lt;/p&gt;

&lt;p&gt;This is critical. A skill that succeeds 100% of the time but uses 50,000 tokens per run isn't necessarily better than one that succeeds 95% of the time using 5,000 tokens. Pareto selection lets you keep multiple specialized variants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 5: Human-in-the-Loop Review&lt;/strong&gt;&lt;br&gt;
The winning variant isn't automatically deployed. GEPA generates a &lt;strong&gt;Pull Request&lt;/strong&gt; with the proposed changes, a diff showing exactly what changed, and the evaluation metrics that justify the change. A human reviews and approves before the skill goes live.&lt;/p&gt;

&lt;p&gt;This safety rail is non-negotiable. Without it, you risk &lt;strong&gt;skill hallucination&lt;/strong&gt; — the agent convincing itself that a broken procedure works because it evaluated against flawed test cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Isn't Reinforcement Learning
&lt;/h3&gt;

&lt;p&gt;GEPA looks superficially like RL, but it's fundamentally different:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Traditional RL&lt;/th&gt;
&lt;th&gt;GEPA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Optimization target&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Neural network weights&lt;/td&gt;
&lt;td&gt;Plain text (Markdown)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Requires GPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No — LLM API calls only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Transparency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Black box&lt;/td&gt;
&lt;td&gt;Fully readable diffs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rollouts needed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Thousands&lt;/td&gt;
&lt;td&gt;~35x fewer than GRPO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Iteration unit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Training step&lt;/td&gt;
&lt;td&gt;Git commit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Nous Research calls this "evolutionary search over text" — and it's a surprisingly effective paradigm. You get the benefits of automated optimization without the opacity of weight updates.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Broader Architecture: What Powers the Loop
&lt;/h2&gt;

&lt;p&gt;The Closed Learning Loop doesn't exist in isolation. It's supported by a comprehensive runtime architecture:&lt;/p&gt;

&lt;h3&gt;
  
  
  Three-Layer Memory System
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Layer 1 — Core Memory&lt;/strong&gt;: &lt;code&gt;SOUL.md&lt;/code&gt; (persona), &lt;code&gt;MEMORY.md&lt;/code&gt; (facts), &lt;code&gt;USER.md&lt;/code&gt; (preferences). Loaded every session. Think of it as the agent's "identity."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layer 2 — Procedural Memory&lt;/strong&gt;: The skill library. Loaded on demand via progressive disclosure. This is where the learning loop writes to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layer 3 — Episodic Memory&lt;/strong&gt;: SQLite database with full session history, FTS5 full-text search, and LLM-summarized recall. The raw material that GEPA mines for improvements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Model Agnostic by Design
&lt;/h3&gt;

&lt;p&gt;Hermes doesn't lock you into a provider. It works with OpenAI, Anthropic, OpenRouter, Nous Portal, and local models via Ollama or vLLM. Swap models without changing skills — the procedural knowledge is in Markdown, not in weights.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Platform Gateway
&lt;/h3&gt;

&lt;p&gt;A single Hermes process can serve you across CLI, Telegram, Discord, Slack, WhatsApp, Signal, and Email simultaneously. Your skills, memory, and learning history follow you across every surface.&lt;/p&gt;

&lt;h3&gt;
  
  
  ~70 Built-In Tools + MCP Extensibility
&lt;/h3&gt;

&lt;p&gt;Web search, browser automation (with anti-detection via Camofox), terminal, file operations, code execution, vision, image generation, and a cron scheduler for autonomous recurring tasks. Plus Model Context Protocol (MCP) support for dynamically loading external tool servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sub-Agent Delegation
&lt;/h3&gt;

&lt;p&gt;For complex workflows, Hermes spawns isolated child agents with their own conversation history and toolsets. Only the final result returns to the parent — preventing context window flooding while enabling parallelizable work.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Should You Actually Use Hermes Agent?
&lt;/h2&gt;

&lt;p&gt;Not every problem needs a self-improving agent. Here's an honest decision framework:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Hermes Agent when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ You need a persistent assistant that handles recurring tasks (daily summaries, weekly reports, ongoing monitoring)&lt;/li&gt;
&lt;li&gt;✅ You want an agent that genuinely gets better at &lt;em&gt;your&lt;/em&gt; specific workflows over time&lt;/li&gt;
&lt;li&gt;✅ You care about data privacy and want full self-hosted control&lt;/li&gt;
&lt;li&gt;✅ You need multi-platform access (message your agent from Telegram, get results in Slack)&lt;/li&gt;
&lt;li&gt;✅ You're doing AI research and want to experiment with skill evolution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use something else when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;➡️ &lt;strong&gt;One-off pipeline orchestration&lt;/strong&gt; → LangGraph gives you more control over deterministic state machines&lt;/li&gt;
&lt;li&gt;➡️ &lt;strong&gt;Quick multi-agent prototyping&lt;/strong&gt; → CrewAI's role-task-crew abstraction is faster to set up&lt;/li&gt;
&lt;li&gt;➡️ &lt;strong&gt;Agent-to-agent collaboration experiments&lt;/strong&gt; → AutoGen's conversational paradigm is more natural&lt;/li&gt;
&lt;li&gt;➡️ &lt;strong&gt;You need a library, not a runtime&lt;/strong&gt; → Hermes is an always-on process, not a function you call&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest truth: if you're building a one-shot data pipeline that runs once and dies, Hermes is overkill. Its value compounds over time. The longer it runs, the more skills it accumulates, the more efficient it becomes. Day one, it's just another agent. Day ninety, it's an agent that knows &lt;em&gt;your&lt;/em&gt; infrastructure, &lt;em&gt;your&lt;/em&gt; coding style, &lt;em&gt;your&lt;/em&gt; failure modes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Compounding Agent Thesis
&lt;/h2&gt;

&lt;p&gt;Here's what I think most people miss about Hermes Agent, and why I believe the Closed Learning Loop matters beyond this one framework:&lt;/p&gt;

&lt;p&gt;The real moat in AI agents isn't who has the best LLM. Models are converging — GPT-4o, Claude, Gemini, Llama, they're all remarkably capable. The real moat is &lt;strong&gt;accumulated institutional knowledge&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every company, every developer, every team has specific procedures, preferences, failure modes, and tribal knowledge that no foundation model can know out of the box. The agent that captures and operationalizes that knowledge — automatically, incrementally, without manual prompt engineering — wins.&lt;/p&gt;

&lt;p&gt;Hermes Agent's Closed Learning Loop is the first serious implementation of this idea at the framework level. It treats every task completion not as an endpoint, but as a data point for improvement. Every error recovered from becomes a guardrail. Every successful workflow becomes a reusable template. Every edge case encountered becomes a documented anti-pattern.&lt;/p&gt;

&lt;p&gt;The result isn't just an agent that runs tools. It's an agent that builds its own playbook — and gets better every time you use it.&lt;/p&gt;

&lt;p&gt;That's not incremental improvement. That's a fundamentally different category of AI system.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Hermes Agent is open-source under the MIT license. You can find the code at &lt;a href="https://github.com/NousResearch/hermes-agent" rel="noopener noreferrer"&gt;github.com/NousResearch/hermes-agent&lt;/a&gt;, the self-evolution pipeline at &lt;a href="https://github.com/NousResearch/hermes-agent-self-evolution" rel="noopener noreferrer"&gt;github.com/NousResearch/hermes-agent-self-evolution&lt;/a&gt;, and the official documentation at &lt;a href="https://hermes-agent.org" rel="noopener noreferrer"&gt;hermes-agent.org&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
      <category>ai</category>
    </item>
    <item>
      <title>Gemma 4 Isn't an AI Model — It's a Deployment Spectrum, and That Changes Everything</title>
      <dc:creator>Nilam Bora</dc:creator>
      <pubDate>Tue, 19 May 2026 06:31:54 +0000</pubDate>
      <link>https://dev.to/nilambuilds/gemma-4-isnt-an-ai-model-its-a-deployment-spectrum-and-that-changes-everything-3n1p</link>
      <guid>https://dev.to/nilambuilds/gemma-4-isnt-an-ai-model-its-a-deployment-spectrum-and-that-changes-everything-3n1p</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Write About Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Question Nobody's Asking
&lt;/h2&gt;

&lt;p&gt;Here's what I don't understand about the discourse around open-weight AI models in 2026:&lt;/p&gt;

&lt;p&gt;Why does everyone keep reviewing them like they're standalone products?&lt;/p&gt;

&lt;p&gt;"Gemma 4 scores X on MMLU." "Llama 4 has a 10 million token context window." "Phi-4 is the best at math per parameter." Every review reads like a spec sheet comparison. As if we're buying refrigerators.&lt;/p&gt;

&lt;p&gt;But when I actually sat down with Gemma 4 — not the benchmarks, not the blog posts, but the actual model family, all four sizes — I realized that benchmarks were the wrong lens entirely. Google DeepMind didn't ship a model. &lt;strong&gt;They shipped a deployment spectrum.&lt;/strong&gt; And that distinction, once you understand it, changes how you think about building with AI.&lt;/p&gt;

&lt;p&gt;Let me explain what I mean.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Old Mental Model Is Broken
&lt;/h2&gt;

&lt;p&gt;For the past three years, the open-weight model conversation has been dominated by a single question: &lt;em&gt;"Which model is the best?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And "best" always meant the same thing: highest score on the hardest benchmark. We talked about models like they were Formula 1 cars — only one can win, and winning means being the fastest on the same track.&lt;/p&gt;

&lt;p&gt;This mental model made sense in the GPT-3 era, when you had one model, it ran on a cloud server, and you called it via API. There was one deployment target. One hardware profile. One question.&lt;/p&gt;

&lt;p&gt;But here's what's changed: &lt;strong&gt;AI isn't just an API anymore.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 2026, AI runs in your browser. It runs on your phone. It runs on a Raspberry Pi monitoring your greenhouse. It runs on an air-gapped corporate laptop that's never seen the internet. It runs on a single consumer GPU at 3 AM because your side project can't afford cloud inference.&lt;/p&gt;

&lt;p&gt;The deployment surface has shattered into a thousand fragments. And if your model family only gives you one size that works in one place — congratulations, you've built a sports car for a world that needs a vehicle fleet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gemma 4: One Brain, Four Bodies
&lt;/h2&gt;

&lt;p&gt;This is where Gemma 4 does something I haven't seen any other model family do as deliberately. It doesn't give you one model in different sizes. It gives you &lt;strong&gt;four distinct architectures, each engineered from the ground up for a specific deployment reality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let me break this down, because the details matter:&lt;/p&gt;

&lt;h3&gt;
  
  
  E2B — The Spy in Your Pocket
&lt;/h3&gt;

&lt;p&gt;2 billion effective parameters. Runs on a high-end phone. Runs on a Raspberry Pi 5 with 8GB of RAM. &lt;strong&gt;Runs without an internet connection.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The E2B isn't a watered-down version of the big model. It's a purpose-built edge model with native audio input — yes, it can process raw speech directly, no transcription pipeline needed — and 128K tokens of context. It uses a dense architecture with Per-Layer Embeddings (PLE), which means every layer gets its own learned embedding, allowing for richer representations at a fraction of the parameter count.&lt;/p&gt;

&lt;p&gt;Think about what this means. You can build a voice-controlled assistant that runs entirely on a $75 single-board computer. No cloud calls. No API keys. No monthly bill. No data leaving the device. The user speaks, the model listens, reasons, and responds — all locally.&lt;/p&gt;

&lt;p&gt;A year ago, this was a research demo. Today, it's a &lt;code&gt;pip install&lt;/code&gt; away.&lt;/p&gt;

&lt;h3&gt;
  
  
  E4B — The Daily Driver
&lt;/h3&gt;

&lt;p&gt;4 billion effective parameters. This is the model for laptops and mid-range hardware. It keeps everything the E2B has — audio, images, 128K context — but adds enough reasoning depth to handle tasks that would trip up the smaller sibling.&lt;/p&gt;

&lt;p&gt;I think of the E4B as the Toyota Corolla of AI models. Not flashy. Not headline-grabbing. But it starts every morning, handles whatever you throw at it, and does it on hardware that hundreds of millions of people already own.&lt;/p&gt;

&lt;p&gt;If you're building a developer tool that needs to work offline — a local code assistant, a documentation summarizer, an accessibility layer for audio content — the E4B is probably your model. Not because it's the smartest. Because it's the one your users can actually run.&lt;/p&gt;

&lt;h3&gt;
  
  
  26B MoE — The Clever Optimizer
&lt;/h3&gt;

&lt;p&gt;This one is fascinating. 26 billion total parameters, but only 3.8 billion active per token.&lt;/p&gt;

&lt;p&gt;The Mixture of Experts (MoE) architecture means the model has specialized "expert" subnetworks, and a router decides which experts to activate for each token. So you get the knowledge capacity of a 26B model with the inference cost of a 4B one.&lt;/p&gt;

&lt;p&gt;In practical terms: this model runs on a single consumer GPU. A used RTX 3090 from eBay. An M-series MacBook with 32GB of unified memory. It supports video input (up to 60 seconds), 256K context, and reasoning mode.&lt;/p&gt;

&lt;p&gt;The 26B MoE is for people who need real intelligence but can't (or won't) rent a data center. Indie devs. Startups pre-revenue. Researchers at universities that aren't Stanford. The vast majority of builders on the planet.&lt;/p&gt;

&lt;h3&gt;
  
  
  31B Dense — The Heavyweight
&lt;/h3&gt;

&lt;p&gt;31 billion dense parameters. Full video support. 256K context. This is the model that goes toe-to-toe with GPT-4-class systems on reasoning benchmarks — ranked #3 on Arena AI's text leaderboard at release.&lt;/p&gt;

&lt;p&gt;But here's the part that doesn't show up in benchmarks: it runs on a single workstation. Not a cluster. Not a multi-GPU rig. One machine. The kind that sits under a developer's desk.&lt;/p&gt;

&lt;p&gt;In the Llama 4 world, getting frontier-class reasoning means deploying Maverick — a 400B parameter MoE behemoth that needs multi-GPU servers. In the Gemma 4 world, you download a GGUF file, point Ollama at it, and you're having a conversation with a model that matches or beats most closed-source alternatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Spectrum Matters More Than Any Single Model
&lt;/h2&gt;

&lt;p&gt;Here's the argument I want to make, and I want to make it clearly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The most important innovation in Gemma 4 is not any individual model. It's that all four models share the same training lineage, the same capabilities framework, and the same API surface.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This means you can architect a system where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;E2B&lt;/strong&gt; runs on a user's phone, handling real-time voice commands and basic reasoning offline&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;E4B&lt;/strong&gt; runs on a laptop, processing documents and generating drafts without cloud dependencies&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;26B MoE&lt;/strong&gt; runs on a local server, handling complex multi-step workflows with visual understanding&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;31B Dense&lt;/strong&gt; runs on a workstation (or cloud instance during peak), providing frontier-quality reasoning when it matters most&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the code that talks to all of them is nearly identical. The prompts transfer. The function-calling schema transfers. The system instructions transfer. You're not learning four different APIs or managing four incompatible prompt formats. You're working with a single coherent model family that scales from your pocket to your server rack.&lt;/p&gt;

&lt;p&gt;This is what I mean by "deployment spectrum." It's not four models. It's one intelligence at four resolution levels, deployable across the entire range of hardware that exists in the real world.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Apache 2.0 Bombshell
&lt;/h2&gt;

&lt;p&gt;Let me address the elephant in the room: licensing.&lt;/p&gt;

&lt;p&gt;Gemma 4 ships under Apache 2.0. Not a "Community License" with asterisks about monthly active users. Not a custom license that lawyers need to review. Apache 2.0 — the same license as Kubernetes, TensorFlow, and Android.&lt;/p&gt;

&lt;p&gt;For individual developers, this means: do whatever you want. Fine-tune it. Distill it. Ship it in a commercial product. Embed it in hardware. No phone call to Google required.&lt;/p&gt;

&lt;p&gt;For enterprises, this means something even more important: &lt;strong&gt;digital sovereignty.&lt;/strong&gt; You can deploy Gemma 4 on air-gapped servers inside your own data center. Patient data stays in the hospital. Financial data stays in the bank. Legal documents stay in the firm. The model runs where your data lives, not the other way around.&lt;/p&gt;

&lt;p&gt;In a world where data regulations are tightening every quarter and "but the cloud provider says they won't look at your data" is no longer a satisfactory answer to compliance teams — Apache 2.0 isn't a feature. It's a prerequisite.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Everyone Else Is Getting Wrong
&lt;/h2&gt;

&lt;p&gt;I've read about thirty "Gemma 4 review" articles in the past few weeks. Most of them fall into one of three categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Benchmark table → "It's good"&lt;/strong&gt; — Useful but boring. Scores without context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"I ran it locally and it worked"&lt;/strong&gt; — Great, but a thousand people have written that article.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Gemma 4 vs. Llama 4 vs. Phi-4"&lt;/strong&gt; — Comparison charts that miss the point because they compare each model family's flagship instead of comparing deployment strategies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what I think most people are missing:&lt;/p&gt;

&lt;h3&gt;
  
  
  The real competition isn't model vs. model. It's ecosystem vs. ecosystem.
&lt;/h3&gt;

&lt;p&gt;When you choose Gemma 4, you're not just choosing a model. You're choosing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apache 2.0&lt;/strong&gt; — vs. Llama's Community License that restricts companies above 700M MAU, and requires specific usage obligations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native multimodality at every size&lt;/strong&gt; — vs. competitors where vision/audio is only available at the largest tier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google AI Studio + Hugging Face + Kaggle + OpenRouter&lt;/strong&gt; — four free access channels vs. competitors with one or two&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Function calling and structured output baked in&lt;/strong&gt; — vs. models where agentic features are fine-tuned on top&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Gemini API compatibility&lt;/strong&gt; — meaning code you write for Gemma works with Gemini when you need to scale up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ecosystem coherence is a strategic advantage that doesn't show up on any leaderboard. But it shows up in your codebase, your deployment pipeline, and your total cost of ownership.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reasoning Mode: Not a Gimmick
&lt;/h2&gt;

&lt;p&gt;Every model in the Gemma 4 family — including the tiny E2B — supports a reasoning mode where the model generates explicit chain-of-thought tokens before producing its final answer. Up to 4,000 tokens of "thinking out loud."&lt;/p&gt;

&lt;p&gt;I've seen people dismiss this as a gimmick, a marketing checkbox to compete with OpenAI's reasoning models. But here's why it matters for practical builders:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reasoning mode gives you observability into the model's decision-making process.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When your agent takes a wrong action, you can look at the reasoning trace and understand &lt;em&gt;why&lt;/em&gt;. Was it a bad premise? A logical error? A hallucination in the intermediate steps? This isn't just useful for debugging — it's essential for building trust in autonomous systems.&lt;/p&gt;

&lt;p&gt;And the fact that even the E2B supports it means you can have an on-device agent that not only acts, but explains itself. On a phone. Offline. Under Apache 2.0.&lt;/p&gt;

&lt;p&gt;Try finding that combination anywhere else in the market.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Gemma 4 Falls Short (Honest Assessment)
&lt;/h2&gt;

&lt;p&gt;I'd be dishonest if I didn't address the gaps. No model family is perfect, and pretending otherwise doesn't help anyone.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Context Window Isn't King
&lt;/h3&gt;

&lt;p&gt;Gemma 4's largest models top out at 256K tokens. That's generous by most standards, but Llama 4 Scout offers 10 million tokens. If your use case involves ingesting entire codebases, processing book-length documents in a single pass, or building RAG systems over massive corpora — Llama 4 has a structural advantage that Gemma 4 can't match.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The 31B Dense Is Slower Than Expected Locally
&lt;/h3&gt;

&lt;p&gt;The 31B model was trained with Multi-Token Prediction (MTP) heads designed to accelerate inference. But in practice, these MTP heads are stripped from the public GGUF weights, meaning local inference speeds are slower than the architecture suggests. If you're deploying the 31B for real-time interactive use, expect to invest in quantization tuning and hardware optimization.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Community Ecosystem Is Still Young
&lt;/h3&gt;

&lt;p&gt;Compared to Llama's massive fine-tuning ecosystem and Hugging Face's years of accumulated tooling around Meta's models, Gemma 4's community is smaller. Fewer LoRA adapters. Fewer domain-specific fine-tunes. Fewer "I tried X and here's what happened" blog posts (ironically, including this one).&lt;/p&gt;

&lt;p&gt;This will change with time and adoption, but right now, if you need a pre-built fine-tune for medical, legal, or financial domains, you'll find more options in the Llama ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Video Support Is Limited
&lt;/h3&gt;

&lt;p&gt;The workstation models (26B and 31B) support video input, but capped at 60 seconds at 1 FPS. For short clips and thumbnails, this is fine. For anything resembling real video analysis — security footage, lecture recordings, sports clips — you'll need something else or a creative chunking strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Actual Recommendation
&lt;/h2&gt;

&lt;p&gt;Here's what I'd tell a developer who asks me "Should I use Gemma 4?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're building something that needs to run locally — on a laptop, on a phone, on edge hardware — Gemma 4 is the best option available today.&lt;/strong&gt; Not because any single model is the absolute best at any single benchmark, but because the family gives you a coherent path from prototype to production across the entire deployment spectrum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're building a cloud-only application where cost-per-token is your primary concern and you'll never need to run anything locally&lt;/strong&gt; — you could pick any of the major open-weight families and be fine. The differences at the top end are marginal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you need million-token context windows&lt;/strong&gt; — Llama 4 Scout is your model. Full stop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you need the absolute smallest model for the most constrained hardware&lt;/strong&gt; — Phi-4 Mini and Gemma 4 E2B are both excellent, but Gemma 4's multimodal capabilities (especially native audio) give it an edge for real-world edge deployments.&lt;/p&gt;

&lt;p&gt;The right answer, as always, depends on where your code needs to run. And that's precisely the point. Gemma 4 is the first model family that treats that question as fundamental rather than incidental.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Here's the thought I keep coming back to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The history of computing is a history of intelligence moving closer to the user.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mainframes centralized everything. PCs put a computer on every desk. Smartphones put one in every pocket. The cloud briefly reversed the trend — pulling compute back to data centers — but the pendulum is swinging again.&lt;/p&gt;

&lt;p&gt;AI has been a cloud-first technology for its entire commercial life. Every ChatGPT conversation, every Midjourney image, every Claude response you've ever received — processed in a data center hundreds or thousands of miles away. Your data travels there, gets processed, and the result comes back. You never own the model. You never control the pipeline. You're renting intelligence.&lt;/p&gt;

&lt;p&gt;Gemma 4 is part of a broader movement to change that. Not "local AI" as a novelty or a hobbyist pursuit, but local AI as a genuine alternative to the cloud-dependent default. A model that can reason, see, hear, and act — running on hardware you own, under a license that doesn't restrict you, processing data that never leaves your building.&lt;/p&gt;

&lt;p&gt;We're not there yet. Local models are still behind frontier cloud models on the hardest tasks. The tooling is still maturing. The ecosystem is still growing.&lt;/p&gt;

&lt;p&gt;But the gap is closing faster than anyone predicted. And Gemma 4 — with its four-model deployment spectrum, its Apache 2.0 license, and its "one family, runs everywhere" philosophy — is probably the strongest argument yet that the future of AI isn't exclusively in the cloud.&lt;/p&gt;

&lt;p&gt;It's in your pocket. On your desk. In your server room. Wherever your users and your data actually are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's&lt;/strong&gt; the revolution. Not a bigger number on a benchmark. A smarter model in more places.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your take? Are you building with Gemma 4 locally, or is cloud inference still the default for you? I'm especially curious about edge deployment stories — if you've gotten E2B or E4B running on unconventional hardware, I'd love to hear about it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>OpenClaw Isn't a Chatbot — It's the Unix of Personal AI</title>
      <dc:creator>Nilam Bora</dc:creator>
      <pubDate>Fri, 24 Apr 2026 16:06:49 +0000</pubDate>
      <link>https://dev.to/nilambuilds/openclaw-isnt-a-chatbot-its-the-unix-of-personal-ai-3b9p</link>
      <guid>https://dev.to/nilambuilds/openclaw-isnt-a-chatbot-its-the-unix-of-personal-ai-3b9p</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/openclaw-2026-04-16"&gt;OpenClaw Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;I almost dismissed OpenClaw the first time I heard about it.&lt;/p&gt;

&lt;p&gt;"Another AI wrapper," I thought. "Probably a ChatGPT skin with a Telegram bot glued on top." I'd seen a dozen of these. They all promise you a personal assistant, and they all end up being a slightly less convenient way to use the same chat interface you already have open in a browser tab.&lt;/p&gt;

&lt;p&gt;I was wrong. Spectacularly, fundamentally wrong.&lt;/p&gt;

&lt;p&gt;After spending real time with OpenClaw — reading the source, building skills, breaking things, rebuilding them — I've come to a conclusion that might sound ridiculous at first:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenClaw is doing for personal AI what Unix did for computing.&lt;/strong&gt; And if you understand why, you'll understand why it matters far more than its viral popularity suggests.&lt;/p&gt;

&lt;p&gt;Let me explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unix Philosophy, Briefly
&lt;/h2&gt;

&lt;p&gt;In the 1970s, Ken Thompson and Dennis Ritchie built an operating system around a set of principles that felt almost radical at the time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Do one thing and do it well.&lt;/strong&gt; Each program should handle a single task.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programs should work together.&lt;/strong&gt; The output of one becomes the input of another.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text is the universal interface.&lt;/strong&gt; Everything communicates through plain, readable streams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build tools, not applications.&lt;/strong&gt; Let users compose solutions from small pieces.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These ideas didn't just survive — they conquered. Every server running your favorite website, every phone in your pocket, every cloud instance spinning up right now — all of them trace their lineage back to these four principles.&lt;/p&gt;

&lt;p&gt;The reason Unix won wasn't because it was the most powerful system. It won because it was the most &lt;em&gt;composable&lt;/em&gt; system. And composability scales in ways that monoliths never can.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now Look at OpenClaw
&lt;/h2&gt;

&lt;p&gt;When you strip away the hype and the viral Twitter threads and the "I let an AI run my life for a week" clickbait, OpenClaw's architecture tells a remarkably familiar story.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 1: Do One Thing Well — The Skill System
&lt;/h3&gt;

&lt;p&gt;The fundamental unit of OpenClaw isn't a prompt. It's a &lt;strong&gt;skill&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A skill is a directory containing a &lt;code&gt;SKILL.md&lt;/code&gt; file — a plain Markdown document with YAML frontmatter that tells the agent what a particular capability is, when to use it, and how to execute it.&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="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;morning_briefing&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Compile and deliver a morning summary of calendar, weather, and top news.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Morning Briefing&lt;/span&gt;

When the user asks for a morning update, or when triggered by the 7:00 AM schedule:
&lt;span class="p"&gt;
1.&lt;/span&gt; Check the user's Google Calendar for today's events
&lt;span class="p"&gt;2.&lt;/span&gt; Fetch weather for the user's configured location
&lt;span class="p"&gt;3.&lt;/span&gt; Pull top 3 headlines from configured news sources
&lt;span class="p"&gt;4.&lt;/span&gt; Compile into a concise summary
&lt;span class="p"&gt;5.&lt;/span&gt; Send via the user's preferred channel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No Python class hierarchy. No plugin interface to implement. No SDK to install. A skill is a document that describes a single capability in natural language, and the agent interprets and executes it.&lt;/p&gt;

&lt;p&gt;This is &lt;code&gt;grep&lt;/code&gt;. This is &lt;code&gt;sort&lt;/code&gt;. This is &lt;code&gt;wc&lt;/code&gt;. A small, focused tool that does one thing and does it well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 2: Programs Should Work Together — Composability
&lt;/h3&gt;

&lt;p&gt;Here's where it gets interesting. Skills in OpenClaw aren't isolated. They compose.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;morning_briefing&lt;/code&gt; skill calls the calendar, calls the weather API, calls the news source. But each of those could be its own skill too. You might have a &lt;code&gt;google_calendar&lt;/code&gt; skill that handles all calendar interactions, a &lt;code&gt;weather_lookup&lt;/code&gt; skill that knows how to query multiple weather providers, and a &lt;code&gt;news_digest&lt;/code&gt; skill that curates headlines.&lt;/p&gt;

&lt;p&gt;The morning briefing skill doesn't need to know how any of those work internally. It just needs to know they exist.&lt;/p&gt;

&lt;p&gt;This is piping. This is &lt;code&gt;cat access.log | grep 404 | sort | uniq -c | sort -rn&lt;/code&gt;. Small pieces, loosely joined, producing results that no single piece could achieve alone.&lt;/p&gt;

&lt;p&gt;And the key insight is the same one Unix taught us fifty years ago: &lt;strong&gt;you don't need to predict in advance what combinations users will want.&lt;/strong&gt; You give them sharp tools and the ability to compose, and they build things you never imagined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 3: Text Is the Universal Interface — Markdown All the Way Down
&lt;/h3&gt;

&lt;p&gt;OpenClaw skills are Markdown. The agent's configuration is text files in a workspace directory. Communication happens through natural language over messaging platforms. Memory is stored as structured text.&lt;/p&gt;

&lt;p&gt;There's no proprietary format. No binary blobs. No "export your workflow as a JSON file that only our platform can read." If you can read a text file, you can understand, modify, duplicate, and share any part of an OpenClaw setup.&lt;/p&gt;

&lt;p&gt;This is profoundly important for a reason that goes beyond convenience. Text as interface means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version control works.&lt;/strong&gt; Put your skills in a Git repo. Track changes. Roll back mistakes. Branch and experiment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharing works.&lt;/strong&gt; Send someone a &lt;code&gt;SKILL.md&lt;/code&gt; file. They drop it in their workspace. Done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging works.&lt;/strong&gt; When something goes wrong, you read the skill instructions. They're in English. There's no stack trace to decode, no minified JavaScript to untangle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Unix insight was that text streams were the lowest common denominator that everything could agree on. OpenClaw's insight is that natural language is the new text stream — the interface that both humans and AI models can read, write, and reason about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 4: Build Tools, Not Applications
&lt;/h3&gt;

&lt;p&gt;This is the big one. This is where OpenClaw diverges from every other "personal AI" product on the market.&lt;/p&gt;

&lt;p&gt;Siri is an application. Alexa is an application. Google Assistant is an application. They're monolithic systems built by large teams, with fixed capabilities, governed by product roadmaps decided in boardrooms you'll never enter. You use them. You don't build with them.&lt;/p&gt;

&lt;p&gt;OpenClaw is a &lt;em&gt;toolkit.&lt;/em&gt; It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A runtime that can execute skills&lt;/li&gt;
&lt;li&gt;A messaging bridge to reach you wherever you are&lt;/li&gt;
&lt;li&gt;A memory system to maintain context&lt;/li&gt;
&lt;li&gt;A scheduler to run things without you&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you build on top is entirely up to you. There's no "approved skill store." There's no review process. There's no waiting for a product team to decide that your use case matters.&lt;/p&gt;

&lt;p&gt;If you've ever felt the difference between using a Mac app and piping commands together in a terminal — that controlled, curated experience versus the raw, limitless power of composition — you already understand the difference between conventional AI assistants and OpenClaw.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means in Practice
&lt;/h2&gt;

&lt;p&gt;Let me move from philosophy to something concrete. Here's a real workflow I built with three skills, and it illustrates why the composable approach actually matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; I wanted my agent to monitor a GitHub repository for new issues, triage them based on labels and content, draft an initial response, and alert me via Telegram only if the issue looks like it needs my personal attention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With a monolithic AI assistant,&lt;/strong&gt; this is either impossible or requires some elaborate Zapier/n8n chain with brittle webhooks and API tokens scattered across three different platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With OpenClaw,&lt;/strong&gt; it's three skills:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill 1: &lt;code&gt;github_watcher&lt;/code&gt;&lt;/strong&gt; — Polls a repo for new issues on a cron schedule, stores raw issue data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill 2: &lt;code&gt;issue_triage&lt;/code&gt;&lt;/strong&gt; — Reads new issues, classifies them (bug/feature/question/spam), estimates complexity, and decides if they need human attention based on configurable rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill 3: &lt;code&gt;smart_notify&lt;/code&gt;&lt;/strong&gt; — Takes triage results and sends me a Telegram message only for issues flagged as needing my input. Includes a summary, not the raw issue dump.&lt;/p&gt;

&lt;p&gt;Each skill is a single &lt;code&gt;SKILL.md&lt;/code&gt; file. Each one does one thing. They compose through the agent's natural ability to chain operations. And here's the kicker — I can reuse &lt;code&gt;smart_notify&lt;/code&gt; for completely different workflows. It doesn't know or care that it's being fed GitHub issue data. It just knows how to decide whether something is worth interrupting me about.&lt;/p&gt;

&lt;p&gt;Try doing that with Siri.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Honest Risks
&lt;/h2&gt;

&lt;p&gt;I'd be dishonest if I wrote a love letter without mentioning the risks, and you deserve the full picture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenClaw with shell access is a loaded weapon.&lt;/strong&gt; The same power that lets it manage your files, run scripts, and automate workflows also means a poorly written skill, a hallucinating model, or a prompt injection attack could do real damage. There are documented cases of agents deleting files they shouldn't have touched, sending messages that were never intended, and racking up API bills through runaway loops.&lt;/p&gt;

&lt;p&gt;This is not hypothetical. This is real. And if you're going to use OpenClaw seriously, you need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run it on an isolated machine.&lt;/strong&gt; A Raspberry Pi, an old laptop, a cheap VPS. Never your primary workstation with your personal files and credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit third-party skills before installing them.&lt;/strong&gt; Read the &lt;code&gt;SKILL.md&lt;/code&gt;. Understand what shell commands it might execute. If you wouldn't run a random bash script from the internet, don't install a random OpenClaw skill either.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start with read-only skills.&lt;/strong&gt; Build things that fetch and summarize before you build things that create and delete.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Unix parallel holds here too, by the way. &lt;code&gt;rm -rf /&lt;/code&gt; has existed since the 1970s. Power and danger are inseparable. The answer was never to remove the power — it was to teach people to use it wisely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Goes Next
&lt;/h2&gt;

&lt;p&gt;If OpenClaw's trajectory follows the Unix playbook, here's what I think happens:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Short-term:&lt;/strong&gt; The skills ecosystem explodes. We're already seeing community-built skills on ClawHub, but we're in the "early package manager" era — think npm circa 2012. Quality is inconsistent, discoverability is poor, but the velocity is real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Medium-term:&lt;/strong&gt; Conventions emerge. Right now every skill author structures their &lt;code&gt;SKILL.md&lt;/code&gt; slightly differently. We'll see community standards solidify around things like: how to declare dependencies between skills, how to specify input/output formats, how to handle errors gracefully. This is the &lt;code&gt;.bashrc&lt;/code&gt; and &lt;code&gt;Makefile&lt;/code&gt; era.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long-term:&lt;/strong&gt; Composition protocols. When your OpenClaw agent can delegate tasks to my OpenClaw agent through a standard protocol — something like the Agent2Agent (A2A) protocol that Google just pushed to production — we'll have something genuinely new. Not just personal AI, but a &lt;em&gt;network&lt;/em&gt; of personal AI agents, each specialized, each autonomous, composing together to handle tasks that no single agent could manage alone.&lt;/p&gt;

&lt;p&gt;We're at the beginning of that curve. And if history is any guide, the people who learn to think in composable, tool-oriented ways today will have a massive advantage when the ecosystem matures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started: The Three-Skill Rule
&lt;/h2&gt;

&lt;p&gt;If you're new to OpenClaw and want to start building, here's my recommendation: &lt;strong&gt;build three skills before you build anything ambitious.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill 1: A fetcher.&lt;/strong&gt; Something that pulls information from an external source — weather, calendar, RSS feed, API endpoint. This teaches you how skills interact with the outside world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill 2: A processor.&lt;/strong&gt; Something that takes data and transforms it — summarize, classify, filter, reformat. This teaches you how skills reason about information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill 3: A notifier.&lt;/strong&gt; Something that delivers a result to you — Telegram message, email draft, file write. This teaches you how skills close the loop.&lt;/p&gt;

&lt;p&gt;Once you have these three, you've built a pipeline. And once you've built one pipeline, you understand the mental model. Everything after that is just variation and refinement.&lt;/p&gt;

&lt;p&gt;The installation is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://openclaw.ai/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The onboarding wizard handles model configuration and messaging channel setup. And from there, every skill you build is just a Markdown file in your workspace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.openclaw/workspace/skills/my-first-skill
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop a &lt;code&gt;SKILL.md&lt;/code&gt; in there, restart the gateway, and you're live. The entire feedback loop from idea to running skill can be under five minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;There's a quote from Doug McIlroy, the inventor of Unix pipes, that I think about a lot:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OpenClaw didn't invent this philosophy. It inherited it. And by applying these decades-old principles to the newest frontier in computing — autonomous AI agents — it's produced something that feels genuinely different from everything else in the market.&lt;/p&gt;

&lt;p&gt;Not because it's the most powerful AI system. Not because it uses the best model. But because it gives you tools instead of an application, composition instead of configuration, and ownership instead of subscription.&lt;/p&gt;

&lt;p&gt;The last time software was built this way, we got Linux, the internet, and everything that runs on top of them.&lt;/p&gt;

&lt;p&gt;I'm not saying OpenClaw is the next Linux. That would be absurd.&lt;/p&gt;

&lt;p&gt;But I am saying it's built on the same ideas. And those ideas have a pretty good track record.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you've built something with OpenClaw or have thoughts on the composability angle, I'd genuinely love to hear about it. Drop a comment or find me on the DEV community — let's compare notes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Forget the Flashy Keynote — The A2A Protocol Is the Real Revolution From Google Cloud Next '26</title>
      <dc:creator>Nilam Bora</dc:creator>
      <pubDate>Thu, 23 Apr 2026 14:11:40 +0000</pubDate>
      <link>https://dev.to/nilambuilds/forget-the-flashy-keynote-the-a2a-protocol-is-the-real-revolution-from-google-cloud-next-26-1c5l</link>
      <guid>https://dev.to/nilambuilds/forget-the-flashy-keynote-the-a2a-protocol-is-the-real-revolution-from-google-cloud-next-26-1c5l</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-cloud-next-2026-04-22"&gt;Google Cloud NEXT Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Everyone's Talking About the Wrong Thing
&lt;/h2&gt;

&lt;p&gt;Google Cloud Next '26 dropped like a thunderstorm. The internet exploded over the Apple partnership, the slick Gemini Enterprise Agent Platform demos, and 8th-Gen TPUs. And look — those are legitimately exciting. But after watching the keynotes, reading the docs, and spending a few hours actually digging into what shipped, I'm convinced the announcement that will reshape how we build software didn't even make the front page of Hacker News:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Agent2Agent (A2A) Protocol is now in production at 150+ organizations, it's at v1.2, and it's officially governed by the Linux Foundation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're a developer who builds anything that talks to other services — and let's be honest, that's all of us — this is the announcement you should be losing sleep over.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Quick Primer: What Is A2A, and Why Should You Care?
&lt;/h2&gt;

&lt;p&gt;Think about how services communicate today. We write REST endpoints. We wrangle GraphQL schemas. We negotiate API contracts across teams, build custom SDKs, and maintain brittle integration layers that eat 20-40% of our development cycles. Now scale that problem to AI agents.&lt;/p&gt;

&lt;p&gt;In an agentic world, you don't just have &lt;em&gt;your&lt;/em&gt; service calling &lt;em&gt;their&lt;/em&gt; API. You have autonomous systems — agents — that need to discover each other, negotiate capabilities, delegate tasks, and report results, &lt;em&gt;all without a human choreographing every step&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That's the problem A2A solves. And here's how it works, in plain English:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Agent Cards: The Business Card for Software
&lt;/h3&gt;

&lt;p&gt;Every A2A-compliant agent publishes a discoverable "Agent Card" at a well-known URL (&lt;code&gt;/.well-known/agent-card.json&lt;/code&gt;). This card describes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Who the agent is&lt;/strong&gt; — name, description, version&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What it can do&lt;/strong&gt; — its capabilities and skills&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How to talk to it&lt;/strong&gt; — endpoints, auth requirements, supported protocols&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as a combination of OpenAPI spec and DNS record, but purpose-built for autonomous AI systems. Any agent on the network can discover and evaluate another agent's capabilities without a human ever writing an integration doc.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Communication Over Familiar Rails
&lt;/h3&gt;

&lt;p&gt;A2A doesn't reinvent the wheel. It uses &lt;strong&gt;HTTP/HTTPS&lt;/strong&gt;, &lt;strong&gt;JSON-RPC 2.0&lt;/strong&gt;, and &lt;strong&gt;Server-Sent Events (SSE)&lt;/strong&gt; for streaming. If you've written a webhook handler this decade, you already know 80% of the transport layer.&lt;/p&gt;

&lt;p&gt;This is a deliberate and brilliant design choice. By building on existing web infrastructure, A2A inherits decades of tooling: load balancers, API gateways, observability stacks, WAFs — all of it works out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Task Lifecycle Management for Long-Running Work
&lt;/h3&gt;

&lt;p&gt;Here's where A2A separates itself from anything that came before. It includes a structured task lifecycle with explicit states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pending&lt;/code&gt; → task received, queued for execution&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;in-progress&lt;/code&gt; → agent is actively working&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;completed&lt;/code&gt; → results ready&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;failed&lt;/code&gt; → something broke, and here's why&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't just status tracking. It's a &lt;em&gt;contract&lt;/em&gt; that enables agents to manage complex, multi-step workflows across organizational boundaries. A client agent can kick off a task, go handle other work, and poll or stream for results — exactly like a well-designed async job system, but standardized across the entire ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Security That Enterprises Actually Need
&lt;/h3&gt;

&lt;p&gt;The v1.2 update (which dropped alongside Cloud Next) added &lt;strong&gt;cryptographically signed agent cards&lt;/strong&gt; for domain verification, alongside &lt;strong&gt;OAuth 2.0&lt;/strong&gt; and &lt;strong&gt;mTLS&lt;/strong&gt; support. This isn't a research protocol being bolted onto production systems. It was built for production from day one.&lt;/p&gt;

&lt;p&gt;Combined with Google Cloud's &lt;strong&gt;Model Armor&lt;/strong&gt; for inline traffic sanitization, you get a security story that doesn't require security teams to reinvent the wheel for every agent deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters More Than the Gemini Enterprise Agent Platform
&lt;/h2&gt;

&lt;p&gt;Don't get me wrong — the Gemini Enterprise Agent Platform (the thing that used to be Vertex AI) is impressive. The Agent Designer's no-code canvas, the Inbox for managing long-running agent workflows, the Agent Registry — all genuinely useful tools.&lt;/p&gt;

&lt;p&gt;But here's my hot take: &lt;strong&gt;platforms are proprietary; protocols are permanent.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Gemini Enterprise Agent Platform is a Google product. It's excellent, and if you're in the Google Cloud ecosystem, you should absolutely use it. But the A2A protocol is an &lt;em&gt;open standard&lt;/em&gt; under the Linux Foundation. It's already integrated into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google's Agent Development Kit (ADK)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LangGraph&lt;/strong&gt; (LangChain)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LlamaIndex Agents&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Semantic Kernel&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AutoGen&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the rare case where a major cloud vendor released something that helps &lt;em&gt;everyone&lt;/em&gt;, including developers on competing platforms. That's not altruism — it's a bet that standardization grows the pie faster than lock-in. And historically, that bet tends to be right (see: HTTP, TCP/IP, OAuth, OpenTelemetry).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Developer Impact: What Changes Right Now
&lt;/h2&gt;

&lt;p&gt;Let me paint a practical picture. Say you're building a customer support system. Today, your architecture probably looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → Your App → Custom LLM Integration → Custom CRM API Wrapper 
                                          → Custom Billing API Wrapper
                                          → Custom Knowledge Base Search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every integration is bespoke. Every connection is a maintenance liability. Every new data source requires a new adapter, new auth handling, new error recovery logic.&lt;/p&gt;

&lt;p&gt;With A2A in the mix, it looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → Your Orchestrator Agent 
        → discovers CRM Agent (via Agent Card)
        → discovers Billing Agent (via Agent Card)  
        → discovers Knowledge Agent (via Agent Card)
        → delegates tasks via standard A2A protocol
        → monitors lifecycle states
        → composes results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The orchestrator doesn't need to know &lt;em&gt;how&lt;/em&gt; the CRM agent works internally. It just needs to read the Agent Card, understand the capabilities, and communicate via the standard protocol. When Salesforce ships their own A2A-compliant agent tomorrow, your system picks it up without a single line of new integration code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's the revolution.&lt;/strong&gt; Not any single agent being smarter, but all agents being able to work together without us hand-wiring every connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  A2A vs. MCP: Complementary, Not Competing
&lt;/h2&gt;

&lt;p&gt;I've seen some confusion about how A2A relates to the Model Context Protocol (MCP), so let me clarify:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MCP&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;A2A&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Connect agents to &lt;em&gt;tools and data&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;Connect agents to &lt;em&gt;other agents&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Relationship&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent ↔ Resource&lt;/td&gt;
&lt;td&gt;Agent ↔ Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Analogy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;USB port for peripherals&lt;/td&gt;
&lt;td&gt;TCP/IP for networked systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Query my database"&lt;/td&gt;
&lt;td&gt;"Hey CRM Agent, look up this customer"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They're complementary layers. MCP gives your agent hands and eyes. A2A gives it colleagues. The Agentic Data Cloud and Knowledge Catalog (also announced at Next '26) sit at the MCP layer — providing the context and grounding agents need. A2A sits above, orchestrating the collaboration between specialized agents.&lt;/p&gt;

&lt;p&gt;If you're building anything non-trivial in the agentic space, you'll need both.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Think Is Still Missing
&lt;/h2&gt;

&lt;p&gt;No protocol is perfect at v1.2, and A2A has some gaps I'd love to see addressed:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Discovery at Scale
&lt;/h3&gt;

&lt;p&gt;Agent Cards at well-known URLs work great when you know where to look. But what about discovering agents you don't know exist? There's no standardized registry or marketplace protocol yet. Google's Agent Registry helps within the GCP ecosystem, but the open protocol needs a decentralized discovery mechanism — something like DNS for agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Economic Primitives
&lt;/h3&gt;

&lt;p&gt;When Agent A delegates a task to Agent B, who pays? A2A has no built-in concept of metering, billing, or cost negotiation. As we move toward agent marketplaces (Google mentioned one in Project Mariner's Q4 2026 roadmap), this will become critical.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Semantic Versioning for Capabilities
&lt;/h3&gt;

&lt;p&gt;Agent Cards describe capabilities, but there's no standard for versioning those capabilities. When an agent updates its skills, how do clients know what changed? We need something like semver for agent capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Debugging Multi-Agent Workflows
&lt;/h3&gt;

&lt;p&gt;Tracing a single agent is hard enough. Tracing a conversation across 5 agents from 3 different vendors? The observability story needs work. OpenTelemetry integration for A2A traces would be a game-changer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture: Google's Bet on the Agentic Enterprise
&lt;/h2&gt;

&lt;p&gt;Zoom out, and the entire Cloud Next '26 narrative clicks into place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemini Enterprise Agent Platform&lt;/strong&gt; = the &lt;em&gt;factory&lt;/em&gt; where you build agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Designer&lt;/strong&gt; = the &lt;em&gt;blueprinting tool&lt;/em&gt; for non-engineers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Catalog + Agentic Data Cloud&lt;/strong&gt; = the &lt;em&gt;fuel&lt;/em&gt; (trusted context from enterprise data)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model Armor + Agentic Defense&lt;/strong&gt; = the &lt;em&gt;guardrails&lt;/em&gt; (security and governance)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A Protocol&lt;/strong&gt; = the &lt;em&gt;roads&lt;/em&gt; connecting everything together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8th-Gen TPUs + Virgo Network&lt;/strong&gt; = the &lt;em&gt;power grid&lt;/em&gt; underneath it all&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Apple partnership? It's validation that Google's AI infrastructure is best-in-class — Apple choosing Google Cloud to build its next-gen foundation models is a vote of confidence in the Virgo fabric and TPU architecture. But for us as developers, it doesn't change what we build or how we build it.&lt;/p&gt;

&lt;p&gt;A2A does. It changes the &lt;em&gt;architecture of collaboration&lt;/em&gt; between intelligent systems. And that's a shift that will compound for years.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Should Do This Week
&lt;/h2&gt;

&lt;p&gt;If any of this resonated, here's my practical advice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Read the A2A spec.&lt;/strong&gt; It's well-written and surprisingly short. Start at &lt;a href="https://google.github.io/A2A/" rel="noopener noreferrer"&gt;google.github.io/A2A&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build a toy Agent Card.&lt;/strong&gt; Publish a &lt;code&gt;/.well-known/agent-card.json&lt;/code&gt; for one of your existing services. Even if you don't build the full A2A server, the exercise of describing your service's capabilities in a machine-readable format is incredibly clarifying.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Try the ADK.&lt;/strong&gt; Google's Agent Development Kit has native A2A support out of the box. Spin up two agents and watch them talk. There's something magical about seeing autonomous systems discover and delegate to each other.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Think about your integration tax.&lt;/strong&gt; Look at your current codebase. How much code exists purely to connect System A to System B? That's the code A2A is designed to eliminate. Start identifying the integration seams where a standardized protocol could replace bespoke glue code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Watch the Developer Keynote replay.&lt;/strong&gt; The showcase of Agent Designer building a multi-agent workflow in natural language is legitimately impressive, and it demonstrates the full A2A lifecycle in action.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Every major platform shift has been catalyzed by a protocol, not a product. The web wasn't built on Netscape — it was built on HTTP. Mobile wasn't defined by the iPhone — it was enabled by LTE. Cloud computing wasn't created by AWS — it was powered by APIs and OAuth.&lt;/p&gt;

&lt;p&gt;The agentic era will be no different. And A2A is the protocol that makes it possible.&lt;/p&gt;

&lt;p&gt;Google Cloud Next '26 was packed with flashy demos and blockbuster partnerships. But the most important thing they shipped was a boring, beautiful, open protocol that lets AI agents work together without asking permission from any single vendor.&lt;/p&gt;

&lt;p&gt;That's the one worth your attention. That's the one worth building on.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your take? Is A2A the game-changer I think it is, or am I overreacting? Have you tried building with the protocol yet? I'd love to hear about your experience in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>cloudnextchallenge</category>
      <category>googlecloud</category>
      <category>ai</category>
    </item>
    <item>
      <title>I built a niche API for Indian developers because no one else did — here's the whole story</title>
      <dc:creator>Nilam Bora</dc:creator>
      <pubDate>Thu, 23 Apr 2026 07:43:58 +0000</pubDate>
      <link>https://dev.to/nilambuilds/i-built-a-niche-api-for-indian-developers-because-no-one-else-did-heres-the-whole-story-33d8</link>
      <guid>https://dev.to/nilambuilds/i-built-a-niche-api-for-indian-developers-because-no-one-else-did-heres-the-whole-story-33d8</guid>
      <description>&lt;p&gt;I've been building in public for a while now, and this is the project I'm most excited to share.&lt;br&gt;
The problem&lt;br&gt;
If you've ever worked on Indian invoicing, cheque printing, or accounting software, you've run into this: you need to print a number in words. Not just "one hundred fifty thousand" — but "Rupees One Lakh Fifty Thousand Only."&lt;br&gt;
The Indian number system uses Lakhs and Crores, not Millions and Billions. Every Indian fintech app, every GST invoice generator, every cheque printing system needs this.&lt;br&gt;
I searched RapidAPI. Nothing. Stack Overflow is full of half-working snippets. PyPI has abandoned packages. So I decided to fix that.&lt;br&gt;
What I built&lt;br&gt;
RupeesInWords is a REST API that converts any number to Indian Rupees in words.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/v1/convert?number=150000
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;150000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"words"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rupees One Lakh Fifty Thousand Only"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"indian_formatted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1,50,000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency_symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rupees"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Features:&lt;/p&gt;

&lt;p&gt;Full Lakh/Crore/Paise support&lt;br&gt;
Batch conversion (up to 50 numbers per request)&lt;br&gt;
Indian comma formatting (1,50,000)&lt;br&gt;
Multiple currency symbols (₹, Rs., INR, Rupees)&lt;br&gt;
Clean error handling for edge cases&lt;/p&gt;

&lt;p&gt;The open-core model&lt;br&gt;
The core converter logic is open-source on GitHub:&lt;br&gt;
👉 &lt;a href="https://github.com/NEXUS-Lord/rupees-in-words" rel="noopener noreferrer"&gt;https://github.com/NEXUS-Lord/rupees-in-words&lt;/a&gt;&lt;br&gt;
Pure Python. Zero dependencies. MIT license. If you want to self-host or use it as a library, it's right there.&lt;br&gt;
The hosted API — with API keys, rate limiting, batch endpoints, and uptime — is on RapidAPI:&lt;br&gt;
👉 &lt;a href="https://rapidapi.com/NEXUSLord/api/rupeesinwords-indian-number-to-words" rel="noopener noreferrer"&gt;https://rapidapi.com/NEXUSLord/api/rupeesinwords-indian-number-to-words&lt;/a&gt;&lt;br&gt;
Free tier available: 100 requests/month, no credit card required.&lt;br&gt;
This is a classic open-core model. The library is free. The service is monetized. The open-source version builds trust and GitHub stars — the hosted API generates revenue.&lt;/p&gt;

&lt;p&gt;The tech stack&lt;/p&gt;

&lt;p&gt;Python + FastAPI — automatic Swagger UI at /docs out of the box&lt;br&gt;
Render.com — deploys directly from GitHub, free tier to start&lt;br&gt;
RapidAPI — marketplace and billing layer&lt;/p&gt;

&lt;p&gt;The entire infrastructure setup took less than an hour. FastAPI's auto-generated docs alone saved me hours of documentation work.&lt;br&gt;
What I learned&lt;br&gt;
The hardest part wasn't building the API — it was validating the idea first. Before writing a single line of code, I searched RapidAPI, GitHub, and PyPI to confirm nothing like this existed for Indian developers. That 20 minutes of research saved me from building something nobody needed.&lt;br&gt;
The Indian developer market is massively underserved by API tooling. Western developers have thousands of niche APIs available. Indian developers are still copy-pasting Stack Overflow snippets for basic financial formatting. That gap is the opportunity.&lt;br&gt;
What's next&lt;br&gt;
I'm targeting 5,000 GitHub stars by July 2026 and building this as a proof-of-concept for the full pipeline:&lt;br&gt;
Identify a niche problem → build a clean solution → open-source the core → monetize the hosted version.&lt;br&gt;
If you're building Indian fintech tools, invoicing software, or anything that needs Indian number formatting — try the free tier and tell me what I'm missing. Edge cases, feature requests, weird number formats — I want to hear all of it.&lt;br&gt;
GitHub: &lt;a href="https://github.com/NEXUS-Lord/rupees-in-words" rel="noopener noreferrer"&gt;https://github.com/NEXUS-Lord/rupees-in-words&lt;/a&gt;&lt;br&gt;
Try it free — 100 requests/month, no credit card: &lt;a href="https://rapidapi.com/NEXUSLord/api/rupeesinwords-indian-number-to-words" rel="noopener noreferrer"&gt;https://rapidapi.com/NEXUSLord/api/rupeesinwords-indian-number-to-words&lt;/a&gt;&lt;br&gt;
Building in public. One niche API at a time.&lt;/p&gt;

</description>
      <category>api</category>
      <category>python</category>
      <category>webdev</category>
      <category>fintech</category>
    </item>
  </channel>
</rss>
