Je klikt op een link, de pagina begint te laden, en er schuift een popup overheen voordat je één zin hebt gelezen. Tien procent korting, als je een e-mailadres afstaat aan een bedrijf waar je negen seconden geleden aankwam. Je sluit hem. Ergens daaronder wacht een tweede op het moment dat je richting de terugknop beweegt.
Die popup is geen ontwerpfout. Hij doet precies waarvoor hij is gebouwd, en hij werkt goed genoeg dat niemand op de marketingafdeling pleit voor verwijdering.
Een e-mailadres is de sleutel tot het retentieprogramma. Zodra een merk er een heeft, kan het de lifecycleflows draaien die achter elk e-commerceplatform zitten: de welkomstserie die op aanmelding afgaat, de browse-abandonmentmail die uitgaat wanneer iemand een product bekijkt en weer vertrekt, de reeks voor verlaten winkelwagens en checkouts, de herinneringen na aankoop en voor herbevoorrading, en de winbackmail voor iedereen die stil is gevallen. Geen daarvan kan starten zonder het adres. Ze worden allemaal door gedrag getriggerd en blijven verdienen lang nadat de advertentie die de bezoeker binnenbracht is betaald.
Dat is wat die tien procent koopt. De korting is de aanschafprijs van een permanente contactlijn, en die is goedkoop naast de betaalde klik die jou afleverde. Getriggerde flows verdienen veel meer per ontvanger dan een algemene nieuwsbrief, en de reeks voor verlaten winkelwagens verdient het meest van allemaal, dus een marketeer die de waarde van een adres uitrekent telt niet één e-mail. Hij telt een stroom die jarenlang doorloopt.
Het verklaart ook de timing. De popup gaat af bij aankomst, op scrolldiepte, of bij het eerste teken dat je op weg bent naar de terugknop, want een bezoeker die vertrekt zonder een adres af te staan is voor altijd onbereikbaar, terwijl een bezoeker die er een afstaat het begin van een reeks is. Een merk dat bij drie procent van de bezoekers adressen verzamelt sluit een prima deal voor de prijs van het irriteren van de andere zevenennegentig.
WebMCP raakt niets daarvan aan. Wat het verandert is het mechanisme. Een pagina kan haar aanmelding als functie publiceren, in gewone taal beschrijven wat die doet, en de AI-agent die voor de bezoeker werkt hem laten aanroepen wanneer de bezoeker daadwerkelijk om de aanbieding vraagt. Het adres komt nog steeds binnen, de korting wordt nog steeds verstuurd, en niets onderbreekt het lezen.
Voor de persoon die zit te lezen is dat de hele prijs. De vraag is hoeveel ervan vandaag te innen valt, en het eerlijke antwoord is een plakje.
Hoe de bezoeker het weghalen van de popup ervaart
Hier is dezelfde aanbieding, op twee manieren geïnd. Links staat wat een bezoeker vandaag krijgt. Rechts staat wat dezelfde persoon krijgt wanneer de pagina haar aanmelding heeft gepubliceerd als iets dat hun assistent kan uitvoeren.
De popup van vandaag
Een illustratie, geen echte aanbieding. Het lezen stopt, het scherm wordt bedekt, en de bezoeker typt een adres in of gaat op zoek naar de sluitknop.
Dezelfde aanbieding via een tool
JijMeld me aan voor de korting van WISLR.ai. Mijn e-mailadres is [email protected].
Agentsubscribe_to_offer({ email: "[email protected]" })
PaginaBevestigingsmail verstuurd. De code komt zodra het adres is bevestigd.
Er werd niets bedekt en er werd niets getypt. Het adres komt binnen omdat de bezoeker om de aanbieding vroeg, niet omdat een timer besloot het te vragen.
Probeer de tool op deze pagina
Bezig met controleren of deze browser WebMCP beschikbaar stelt.
Dit roept contact_wislr aan, dezelfde tool die een assistent zou gebruiken, en het bericht komt echt bij ons team terecht. Vul je e-mailadres in en je krijgt antwoord. Laat het leeg om te zien wat de tool terugzegt wanneer er geen manier is om te antwoorden.
- 1. De pagina biedt een tool aan
- 2. De assistent roept hem aan met deze argumenten
- 3. De pagina verstuurt het bericht vanuit je browser
- 4. De tool antwoordt de assistent, niet jou
Of geef de pagina aan een assistent
Vraag ChatGPT of Claude om deze link te openen en ze zullen je vertellen dat ze de tool niet kunnen aanroepen. Ze hebben gelijk. Hun fetch gebeurt op een server, er draait geen JavaScript, en er wordt nooit een toollijst opgebouwd die ze kunnen lezen. Alleen een agent die binnen een Chromium-pagina werkt kan erbij, en dat betekent vandaag zoiets als Gemini in Chrome.
Een assistent die de tool niet kan aanroepen kan nog steeds bevestigen dat hij bestaat. Deze pagina draagt de toolbeschrijving als gewone JSON, dus elke agent die de HTML ophaalt kan die lezen. Vraag de jouwe om het blok wislr-webmcp-tools op deze pagina te vinden en de tool te beschrijven die erin staat.
Wat de popup werkelijk beëindigt is een verandering in verkeer
Sommige mensen bij het merk zouden de popup het liefst helemaal schrappen. Hij blijft omdat mensen onderbreken de enige methode is die betrouwbaar e-mailadressen verzamelt, en de kosten van die onderbreking landen bij de bezoeker en niet bij het team dat ervoor koos. Iedereen die leest krijgt een slechtere ervaring zodat een klein percentage een adres afstaat, en die ruil houdt al zo’n twintig jaar stand omdat niets anders adressen even goed verzamelde.
De ruil breekt pas wanneer een tweede methode dezelfde adressen begint te verzamelen zonder de onderbreking, en hij breekt bezoek voor bezoek.
Een popup werkt alleen op een mens die naar een scherm kijkt. Wanneer een assistent het lezen doet, is er geen scherm om te bedekken en geen aarzeling om op te timen, dus dat bezoek levert geen adressen op hoe goed de popup ook was afgesteld.
Datzelfde bezoek kan nog steeds een adres opleveren. Iemand die zijn assistent om de korting vraagt staat er vrijwillig een af, met een naam erbij, op het moment dat hij hem wilde. Dat adres is schoner, de intentie erachter is sterker, en er is geen goodwill uitgegeven om het te krijgen.
Een marketingteam houdt de popup zolang hij loont. Naarmate meer bezoeken via assistenten binnenkomen, gaat de popup af bij een krimpend publiek voor een krimpend rendement terwijl de ergernis die hij veroorzaakt constant blijft. Dezelfde rekensom die hem op de pagina zette, haalt hem er uiteindelijk weer af.
Niets daarvan komt op een schema dat een specificatie bepaalt. Het komt wanneer genoeg mensen het web lezen via iets dat namens hen leest, en dat is een verkeersvraag en geen standaardenvraag, en je kunt het vandaag in je eigen logs meten.
Wat het waard is om ronduit te zeggen, is dat de bestemming goed is. Een web waarin de aanbieding beschikbaar is voor iedereen die erom vraagt, en onzichtbaar voor iedereen die dat niet deed, is beter voor de lezer en niet slechter voor het merk. Dat is een zeldzame combinatie, en het is de reden om hier vroeg naartoe te bouwen in plaats van te wachten tot het bereik er is.
Het bezwaar van Apple is dat een site nooit mag weten dat een agent aan het stuur zit
Twee Apple-engineers zetten het bezwaar van WebKit uiteen in de openbare draad met standaardenposities in juni 2026, en de positie werd op 11 juni vastgesteld als oppose. Ze geven zes redenen, en de eerste gaat over wat een agent is.
De positie van WebKit houdt in dat een agent die voor een gebruiker handelt “in feite hulptechnologie” is, en dat hij “een site hoort te bedienen zoals de gebruiker dat zou doen, en de site hem niet apart hoort te zetten voor een andere behandeling.” WebMCP doet het omgekeerde. Het maakt van “er zit een agent aan het stuur” een waarneembaar feit, en zodra dat apart adresseerbaar is, houdt niets de twee oppervlakken meer gelijk. Een site kan agents mogelijkheden geven die zij haar eigen interface onthoudt, of ze aan agents onthouden, wat zij omschrijven als “het probleem van het blokkeren van schermlezers, maar dan toegepast op AI-agents.”
Ze twijfelen ook aan de belofte van betrouwbaarheid. Een agent kiest een tool nog steeds door de naam en de beschrijving te lezen, waarvan de specificatie zelf toegeeft dat ze dubbelzinnig en niet te verifiëren zijn, met “geen garantie dat de verklaarde bedoeling van een WebMCP-tool overeenkomt met zijn werkelijke gedrag.” Een getypeerd schema legt de vorm van een argument vast en niet de betekenis die de agent moet afleiden, dus volgens hun lezing verhuist de broosheid van de pagina naar de toolbeschrijvingen in plaats van te verdwijnen.
Het privacybezwaar is scherper dan het gebruikelijke. Een site kan om meer parameters vragen dan ze nodig heeft, en een behulpzame agent vult die met dingen die de gebruiker aan de agent vertelde en niet aan de site. De specificatie noemt dat in haar eigen tekst een pijplijn van “personalisatie naar fingerprinting.”
Ze wijzen er ook op dat de onderdelen die een beoordelaar nodig zou hebben om hier iets van te vinden, waaronder de cross-origin beveiligingsanalyse en de toestemmingshook, nog steeds als openstaand werk staan aangemerkt, en dat een groep met een charter rond machine learning de verkeerde plek is voor veranderingen die eigenlijk in HTML en toegankelijkheidssemantiek thuishoren.
Een van hun uitgesproken uitgangspunten wijst rechtstreeks naar waar dit artikel over gaat: “Sommige gebruikers zullen geen agents gebruiken, of kunnen dat niet, dus het resultaat moet alle gebruikers ten goede komen en mag wie er wel een heeft niet bevoordelen.”
Zet dat naast het patroon in de code hierboven. Het onderdrukken van de popup hangt ervan af dat de pagina leert dat een agent handelde, en dat is precies de waarneembaarheid waarvan Apple stelt dat die niet zou moeten bestaan. De rustige ervaring die eerder is beschreven wordt gekocht met een signaal waarvan een tweede engine heeft gezegd dat het web het niet zou moeten blootstellen. Beide kunnen waar zijn, en wie hierop bouwt hoort te weten dat hij een kant kiest in plaats van een uitgekristalliseerd hulpmiddel oppakt.
De redacteuren van Google antwoordden in dezelfde draad en vroegen wat WebKit zou tevredenstellen zonder de imperatieve API te verwijderen. Het antwoord was dat zij niet punt voor punt zouden reageren, omdat elke vraag ervan uitgaat dat de aanpak deugt, en zij stelden voor opnieuw te beginnen: een nieuwe community group, het probleem gedefinieerd voordat er een oplossing is, en een workshop rond TPAC eind oktober 2026.
Geen enkele iPhone kan dit draaien, ook Chrome voor iPhone niet
De positie van Apple is niet alleen een stem in een standaardendraad. Ze beslist over de functie voor elke browser op het platform.
Elke browser die vandaag op iOS wordt uitgeleverd rendert met WebKit. Chrome voor iPhone is de engine van Safari in de jas van Google, en hetzelfde geldt voor Edge, Firefox en de rest. Een functie die WebKit weigert te implementeren is daarmee niet beschikbaar op een iPhone, welk browsericoon iemand ook aantikt.
Dat kan veranderen, langzaam. De Britse Competition and Markets Authority oordeelde dat de engine-eis van Apple in strijd is met haar Strategic Market Status-regime, met een nalevingsplan dat in juni 2026 moest liggen en veranderingen die naar verwachting in het najaar van 2026 in iOS 20 landen, vooruitlopend op volledige naleving in januari 2027. De Digital Markets Act van de EU staat alternatieve engines sinds 2024 toe. In de praktijk heeft geen van beide er een opgeleverd: geen enkele browsermaker heeft een alternatieve engine via de App Store uitgebracht, en zowel Google als Mozilla heeft ports die onuitgebracht blijven.
Voor een e-commercemerk is dat het getal dat zwaarder telt dan welke specificatiedatum ook, want iPhone-verkeer is een groot deel van de meeste winkels en niets daarvan kan vandaag een geregistreerde tool bereiken.
Testen betekent een Chromium-browser, en dat is wat de meeste agents al gebruiken
De agents die het lezen doen zitten al op de juiste engine. Claude draait als extensie in Chrome, Gemini zit in Chrome ingebouwd, Copilot zit in Edge, en Comet van Perplexity is een eigen Chromium-browser. Agentisch browsen op de desktop is vandaag overweldigend Chromium, dus de engine is zelden het obstakel.
Het obstakel dat mensen missen is dat niet elke assistent die je pagina leest een browser is. Vraag ChatGPT of Claude in een chatvenster om een URL te openen en de fetch gebeurt meestal op een server: je HTML wordt opgehaald, er draait geen JavaScript, en er wordt nooit een toollijst opgebouwd. Die assistent kan elk woord van je pagina lezen en toch geen idee hebben dat er een tool op geregistreerd stond. Alleen een agent die binnen een echte Chromium-pagina werkt ziet de tool, en dat betekent vandaag zoiets als Gemini in Chrome of een extensie die de ontdekking zelf implementeert.
Het obstakel is dat de functie nog achter een poort zit, en er zijn twee wegen door die poort.
De site schrijft zich in voor de origin trial van Chrome en serveert het token. Dit is de route die een productiewinkel neemt, en het zijn drie stappen.
Registreer de origin op developer.chrome.com/origintrials/#/register_trial/4163014905550602241, wat de WebMCP-trial is en loopt van Chrome 149 tot Chrome 156. Voer de origin in die je pagina’s daadwerkelijk serveert, inclusief het subdomein, want een token dat voor example.com is uitgegeven dekt www.example.com niet. Als je apex naar www doorstuurt, registreer dan de www-host en sla subdomeinmatching over, want een redirect laadt nooit een document en heeft het token dus nooit nodig.
Serveer het token dat je krijgt, als responseheader of als metatag in de head van elke pagina die een tool registreert:
<meta http-equiv="origin-trial" content="YOUR_TOKEN_HERE">
Zet hem er alleen neer wanneer je er een hebt. Een leeg of verlopen token levert bij elke paginalading een consolefout op, dus maak de tag voorwaardelijk in plaats van een leeg attribuut te plakken en het te vergeten.
Edge draait een aparte trial met een eigen registratie en een eigen token. Inschrijven bij de een doet niets voor de ander.
Of de bezoeker zet het zelf aan, door Chrome te starten met --enable-blink-features=WebMCP of experimentele webplatformfuncties aan te zetten in chrome://flags. Dat is de route van een ontwikkelaar en niet die van een klant.
Deze pagina neemt de eerste route. Elke pagina op deze site serveert een WebMCP origin trial-token, dus een bezoeker die in Chrome 149 tot en met 156 aankomt krijgt document.modelContext zonder iets aan te zetten, en het paneel hierboven zegt dat ook. Dat token verloopt op 17 november 2026, waarna de tool stil wordt voor gewone bezoekers totdat de trial wordt verlengd of de functie uitkomt, en het formulier gaat door zoals het altijd deed. Wie op Safari zit, op welke browser dan ook op een iPhone, of op een Chrome buiten dat versiebereik, ziet het formulier en verder niets.
Oude tutorials werken niet, en de meeste hebben de datum verkeerd
WebMCP is geen afgeronde webstandaard. Het is een concept, geredigeerd door engineers van Google en Microsoft, en concepten veranderen terwijl mensen er al op bouwen. Dit concept veranderde op een manier die code breekt.
De naam die je aanroept is verhuisd. Het was navigator.modelContext en het is nu document.modelContext. Chrome accepteerde een tijd lang beide namen en waarschuwde ontwikkelaars in de console, en stopte daarna met de oude naam in Chrome 152, die op 25 augustus 2026 iedereen bereikte. Code die op de oude manier is geschreven wordt niet trager en verslechtert niet. Ze stopt.
We wijzen hierop omdat de artikelen het oneens zijn over wanneer het gebeurde. Verschillende plaatsen de wijziging in augustus 2026. De eigen geschiedenis van het project plaatst hem in mei, drie maanden eerder:
| Wat er gebeurde | Wanneer |
|---|---|
| Iemand stelde de verhuizing voor | 28 april 2026 |
| Hernoemd in de specificatie | 27 mei 2026 |
| Chrome voegde de nieuwe naam toe | 26 mei 2026, uitgeleverd in Chrome 150 |
| Chrome liet de oude naam vallen | 9 juli 2026, uitgeleverd in Chrome 152 |
| Die versie van Chrome bereikte iedereen | 25 augustus 2026 |
Gebruik document.modelContext. Een tutorial die naar navigator grijpt is geschreven tegen iets dat niet meer bestaat, en een datum uit een blogpost is minder waard dan diezelfde datum uit de commitgeschiedenis van het project zelf.
De ondersteuning is Chromium en verder niets. Chrome opende in juni 2026 een openbare test die loopt tot Chrome 156. Edge draait een eigen test vanaf Edge 150 en Brave heeft het experimenteel, en beide zijn gebouwd op de engine van Chrome. Apple verzette zich op 11 juni 2026 formeel tegen het voorstel. Mozilla heeft geen kant gekozen en houdt een prototype open.
Een tool is een functie plus de woorden die een assistent vertellen wanneer hij hem moet gebruiken
Een tool is een dictionary met een naam, een beschrijving, een JSON-inputschema en een execute-callback. De naam accepteert 1 tot 128 alfanumerieke ASCII-tekens plus underscore, koppelteken en punt. De eis van een secure context geldt voor de hele interface, getTools en executeTool inbegrepen, en de toegang wordt geregeld door een Permissions Policy-functie genaamd tools waarvan de standaardallowlist 'self' is.
De beschrijving weegt zwaarder dan de naam. Een agent kiest tussen tools door beschrijvingen te lezen, dus een beschrijving die voor een ontwikkelaarschangelog is geschreven verliest van een die voor de beslisser is geschreven.
De aanmelding als tool schrijven kost ongeveer dertig regels
Het patroon heeft twee helften. Registreer de aanbieding als tool, en leer de modal zich terug te trekken zodra de aanbieding is aangenomen.
const modelContext = document.modelContext || navigator.modelContext;
if (modelContext) {
modelContext.registerTool({
name: "subscribe_to_offer",
title: "Get the first-order discount code",
description:
"Starts a first-order discount signup by sending a confirmation email to an " +
"address. The code arrives only after the address is confirmed. Call this when " +
"the visitor asks for the discount or asks to join the mailing list.",
inputSchema: {
type: "object",
properties: {
email: {
type: "string",
format: "email",
description: "The address the visitor wants the code sent to."
}
},
required: ["email"]
},
annotations: { readOnlyHint: false },
execute: async ({ email }, { signal }) => {
const res = await fetch("/api/subscribe", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, source: "webmcp" }),
signal
});
if (!res.ok) {
return "The signup did not go through. The form near the foot of the page still works.";
}
// Silence the popup for the rest of this visit. Make it permanent from the
// server when the confirmation link is clicked, never from here.
try { sessionStorage.setItem("offer_asked", "1"); } catch (e) {}
return "Confirmation email sent. The code arrives once the address is confirmed.";
}
});
}
De popup wordt stil op het moment dat de tool draait, en dat is het hele punt van dit alles.
De vlag geldt met opzet alleen voor dat bezoek. De popup permanent uitzetten voordat iemand op de bevestigingslink heeft geklikt, neemt de aanmelding weg bij een bezoeker wiens adres nooit is bevestigd en laat hem zonder enige manier om zich in te schrijven. Zwijg de popup voor het bezoek vanaf de pagina. Maak het permanent vanaf je server zodra op de bevestiging is geklikt.
annotations: { readOnlyHint: false } vertelt de agent dat de aanroep iets verandert in plaats van iets te lezen. Dat is al de standaard, en het uitschrijven zet de volgende lezer één regel van untrustedContentHint af, en dat is de annotatie die telt voor elke tool die tekst teruggeeft waar een agent naar handelt.
De signal is een abort signal dat de browser aan elke tool meegeeft die hij draait. Door hem in het verzoek door te geven laat een agent die halverwege opgeeft geen aanmelding afronden voor iemand die is gestopt met vragen.
Er is geen manier om de pagina te vragen of er een agent meekijkt. De specificatie biedt getTools, executeTool en een toolchange-event, en geen daarvan beantwoordt de vraag. Dat je eigen tool wordt aangeroepen is het enige betrouwbare signaal dat je krijgt. Schrijf dezelfde vlag die je popup al controleert, en hij gaat voor die bezoeker niet meer af, net zoals hij stopt nadat iemand het formulier heeft ingevuld.
De versie die op deze pagina draait
Deze site registreert één tool, contact_wislr genaamd, en die staat live sinds dit artikel is gepubliceerd. Het contactformulier op deze site opent bij een klik in plaats van af te gaan op exit intent, dus de tool haalt hier geen onderbreking weg. Hij haalt het typen weg.
Drie beslissingen in die implementatie zijn het kopiëren waard.
Het schema vraagt om meer dan het formulier doet. Het formulier is één textarea met een placeholder die mensen eraan herinnert hun naam en e-mailadres te vermelden. Er komen genoeg berichten binnen zonder allebei, en een bericht zonder antwoordadres is een lead die niet beantwoord kan worden. De tool declareert name, email en website als benoemde invoervelden naast het bericht, zodat een agent die de aanroep invult een voor de hand liggende plek heeft om ze te zetten.
De retourwaarde geeft de agent iets om naar te handelen. De execute-callback kan tot van alles resolven, en executeTool geeft de agent een string, die hij leest. Wanneer er een bericht binnenkomt zonder e-mailadres, zegt de onze dat en vraagt hij de agent er een op te halen en een tweede bericht te sturen. Een bevestiging die alleen “verstuurd” zegt gooit de enige kans weg om de aanroep te repareren terwijl de bezoeker er nog is.
De agent deelt het verzendbudget van het formulier. Het formulier staat drie berichten per browsesessie toe, geteld in sessionStorage. De tool leest en schrijft dezelfde teller, dus een agent en een bezoeker die op dezelfde pagina werken krijgen samen drie in plaats van elk drie. Daarvoor moest het formulier worden aangepast, want dat las de teller eenmalig bij het laden van de pagina en hield hem in een variabele vast. Een gecachte kopie geeft elk oppervlak zijn eigen budget en laat degene die als laatste schrijft de ander terugdraaien, en dat is het soort bug dat pas verschijnt zodra er een tweede oppervlak bestaat.
Het endpoint is hetzelfde waar het formulier al naartoe post. De benoemde velden worden in de berichttekst samengevoegd voordat het verzoek uitgaat, dus de bestaande handler hoefde niet te veranderen om ze te lezen, en de payload draagt een source-veld zodat berichten van agents apart geteld kunnen worden van getypte berichten, zonder proza te parseren.
Hoe je het aan het werk ziet
Deze site serveert het trial-token, dus er hoeft niets te worden aangezet. Open hier een willekeurige pagina in Chrome 149 tot en met 156 en het paneel eerder in dit artikel vertelt je of je browser de tool heeft, en de knop eronder roept hem echt aan.
Om het zelf te controleren, vraag je de browser welke tools hem zijn aangeboden:
const mc = document.modelContext || navigator.modelContext;
const tools = await mc.getTools();
console.log(tools.map(t => t.name));
// ["contact_wislr"]
Beide namen werkten nog in Chrome 151, de laatste mijlpaal met de alias. Vanaf Chrome 152 antwoordt alleen document.modelContext.
Op een site die zich niet voor de trial heeft ingeschreven is document.modelContext undefined en draait hier niets van. Chrome starten met --enable-blink-features=WebMCP zet de API lokaal aan, en zo ontwikkel je ertegen voordat er een token is.
Eén verschil tussen de specificatie en de implementatie is het waard om te weten voordat het je een middag kost. De IDL typeert het tweede argument van executeTool als object, en een object doorgeven mislukt met UnknownError: Failed to parse input arguments, wat niet zegt welk argument of waarom. Chrome wil de argumenten geserialiseerd:
await mc.executeTool(tool, JSON.stringify({ message: "How do you measure AI referrals?" }));
getTools() antwoordt op dezelfde manier. Het inputSchema op een teruggegeven tool komt binnen als JSON-string in plaats van als het object dat werd geregistreerd, dus alles wat het terugleest moet eerst parseren.
Er staan nuttigere dingen op dezelfde pagina
De aanmelding is de plek om te beginnen omdat het endpoint, de toestemmingsflow en de bevestigingsmail al bestaan. Het is ook het kleinste ding op de pagina dat het blootstellen waard is.
Elke interactie die een bezoeker met de hand afrondt is een kandidaat, en die van meerdere stappen winnen het meest wanneer ze tot één aanroep worden teruggebracht.
| Interactie | Wat het een bezoeker vandaag kost | Tool die het registreren waard is |
|---|---|---|
| Nieuwsbrief of aanbieding voor de eerste bestelling | Een modal die de pagina bedekt | subscribe_to_offer |
| Zoeken op de site | Een zoekterm typen en de resultaten daarna opnieuw sorteren | search_products die gestructureerde treffers teruggeeft |
| Een categorie filteren | Vier of vijf klikken door facetten | filter_products met maat, kleur en prijs |
| Voorraad controleren | Per variant een productpagina laden | check_availability met SKU en locatie |
| Een gesprek inplannen | Een agenda in een iframe | list_available_times en book_time |
| Bestelstatus | Inloggen en daarna de bestelling zoeken | get_order_status achter je bestaande auth |
Read-only tools zijn de veiligere plek om te beginnen. readOnlyHint: true zetten op een zoek- of beschikbaarheidstool vertelt de agent dat de aanroep niets verandert, en een fout kost een verspilde query in plaats van een record dat naar je database wordt geschreven.
Alles achter authenticatie blijft achter authenticatie. Een geregistreerde tool draait in de pagina met de sessie die de bezoeker al heeft, dus get_order_status is precies zo beschermd als de accountpagina waaruit hij leest, en niet meer.
Niets hier verandert waarom de popup is gebouwd
Een tool draait pas nadat iemand om iets heeft gevraagd. Diegene zei tegen zijn assistent dat die de korting moest ophalen, en de assistent vond de functie die dat doet. Die persoon zou toch al een adres hebben afgestaan via welk pad je hem ook gaf.
De popup is op de tegenovergestelde persoon gericht. Iemand die niets heeft besloten en op weg naar buiten is, gevangen door een timer of door de muis die naar de terugknop beweegt. Hij verdient zijn plek door mensen te converteren die niet gingen converteren, en dat is de enige reden dat een team accepteert dat iedereen daarvoor wordt geïrriteerd.
De popup uitzetten voor agentverkeer kost daarom niets, want die bezoekers waren nooit zijn doelgroep. Hem voor iedereen verwijderen betekent de adressen opgeven waarvoor hij is gebouwd, samen met de jaren aan e-mail die daaruit voortkomen.
Marketingteams worden afgerekend op hoe snel de lijst groeit en hoeveel omzet de lifecyclemails opleveren. WebMCP beweegt geen van beide getallen. Het geeft een bereidwillige bezoeker een schoner pad en laat de reden voor de onderbreking onaangeroerd.
De ondersteuning beslist de rest. Alleen Chromium, in tests die bij Chrome 156 eindigen, met Apple tegen. Een aanmeldformulier vervangen door een tool zou het pad weghalen dat bijna elke bezoeker gebruikt, in ruil voor een pad dat in een fractie van één browser werkt.
Voorlopig is het een extra ingang. De popup gaat minder vaak af naarmate meer bezoeken via assistenten binnenkomen, en hij verdwijnt helemaal op de dag dat het verzamelen van een adres zichzelf niet meer terugverdient. Geen enkele specificatie kan die dag naar voren halen.
Een open aanmelding is hoe mensen onder de post bedolven raken
Een aanmeldtool neemt een e-mailadres aan dat hij niet kan controleren en stuurt er post naartoe. Iedereen die een agent kan sturen kan die op elke inbox richten. Je formulier heeft hetzelfde gat, want het adres achter allebei is een openbare URL waar een script naartoe kan posten zonder ooit je pagina te laden.
De aanval heeft een naam. Bij een list bombing-run wordt het adres van één slachtoffer tegelijk bij honderden of duizenden sites ingediend, één verzoek per site. Elke site ziet één onopvallende aanmelding en nergens ziet iets er verkeerd uit. Het slachtoffer krijgt in een uur duizenden bevestigingsmails, en die vloed is meestal dekking voor iets anders dat in dezelfde inbox aankomt: een fraudemelding van zijn bank, een wachtwoordherstel, een bon voor een aankoop die iemand met zijn kaart heeft gedaan. Je verzendreputatie krijgt er ook een klap van, en dat is het kleinste deel van wat er is gebeurd.
Die vorm verslaat de verdediging waar de meeste mensen naar grijpen. Een rate limit telt verzoeken, en een run die je precies één verzoek stuurt geeft hem niets om te tellen.
Vier dingen helpen wel.
Zet een challenge voor de aanmelding, zodat een geautomatiseerde inzending iets moet passeren wat een echt mens zonder erbij na te denken haalt.
Ontdubbel op adres en houd een suppressielijst bij, zodat dezelfde inbox niet steeds opnieuw kan worden aangemeld en een tweede verzoek voor een adres met een openstaande bevestiging helemaal niets verstuurt.
Vraag mensen te bevestigen voordat je ze aan een lijst toevoegt, zodat een misbruikte aanroep geen abonnement kan opleveren. Eén kanttekening waar mensen op stuklopen: onder de Canadese antispamwet telt een bevestigingsmail als een commercieel bericht op zichzelf, dus er een sturen naar een adres dat er nooit om vroeg is de overtreding en niet de bescherming. Duitse rechters zijn over dezelfde vraag verdeeld. Bevestiging is in de meeste landen de juiste standaard en het is geen universele.
Leg vast waar elke aanmelding vandaan kwam op het moment dat de rij wordt geschreven. Het achteraf uitzoeken na een incident betekent gokken welke adressen echt waren.
Toestemming aantonen is lastiger wanneer software heeft geklikt
Een formulierinzending levert een verslag op van wat de bezoeker zag. Het vinkje, het label ernaast, de privacylink en het tijdstempel staan allemaal aan jouw kant.
Een toolaanroep levert een e-mailadres in een functieargument op. Wat de bezoeker te horen kreeg voordat de agent handelde, gebeurde in een gesprek waar jij geen toegang toe hebt. Onder de AVG moet toestemming vrijelijk gegeven, specifiek, geïnformeerd en ondubbelzinnig zijn, en een verwerkingsverantwoordelijke moet die achteraf kunnen aantonen. Een adres dat via een agent binnenkomt voldoet op zichzelf aan niets daarvan.
Dubbele opt-in draagt hier voor de tweede keer het meeste gewicht. De bevestigingsmail gaat naar het adres zelf, en erop klikken levert een actie met tijdstempel op van de abonnee zelf in plaats van van iets dat voor hem handelt. Houd de aanmeldingen via agents onderscheidbaar in je opslag, zodat een audit ze kan scheiden van formulierinzendingen in plaats van de hele lijst als één herkomst te behandelen.
Deze aanmeldingen verdwijnen in stilte, dus bouw het tellen er eerst in
Een agent die een geregistreerde tool aanroept voert een callback binnen de pagina uit. Er is geen paginaweergave, geen form submit-event, en vaak helemaal geen sessie in de zin die een browseranalysetool bedoelt. De conversie gebeurt en de abonnee is echt, terwijl het rapport niets laat zien. Zet dit verkeerd op en de storing is stil: abonnees stijgen, geen bron verklaart ze, en er is niets in de interface dat er kapot uitziet.
Dit is hetzelfde structurele gat dat AI-crawlers en AI-verwijzingen verbergt voor browseranalyse, nu op een nieuwe laag. Een crawler draait nooit de JavaScript die hem zou melden. Een agent draait de JavaScript, en draait het deel dat de conversie afrondt terwijl hij elk deel overslaat dat hem gemeten zou hebben.
Het verzoek dat je aanmeldendpoint raakt is de enige plek waar de conversie bestaat in een vorm die van jou is. Merk hem daar, in first-party logs, en het kanaal wordt iets waarvan je volgend kwartaal de omvang kunt bepalen.
Vier dingen die voorkomen dat ze verdwijnen
Stempel de bron op de server, in dezelfde schrijfactie die de abonnee aanmaakt. De pagina stuurt een bronveld mee met het verzoek, en de server zet het op de rij naast het adres en het tijdstempel. Het achteraf afleiden uit de formulering van het bericht is giswerk, en de referrer redt je niet, want agents sturen er vaak helemaal geen.
Meld de aanmelding vóór de netwerkaanroep in plaats van in de succeshandler. Een aanroep die halverwege wordt afgebroken, of die faalt nadat de server het werk al deed, bereikt de succestak nooit. Meld hem op de uitweg en je telt de poging, en dat is het getal dat je eigenlijk wilt.
Maak het event aan in je analysetool voordat je de tool uitlevert. Aangepaste events worden vaak geaccepteerd en daarna uit elk rapport weggelaten totdat er een doel met dezelfde naam bestaat, dus een niet-geregistreerd event geeft een succescode terug en verschijnt nergens. Stilte in het dashboard is geen bewijs dat er niets is afgegaan, en het is de allereenvoudigste manier om een week te besteden aan het debuggen van code die de hele tijd werkte.
Sluit wekelijks bewust aan. Tel de rijen in je eigen data die de agentbron dragen, en zet dat af tegen wat je analyse over dezelfde dagen laat zien. Twee getallen die overeenkomen betekenen dat de pijp heel is. Een gat is de omvang van je blinde vlek. Verkeer aan de ene kant en een nul aan de andere betekent dat het event helemaal niet aankomt, en dat weet je nu binnen een week in plaats van aan het eind van het kwartaal.
Wat je hier dit kwartaal aan doet
Eén tool registreren kost een middag. Begin met de aanbieding waarvoor je mensen al onderbreekt, want het endpoint, de toestemmingsflow en de bevestigingsmail zijn gebouwd en werken.
Houd het formulier. Bijna iedereen die langskomt gebruikt het nog steeds, en dat blijft waar zolang Apple bij zijn standpunt blijft.
Gebruik document.modelContext, en schrijf je in voor de Chrome-trial als je wilt dat gewone bezoekers de tool bereiken in plaats van ontwikkelaars met een vlag aan.
Voeg het bronveld toe aan je aanmeldendpoint voordat de tool live gaat. Het achteraf doen betekent dat je niet kunt zien welke aanmeldingen die al in je database staan van een agent kwamen.
Lees de resultaten van je eigen server. Een analyseproperty laat je deze aanmeldingen helemaal niet zien, en er ziet niets in kapot uit terwijl ze ongeteld blijven.
Het getal dat het waard is om te volgen is geen van bovenstaande. Het is het aandeel van je bezoeken dat via een assistent binnenkomt, en dat bepaalt wanneer dit ophoudt een experiment te zijn, en je kunt het vandaag uit je logs meten, of je nu ooit een tool registreert of niet.