deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Chrome extension lets Claude Code call a site's WebMCP tools remotely

A dev.to post by AgentRQ describes a Chrome extension that exposes a page's WebMCP tools to outside MCP agents like Claude Code, which can then run calls in your signed-in browser tab while writes wait for human approval.

Chrome extension lets Claude Code call a site's WebMCP tools remotely

What the extension does

WebMCP is a young browser standard that lets a page offer tools to AI agents by registering them on document.modelContext, each with a name, a description and a JSON Schema for its input. According to a dev.to post by AgentRQ, the team behind the tool, that design leaves a limit open: the tools live in the page's JavaScript, so only an agent running in that same tab can reach them. A terminal session of Claude Code, an agent on a build machine, or a job woken by cron elsewhere has no access.

The Chrome extension AgentRQ describes closes that gap. Share a site with a workspace via the extension's popup, and any MCP client — Claude Code, Codex or another agent — can discover and call that site's tools from anywhere. The call still executes inside your signed-in tab, and anything that modifies state pauses for your approval. The same popup shows the live terminal of every connected agent on every linked machine.

Observing without impersonating

The obvious approach — injecting a modelContext object and watching what the page puts in it — was rejected, the post explains, because the extension would then decide which pages get WebMCP, and a page that feature-detects the API would detect the extension instead of Chrome. Instead, a small observer script runs in the page's own JavaScript world at document start and wraps the browser's native registerTool, recording what is registered while letting calls pass through to Chrome. If the browser has no modelContext, the observer stays inert.

Three edge cases mattered: pages can withdraw tools through an AbortSignal, and in-flight calls then fail with a clear error rather than hanging; re-registering a name replaces the older tool; and descriptors that cannot survive JSON serialization are dropped, since they could never be described to a remote agent.

Crossing the content-script boundary safely

Content scripts run in two worlds: the main world shares JavaScript with the page but cannot use extension APIs; the isolated world can, but cannot see page objects. The design therefore needs two scripts talking over the DOM, which the page can also observe. A fixed event name would let any page eavesdrop on calls or forge results. Instead, the isolated-world bridge generates a random UUID, drops it on the html element as a data attribute, and the observer reads and deletes it before page scripts run. Every message travels as a CustomEvent whose event type is that nonce, so the page cannot subscribe or forge. The observer also caches references to dispatchEvent, CustomEvent and JSON at startup to resist later patching. One subtle gotcha the team hit: Chrome orders document-start scripts by registration ID rather than registration order, so the bridge's ID has to sort before the observer's.

Reaching a browser behind NAT

A server cannot reach a browser behind NAT, so the browser dials out: the extension's Manifest V3 service worker opens a WebSocket to the AgentRQ server. Per the post, that raised three problems. Service-worker sockets carry no cookies, solved by first obtaining a one-minute ticket with the normal sign-in cookie. Chrome kills idle workers, and server pings do not count as traffic, so the worker pings every 20 seconds itself. The socket only opens while at least one site is shared, reconnecting with backoff from one to thirty seconds.

Tabs, navigation and token budgets

The worker routes each call to the most recently used tab of that origin that offers the tool, and reopens the site in a background tab if you have closed them all. Calls are tracked per document rather than per tab, because after a cross-site navigation the new page can announce its tools before the old page's unload event arrives. The back/forward cache restores pages without re-running scripts, so the bridge re-announces its saved tool list on a persisted pageshow.

To protect the agent's context window, the MCP surface is split into listSiteTools (names and descriptions only), getSiteToolDefinition (one full schema on demand) and callSiteTool. The server validates arguments against the page's own schema before anything reaches the browser, so malformed calls fail fast; calls have a 60-second deadline and results are capped at 256 KiB.

Why it matters

The security model is the most interesting part. The remote agent acts with your session but never sees a password, cookie or API token — to the site, it is just you in your tab using a tool the site chose to offer. Read-only tools run automatically, anything else asks first, with per-site and per-tool “always allow” options, and every write is tied to a visible taskId. Only a human can share a site, and detection is off by default. More broadly, this sketches where browser-exposed AI tooling is heading: websites become tool providers not just for in-tab assistants but for the agents doing real work in terminals and on servers, with the browser acting as the authenticated, user-supervised execution environment. The account is first-person and self-reported by the extension's builders, so the engineering claims await independent verification, but the architecture is a credible blueprint for remote access to WebMCP.

  • #mcp
  • #webmcp
  • #chrome-extension
  • #claude-code
  • #ai-agents
  • #browser

Related posts