Browser session

A browser session (pipeline/browser/bridge.js) is the pipeline's only path to a web page. The pipeline never launches its own browser and never touches a local browser profile: every page action goes through an MCP server the config declares, Weles or the Playwright MCP server.

Which layer runs

The config's browser section declares exactly one layer:

  • browser.weles drives Weles through its MCP stdio server. command and args start it (weles-mcp when command is absent); headless and engine are passed to Weles when the browser starts. Every key is optional.
  • browser.playwright_mcp drives the Playwright MCP server, for a user without Weles. command and args are required; the studio selectors are passed to the server as Playwright targets, and an evaluated value is read from the Result section of its browser_evaluate reply.

No browser section, an empty one, any other key under browser, or both layers is refused by name before anything starts.

Shape

  • McpStdioClient (pipeline/host/weles.js) — a JSON-RPC 2.0 client over a spawned MCP stdio server, shared by both layers and by the Blender session. The child gets PATH and HOME only, so no credential of the pipeline leaks through inheritance. A request settles with the server's answer, or fails when the server exits.
  • WelesBrowserSession — one Weles browser slot end to end: weles_browser_start → weles_page_new per page → weles_browser_close plus process shutdown. WelesPage wraps goto, text, click(selector), fill(selector, value), screenshot(path) and evaluate(expression).
  • PlaywrightMcpSession (pipeline/browser/playwright_mcp.js) — one page, the server's current tab, with the same page operations.

Weles answers each tool with one text item holding a JSON object; the session reads browserId and pageId from it, and a reply without them is refused quoting the reply.

Lifecycle

Only the studio job opens browser sessions. The session is closed in a finally, so a failed job never leaks a browser slot.

Refusals

  • no browser layer is configured: declare browser.weles to drive Weles, or browser.playwright_mcp (command, args) to drive the Playwright MCP server without Weles; the browser section is empty: …; browser.<key> is not a browser layer: …; both browser.weles and browser.playwright_mcp are declared: keep the one this pipeline uses; browser.<layer> must be an object, got <value>.
  • browser.playwright_mcp.command must name the program that starts the Playwright MCP server; browser.playwright_mcp.args must be a list of strings, got <value>.
  • MCP server <command> process failed to start: <reason> — the program is not on PATH or died at spawn; MCP server <command> process exited (code N, signal S) — every pending request fails with it.
  • MCP server <command> answered error <code>: <message>; MCP server <command> tool <name> failed: <content>.
  • weles MCP reply carries no browserId (or pageId), weles MCP reply is not one text item, weles MCP reply is not JSON (<reason>): <text>.
  • playwright MCP browser_evaluate reply has no Result section: <text> and playwright MCP browser_evaluate Result is not JSON (<reason>): <body>.

Environment

Both servers receive only PATH and HOME. Credentials are not passed to the browser layer's environment; the studio job fills them into the page from the resolved config — see configuration.