browser_surface
Control browser automation in parallel AI agent workspaces to open pages, interact with elements, execute scripts, and capture screenshots.
Instructions
Interact with a browser surface (open, navigate, snapshot, click, type, eval, wait)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Browser action to perform | |
| surface | No | Target surface ref | |
| workspace | No | Target workspace ref | |
| url | No | URL for open/goto actions | |
| selector | No | CSS selector for click/type/wait actions | |
| text | No | Text for type action | |
| script | No | JavaScript for eval action | |
| timeout_ms | No | Timeout for wait action |
Implementation Reference
- src/server.ts:544-617 (handler)The handler for the browser_surface tool. It processes the action and arguments, prepares command-line arguments for the browser client, and executes the call.
async (args) => { try { const browserArgs: string[] = []; if (args.surface) { browserArgs.push("--surface", args.surface); } switch (args.action) { case "open": browserArgs.push("open"); if (args.url) { browserArgs.push(args.url); } break; case "goto": requireValue(args.surface, "surface is required for goto"); requireValue(args.url, "url is required for goto"); browserArgs.push("goto", args.url); break; case "snapshot": requireValue(args.surface, "surface is required for snapshot"); browserArgs.push("snapshot"); break; case "click": requireValue(args.surface, "surface is required for click"); requireValue(args.selector, "selector is required for click"); browserArgs.push("click", args.selector); break; case "type": requireValue(args.surface, "surface is required for type"); requireValue(args.selector, "selector is required for type"); requireValue(args.text, "text is required for type"); browserArgs.push("type", args.selector, args.text); break; case "eval": requireValue(args.surface, "surface is required for eval"); requireValue(args.script, "script is required for eval"); browserArgs.push("eval", args.script); break; case "wait": requireValue(args.surface, "surface is required for wait"); if (!args.selector && !args.text && !args.timeout_ms) { throw new Error( "wait requires at least one of selector, text, or timeout_ms", ); } browserArgs.push("wait"); if (args.selector) { browserArgs.push("--selector", args.selector); } if (args.text) { browserArgs.push("--text", args.text); } if (args.timeout_ms) { browserArgs.push("--timeout-ms", String(args.timeout_ms)); } break; case "url": requireValue(args.surface, "surface is required for url"); browserArgs.push("url"); break; } const result = await client.browser(browserArgs); // browser_surface actions map to cmux browser-surface subcommands return ok({ action: args.action, surface: args.surface, result, }); } catch (e) { return err(e); } }, - src/server.ts:511-543 (registration)Registration and schema definition for the browser_surface tool.
// 10. browser_surface server.tool( "browser_surface", "Interact with a browser surface (open, navigate, snapshot, click, type, eval, wait)", { action: z .enum([ "open", "goto", "snapshot", "click", "type", "eval", "wait", "url", ]) .describe("Browser action to perform"), surface: z.string().optional().describe("Target surface ref"), workspace: z.string().optional().describe("Target workspace ref"), url: z.string().optional().describe("URL for open/goto actions"), selector: z .string() .optional() .describe("CSS selector for click/type/wait actions"), text: z.string().optional().describe("Text for type action"), script: z.string().optional().describe("JavaScript for eval action"), timeout_ms: z .number() .int() .positive() .optional() .describe("Timeout for wait action"), },