Skip to content

Make tools Document-scoped instead of Window-scoped #173

Closed

Description

@domfarolino

It's important that tools are document-scoped. Most of the time Window/Navigator and Document are 1:1, however navigations away from the initial about:blank Document share a Window object, which complicates things.

The case where this is observable is when you register tools with the initial about:blank Document, and then navigate away from it. Per the current spec, after the navigation, calls to navigator.modelContext return the same object that holds the same map of tools, which means tools are effectively shared across this navigation.

I recently caught this bug in Chromium when working on the iframe + permission policy implementation, and ended up changing Blink's implementation such that:

  1. The backing ModelContext interface object is stored on Document instead of Navigator
  2. The navigator.modelContext IDL getter doesn't just return the same object; instead it consults its Window's active Document, and returns its ModelContext object. It returns null if the Window isn't available (detached document) or if the document isn't fully active (bf-cache).

I'll update the spec to agree with this.


Follow-up: API placement

An oddity of the above is that the API is effectively scoped to the Document, yet it lives off of navigator. I personally never liked putting things on navigator, and would recommend that we do one of two things:

Activity

  1. self-assigned this
    on Apr 28, 2026
  2. bwalderman commented on Apr 28, 2026

    @bwalderman
    Collaborator

    I agree document is the most intuitive as far as web pages go. If we eventually do implement WebMCP in service workers though, I'm not sure where the best home for modelContext would be, if not Navigator. Maybe self?

  3. domfarolino commented on May 1, 2026

    @domfarolino
    CollaboratorAuthor

    Good point about eventual Worker-exposed tools. The global (self) would make sense to cater to all contexts, but if the options really becomes self vs navigator, I'm wondering if we should even bother moving it at all...

  4. bwalderman commented on May 1, 2026

    @bwalderman
    Collaborator

    The global (i.e. self, window) may be the right compromise here. We could expose the modelContext namespace there but use the currently active document as the backing storage so that tools aren't pesisted across navigations.

  5. domfarolino commented on May 18, 2026

    @domfarolino
    CollaboratorAuthor

    Hmm, but that's no different from keeping it on navigator, except for the fact that self is just more "general", but with more risk of collision.

  6. domfarolino commented on May 20, 2026

    @domfarolino
    CollaboratorAuthor

    I spoke with the TAG and they recommended that we move the modelContext object to document, which I am supportive of, with a still-reasonable path for extending to workers in the future: w3ctag/design-reviews#1231 (comment). Does anyone object?

  7. domfarolino commented on May 20, 2026

    @domfarolino
    CollaboratorAuthor

    I spoke with the TAG and they recommended that we move the modelContext object to document, which I am supportive of, with a still-reasonable path for extending to workers in the future: w3ctag/design-reviews#1231 (comment). Does anyone object?

  8. bwalderman commented on May 21, 2026

    @bwalderman
    Collaborator

    SGTM. Thanks for bringing this to the TAG.

  9. beaufortfrancois commented on May 21, 2026

    @beaufortfrancois
    Collaborator

    I do think self.modelContext could be potentially confusing given window.self in https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-self but we'll see. I won't oppose to document.modelContext.

  10. domfarolino commented on May 21, 2026

    @domfarolino
    CollaboratorAuthor

    Well self.modelContext would mean the same thing as window.modelContext, since they are the same object. But lots of APIs hang off of window without too much confusion. Do you think that's alright?

  11. beaufortfrancois commented on May 22, 2026

    @beaufortfrancois
    Collaborator

    I meant some developers (or agents nowadays) could be confused because they see self.modelContext without realizing they're in a worker context and start using it now in a window context which suddenly doesn't work because window.self.modelContext is not a thing IIUC, only window.self.document.modelContext right?

  12. domfarolino commented on May 22, 2026

    @domfarolino
    CollaboratorAuthor

    That's correct. But you'll have to know what context you're in even if we put the API on self. You need to know that just because self.modelContext exists, you can't always run:

    self.modelContext.registerTool({
      name: "scrape_dom",
      description: "the DOM scraper"
      async execute() => document.querySelector('body').textContent;
    })

    because the DOM doesn't exist in workers.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions