Unlike many MCP servers, where the available tool set is relatively stable for the lifetime of the server, WebMCP tools may change frequently as the user moves through a site:
- Framework components mount and unmount
- Async hydration completes after the page's
load event
- SPA navigations / route changes
- Full-on MPA navigations
- Changes in UI state that usher in new tools and unregister irrelevant ones
In our experience, agents operating web pages generally have a heuristic for deciding when a page has "loaded" or "settled" enough to create a page observation for the model, including the page's list of WebMCP tool.
The problem is that registration of all of a site's relevant tools might not be synchronized with the agent's page-stability heuristic. A page may "look ready" to the agent while an important batch of tools is still being registered, and an observation might then end up with a partial view of relevant tools designed for it.
Based on how we've seen agents being built, we anticipate this will be an issue, but we'd love feedback from other real-world browser-use agents to know if this problem statement resonates. We'd love to get a signal from at least the following folks:
Does your experience with browser agents resonate with the issue described above, whether related to WebMCP or beyond it? Would your agents benefit from letting developers provide input to existing page/tool stability heuristics?
We propose an API to let developers signal to any listening agents:
"My currently registered tools are still in flux. If you are about to take an initial or refreshed observation of my tools, please wait until I signal that this transition is complete."
We don't intend to standardize how page observations are taken. This is just about giving developers a way to provide a signal that agents can incorporate in their observation heuristics.
Example problem
Consider a page whose initial HTML becomes interactive before its WebMCP-specific code finishes loading:
// The page may already appear "loaded" or "settled" to an agent.
await import("./webmcp-tools.js");
document.modelContext.registerTool({
name: "search_products",
// ...
});
document.modelContext.registerTool({
name: "issue_refund",
// ...
});
document.modelContext.registerTool({
name: "add_review",
// ...
});
If the agent decides to observe the page between page readiness and completion of these registrations, the model may see only a partial tool set.
A similar issue can occur during SPA navigations, where a route transition causes one group of tools to disappear and another group to be registered asynchronously.
Strawman API proposal
One possible shape is an explicit begin/end signal:
const stability = document.modelContext.beginToolUpdate();
try {
const tools = await import("./webmcp-tools.js");
await tools.register();
} finally {
stability.end();
}
While the tool-update scope is active, the page is indicating that its registered tool set should not yet be considered stable. The API could be nestable so that independent components can participate without coordinating through a single global promise:
const a = document.modelContext.beginToolUpdate();
const b = document.modelContext.beginToolUpdate();
a.end();
// Tool set is still unstable.
b.end();
// Tool set is now stable.
The browser should impose an upper bound on how long an outstanding stability signal can delay an observation, and agents will likely need their own preotections regardless. Both of these mreasures prevent a broken (or misbehaving) page from indefinitely blocking an agent.
(Disclaimer: the exact shape of the API above are only illustrative and are very up for debate).
SPA and dynamic transitions
One of the most common use cases for this API would be during SPA navigations, which are common on the web, and where agent page stability heuristics are likely to vary a lot:
async function navigate(path) {
const update = document.modelContext.beginToolUpdate();
try {
await router.navigate(path);
await registerToolsForRoute(path);
} finally {
update.end();
}
}
Initial page load
To signal tool instability on initial page load, I think we have two options:
- Force developers to call
beginToolUpdate() super early, in <head> JavaScript for example; or
- Provide a declarative,
<meta> tag way to load a page with an immediate signal of tool instability, and make developers signal the end of that imperatively with JS
<meta name="tool-stability" content="pending">
<script>
await App.slowHydration(); // Loads lots of tools asynchronously.
document.modelContext.toolsAreStable();
</script>
Alternatives considered: "tool snapshot requested" event
Another possible design is for the browser to fire an event immediately before it intends to observe tools:
[SecureContext, Exposed=Window]
interface ToolObservationEvent : Event {
undefined waitUntil(Promise<any> promise);
};
partial interface ModelContext {
attribute EventHandler ontoolobservation;
};
A page could then delay the agent's observation with waitUntil(). This is attractive because it directly synchronizes the page with an observation attempt. But it assumes that agents have a discrete "tool snapshot" step that the browser can expose, and achieves the same thing as our above proposal, while unnecessarily exposing implementation details of the agent. It also gets confusing to developers when there are multiple agents driving a page.
The developer would likely use this API like this:
window.toolsAreStable = true;
async function loadMoreTools() {
window.toolsAreStable = false;
// Load more tools
// ...
window.toolsAreStable = true;
}
document.modelContext.ontoolsnapshotrequested = e => {
if (!window.toolsAreStable) {
e.waitUntil(/*some promise*/);
}
// Otherwise, do nothing.
}
In this case, the developer isn't interested in knowing when the agent is grabbing the list of tools, or how many agents are grabbing the list of tools. Instead, they're maintaining their own tool stability bookkeeping that simple gets surfaced to the agent through the event, making the event unimportant in the exchange.
Relationship to toolchange
Agents can still react incrementally to toolchange throughout the lifetime of the document, but since we've observed that an agent's heavy "page snapshot" / "page observation" infrastructure is unlikely to take place on every toolchange event, we still wind up with the page observation gap that motivates this issue.
Unlike many MCP servers, where the available tool set is relatively stable for the lifetime of the server, WebMCP tools may change frequently as the user moves through a site:
loadeventIn our experience, agents operating web pages generally have a heuristic for deciding when a page has "loaded" or "settled" enough to create a page observation for the model, including the page's list of WebMCP tool.
The problem is that registration of all of a site's relevant tools might not be synchronized with the agent's page-stability heuristic. A page may "look ready" to the agent while an important batch of tools is still being registered, and an observation might then end up with a partial view of relevant tools designed for it.
Based on how we've seen agents being built, we anticipate this will be an issue, but we'd love feedback from other real-world browser-use agents to know if this problem statement resonates. We'd love to get a signal from at least the following folks:
Does your experience with browser agents resonate with the issue described above, whether related to WebMCP or beyond it? Would your agents benefit from letting developers provide input to existing page/tool stability heuristics?
We propose an API to let developers signal to any listening agents:
We don't intend to standardize how page observations are taken. This is just about giving developers a way to provide a signal that agents can incorporate in their observation heuristics.
Example problem
Consider a page whose initial HTML becomes interactive before its WebMCP-specific code finishes loading:
If the agent decides to observe the page between page readiness and completion of these registrations, the model may see only a partial tool set.
A similar issue can occur during SPA navigations, where a route transition causes one group of tools to disappear and another group to be registered asynchronously.
Strawman API proposal
One possible shape is an explicit begin/end signal:
While the tool-update scope is active, the page is indicating that its registered tool set should not yet be considered stable. The API could be nestable so that independent components can participate without coordinating through a single global promise:
The browser should impose an upper bound on how long an outstanding stability signal can delay an observation, and agents will likely need their own preotections regardless. Both of these mreasures prevent a broken (or misbehaving) page from indefinitely blocking an agent.
(Disclaimer: the exact shape of the API above are only illustrative and are very up for debate).
SPA and dynamic transitions
One of the most common use cases for this API would be during SPA navigations, which are common on the web, and where agent page stability heuristics are likely to vary a lot:
Initial page load
To signal tool instability on initial page load, I think we have two options:
beginToolUpdate()super early, in<head>JavaScript for example; or<meta>tag way to load a page with an immediate signal of tool instability, and make developers signal the end of that imperatively with JSAlternatives considered: "tool snapshot requested" event
Another possible design is for the browser to fire an event immediately before it intends to observe tools:
A page could then delay the agent's observation with
waitUntil(). This is attractive because it directly synchronizes the page with an observation attempt. But it assumes that agents have a discrete "tool snapshot" step that the browser can expose, and achieves the same thing as our above proposal, while unnecessarily exposing implementation details of the agent. It also gets confusing to developers when there are multiple agents driving a page.The developer would likely use this API like this:
In this case, the developer isn't interested in knowing when the agent is grabbing the list of tools, or how many agents are grabbing the list of tools. Instead, they're maintaining their own tool stability bookkeeping that simple gets surfaced to the agent through the event, making the event unimportant in the exchange.
Relationship to
toolchangeAgents can still react incrementally to
toolchangethroughout the lifetime of the document, but since we've observed that an agent's heavy "page snapshot" / "page observation" infrastructure is unlikely to take place on everytoolchangeevent, we still wind up with the page observation gap that motivates this issue.