deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

TrickyBird disables WebMCP on proxied pages before exposing one open_site tool

A dev.to build note explains how the TrickyBird web proxy had to block WebMCP tool registration across proxied frames before it could safely expose a single open_site tool to browser agents.

TrickyBird disables WebMCP on proxied pages before exposing one open_site tool

A proxy flattens the isolation WebMCP relies on

The developer behind TrickyBird, a web proxy, has published a build note on dev.to describing what the service had to change before it could offer a WebMCP tool to browser agents — and the first change was switching the capability off everywhere else.

WebMCP lets a page hand the browser's agent a real function instead of a DOM to interpret, through a call to document.modelContext.registerTool with a name, description, input schema and execute callback. The feature sits behind a Permissions Policy whose default is self. On an ordinary site that default provides isolation for free: an advertisement frame is a different origin, so it cannot register anything into the host page.

A proxy destroys that assumption. According to the author, every frame on a proxied page — the content and its ads alike — is served from the proxy's own origin, so self covers all of them. A frame belonging to whichever site a reader had opened could register a tool, and the agent would then invoke it inside that reader's session.

Locking tools down before turning one on

The first WebMCP change TrickyBird shipped was a refusal. The gateway now declares tools=() in the Permissions-Policy header of every document it serves. With WebMCP enabled by flag, registerTool on a proxied page rejects with NotAllowedError, and so does a call from a freshly created about:blank frame — the very case the flattened origin model would otherwise have admitted. The author states both behaviours were measured in Chrome 152.

On top of the header, an injected shim deletes document.modelContext from proxied pages, so a site that probes for the API discovers it is absent rather than present-but-refusing. The header is what actually enforces the restriction, the author notes, because any realm the shim fails to reach still inherits it.

The one tool it does expose

The tool itself lives on TrickyBird's home page, which serves only the company's own HTML. Called open_site, it accepts an address, runs the same validation the page's form already uses, and navigates the tab to the proxied result. Input that is not a site is rejected, and the author emphasises that it never performs a search.

A promise that isn't always a promise

The note also records a bug worth copying if you ship the same pattern. The draft specification says registerTool returns a promise, and the original effect hook was written for that: chain a .catch, then return the cleanup. On some Chrome OS and Edge builds, however, the call returned undefined instead; .catch then threw inside the effect before any cleanup existed, and the next mount of the page raised InvalidStateError with a duplicate tool name.

The fix is a single line of defensive shaping: wrap the call in Promise.resolve() inside a try block, so a rejection, a synchronous throw and a bare undefined all settle the same way and the cleanup is always returned.

How the result was checked

Two verifications are offered. Lighthouse 13.4.1 includes an agentic-browsing category, where the home page scores 1, unchanged from before the tool existed; the registration table lists open_site and the schema validity audit also scores 1. Separately, Chrome 152 lists open_site on trickybird.com.

Expectations are deliberately modest. The author writes that the only consumer available today is the ChatGPT desktop browser, and that none of its user agents have appeared in TrickyBird's own traffic — although it is not required to identify itself, so that absence may mean less than it sounds.

Why it matters

This is one of the first practical accounts of what WebMCP means for services that serve other people's content under a single origin. The self default that protects ordinary sites offers nothing to proxies, HTML-rewriting layers or embedding services; any of them exposing agent tools will likely need the same header-based opt-out before exposing anything of their own.

The note also documents real implementation drift in a young API: something specified as promise-returning behaves differently across Chrome OS and Edge builds, and the defensive wrapping pattern is a useful reference for anyone calling registerTool before the spec settles.

Finally, it is a reminder of where adoption actually stands. With agent traffic still effectively invisible to publishers, integrating WebMCP early is a bet on how the ecosystem will take shape, not a play for measurable users today.

  • #webmcp
  • #permissions-policy
  • #browser-agents
  • #web-proxy
  • #chrome