WebMCP

WebMCP Meets Headless Agent: How Firecrawl Bridges the Browser Gap

Chrome's own docs say headless browsers cannot call WebMCP tools yet. A walkthrough of the tool model, the Chrome 157 timeline, and how Firecrawl interact bridges the gap with a real cloud browser.

WebMCP Meets Headless Agent: How Firecrawl Bridges the Browser Gap — article cover
On this page8 SECTIONS
  1. WebMCP: Websites Declare Their Own Agent Tools
  2. The Hard Limit Chrome Draws: No Headless Calls
  3. The Local Alternative: agent-browser and Its Cost
  4. Firecrawl Interact: A Real Browser in the Cloud
  5. The Booking Demo: One Tool Call, End to End
  6. A Spec Still in Motion, and Two Engineering Red Lines
  7. Builder Guidance
  8. Sources

For an agent, today’s web is still built for humans: to book a restaurant table it has to scrape the form HTML, identify the name, phone, date, and party-size fields, fill them one by one, and verify the result with screenshots or DOM checks. Every run rebuilds its understanding of the page, token cost grows with the number of fields, and a redesign often breaks the flow.

The Firecrawl WebMCP demo flips the direction: instead of training agents to operate human interfaces better, let websites declare the tools an agent may use. This piece walks the WebMCP tool model, the hard limit Chrome draws for headless environments, and how Firecrawl closes the gap with a real cloud browser.

WebMCP: Websites Declare Their Own Agent Tools

WebMCP is a web platform proposal from engineers at Google and Microsoft: developers register tools on the page with JavaScript (HTML declarations are planned), and each tool carries a name, a description, a JSON Schema inputSchema, and the execute logic that actually runs it — exactly like a regular MCP tool. The registration API is document.modelContext.registerTool; required fields are explicit in the schema, so the agent never scrapes the DOM to guess the form structure.

The demo’s restaurant booking turns multi-field form-filling into a single book_table_le_petit_bistro tool call. The execute function receives validated arguments, fills the form fields, and runs the page’s own validateForm(). Failed validation returns isError: true with the error; success shows a confirmation modal and returns the reservation text. On the discovery side, document.modelContext.getTools() lists the page’s registered tools (name, description, inputSchema), and document.modelContext.executeTool() invokes one by name with JSON arguments.

The Hard Limit Chrome Draws: No Headless Calls

The spec looks complete; the problem is where it runs. Chrome’s WebMCP docs, as relayed by the article, state plainly: there is no support for agents to call these tools in a headless browser. The agent must drive a live browser directly, and the browser has to onboard the agent. A terminal harness like Claude Code has no real tab to operate, so it cannot even see what a site has registered.

The timeline sharpens the awkwardness. WebMCP is expected to ship natively in Chrome 157 (per the article, roughly November 2026 for stable), but at writing time stable Chrome is only at 150; the feature rolls out behind a flag and through origin trials, and today’s demo depends on the @mcp-b/webmcp-polyfill package. Even when native support lands, until the headless restriction lifts, Claude Code stays on the wrong side of the door.

The Local Alternative: agent-browser and Its Cost

Vercel Labs’ agent-browser is the local route: it runs a browser you can drive with code on your machine, and agent-browser eval executes JavaScript inside the page — equivalent to calling getTools() and executeTool() from the console.

The cost is on the deployment side: the machine needs a real browser, and the first run downloads Chrome for Testing. Inside a CI pipeline, a locked-down workstation, or a cloud runtime, installing and maintaining a browser is rarely practical.

Firecrawl Interact: A Real Browser in the Cloud

Firecrawl’s role is to close that gap: the interact endpoint runs a real browser in Firecrawl’s cloud, so a headless harness gets a live tab without shipping a browser itself. Control comes two ways — describe intent in a prompt, or execute code directly — and the browser lives in Firecrawl’s cloud sandbox with zero local installs.

The flow is scrape, then interact: call scrape with maxAge: 0 to force a real browser load and obtain a scrapeId — a cache hit returns a scrapeId with no live session behind it — then run interact against that same scrapeId, and finish with stopInteraction. The interact code runs inside the cloud browser, where page is a connected session’s Playwright Page; Node Playwright is the default code mode, with Python Playwright and the bash agent-browser command also supported.

// 1. discover — list tools registered by the page
const tools = await page.evaluate(() => document.modelContext.getTools());
// 2. execute — arguments travel base64-encoded, decoded in-page
const result = await page.evaluate(async (b64) => {
  const tool = (await document.modelContext.getTools())
    .find((t) => t.name === "book_table_le_petit_bistro");
  return document.modelContext.executeTool(tool, atob(b64));
}, argsB64);

Tool arguments travel base64-encoded (argsB64) and are decoded inside the page with atob, keeping quoting reliable across Firecrawl’s transport. From the agent’s perspective, the whole thing is a single tool call proxied through a headless-friendly API. The approach works purely because the cloud side is a real browser — WebMCP already works there, and Firecrawl needs no special integration of its own.

The Booking Demo: One Tool Call, End to End

The demo site is adapted from Google’s French Bistro demo: the author first removed the site’s existing tools as the before baseline — the agent was left with the slow path of scraping every input, filling each one, and verifying with screenshots — then added the tool back on a stage-1 branch. A small runner wraps discovery and execution, and Claude Code is pointed at it. Asked to book a table for two next Thursday, the agent finds the tool and identifies the missing fields (time, phone) — which the source warns it may ask you for or simply make up — and completes the reservation in one call, with no local browser, no scraping, and no screenshots.

A Spec Still in Motion, and Two Engineering Red Lines

Every step of this approach stands on a moving floor. The API namespace has already changed from navigator.modelContext to document.modelContext, and plain HTML tag declarations are on the roadmap — discovery scripts like the one above will need rewriting. Two engineering red lines belong in your defaults: every scrape-interact pair requires a live session, so maxAge: 0 cannot be skipped; and while base64-encoded arguments are reliable, they add an encoding layer you must remember when debugging.

Builder Guidance

Three judgments to take away. First, site owners can register tools with the polyfill today: a tool interface is more stable than page structure, and the investment carries straight into native support. Second, agent builders should wrap interact behind a single, governed tool: a fixed allowlist of sites, validated input schemas, restricted actions, and operation logs — headless is just an execution location, and governance cannot be headless with it. Third, watch Chrome 157 and the spec’s motion: until there is an official headless story, the real-cloud-browser route is the most practical bridge where a harness cannot ship a local browser — a way to use WebMCP today.

Sources

AI-assisted summary compiled from the sources above, reviewed by a human before publishing.

SHAREXEMAIL