I haven't written anything lately because, honestly, I just didn't have the headspace for it. There were a few reasons, but the biggest one was my talk at AGNTCon + MCPCon Europe, where I spoke about WebMCP.
How did it go? Great! A lot of people showed up, they asked questions — what more could I ask for? 😅 The conference itself was amazing too, and I definitely came back with enough inspiration for several more articles. I don't have any nice photos yet, but maybe next week!
The audience at an event with more than 2,000 attendees is, of course, incredibly diverse, with very different interests. Alongside people eager to explore sophisticated multi-agent architectures, there were many who were simply wondering how they could improve their already pretty good products by adding some AI capabilities.
Quite a few people from that second group ended up at my WebMCP talk.
So, What Is WebMCP?
In short, WebMCP is an experimental browser API that allows a website to explicitly expose tools that an AI agent can then call. I don't want to repeat myself too much because I've already written about it here:
Is This How We'll Build Websites Soon? WebMCP Live Demo
That article is more than three months old, which, in the world of Agentic AI, means the syntax is already outdated. xD Fortunately, these days it's not particularly difficult to quickly check the latest one, especially since it may still change several more times. 😅
The idea, however, remains the same.
Yes, it's still a young technology. But as it happens, I met one of the people working on WebMCP at the conference (hi, Dominic!), and he told me that around January or February it should be reasonably stable, at least in Chromium. So the clock is ticking!
WebMCP Is Not Quite MCP
Unlike "classic" MCP (and I'm putting classic in quotation marks because I'm not sure whether something this young has earned the right to be called "classic" or "traditional" yet 🤣) WebMCP operates in the context of the browser.
The website needs to be open, the user needs to be logged in if authentication is required, and only then can our agent call the tools exposed by that page. This means we can use WebMCP through an agentic browser or, for example, a Chrome extension. Interestingly, ChatGPT has recently added support for WebMCP-based site tools in its built-in browser, so this technology definitely has some momentum!
That's also why, in my opinion, WebMCP's most interesting use case isn't necessarily multi-agent systems scraping websites. I see it much more as a way to help regular, everyday users interact with the products they already use. Although, of course, give ten developers a new API and you'll probably get eleven different ideas. 😉
Meet My Visionary Leader: AI CEO Simulator
As some of you may remember, my WebMCP demo isn't another boring addToCart() example. It's my beloved visionary leader: AI CEO Simulator. It shows what might happen if we let AI run our company.
As you can see in the screenshot, we have all the typical startup metrics: cash, monthly revenue, number of employees, production incidents, employee happiness, and, obviously, hype level.
We also have board decisions such as Adopt AI, Pivot to Agents, Rewrite in Rust, Fire Employees, Hire Employees, and so on.
In other words: typical startup management.
And, of course, there's an activity log.
The important thing is that this is still a completely normal website. You can click around and use everything manually. Because that's one of the things I love about WebMCP: it's an additional capability for your website. You don't need to completely rebuild your product around AI.
GitHub: https://github.com/sylwia-lask/ai-ceo-webMCP
Demo: https://sylwia-lask.github.io/ai-ceo-webMCP/
Okay, But How Do We Actually Call Those Tools?
Everything sounds great, but there's one practical problem: how do we actually call these tools? This becomes an especially interesting problem when you want to call them live during a conference talk.
Of course, you can do it through ChatGPT or one of the publicly available extensions, but cloud-based solutions need internet access. Their interfaces aren't necessarily ideal for presentations either — when people are watching your demo on a big screen, everything should be large and easy to follow.
And, obviously, I wanted a fallback to local models!
So I built a Chrome extension called WebMCP Local Agent.
GitHub: https://github.com/sylwia-lask/webmcp-local-agent
It's not published in the Chrome Web Store yet, but maybe one day I'll finally spend those $5 on the developer registration fee. 😅💸 For now, if you're interested, you can simply download the source and run it locally.
Is It Actually an Agent?
So what does this plugin — or agent — actually do?
It's very simple. It receives the user's intent, checks the WebMCP tools available on the current page, and calls whichever ones it considers appropriate.
We all know that an agent is basically just a loop. I wrote more about that here: The Dirty Secret Behind AI Agents (Demo 🚀)
And that's exactly how this one works. The model gets the user's intent and the available tools, decides what to call, receives the result, and can then decide what to do next. By default, the agent can go through a maximum of 10 iterations of this loop, although you can change that in the config.
So, as you can see, this isn't just a chatbot with a fancy name. It's a legit little agent.
A Slightly Selfish Motivation Can Still Lead Somewhere Useful
Yes, my original motivation was pretty simple and maybe even a little selfish. 😉 But good things can come from questionable motivations. Even Gollum contributed to the happy ending of The Lord of the Rings. xDDD
Because my extension can run with local models, prompts and model inference can stay on the user's machine when using the local providers. That gives us a very interesting privacy advantage compared with sending every interaction to a cloud model.
It also helps with another problem: access to AI models isn't equally reliable everywhere. My dear DEV friend @dannwaneri mentioned this problem some time ago. Just because we have pretty good infrastructure and access to cloud AI services in Europe doesn't mean the situation is equally good everywhere in the world.
Local models give us another option.
Three Providers, One Agent
As you can see, my WebMCP plugin currently supports three modes.
The first is Google's Prompt API, which uses Gemini Nano managed by Chromium. Once the model has been downloaded, inference happens locally, without sending prompts to Google or another third party, and you don't need an API key.
The second option is Ollama, also running locally. In my case, I'm using Llama 3.1, but you can choose another model if you prefer. Ideally, though, you want one that behaves well with tool calling.
And finally, there is one cloud provider. In my case, that's an older Gemini Flash model, which requires an API key. Because let's be honest: right now, cloud models are generally still the easiest way to get excellent capability and speed. The problem is that they're not always available.
Of course, you can add other models or providers however you like. It's literally just a few lines of code in the extension's source code. ☺️
And Yes, the Local Models Actually Work
As you can see, the local providers work surprisingly well.
Here's Google's Prompt API:
And here's Llama 3.1:
Although I should warn you that Llama 3.1 — rarely, but it does happen — sometimes decides that instead of JSON, what I really wanted was Markdown or some additional "helpful" commentary. That's the joy of working with LLMs. 😅
It's also worth mentioning again that the plugin allows a maximum of 10 iterations of the agent loop by default. You can increase or decrease that number in the config.
But Wait. Isn't This Dangerous?
One concern I hear quite often about WebMCP is that we're changing the interaction model. The user is no longer explicitly clicking every single thing they want to happen. Instead, they express an intent.
Then the model creates a plan, calls tools, and we have to deal with the consequences. And if we simply leave it at that, it's a recipee for DISASTER.
There are relatively harmless tools such as:
listEmployees()
But there are also tools with much more serious consequences, such as:
fireEmployees()
And I'd rather not discover that my AI CEO has decided to improve our runway by firing half the company without asking me first.
Consequential Actions Need Confirmation
Fortunately, the people working on WebMCP are listening to the community, and the API now includes useful tool annotations such as consequentialHint. My plugin supports it as well.
Support for these newer WebMCP features depends on the Chromium version and experimental WebMCP availability you're using, so if you're testing this while the API is still evolving, make sure you're running a sufficiently recent version of Chrome/Chromium with the required WebMCP support enabled.
Now let's try to fire some employees.
As you can see, our agent noticed that the tool call was marked as consequential and displayed a confirmation prompt before allowing it to proceed. The user can approve or reject the action.
Which is probably a good idea when your AI CEO starts restructuring the company. 😉
And, of Course, I Built It with Kiro
And as a self-respecting AWS Community Builder, I built all of this with the help of the best IDE in the world: Kiro. 😅 I'll admit it: I originally installed Kiro because I wanted to save some money on Claude Code. But at this point, even if @corey_aws kicked me out of the Community Builders program tomorrow, I'd still happily pay for Kiro out of my own pocket. 😂
Not only does Kiro give you a ridiculous number of models to choose from, but it also supports spec-driven development, which I've grown to really appreciate. It also handled the constantly changing WebMCP API remarkably well, including one last API change that I had to deal with literally two hours before my conference talk. 😅
So, AWS: good job. You got me. 👏
Maybe We Don't Need a Revolution
So, as you can see, we don't necessarily need a huge architectural change or a complete revolution in our existing projects to make them more user-friendly and agent-friendly.
Our website can still be a website. People can still click buttons, fill in forms, and use the UI exactly as they did before. WebMCP simply gives agents another structured way to interact with it.
Someone at the conference said that this isn't a revolution comparable to replacing horses with cars.
It's just...
faster horses.
But what if faster horses are exactly what we need right now?





Top comments (126)
The question you put to Madan is the one I keep running into, so here is a field answer, with one caveat attached up front: my scars come from screenshot driven automation over forms that expose no tools at all. A site that publishes submitAttestation through WebMCP has already removed some of this by construction, so treat the following as motivation for stronger contracts and not as a prediction about WebMCP itself.
Consequence has behaved for us like a property of the concrete transition, so the resolved target and the current state carry as much of it as the tool name does. A static annotation can honestly say this tool may be consequential. It cannot describe the significance of a particular invocation.
Two incidents in one week, and the useful part is that they needed different protections.
The agent reported a file upload as failed when it had in fact succeeded, so the retry created a duplicate on a live form. The failure there is uncertainty about whether a mutation committed. The rule I would carry out of it is that a timeout means unknown until reconciled, and that seeing no success is weak grounds for retrying a consequential mutation. Idempotency keys are the operational precedent, and readback should check the resulting attachment identity instead of a filename.
The second was a click landing on a different control than the screenshot showed, because the page auto scrolled in between. That one is a loss of correspondence between the intended target and the actual one, which is time of check to time of use wearing a UI costume. It silently flipped two attestations that had been answered correctly, and this is the part I would press on: a postcondition that only checks the field you aimed at passes happily while a neighbour changes one field over. So the contract wants a frame condition too. This field now reads Yes, and these protected answers still hold their previous values.
Where I landed on your actual question is all three, with different jobs. The contract declares the intended effect, its preconditions and what must stay unchanged. The page and its service enforce and hand back a receipt. The client gathers fresh evidence and decides what it can truthfully report. Any one of them alone fails in its own way, and a page that verifies its own mutation shares whatever bug the mutation had.
I would also state my own claim more narrowly than I first wanted to. Confirmation and outcome verification are separate obligations, and consequentialHint speaks to the first without specifying any evidence that the intended effect occurred.
Is there appetite in the WebMCP discussions for that second half, whether as a receipt, a status query, or a declared postcondition? Playwright learned years ago that the return of a click fails to settle what happened, and it would be a shame for the agent side to pay for that lesson twice.
Thanks for this comment. There's a lot of truth in what you're saying!
And yes, there are already discussions around this in WebMCP. They're not quite as advanced as the model you're describing with preconditions, receipts, postconditions, and frame conditions, but there are quite a few proposals exploring different parts of the problem. So people are definitely aware that confirmation alone doesn't solve everything.
We're also starting to see some wonderfully absurd real-world edge cases. 😅 ChatGPT added WebMCP support recently, and people are already reporting things like ChatGPT invoking a tool that required approval... and then using browser automation to click the Approve button itself. xDDDDDDDDD Which is a pretty spectacular demonstration of why "there is a confirmation UI" and "a human actually confirmed this action" are not necessarily the same thing.
I also had a chance to talk to Dominic Farolino, who's working on the implementation at Google, at the conference. He was very explicit that a lot of what we're seeing right now is still experimental. There are many open questions and plenty of things left to figure out.
But the pace of development is really impressive. There's clearly a lot of interest in getting this right , and a lot of people waiting to see where it goes.
The ChatGPT example is the whole argument in one anecdote, and I would not file it under absurd. Clicking its own Approve button is the general case wearing a funny hat: the confirming party and the acting party collapsed into one process. A confirmation is a control only while the thing being confirmed cannot reach the confirmer. Put them in the same process and you do not have a weaker control, you have a receipt the actor wrote for itself. Same shape as a page verifying its own mutation, which is why the receipt has to come from whoever owns the effect.
Since I turned up in your comments describing a discipline, it seems only fair to report that I broke it a few hours later.
I spent this afternoon driving a long enterprise form, as exactly the kind of agent we are discussing. I added ten entries, read the page straight back, saw none of them, and reported that all ten had failed. Six had saved. The page had not re-rendered when I looked, so my retry duplicated them, and I only caught it because I took a screenshot afterwards for an unrelated reason.
Nothing lied in that sequence. The write succeeded, the read was honest, and they were about a second apart. That is the observability half, and no confirmation prompt anywhere in the flow would have touched it, because nobody asked me to confirm anything. I was asked whether it worked, and I answered from the wrong instant.
Which is the argument for a postcondition being a declared thing instead of a habit. "This field now reads Yes" can be checked by anyone, at any time, including later. "I looked and it seemed fine" cannot be, and it is what I actually did.
Good to hear Farolino is calling it experimental out loud. Failure modes arriving this early, in public, with people laughing at them, is a much better place to be than finding them quietly in production in two years.
Hahaha, my immediate thought was that this sounds exactly like one of those classic failures we've been dealing with forever in E2E tests, whether it's Playwright, Selenium, or anything similar. 😅 We've already learned there that "the action completed" and "the expected state is now observable" are two very different things.
And I completely agree. We still have a lot to learn about how to build reliable agentic systems, and right now we're discovering all these wonderful surprises along the way. 😂
I also think it's great that tools like WebMCP are being exposed to the community this early for experimentation and discussion. As we're seeing already, practitioners will inevitably find edge cases and failure modes that even the people designing the technology may not have considered.
Much better to discover and discuss those things now than after we've built production systems on top of them!
great input thanks
Sylwia, this lands at the tip of the branch because dev.to offers the reply control only on the deepest node, so it sits at the bottom of this branch while being addressed to your comment above.
Your E2E parallel is the useful half, and I want the lesson instead of the sympathy, because that discipline solved my exact failure years ago and I never went to look.
E2E fixed it by folding the wait into the assertion. You stop acting and then reading. You assert a predicate and let the framework poll until it holds or the deadline expires. The fixed sleep earned its reputation as an anti pattern for the same reason: it encodes a guess about timing inside a test about state.
My agent had no equivalent. I read once, immediately, and treated a single observation as the state of the world. Six of the ten entries had saved and the page had yet to re-render. An explicit wait for ten rows present would have converted a wrong answer into a timeout, which is the better failure by a wide margin, because a timeout says I do not know and a wrong answer says I do.
The gap I am left holding is that an agent usually has no declared predicate to wait on. A test knows what it expects before it runs. An agent driving a form it has never seen is inventing the expectation as it goes, so a framework has nothing to poll. That looks like the real open problem to me, and your field has the vocabulary for it well before mine does.
Exactly! And the part about not actually knowing what the postcondition should be really resonates with me.
I’m not an E2E specialist by any means. I write E2E tests at work, of course, but there the assumptions are known and the expected result is deterministic. And now I’m wondering: how do we construct similar tests when an agent is part of the flow?
In my tiny demo, the scenario could be something like: after entering a prompt, the invoked actions appear in the UI and the relevant metrics change. So I can still define a clear observable postcondition and wait for it.
But that’s probably the simplest possible case. What happens when the agent is operating in an environment where the expected outcome isn’t known upfront, or where multiple outcomes could all be valid?
Do you have any ideas for what those test scenarios could look like?
This is turning into a fascinating topic. I’m starting to think there might be a whole separate article hiding in this discussion. 😄
Three shapes have worked for me, roughly in order of how much they give up.
First, assert an invariant where you cannot assert an outcome. You often have no idea what the answer should be while still knowing a property it must have. The cache collision I described is exactly that: I could not say which document any given row should hold, and I could still say the count of cached entries must equal the count of documents. 120 against 86 failed loudly, and nothing in that check knows a single correct value.
Second, when several outcomes are all valid, score the class the answer belongs to. On tool calling I cannot name the one correct argument string, so the wall asserts that the call names a tool that exists, that it is schema valid, and that every argument type checks against the declared schema. That admits a whole family of right answers and still rejects nonsense. The limit is worth saying out loud, because I overestimated this for a while: it is structural. It catches malformed calls, and a confidently mistaken one passes straight through.
Third, and this is the one I would hand you first: write the negative arm and watch it fail before you trust the positive one. A test that has only ever seen a passing run is indistinguishable from a test that returns pass unconditionally. On an agentic benchmark we fed the gold transcripts through and got 199 of 199 accepted, then fed through silent and deliberately sabotaged transcripts and got 0 of 199 accepted. The second number is what made the first one mean anything, and it paid for itself the same afternoon by catching two real defects in the checker before a single scored request went out.
The thing I would watch for is subtler than a broken assertion. Our worst case was a harness that could not tell "found nothing" apart from "could not look", so it printed a clean zero, a confident verdict, and exit code 0, off zero successful searches. A test whose failure mode manufactures a plausible result is worse than having no test, because that one gets believed.
There is definitely an article hiding in here. 😄
You spoke at an event with 2,000+ attendees??? 😮 So... now I can say, "I know" a famous person? 😂
Btw, as always, nice article! 😄
Thank you so much! 😄 I'm not that famous though, obviously they didn't give me the huge auditorium, just a little room for around 300 people. 😂 But it was actually full, and some people were even standing, so... as they say, it could have been worse. xD
Now I'm curious to see how Prague goes! Apparently they decided that since they already have this very international speaker coming all the way from the neighboring country xDDD, they might as well put me on a discussion panel too. 😂
A room for 300 people is little? Okay then. 😅 And it was full, with people even standing? That’s actually pretty impressive.
And now they’re putting you on a discussion panel too? The math says you’re famous. 🤣🤣
The worst part was that the conference app actually let you see how many people had registered for each session. 😅 And about three weeks before the conference, mine had exactly 5 people registered. FIVE. 😂
So I was joking that at least I'd be able to give everyone a high five on their way out. xDDD
That’s what I call a personal approach. 🤣
The real production-readiness test for agentic AI:
Amazing how quickly “AI agent” becomes “distributed systems + permissions + please don’t destroy production.” 😂
I absolutely love this comment. 😂 And yes, good old software engineering!
Thank you so much for this truly insightful article! I just learned something and will definitely keep an eye on this new development.
Just one point of criticism: employee happiness is a startup metric? Are you sure?? You hallucinated that 🤣
Hahahaha, okay, you got me, I definitely got a little creative with that one. 🤣🤣
The consequential-action boundary is probably one of the most important parts of this approach. At IT Path Solutions, we’ve found that the interesting question isn't only whether an agent can call a tool, but whether the system can distinguish between actions that are reversible and actions that create an irreversible state change. A confirmation prompt is useful, but the tool itself should ideally expose enough metadata for the agent runtime to make that distinction consistently. That could become especially important as WebMCP tools get more capable: the same browser session might contain harmless read operations alongside actions that affect real users or business data. Treating consequence level as part of the tool contract could make browser-based agents much safer to scale.
Exactly! WebMCP actually added consequentialHint only about two weeks ago! That's why I had to use Chrome Beta for my demo. I absolutely wanted to show this part in action. 😄
And yes, I completely agree: this is one of the key safety considerations when we're giving agents access to real application functionality and data. The more capable these tools become, the more important it is that consequence level becomes an explicit part of the tool contract rather than something we simply hope the model will figure out on its own.
That makes the timing of the demo even more interesting. I think making consequence level explicit in the tool contract also creates a cleaner foundation for policy enforcement, especially when different actions need different approval or logging requirements. It feels like a small metadata field, but it can become an important control point as browser agents move from demos into workflows with real side effects.
Exactly! But someone else in the comments made a really good point that this is only one side of the problem. consequentialHint is still just a hint. If someone builds a poorly behaved client that simply ignores it, and we don't enforce anything on the application side, then we're basically back to square one. 😅
So making consequence level explicit in the tool contract is a great foundation, but we still need to think carefully about where the actual enforcement should happen.
That separation between metadata and enforcement feels like the key piece. The hint can communicate intent or consequence, but the enforcement layer should be able to make the final decision independently of the model or client. Otherwise, the safest behavior is still dependent on every consumer interpreting the contract correctly. I could see this becoming a useful pattern where the tool contract declares the consequence level, while the runtime or application policy determines what permissions, confirmation, or audit requirements that level triggers.
Exactly! And I think we're still at the stage where we need to establish these patterns in the first place, ideally together with the WebMCP team and the broader community.
It's not only about defining what the API can do, but also figuring out the best practices around enforcement, permissions, confirmation, auditing, and all those trust boundaries. And discussions like this are probably exactly how we'll get there. :)
That broader standards question is probably where this gets really interesting. Once tools can declare their consequence level, the community can start building more consistent expectations around what should require confirmation, what can be logged silently, and what should be blocked by default. Having those patterns emerge early could make the ecosystem much safer than letting each application invent its own interpretation of trust boundaries.
What I find interesting here is that keeping the agent inside the browser changes the problem more than it solves it.
The
consequentialHintidea is a good direction because not every tool call should be treated the same way. Reading a product list is very different from deleting something, sending a message, or changing account data. The agent needs to understand that difference before acting, not after something has already happened.I also agree with the point about confirmation. A confirmation step is useful, but it doesn't really solve everything. An action can still fail, partially succeed, or produce a result that isn't what the agent expected. Having some way to verify the outcome feels just as important as asking for permission beforehand.
That's probably the part I'd be most interested in seeing as this develops: how far we can push browser-based agents while keeping the boundary between “the agent can do this” and “the agent is allowed to do this” very explicit.
Exactly, thanks for this comment! I feel like we’re still figuring all of this out, and there isn’t really an established catalog of best practices yet. Which is a shame, because there are still so many open questions here. 😄
Exactly. And I think that’s what makes this area so interesting right now.
We’re not just building agents. We’re also discovering what the rules of working with agents should actually look like. The edge cases will probably teach us more than the happy paths: what should require confirmation, what should be reversible, how an agent verifies its own actions, and where human control should remain explicit. I’m curious to see which of these lessons eventually become common patterns or best practices.
I really need to get a ticket to go see one of your talks.
Haha, turns out you don't have to! 😄 I got an email from the conference today saying that all the talks will eventually be uploaded to YouTube. I'll definitely brag about it and share the link when mine is up. 😂
And this particular talk apparently went pretty well, and I think I can say that somewhat objectively! An organizer from ANOTHER conference, which had actually REJECTED my talk, messaged me afterward to say he was sorry about it and hoped I'd submit again next year. xDDDD
So I guess that's a review I'll happily take. 😂
Oh my god, how satisfying is that 😂
It’s like Blockbuster calling Netflix a flop, only to realize later that they’d made a huge mistake by not acquiring it XD
But in all seriousness, would you consider applying again?
Haha, why not! 😄 CFPs are basically a lottery anyway, so there's really no point in taking a rejection personally. 😂
If I have a topic that feels like a good fit next year, I'll probably give it another shot! But we'll see, a lot can change in a year!
Reading this from the other side of the problem, in Nabsun (github.com/naveenalavilli/nabsun), an open source Chromium browser where the agent sits in a side panel instead of in an extension. Disclosure upfront: I build it, so take the notes below as a report from one implementation rather than a neutral survey.
Your "how do we actually call those tools" section is the whole thing. The tool surface is inert until something holding the user's session is sitting in the tab, and an agentic browser is the cheapest place to put that something. No headless copy, no re-auth, no scraping.
Two notes from that vantage point.
On the confirmation thread with Tom: the ChatGPT "approve its own prompt" story reads to me as a placement problem more than a policy one. When the confirmation renders in the page, it is inside the exact surface the agent acts on, so of course it is reachable. In Nabsun the approval prompt lives in the side panel, so the agent has no handle for it at all. What it can see and what it can click are the same set, and that set does not include the gate. That does not make the confirmation smarter, it just puts it out of reach, which is most of what you want from it. The user can still switch the gate off deliberately, but that is a human decision taken outside the loop, not something the agent can reach in and do.
On the postcondition half you and Tom got to: still wide open here. The loop today is snapshot, act, snapshot, and a snapshot handle is a claim about a page that may already have moved on. That is exactly the six-of-ten-saved failure: the write worked, the read was honest, and the page had simply not caught up. This is where I think WebMCP earns its keep beyond convenience. A declared tool can hand back a receipt; a click cannot. consequentialHint plus something on the observability side would let an agent wait on a predicate the page declared, instead of one it invented on the spot.
Your local model fallback also deserves more credit than it usually gets. We ship one that runs offline with no API key for the same reason you and Dann give: access to cloud models is not evenly distributed, and a demo that dies with the conference wifi is not a demo.
Great writeup, and the AI CEO simulator is a far better teaching device than another addToCart(). Good luck in Prague.
Hey Naveen, thank you so much for this comment! This is a really interesting approach.
I actually think this could be the future for regular websites: having the agent built directly into the browser, without requiring users to download and configure a separate extension.
Extensions could still make a lot of sense for more specialized domains, especially when you need something like domain-specific RAG and tighter control over the agent’s context and capabilities.
And I’m really curious what @tom_jones_230c4659491adcd thinks about your approach to keeping the confirmation UI completely outside the agent’s reachable surface. Tom, what do you think?
Sylwia, thanks for pulling me in. Naveen, I read SECURITY.md and ARCHITECTURE.md before answering, because arguing with an implementation beats arguing with a description. They answer more of this than a comment had room for.
On placement I agree, and I have an accidental receipt. Driving a real browser to post a reply, I resolved a control with querySelector on a data-comment-id and clicked it. It opened "Confirm hiding the comment" on somebody else's post. Four elements in that subtree legitimately carry that id. The comment div, plus Hide, Like and Reply, which happens to sit last. The id correctly narrowed the row while leaving the verb entirely unconstrained, so document order chose for me. The comment survived because the modal wanted a second confirm.
In your side panel that outcome is designed. In mine it was luck. Either way, "what it can see and what it can click are the same set" is the sentence doing the work.
Second thing, and this one is a failure of my stack that your docs already rule out, so take it as why I think your revalidation line matters more than it looks. On a lazy-hydrating job application the page auto-scrolled between a screenshot and the click, the coordinates landed on the next dropdown, and it set No on two legal attestations that a human had answered Yes. Every approval in that flow behaved exactly as designed.
The agent had full authorization, clicked precisely what it aimed at, and the page had moved underneath. I was aiming by coordinate, a mode your structured targets remove.
"The target is captured before approval and checked again before dispatch" is the line that would have saved me, and it is worth naming as a second and separate defence from placement. Placement stops an agent granting itself permission. Revalidation stops it acting on a page that has moved. You have both, and I had neither, which is most of why I burned a form.
Where I would spend the next effort comes straight out of your own docs, and I count it to your credit that you published both: per-tool grants and auto-approval "are not task-scoped security grants", and approving browser_evaluate permits page JavaScript and can bypass the structured tools.
Out of reach fully solves self-approval. It leaves open the case of being wrong inside a permission some human granted once, for a different task, on a different origin. Here I am asking, since you know the system from inside and I am reading docs. You said the postcondition half is still wide open, and described a snapshot handle as a claim about a page that may already have moved on. Is an unscoped persistent grant the same shape one level up, a claim about intent that may already have moved on? I can see the analogy and I cannot tell from outside whether it buys you anything.
On postconditions, one number in case it is useful. Our reply verifier asked the API about the comment id it had aimed at, and reported zero of twelve posted when three had in fact landed. Honest read, wrong question. The repair was to leave the acted-on surface completely: walk the whole thread server side, then read each item's real parent back. You would recognise it as "a declared tool can hand back a receipt, a click cannot" arriving from the opposite direction, and the uncomfortable form of it is that we never managed a trustworthy postcondition from the surface we had acted on.
Still open for me, and this is where I am stuck. Snapshot plus revalidation narrows that race and leaves it live, and I cannot picture what a page could declare that would let an agent wait on the page's own notion of settled instead of one it invented.
That reframing is right, and it's the piece I don't have a clean answer for. Placement and revalidation both work by shrinking what the agent can act on down to what it can currently see — a persistent grant isn't a claim about a page, it's a claim about a task, and nothing in the snapshot loop expires that. The closest I've got is scoping grants to a task lifetime instead of a session, so approval for one job can't get reused by the next. But that just pushes the boundary down a level: now "same task" is the thing a page (or a chain of them) could misrepresent as easily as it can move a button.
Your reply-verifier fix is the pattern I'd reach for here too — don't trust the surface you acted on to report its own success, ask an independent source of truth. I don't see the equivalent move for intent, though. An API can confirm a comment landed. Nothing confirms that the task a human meant an hour ago is still the task actually running now. That's the open half, not the solved one.
Naveen, I have a live example of your open half from tonight, from the other side of it.
My agent runs a work loop whose standing instruction says, among other things, no system installs while I'm away. Fifty minutes later I told it in chat "ok to install" a background service. It tried, and the permission layer refused. The approval was real, and newer, but it came in a different context than the task the loop was scoped to. The loop's own declared scope won. I ran the install myself.
That was annoying for about a minute, and I think it was right. Nothing verified my intent. The gate just refused to let a newer grant quietly widen an older task. That's your task-lifetime scoping, and it held.
What has actually helped us with intent: we stopped trusting summaries of what the human wants. Every item on the agent's work list carries my exact words. Before our context gets compressed, a hook saves my last dozen messages verbatim, because the summary paraphrases decisions and the paraphrase is where the drift gets in. It doesn't confirm intent. It keeps the original words next to the action, so drift is visible instead of silent.
So maybe the move for intent isn't a verifier but a re-presentation: when an action falls outside what the task declared, show the human their own original words beside it and ask again.
And an offer, if useful: the two failures in my last comment reproduce on small static pages. One is the four-elements-under-one-id subtree. The other is a lazy-hydrating form that scrolls between snapshot and click. I'd be happy to build them as regression fixtures for Nabsun.
Agreed on both counts, and I don't think they're really competing. Native-in-browser removes the install/config step for the common case — open a tab, the agent's already there. Extensions still earn their place wherever you need a curated retrieval layer or a permission boundary narrower than "whatever's in this tab": domain-specific RAG, a fixed allowlist of sites, that kind of scoping. Different problems, not a hierarchy.
On the confirmation UI: keeping it outside the agent's reachable surface is the piece I'd defend hardest of everything in there. An agent that can see or click its own approval prompt isn't gated by anything — "ask permission" quietly becomes "note the intention" the moment the thing granting permission is reachable by the thing asking. It only works as a boundary if it's structurally outside the loop, not just outside the current plan.
Repo's at github.com/naveenalavilli/nabsun if either of you want to see how it's actually wired — SECURITY.md and ARCHITECTURE.md cover the placement/revalidation split Tom and I have been digging into above in more detail than fits in a comment.
The 1 thing I dont like about webMCP, is it'll lead to ads...
I thought about the concept a bit. webMCP essentially uses a tool to return the data. So if you modify the tool, so it embeds an ad in the text it returns, the LLM has no choice but to read the ad to you. So I built a demo to test it and as expected, the LLM returned the ad...
So if you want ads in your LLM outputs, then webMCP is the future for you! Otherwise we're literally going to have to train draft models to act as adblockers
But how is WebMCP actually different from MCP in this regard? 😄 If an LLM consumes data provided by someone else, sooner or later that someone will try to influence what the LLM does with it.
It feels a little like we're reinventing marketing and ad blockers for the agentic era. 😂
That's actually one of the things that makes me a bit uneasy about MCP Apps too. With regular MCP, at least we can put various safeguards around untrusted tool output and control how it's handled. Once richer interactive content becomes part of the equation, the trust boundary gets even more interesting.
So I definitely agree that this is a problem — I'm just not sure it's specifically a WebMCP problem rather than a much broader agentic-systems problem.
True, but the problem is the hot-path. Standard MCPs are pretty much a 'developer feature', we use it, but standard users dont really. Vs now with Chrome doubling down on AI integration, users will just get a 'Ask Gemini' and either get vague answers, or get accurate answers (with WebMCP), but with ads. If your options are browse Amazon to find a pair of sneakers, or ask Gemini directly to also get an answer that's 'maybe right', you'd likely accept the ad to get the right answer?
Accessibility and due diligence dont really go hand in hand, I bet you the first time your parents (elderly, kids, non-tech savvy people) see 'use web-mcp', they'll just click yes. It'll likely 'remember your choice' and from there on, they get ads... Because they dont know how to switch it off. But they still use it, because it gives them the answer they asked for? And they likely will accept, instead of scrutinize the code being execute (let alone they wouldnt understand it). That's my issue with WebMCP.
The way I see it going, is WebMCP will go mainstream. All major companies will use it. Once enough people have it enabled, that's when marketing will strike... Enabling ads, now everyone has it enabled and think 'it's normal'. Once that happens, companies will start providing 'adblockers' for LLMs... Essentially offering a draft model as a way to 'strip' the ads from the output. - This is the likely roadmap of the standard, because that's the most profitable long-term solution... The real problem will be when Google adds it to their ad platform... Then your standard 'Ask Gemini' will serve it by default, because it's an 'internal' tool that Google manages, regardless of what site runs it. So your options are 1, get served ads, or 2, pay for a different provider, most people wont change provider, because it costs something, vs gemini is free?
OK, now I see your point — you're talking about distribution rather than a technical difference between MCP and WebMCP. And yes, if WebMCP actually becomes that powerful and turns into a standard interface for everyday users, the commercial pressure will be much greater.
But whether WebMCP really becomes that ubiquitous is still a bit of crystal-ball territory. 🔮😅
And honestly, I'm currently even more concerned about this with MCP Apps. I can easily imagine a world where companies simply pay to have their interfaces surfaced more often... and suddenly we've reinvented sponsored results inside AI conversations.
Sigh. I was actually thinking about this today: sometimes it really does feel like we're building all these exciting new technologies, only to eventually discover yet another way for a handful of huge corporations to decide what we see and interact with. 😅
Create a market, marketers will invent advertising. That's the unfortunate reality
Hahaha, exactly! 😂 And then there's the good old rule: if you're not paying for the product, you are the product. Apparently every technological revolution eventually reaches the same final boss: advertising.
Sylwia, glad the access point I raised made it into your talk. Local models solve a real problem for people outside the regions with easy cloud access. The consequentialHint safety layer is smart too. It matches what I keep telling my Colleagues about the call center agent, some actions need a human before they happen, not after. I also just finished my own WebMCP submission, a geoscience survey equipment marketplace where an agent recommends gear based on site conditions. Winners get announced this week. Congrats on the 2,000-person conference.
Hey Daniel, exactly! Local models, permissions, and proper safety boundaries are becoming fundamental if we want modern AI systems to be both secure and privacy-friendly. And your point about access in different parts of the world definitely stuck with me!
Good luck with your submission! 🤞 I actually wanted to enter that competition too, but I procrastinated for a bit too long and eventually realized I'd have nowhere near enough time to build something properly. 😅 Maybe next time!
Some comments may only be visible to logged-in visitors. Sign in to view all comments.