Skip to main content
Engineering 2026-07-07

See What a WebMCP Agent Changed on Your Page

MCP Trail

MCP Trail Team

Developer Relations

See What a WebMCP Agent Changed on Your Page

See What a WebMCP Agent Changed on Your Page

Short answer: When a WebMCP agent calls a tool, the edit happens with no cursor and no click — it’s invisible. @mcptrail/webmcp-highlight makes it visible: it wraps each tool call as a transaction, diffs the DOM before and after, and draws an overlay ring around exactly what changed, with a change timeline, off-screen reveal that scrolls the change into view, and an aria-live announcement for screen readers. It’s zero-config — theme colors are inferred from your page — and it’s the one library in this set already published to npm.

A human editing your page leaves a trail: a cursor moving, a button depressing, a field lighting up on focus. An agent leaves none of that. It calls update_cart and three prices change somewhere in the DOM, silently, with nothing to tell you where. That’s disorienting for you as a developer and invisible to a user relying on assistive tech. This library restores the trail. (For the API underneath, see What is WebMCP?.)

The problem: agent edits are invisible

Every affordance we rely on to follow a change on a web page assumes a human is making it. Agents break that assumption completely.

  • No cursor. Nothing moves toward the thing being changed.
  • No click or focus. The element that changed never lights up.
  • No locality. A single tool call can touch several elements at once, scattered across the page — some of them off-screen entirely.

The result: an agent does real work — updates a total, adds a row, changes a status — and you’re left scanning the page trying to spot what’s different. For a screen-reader user, “what’s different” may never be announced at all.

One call to make changes visible

@mcptrail/webmcp-highlight (github.com/ElBartoTn/webmcp-highlight, MIT — already on npm) wraps your tool calls and outlines whatever they touch.

npm install @mcptrail/webmcp-highlight
import { createWebMcpHighlight } from "@mcptrail/webmcp-highlight";

const wmh = createWebMcpHighlight();
wmh.autoWrapRegisterTool();   // every tool call now diffs the DOM and highlights changes

createWebMcpHighlight() sets up the overlay, and autoWrapRegisterTool() patches navigator.modelContext.registerTool so every tool — present and future — runs inside a transaction. When a call finishes, the library diffs the DOM against the snapshot it took before the call and draws a ring around each element that changed. No per-tool wiring, no list to maintain.

What the overlay shows

The highlight is more than a colored border. Each of these is on by default:

FeatureWhat it does
Overlay ringDraws an outline around every element a tool call changed
Change timelineA running list of calls and what each one touched, so you can step back through history
Off-screen revealIf a change happened below the fold, scrolls it into view so you never miss it
aria-live announcementAnnounces the change to screen readers, so assistive tech users hear what the agent did
Theme inferenceReads your page’s colors and picks a ring that stands out — zero config

The timeline matters most when an agent chains several calls: instead of one confusing final state, you get an ordered record of each step and its effect. The aria-live announcement is what makes agent actions accessible, not just visible — the change is spoken, not only drawn.

Pair it with the devtools panel

Highlight tells you what changed; it doesn’t give you a way to trigger a call during development. Pair it with @mcptrail/webmcp-devtools and you get both: a panel to invoke any tool by hand, and the overlay showing what that invocation changed.

import { createWebMcpHighlight } from "@mcptrail/webmcp-highlight";
import { createWebMcpDevtools } from "@mcptrail/webmcp-devtools";

const wmh = createWebMcpHighlight();
wmh.autoWrapRegisterTool();   // outline what changes
createWebMcpDevtools();       // a panel to trigger calls by hand

That’s the full loop: trigger a tool from the devtools panel, watch the ring land on what it changed, and step through the timeline if it touched more than one thing.

From seeing changes to approving them

Making agent changes visible is the first step toward controlling them. Once you can see what a tool call did, the natural next question is: should it have been allowed to? That’s the client-side approval pattern — pause a risky call and let a human confirm before it runs.

Highlight funnels naturally into governance. Seeing changes on the page leads directly to approving them before they happen: locally with client-side approvals for WebMCP, and across your whole toolset with MCP Trail, which adds policy, human-in-the-loop approvals, drift attestation, and audit logs so every agent action is accountable — not just visible. Visibility is where trust starts; governance is where it’s enforced.

FAQ

How does it know what an agent changed?

It diffs the DOM. Before a tool call runs, the library snapshots the relevant part of the page; after the call completes, it compares the two and identifies exactly which elements changed. Each of those gets an overlay ring. Because it wraps the call as a transaction, the “before” and “after” are precisely bracketed around that one tool invocation.

Do I have to wrap each tool by hand?

No. Call wmh.autoWrapRegisterTool() once and it patches registerTool, so every tool your app registers — now and in the future — runs inside a highlight transaction automatically. There’s no per-tool configuration and no list to keep in sync as you add tools.

Is it accessible for screen-reader users?

Yes — that’s a core feature, not an afterthought. Alongside the visual ring, each change fires an aria-live announcement, so a screen-reader user hears what the agent changed rather than being left with a silently updated page. Off-screen changes are also scrolled into view, so nothing important happens out of sight.


Explore features · Open MCP Trail

Share this article