<?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: Roland Farkas</title>
    <description>The latest articles on DEV Community by Roland Farkas (@rolandfarkas).</description>
    <link>https://dev.to/rolandfarkas</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%2F789498%2F0a80ad18-d0b6-4234-8caa-47a4fa7241b6.png</url>
      <title>DEV Community: Roland Farkas</title>
      <link>https://dev.to/rolandfarkas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rolandfarkas"/>
    <language>en</language>
    <item>
      <title>ACP vs AP2: the two AI-checkout protocols, and what your store actually has to build</title>
      <dc:creator>Roland Farkas</dc:creator>
      <pubDate>Tue, 21 Jul 2026 21:14:58 +0000</pubDate>
      <link>https://dev.to/rolandfarkas/acp-vs-ap2-the-two-ai-checkout-protocols-and-what-your-store-actually-has-to-build-55d3</link>
      <guid>https://dev.to/rolandfarkas/acp-vs-ap2-the-two-ai-checkout-protocols-and-what-your-store-actually-has-to-build-55d3</guid>
      <description>&lt;p&gt;A few weeks ago I wrote about describing your site once so any AI can use it. Since then the thing I was hand-waving at ("agents will check out for users") stopped being hypothetical. OpenAI shipped ACP and Google shipped AP2, and they solve the same problem in almost opposite ways.&lt;/p&gt;

&lt;p&gt;I implemented the merchant side of both. Here are the field notes, because the differences aren't obvious until you're in them.&lt;/p&gt;

&lt;p&gt;The 30-second version&lt;br&gt;
ACP (Agentic Commerce Protocol, OpenAI + Stripe) is session-based. The agent drives a live checkout session on your server, like a headless cart. It powers ChatGPT's Instant Checkout.&lt;br&gt;
AP2 (Agent Payments Protocol, Google) is mandate-based. Your store signs a "here is the cart and the price" object; the buyer's agent signs a "I authorize this" object. It leans on verifiable credentials and now the FIDO Alliance.&lt;br&gt;
Same goal. Completely different shape.&lt;/p&gt;

&lt;p&gt;ACP: a checkout session you don't own the UI for&lt;br&gt;
ACP is five REST endpoints and a state machine. The agent creates a session, updates it (address, shipping, coupon), and completes it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /checkout_sessions create from line items
POST /checkout_sessions/:id update (address, shipping, discounts) 
POST /checkout_sessions/:id/complete   pay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you return is a CheckoutSession: line items, live shipping options, and totals broken out (subtotal, discount, fulfillment, tax, total). Money is integer minor units (330 = $3.30). Payment completes when the agent hands you a Shared Payment Token and you charge it through Stripe. The card never touches the agent.&lt;/p&gt;

&lt;p&gt;The mental model: it's your existing checkout, minus the browser.&lt;/p&gt;

&lt;p&gt;AP2: sign the cart, don't run the session&lt;br&gt;
AP2 has no session. The agent sends you an Intent Mandate ("a red basketball shoe, under $120"). You price it and return a Cart Mandate you have cryptographically signed:&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;"contents"&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="err"&gt;/*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;W&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;C&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PaymentRequest:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;currency&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&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;"merchant_authorization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;RS256 JWT&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;iss&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;aud&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;jti&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cart_hash&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;That JWT is a short-lived guarantee of the price. Amounts here are decimal major units (19.99), not cents. The buyer's credentials provider then returns a Payment Mandate signed on the user's side, and settlement runs through the payment network. Your job is to sign honestly and verify the binding.&lt;/p&gt;

&lt;p&gt;The part nobody warns you about&lt;br&gt;
If you support both, you're maintaining two different worlds: a stateful session vs a stateless signed document, minor units vs major units, you-charge vs network-settles.&lt;/p&gt;

&lt;p&gt;And a subtle one that ate a day: the AP2 cart_hash has to be byte-identical across whoever computes it, or verification fails. JSON.stringify won't cut it (key order, number formatting, Go sorting map keys...). You need canonical JSON (RFC 8785 / JCS): sorted keys, no whitespace, integers without a decimal point. I only trusted it once every SDK produced the same golden string for the same object.&lt;/p&gt;

&lt;p&gt;Why I didn't just pick one&lt;br&gt;
I don't think merchants should have to. The catalog, the prices, the stock, the "is this allowed" rules are the same regardless of which protocol an agent speaks. So in AI2Web I built both on top of one manifest: describe the store once, and it serves an ACP session or signs an AP2 cart from the same source of truth. Same safety model too: server-authoritative pricing, no card data through the agent, and anything that moves money previews for approval.&lt;/p&gt;

&lt;p&gt;That's the bet from the last post, now with real protocols under it instead of hand-waving.&lt;/p&gt;

&lt;p&gt;What I want to know&lt;br&gt;
Genuinely unsure here, and this is the useful question:&lt;/p&gt;

&lt;p&gt;If you only support one, which and why? Is ChatGPT distribution (ACP) worth more than being on Google's rails (AP2), or vice versa?&lt;br&gt;
Does a layer that gives you both earn its keep, or is two direct integrations honestly fine?&lt;br&gt;
For the crypto folks: is per-merchant Cart Mandate signing the right trust boundary, or is it security theater until the user side is verified by the network?&lt;br&gt;
It's early and open source (code MIT, spec CC-BY).&lt;/p&gt;

&lt;p&gt;Validator you can point at any site: &lt;br&gt;
&lt;a href="https://ai2web.dev" rel="noopener noreferrer"&gt;https://ai2web.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code and spec: &lt;br&gt;
&lt;a href="https://github.com/ai2web-foundation" rel="noopener noreferrer"&gt;https://github.com/ai2web-foundation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two protocols, one catalog. Tell me where that breaks.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>ecommerce</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Check any website's AI readiness from your toolbar</title>
      <dc:creator>Roland Farkas</dc:creator>
      <pubDate>Tue, 14 Jul 2026 23:09:55 +0000</pubDate>
      <link>https://dev.to/rolandfarkas/check-any-websites-ai-readiness-from-your-toolbar-3p9j</link>
      <guid>https://dev.to/rolandfarkas/check-any-websites-ai-readiness-from-your-toolbar-3p9j</guid>
      <description>&lt;p&gt;Shipped a small Chrome extension: click the icon on any site and get its AI Readiness Score out of 100, its tier, and what an AI agent can and cannot do on it. Free, private, one click. Part of the open AI2Web project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/ai2web-ai-readiness-check/dgfgbjlpmhahoafdcfandobbncfjhlle" rel="noopener noreferrer"&gt;https://chromewebstore.google.com/detail/ai2web-ai-readiness-check/dgfgbjlpmhahoafdcfandobbncfjhlle&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>Describe your website once, make it usable by any AI</title>
      <dc:creator>Roland Farkas</dc:creator>
      <pubDate>Sun, 12 Jul 2026 15:12:15 +0000</pubDate>
      <link>https://dev.to/rolandfarkas/describe-your-website-once-make-it-usable-by-any-ai-2n37</link>
      <guid>https://dev.to/rolandfarkas/describe-your-website-once-make-it-usable-by-any-ai-2n37</guid>
      <description>&lt;p&gt;If you have tried to make a website work with AI assistants recently, you have run into the fragmentation. Depending on the platform, you are looking at MCP, WebMCP, ACP, product feeds, OAuth flows, framework-specific tooling, and whatever ships next. Each solves a real slice of the problem. But a site ends up implementing and maintaining several of them separately, per assistant, and re-doing it every time a new protocol appears.&lt;/p&gt;

&lt;p&gt;The web was built for humans. Agents should not have to scrape HTML and guess at your forms. So I built AI2Web to test a different approach: describe your site's capabilities once, and expose them through whichever protocol an AI platform speaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape of it
&lt;/h2&gt;

&lt;p&gt;A site publishes a small, machine-readable manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET  /.well-known/ai2w   discovery anchor
GET  /ai2w               the capability manifest
POST /ai2w/negotiate     agree a capability set + transport
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From that one description, you generate MCP, GraphQL, ACP, OpenAPI and feeds. You do not rebuild for each assistant. When a new protocol wins, you add an adapter, not a rewrite.&lt;/p&gt;

&lt;p&gt;It is explicitly not a replacement for MCP or ACP. It sits above them as an interoperability layer. The bet is that the capability model is the durable part, and the transports are adapters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it in a minute
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# score any live site's AI readiness&lt;/span&gt;
npx &lt;span class="nt"&gt;-p&lt;/span&gt; @ai2web/validator ai2web validate https://ai2web.dev

&lt;span class="c"&gt;# or build a manifest in code&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @ai2web/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ai2web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validateManifest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@ai2web/core&lt;/span&gt;&lt;span class="dl"&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;manifest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ai2web&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;Acme&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://acme.example&lt;/span&gt;&lt;span class="dl"&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;ecommerce&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="nf"&gt;capability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&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="nf"&gt;capability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;commerce&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;checkout&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&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="nf"&gt;validateManifest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// AI Readiness Score /100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What exists today (it is early, v0.1)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An open spec, RFCs and a conformance suite&lt;/li&gt;
&lt;li&gt;SDKs you can install now: &lt;code&gt;@ai2web/core&lt;/code&gt; (and PHP, Python, Go and .NET)&lt;/li&gt;
&lt;li&gt;A framework-agnostic server (Node and Cloudflare Workers) and a WordPress/WooCommerce plugin&lt;/li&gt;
&lt;li&gt;Reference adapters that generate MCP, GraphQL, ACP and OpenAPI from one manifest, all routing through one guarded executor&lt;/li&gt;
&lt;li&gt;A live validator (CLI, web, and an MCP tool) and a live discovery service&lt;/li&gt;
&lt;li&gt;Safe by default: discovery is read-only, and anything that moves money or data is risk-tiered and returns a preview for user approval before it runs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I want to know
&lt;/h2&gt;

&lt;p&gt;I am not trying to win a standards race. I am trying to make the AI-ready web simple enough that developers actually want to build it. Whether that abstraction holds, or leaks so badly you would rather just implement MCP directly, is exactly the question I cannot answer alone.&lt;/p&gt;

&lt;p&gt;If you build websites, AI agents, or the tools in between, I would value your criticism:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you already ship MCP, does a capability layer above it earn its keep, or is it just another abstraction to maintain?&lt;/li&gt;
&lt;li&gt;What would actually stop you from adopting it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is open source (code MIT, spec CC-BY).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overview and a validator you can point at any site: &lt;a href="https://ai2web.dev" rel="noopener noreferrer"&gt;https://ai2web.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code and spec: &lt;a href="https://github.com/ai2web-foundation" rel="noopener noreferrer"&gt;https://github.com/ai2web-foundation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Describe once. Works everywhere. That is the whole idea.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
