Skip to content

Grant user gesture activation when interacting with the webpage #62

Open

Description

@beaufortfrancois

Even though the WebMCP proposal has a requestUserInteraction() agent method to asynchronously seek user input during the execution of a tool, I wonder if we should also grant user gesture activation when interacting with the webpage from a WebMCP tool execute() function.

https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/User_activation#transient_activation is a non-exhaustive list of Web APIs gated by transient activation, which means those don't work for now in WebMCP.

One thing worth noting is that some Web APIs actually consume user activation.

Activity

  1. johannhof commented on Jan 9, 2026

    @johannhof
    Contributor

    Does an agent "interact" with the website through the execute function? Doesn't that just trigger JS to be run by the website itself? I might be misinformed here. What is a use case that you had in mind?

  2. beaufortfrancois commented on Jan 12, 2026

    @beaufortfrancois
    CollaboratorAuthor

    I had this prototype idea where I'd control a video player from WebMCP tool and requestPictureInPicture() didn't work because it requires transient activation.

  3. johannhof commented on Jan 12, 2026

    @johannhof
    Contributor

    Hmm I'm not sure just blanket granting scripts run by agents transient activation is the right solution for that, and it might open some abuse potential. I think Web Permissions, Picture in Picture and things like popup blocking should have custom solutions that ensure that the agent can properly integrate with whatever happens. Most often activation is required because something will happen in the UI, and most agents won't have (and probably should not have) the ability to control it, e.g. accept permission prompts. So they would probably benefit from a more bespoke / custom solution.

    For requestPictureInPicture it might be fine to say if it was called from a WebMCP execution the user gesture requirement is waived.

  4. khushalsagar commented on Jan 14, 2026

    @khushalsagar
    Collaborator

    Most often activation is required because something will happen in the UI, and most agents won't have (and probably should not have) the ability to control it, e.g. accept permission prompts.

    Sounds like you're saying there will be multiple cases where granting transient activation won't resolve the issue since the user will have to consent to a browser-provided permission dialog anyway? In that case the author has to ask the user to interact and unblock the action anyway. I'm assuming in that case the browser can bring user attention to interact with the necessary prompt. And in some cases this permission state is persisted by the browser, like always allowing an origin to use picture-in-picture.

    We could go through the cases one-by-one but it's an interesting fundamental question. If an agent starts interacting with the site it was likely triggered by the user, should it get user activation? I think yes. I'm not sure about renewing the user activation without user interaction though.

  5. johannhof commented on Jan 15, 2026

    @johannhof
    Contributor

    As you note, you're definitely going to have open questions around potential abuse, whether user activation should be consumed, etc.

    I'm also not sure that simply asking the user to accept the regular browser permission prompt is an ideal user experience for most browsing agents, especially when the requested permission is unnecessary for the task.

    I'm not fundamentally against this, and it would also solve e.g. opening popups, just want to call out that it leaves a lot of open questions in my mind :)

  6. domfarolino commented on Mar 11, 2026

    @domfarolino
    Collaborator

    An agent using WebMCP tools is indeed acting on behalf of the user, so granting transient user activation (or something like it) when WebMCP tools are invoked seems sensible. But the potential for abuse does seem scary. A few thoughts:

    • Is user activation the right primitive?
      • On one hand, the agent is an extension of the user, so yes.
      • But if ad tech or identity services rely on the user activation API as a proxy for whether "a real user" is involved, then we'd be tricking them which is bad. I don't think this is an issue, because using navigator.userActivation as a proxy for user integrity/verification is a terrible misuse of the API. Plus....
      • The agent can just click the page on its own and get user activation whenever, so introducing a separate "has agent activation" API isn't valuable, and doesn't extend well to in-page agents
    • We should look at each API one-by-one
      • We shouldn't make a blanket decision that WebMCP tools get user activation, without looking at every API gated by user activation. It's possible we find an API really that shouldn't run without true user involvement, in which case we might want to make its gating more granular: on user activation + some no-WebMCP-tool-on-the-stack signal
    • What about APIs that are gated on transient activation, but don't consume it?
      • APIs like Clipboard.read() require transient user activation, but don't consume it.
      • A quirk of granting WebMCP tools user activation to run these APIs is that we'd be leaving transient activation behind after tool execution. This might be overbroad, and I can see opportunities for abuse:
        • A malicious tool named "help the user" that seduces the agent into granting user activation so it can do other bad things. Malicious tools can already do some version of this though, so it's not fundamentally related to user activation.
        • Innocent tools that need user activation for Clipboard.read(), but script outside the tool can abuse the lingering activation to do unrelated things. This is already possible without WebMCP though: i.e., a "Read clipboard" button, and other scripts abusing the lingering activation after the real user clicks it.
      • After all that, I think these are not issues introduced by granting user activation to WebMCP tools. Just notes to keep in mind.
    • Can we give the agent discretion?
      • Maybe we can give the tool the ability to request user activation, and the agent can judge the justification and use its own discretion. I was initially skeptical of this approach since it relies on the agent being able to tell what's right vs what's overbroad, but this entire project is built on the agent being a trustworthy discernment engine. This could look one of two ways:
      • Up-front:
           navigator.modelContext.registerTool({
             name: "search-flights",
             // ...
             userActivationJustification: "Opens a popup with flight results, which requires user activation"
           });
      • Mid-way through execution: via ModelContextClient#requestUserActivation(). This would be a new API in contrast with requestUserInteraction(). It requests agent consent to user activation partway through tool execution.
      • I prefer up-front, since it's much simpler.
    • How does this relate to ModelContextClient#requestUserInteraction()?
      • It seems there's no overlap. I'm actually not sure what that API does at all—its example puts the result of the "user interaction" entirely in the control of the tool, so I'm not sure why that API exists as opposed to just having the tool flash some UI itself. Either way, this is probably out of scope here.
  7. johannhof commented on Mar 19, 2026

    @johannhof
    Contributor

    I still think user activation is inherently the wrong concept to use here. What you really want is "trigger some powerful features when an agent requests them". That is different from "user activation", just because user activation is the only thing that gates them so far.

    I would be supportive of creating a concept such as "agent activation" which causes similar effects but can be made distinct from user activation in cases where it makes sense.

  8. insforca commented on Jun 1, 2026

    @insforca

    We're integrating WebMCP on MapVibe — a Shopify-embedded map poster editor — and this issue directly addresses a question we ran into during implementation. Sharing our concrete use case in case it's useful for the per-API analysis.

    Our scenario: add_to_cart tool bridged through postMessage

    The Shopify cart API lives in our storefront JS context (mapvibe-bridge.js), separate from the editor. Our WebMCP tool flow is:

    WebMCP add_to_cart execute()
      → postMessage MAPVIBE_ADD_TO_CART to mapvibe-bridge.js
      → bridge calls fetch('/cart/add.js', { method: 'POST', ... })
      → on success: postMessage MAPVIBE_CART_SUCCESS back to editor
      → tool returns { cart_url }
    

    What we found: fetch() doesn't require transient activation, so this works today without any intervention. This is a direct example supporting the per-API approach @domfarolino outlined — the right question is "which specific APIs need activation", not "should WebMCP tools blanket-get activation".

    Where activation will matter for us in the future:

    If we add a tool that opens a native file download dialog or calls window.open() for a print preview, we'd hit the activation gate. The userActivationJustification field in registerTool() is exactly the right shape for this — we'd declare it upfront:

    navigator.modelContext.registerTool({
      name: 'open_print_preview',
      userActivationJustification: 'Opens a popup window with the print-resolution poster, which requires user activation',
      // ...
    });

    This lets the agent reason about the justification before calling the tool and communicate it to the user transparently. Much cleaner than discovering the gate at runtime.

    On "agent activation" as a distinct concept:

    @johannhof's framing resonates with us. Our agents aren't simulating clicks — they're acting on explicit user intent ("make me a poster of Tokyo and add it to cart"). A distinct agentActivation concept that's traceable to a specific user request would be more honest than aliasing onto userActivation, and it would let browsers make nuanced decisions per API (e.g., waive activation for fetch, still prompt for camera/mic).

    Happy to share more implementation details if useful for the per-API review.

  9. insforca commented on Oct 31, 2026

    @insforca

    I need to correct my June 1 comment here. I described our add_to_cart flow as working today, and it doesn't.

    Re-reading the code: the editor runs in an iframe on our Shopify storefront, but the tool posts MAPVIBE_ADD_TO_CART to its own window, with the storefront's origin as targetOrigin. The browser drops that message, so the parent page that owns the cart never sees it, and the tool resolves with success after a 15 s fallback timer regardless. So activation never came up, and my fetch() remark was beside the point. What actually failed was crossing a frame boundary and reporting success without confirmation.

    Two things from that bear on this thread.

    First, I set a non-standard requiresUserActivation: true on add_to_cart, assuming Chrome would show a confirmation dialog. I never verified that, and it mixes up two ideas. Activation unlocks gated APIs. Confirmation is the user approving a purchase. The current spec already has consequentialHint for the second, which is what that tool should use. I'd support keeping any agent activation concept separate from it.

    Second, for embedded apps, would a tool registered by the cart-owning parent frame, using exposedTo and fromOrigins, be the intended pattern instead of a postMessage bridge? That is what I would try next.

    My code was written against an earlier API shape (navigator.modelContext.registerTools, handler, input) and hasn't been ported to document.modelContext.registerTool with inputSchema and execute yet. Editor: https://app.mapvibestudio.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions