<?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: Andriy Pyvovarchuk</title>
    <description>The latest articles on DEV Community by Andriy Pyvovarchuk (@andriy_pyvovarchuk).</description>
    <link>https://dev.to/andriy_pyvovarchuk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4047540%2F6ba0b6e9-d68c-4c26-8775-023575f37013.jpg</url>
      <title>DEV Community: Andriy Pyvovarchuk</title>
      <link>https://dev.to/andriy_pyvovarchuk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/andriy_pyvovarchuk"/>
    <language>en</language>
    <item>
      <title>7 llms.txt mistakes I see constantly (and the 30-second fix for each)</title>
      <dc:creator>Andriy Pyvovarchuk</dc:creator>
      <pubDate>Sun, 26 Jul 2026 06:57:50 +0000</pubDate>
      <link>https://dev.to/andriy_pyvovarchuk/7-llmstxt-mistakes-i-see-constantly-and-the-30-second-fix-for-each-10m1</link>
      <guid>https://dev.to/andriy_pyvovarchuk/7-llmstxt-mistakes-i-see-constantly-and-the-30-second-fix-for-each-10m1</guid>
      <description>&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is deceptively simple — it's just Markdown — so most people write one in five minutes and move on. The problem: a file can look perfectly valid and still be broken in ways that quietly waste an AI crawler's time or get it ignored. Here are the seven mistakes I run into most, and the quick fix for each.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. More than one H1
&lt;/h2&gt;

&lt;p&gt;The spec wants exactly &lt;strong&gt;one&lt;/strong&gt; top-level &lt;code&gt;# Title&lt;/code&gt;. Extra &lt;code&gt;#&lt;/code&gt; headings scramble the structure a model relies on. &lt;strong&gt;Fix:&lt;/strong&gt; keep a single &lt;code&gt;#&lt;/code&gt;, demote every other heading to &lt;code&gt;##&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. No blockquote summary
&lt;/h2&gt;

&lt;p&gt;The one- or two-sentence &lt;code&gt;&amp;gt;&lt;/code&gt; blockquote right under the title is the &lt;em&gt;first&lt;/em&gt; context a model reads. Skipping it is the single most common miss. &lt;strong&gt;Fix:&lt;/strong&gt; add one line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Acme&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Acme turns CSV files into charts. These links cover setup, the API, and pricing.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Sections with no links (or no sections at all)
&lt;/h2&gt;

&lt;p&gt;Empty &lt;code&gt;##&lt;/code&gt; sections add nothing; a wall of links with no structure is just as bad. &lt;strong&gt;Fix:&lt;/strong&gt; group your key pages under real headings (&lt;code&gt;## Docs&lt;/code&gt;, &lt;code&gt;## Guides&lt;/code&gt;) with a Markdown bullet list of links under each.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Broken links
&lt;/h2&gt;

&lt;p&gt;This is the big one. A file can be flawless Markdown and still point at 404s — which burns crawl budget and erodes trust. Most linters check &lt;em&gt;syntax&lt;/em&gt; and never actually fetch the URLs, so broken links sail straight through. &lt;strong&gt;Fix:&lt;/strong&gt; verify every link resolves. (This is the check I built my validator around — it fetches each one.)&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Relative or &lt;code&gt;http://&lt;/code&gt; links
&lt;/h2&gt;

&lt;p&gt;Models may not resolve relative paths like &lt;code&gt;/docs/start&lt;/code&gt;, and plain &lt;code&gt;http://&lt;/code&gt; links look untrustworthy and can break under HTTPS-only crawling. &lt;strong&gt;Fix:&lt;/strong&gt; use absolute &lt;code&gt;https://&lt;/code&gt; URLs everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The wrong content type
&lt;/h2&gt;

&lt;p&gt;Serve the file as &lt;code&gt;text/plain; charset=utf-8&lt;/code&gt;. A surprising number of servers return &lt;code&gt;text/html&lt;/code&gt; for it (a default misconfiguration), and some consumers then won't treat it as &lt;code&gt;llms.txt&lt;/code&gt; at all. &lt;strong&gt;Fix:&lt;/strong&gt; set the content type explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. A bloated, uncurated dump
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is a &lt;em&gt;curated index&lt;/em&gt;, not a sitemap. Hundreds of undescribed links bury the signal you're trying to send. &lt;strong&gt;Fix:&lt;/strong&gt; keep the best pages, add a short &lt;code&gt;: description&lt;/code&gt; after each, and push secondary links to an &lt;code&gt;## Optional&lt;/code&gt; section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Catch all seven at once
&lt;/h2&gt;

&lt;p&gt;You don't have to eyeball these by hand. Paste your domain into an &lt;a href="https://llms-txt-validator.dev/" rel="noopener noreferrer"&gt;llms.txt validator&lt;/a&gt; — it scores structure, fetches every linked URL, and tells you exactly which of the above to fix, in plain language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm7jsp7e52n6djifk8l1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm7jsp7e52n6djifk8l1s.png" alt="A 100/100 llms.txt report, scored by structure, links and best practices" width="800" height="688"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A clean report: 100/100 with every link fetched. Broken links drag the score down even when the Markdown is perfect — which is exactly the failure mode syntax-only checkers miss.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fix these seven and you're ahead of most &lt;code&gt;llms.txt&lt;/code&gt; files on the web today. The bar is genuinely low right now — which is the opportunity.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>llms.txt vs robots.txt vs sitemap.xml: what actually does what</title>
      <dc:creator>Andriy Pyvovarchuk</dc:creator>
      <pubDate>Sun, 26 Jul 2026 06:26:18 +0000</pubDate>
      <link>https://dev.to/andriy_pyvovarchuk/llmstxt-vs-robotstxt-vs-sitemapxml-what-actually-does-what-506m</link>
      <guid>https://dev.to/andriy_pyvovarchuk/llmstxt-vs-robotstxt-vs-sitemapxml-what-actually-does-what-506m</guid>
      <description>&lt;p&gt;If you run a website in 2026 you now have &lt;em&gt;three&lt;/em&gt; plain-text files that can live at your root and all look suspiciously similar: &lt;code&gt;robots.txt&lt;/code&gt;, &lt;code&gt;sitemap.xml&lt;/code&gt;, and the newcomer, &lt;code&gt;llms.txt&lt;/code&gt;. They get confused constantly — I've seen people add &lt;code&gt;llms.txt&lt;/code&gt; thinking it blocks AI crawlers (it doesn't) or skip it thinking &lt;code&gt;robots.txt&lt;/code&gt; already covers it (it doesn't). Here's the clean mental model.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;robots.txt&lt;/code&gt;&lt;/strong&gt; → controls crawler &lt;strong&gt;access&lt;/strong&gt;: which paths bots may or may not fetch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sitemap.xml&lt;/code&gt;&lt;/strong&gt; → lists &lt;strong&gt;every indexable page&lt;/strong&gt; so search engines miss nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/strong&gt; → curates a &lt;strong&gt;shortlist of high-signal pages&lt;/strong&gt; for AI models at answer time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Access, coverage, curation. Three different jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  robots.txt is about permission
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;robots.txt&lt;/code&gt; is an access-control convention: "Googlebot may crawl &lt;code&gt;/blog&lt;/code&gt; but not &lt;code&gt;/admin&lt;/code&gt;." It's a bouncer at the door. It doesn't describe your content, doesn't rank it, and isn't written for language models in particular. Blocking or allowing a path there says nothing about &lt;em&gt;what the page is&lt;/em&gt; — only whether a bot may request it.&lt;/p&gt;

&lt;p&gt;Crucially: &lt;strong&gt;&lt;code&gt;llms.txt&lt;/code&gt; is not an access-control file.&lt;/strong&gt; It can't stop an AI crawler from reading anything. If that's your goal, &lt;code&gt;robots.txt&lt;/code&gt; (and server-side rules) is still the tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  sitemap.xml is about coverage
&lt;/h2&gt;

&lt;p&gt;A sitemap tries to be &lt;em&gt;exhaustive&lt;/em&gt;: every URL you want indexed, so search engines don't overlook a page. It's machine-oriented XML for crawlers, not a human-readable summary, and it makes no attempt to say which pages matter most — they're all just listed.&lt;/p&gt;

&lt;h2&gt;
  
  
  llms.txt is about curation
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; is the opposite of exhaustive. It's a hand-picked, Markdown list of the &lt;em&gt;few&lt;/em&gt; pages that best help a model understand and use your site, each with a short description. It exists for &lt;strong&gt;inference&lt;/strong&gt; — the moment a user asks ChatGPT or Claude "how do I do X with your product" — not for training datasets and not for access control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Acme&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Acme turns CSV files into charts. These links cover setup, the API, and pricing.&lt;/span&gt;

&lt;span class="gu"&gt;## Docs&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Quickstart&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/quickstart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: first chart in 5 minutes
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;API reference&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: endpoints and auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where a sitemap says "here is everything," &lt;code&gt;llms.txt&lt;/code&gt; says "here is what's worth your limited context window."&lt;/p&gt;

&lt;h2&gt;
  
  
  You don't choose — you use all three
&lt;/h2&gt;

&lt;p&gt;This is the part people miss. A strong 2026 setup has all three, each doing its job:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Question it answers&lt;/th&gt;
&lt;th&gt;Audience&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;robots.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;May you fetch this?&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;all crawlers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sitemap.xml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;What should you index?&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;search engines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;llms.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;em&gt;What matters most here?&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;AI models&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;robots.txt&lt;/code&gt; governs access, &lt;code&gt;sitemap.xml&lt;/code&gt; ensures coverage, and &lt;code&gt;llms.txt&lt;/code&gt; curates signal for AI. They complement each other; none replaces another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting llms.txt right
&lt;/h2&gt;

&lt;p&gt;The catch with &lt;code&gt;llms.txt&lt;/code&gt; is that it's easy to write one that &lt;em&gt;looks&lt;/em&gt; valid but points at dead links or ships as the wrong content type — and unlike the other two, almost nobody checks it. After you write yours, run it through an &lt;a href="https://llms-txt-validator.dev/" rel="noopener noreferrer"&gt;llms.txt validator&lt;/a&gt; that fetches every linked URL and confirms it resolves, then fix whatever it flags. Aim for no broken links first; structure second.&lt;/p&gt;

&lt;p&gt;Three files, three jobs. Once that clicks, &lt;code&gt;llms.txt&lt;/code&gt; stops being mysterious — it's just the curation layer the web didn't have until AI needed one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I made my website callable by AI agents — the three layers (with the code I shipped)</title>
      <dc:creator>Andriy Pyvovarchuk</dc:creator>
      <pubDate>Sun, 26 Jul 2026 05:26:06 +0000</pubDate>
      <link>https://dev.to/andriy_pyvovarchuk/i-made-my-website-callable-by-ai-agents-the-three-layers-with-the-code-i-shipped-140i</link>
      <guid>https://dev.to/andriy_pyvovarchuk/i-made-my-website-callable-by-ai-agents-the-three-layers-with-the-code-i-shipped-140i</guid>
      <description>&lt;p&gt;"Make your site agent-ready" gets thrown around a lot, but it actually means three &lt;em&gt;different&lt;/em&gt; things to three &lt;em&gt;different&lt;/em&gt; kinds of AI agent — and they stack. I built a small tool (a free llms.txt validator) and wired up all three layers on it, so this is the copy-the-code version, not the hand-wavy one.&lt;/p&gt;

&lt;p&gt;But before the three layers, let's start at the bottom — because the whole stack rests on one small file most sites still don't have.&lt;/p&gt;

&lt;h2&gt;
  
  
  First: what is llms.txt, and why should you care?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;llms.txt is a plain-text file you put at &lt;code&gt;yoursite.com/llms.txt&lt;/code&gt; that tells AI models what your site is about and which pages actually matter.&lt;/strong&gt; That's it. It's written in Markdown, and it's read by AI assistants and crawlers — ChatGPT, Claude, Perplexity, and the growing crowd of AI agents — when they try to understand your site.&lt;/p&gt;

&lt;p&gt;Here's the problem it solves. When an AI tries to "read" your website today, it gets a mess: HTML wrappers, navigation menus, cookie banners, ads, JavaScript that may not even run. It has to guess what's important and burns a big chunk of its limited context window doing it. Often it guesses wrong, or gives up.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;llms.txt&lt;/code&gt; hands the AI a clean, curated map instead — &lt;em&gt;you&lt;/em&gt; decide what your site is and which pages are the good ones, in priority order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Example — Project Management for Teams&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Example is a project-management app. This file points AI assistants&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; at our most useful docs and product pages.&lt;/span&gt;

&lt;span class="gu"&gt;## Docs&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Quickstart&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/quickstart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: get set up in 5 minutes
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;API reference&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: every endpoint, with examples

&lt;span class="gu"&gt;## Product&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Pricing&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/pricing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: plans and limits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two useful mental models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's the AI counterpart to &lt;code&gt;sitemap.xml&lt;/code&gt;.&lt;/strong&gt; A sitemap helps &lt;em&gt;search engines&lt;/em&gt; find every page; &lt;code&gt;llms.txt&lt;/code&gt; helps &lt;em&gt;AI models&lt;/em&gt; understand the few pages that matter, in the format they read most cheaply.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's the flip side of &lt;code&gt;robots.txt&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;robots.txt&lt;/code&gt; says what crawlers may &lt;em&gt;not&lt;/em&gt; touch; &lt;code&gt;llms.txt&lt;/code&gt; says what your site &lt;em&gt;is&lt;/em&gt; and where the value is.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it matters now:&lt;/strong&gt; people increasingly get answers &lt;em&gt;about&lt;/em&gt; your product from an AI assistant instead of clicking to your site. If the AI can't cheaply and correctly understand you, it either skips you or describes you wrong. &lt;code&gt;llms.txt&lt;/code&gt; is your chance to feed it an accurate, curated summary — so you're represented the way you intend. It's a context layer, not a ranking trick: you're not gaming anything, you're just making your site legible to machines.&lt;/p&gt;

&lt;p&gt;(There's an optional companion, &lt;code&gt;llms-full.txt&lt;/code&gt;, that inlines the full text of those pages so an AI can ingest everything in one fetch. Start with &lt;code&gt;llms.txt&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;That's the foundation. Now the three layers that build on it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fro21hjax8277r813bk8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fro21hjax8277r813bk8m.png" alt="The llms.txt validator homepage — paste a domain, get a score in seconds" width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The tool this article is about: paste a domain, it fetches &lt;code&gt;/llms.txt&lt;/code&gt;, checks it against the spec, and tests every link.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here are the three independent layers. You can adopt any one on its own:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;llms.txt&lt;/strong&gt; — context for crawlers reading your site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebMCP&lt;/strong&gt; — tools for an agent driving your UI &lt;em&gt;inside the browser&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A&lt;/strong&gt; — a callable endpoint for another agent hitting you &lt;em&gt;over the network&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Crawler → browser agent → networked agent. Different agents, different mechanisms, zero overlap.&lt;/p&gt;


&lt;h2&gt;
  
  
  Layer 1 — llms.txt: context for crawlers
&lt;/h2&gt;

&lt;p&gt;The baseline, and the highest-value one for most sites. A plain-text &lt;code&gt;llms.txt&lt;/code&gt; at your root tells an AI crawler what your site is and which pages matter, in priority order. It's read at fetch time — no JavaScript, no protocol, no SDK. It's literally Markdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Example Docs&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Developer documentation for the Example API.&lt;/span&gt;

&lt;span class="gu"&gt;## Core&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Quickstart&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/quickstart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: 5-minute setup
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Authentication&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/auth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: API keys and OAuth

&lt;span class="gu"&gt;## Reference&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;API reference&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;: every endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rules that actually matter in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One &lt;code&gt;#&lt;/code&gt; H1 title, one &lt;code&gt;&amp;gt;&lt;/code&gt; blockquote summary.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;##&lt;/code&gt; sections with real Markdown links.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Absolute HTTPS URLs&lt;/strong&gt; — relative links are the single most common failure.&lt;/li&gt;
&lt;li&gt;Serve it as &lt;code&gt;text/plain&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the whole layer. If you do nothing else, do this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2 — WebMCP: tools for in-browser agents
&lt;/h2&gt;

&lt;p&gt;WebMCP lets a page expose callable &lt;strong&gt;tools&lt;/strong&gt; to an AI agent running inside the browser — so instead of the agent guessing at your form fields and clicking around, it invokes a typed action you defined. There are two ways to expose a tool, and I shipped both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Declarative&lt;/strong&gt; — annotate a real form and the browser synthesizes a tool from it. Zero JavaScript:&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;"open_llms_txt_report"&lt;/span&gt;
      &lt;span class="na"&gt;tooldescription=&lt;/span&gt;&lt;span class="s"&gt;"Validate a site's llms.txt and open its report."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"url"&lt;/span&gt; &lt;span class="na"&gt;toolparamdescription=&lt;/span&gt;&lt;span class="s"&gt;"Domain or URL to validate"&lt;/span&gt;&lt;span class="nt"&gt;&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;&lt;strong&gt;Imperative&lt;/strong&gt; — register a tool in JavaScript that returns structured data directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;validate_llms_txt&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="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Validate a website's llms.txt; returns a 0-100 score and findings.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/validate?url=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Guard the imperative call behind &lt;code&gt;if (navigator.modelContext)&lt;/code&gt; so it's a no-op where WebMCP isn't present. Reality check: it's a Chrome origin trial today, so actual reach is tiny. Treat it as a &lt;strong&gt;forward signal and a clean reference&lt;/strong&gt;, not a traffic source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3 — A2A: a callable agent for other agents
&lt;/h2&gt;

&lt;p&gt;The Agent2Agent (A2A) protocol — now under the Linux Foundation — lets other agents &lt;strong&gt;discover and call&lt;/strong&gt; your service over plain HTTP. No browser, no scraping. It's the agent-to-agent counterpart of a public API.&lt;/p&gt;

&lt;p&gt;Two parts: a discovery document (the &lt;strong&gt;agent card&lt;/strong&gt;) and a callable endpoint (the &lt;strong&gt;skill&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The agent card&lt;/strong&gt; — a JSON file at &lt;code&gt;/.well-known/agent-card.json&lt;/code&gt;:&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;"protocolVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.3.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"llms.txt Validator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Validate a website's llms.txt and return a score with findings."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://llms-txt-validator.dev/a2a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"skills"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validate_llms_txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Validate llms.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Given a domain or URL, fetch and validate its llms.txt."&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;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;&lt;strong&gt;The endpoint&lt;/strong&gt; — the card's &lt;code&gt;url&lt;/code&gt; points at a JSON-RPC 2.0 endpoint. An agent calls &lt;code&gt;message/send&lt;/code&gt;; you do the work and return a &lt;code&gt;Task&lt;/code&gt;. A real call:&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="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/a&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;a&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;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&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"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"message/send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parts"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"validate llmstxt.org"&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;span class="p"&gt;}&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;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;…and the reply — a completed task with a human-readable summary &lt;em&gt;and&lt;/em&gt; structured data:&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;"result"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"completed"&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;span class="nl"&gt;"artifacts"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"parts"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Validated llmstxt.org: score 100/100..."&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"ok"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"report"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"scores"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"overall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&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;span class="p"&gt;}&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;span class="p"&gt;}&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;span class="p"&gt;}]&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;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;The agent gets exactly the data it asked for. You don't need the whole protocol to start — pick one real capability, serve a card with one skill, implement the synchronous &lt;code&gt;message/send&lt;/code&gt;, return a completed &lt;code&gt;Task&lt;/code&gt;. Streaming, task history and push notifications are optional (&lt;code&gt;capabilities.streaming: false&lt;/code&gt;) until you need them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one rule: don't publish a signal you can't back
&lt;/h2&gt;

&lt;p&gt;It's tempting to drop an empty agent card or fake form annotations to make some audit go green. &lt;strong&gt;Don't.&lt;/strong&gt; An agent that fetches your card and calls a dead endpoint — or invokes a tool that does nothing — trusts you &lt;em&gt;less&lt;/em&gt; afterward. Every signal should resolve to something real. (This is why the validator I built reports a WebMCP or A2A signal as "present" only when a working implementation actually backs it.)&lt;/p&gt;

&lt;h2&gt;
  
  
  How to verify each layer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;llms.txt&lt;/strong&gt; — run your domain through an &lt;a href="https://llms-txt-validator.dev/" rel="noopener noreferrer"&gt;llms.txt validator&lt;/a&gt;; aim for 100/100 with no broken links.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm7jsp7e52n6djifk8l1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm7jsp7e52n6djifk8l1s.png" alt="A 100/100 llms.txt report broken down by Structure, Links and Best practices" width="800" height="688"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A clean report: 100/100, with Structure / Links / Best practices scored separately. The tool fetches every linked URL, so a broken link drags the score down even when the Markdown is perfect.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WebMCP&lt;/strong&gt; — in Chrome 149+, enable &lt;code&gt;chrome://flags/#enable-webmcp-testing&lt;/code&gt; and run Lighthouse's Agentic Browsing audit; your tools should be listed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A&lt;/strong&gt; — fetch your &lt;code&gt;/.well-known/agent-card.json&lt;/code&gt;, then POST a &lt;code&gt;message/send&lt;/code&gt; call to its &lt;code&gt;url&lt;/code&gt; and confirm you get a completed task back.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;That's the whole stack: llms.txt for crawlers, WebMCP for in-browser agents, A2A for networked ones. Start with llms.txt (real value today), add WebMCP and A2A as forward signals when you have a genuine action or service to expose.&lt;/p&gt;

&lt;p&gt;If you build one, I'd love to see it — drop your agent card in the comments.&lt;/p&gt;

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