interceptor_browser_launch
Launch a stealth Chromium browser with proxy settings, certificate trust, and fingerprint patches to evade detection and simulate human browsing behavior.
Instructions
Launch cloakbrowser (stealth Chromium) with proxy flags and SPKI certificate trust. Built-in source-level fingerprint patches + humanize mode. Driven via Playwright — locator-based tools replace CDP.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | URL to open (default: about:blank) | |
| headless | No | Run headless (default: false) | |
| humanize | No | Enable cloakbrowser's humanize mode (default: true) | |
| human_preset | No | Human behavior preset | default |
| timezone | No | IANA timezone, e.g. 'America/New_York' | |
| locale | No | BCP 47 locale, e.g. 'en-US' | |
| viewport_width | No | Viewport width in px | |
| viewport_height | No | Viewport height in px |
Implementation Reference
- src/interceptors/browser.ts:59-139 (handler)BrowserInterceptor.activate() — the core implementation that launches cloakbrowser (stealth Chromium) via Playwright. Handles proxy config, SPKI certificate trust, humanize mode, viewport, timezone, locale, console logging, and returns targetId.
async activate(options: ActivateOptions): Promise<ActivateResult> { const { proxyPort, certFingerprint } = options; const url = typeof options.url === "string" ? options.url : undefined; const headless = typeof options.headless === "boolean" ? options.headless : false; const humanize = options.humanize !== false; const humanPreset = options.humanPreset === "careful" ? "careful" : "default"; const timezone = typeof options.timezone === "string" ? options.timezone : undefined; const locale = typeof options.locale === "string" ? options.locale : undefined; const viewport = options.viewport as { width: number; height: number } | undefined; const { launchContext } = await import("cloakbrowser"); const args = [ `--ignore-certificate-errors-spki-list=${certFingerprint}`, "--proxy-bypass-list=<-loopback>", "--disable-quic", ]; const context = await launchContext({ headless, proxy: { server: `http://127.0.0.1:${proxyPort}` }, args, humanize, humanPreset, ...(timezone ? { timezone } : {}), ...(locale ? { locale } : {}), ...(viewport ? { viewport } : {}), }); const browser = context.browser(); if (!browser) { await context.close().catch(() => {}); throw new Error("cloakbrowser launchContext returned a context without a browser handle."); } const page = await context.newPage(); const consoleBuffer: ConsoleEntry[] = []; page.on("console", (msg: ConsoleMessage) => { const loc = msg.location(); consoleBuffer.push({ type: msg.type(), text: msg.text(), location: loc.url ? `${loc.url}:${loc.lineNumber ?? 0}:${loc.columnNumber ?? 0}` : "", timestamp: Date.now(), }); if (consoleBuffer.length > CONSOLE_BUFFER_MAX) { consoleBuffer.splice(0, consoleBuffer.length - CONSOLE_BUFFER_MAX); } }); if (url) { try { await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30_000 }); } catch { // Non-fatal: caller can retry via interceptor_browser_navigate. } } const pid = typeof process.pid === "number" ? process.pid : 0; const targetId = `browser_${pid}_${Date.now()}`; const target: ActiveTarget = { id: targetId, description: `cloakbrowser (headless=${headless})`, activatedAt: Date.now(), details: { proxyPort, url: url ?? "about:blank", headless, humanize, humanPreset, ...(timezone ? { timezone } : {}), ...(locale ? { locale } : {}), }, }; this.launched.set(targetId, { target, browser, context, page, consoleBuffer }); return { targetId, details: target.details }; } - src/tools/interceptors.ts:143-153 (schema)Zod schema for the tool's input parameters: url (string), headless (bool, default false), humanize (bool, default true), human_preset (enum default/careful, default default), timezone (string), locale (string), viewport_width (number), viewport_height (number).
{ url: z.string().optional().describe("URL to open (default: about:blank)"), headless: z.boolean().optional().default(false).describe("Run headless (default: false)"), humanize: z.boolean().optional().default(true).describe("Enable cloakbrowser's humanize mode (default: true)"), human_preset: z.enum(["default", "careful"]).optional().default("default") .describe("Human behavior preset"), timezone: z.string().optional().describe("IANA timezone, e.g. 'America/New_York'"), locale: z.string().optional().describe("BCP 47 locale, e.g. 'en-US'"), viewport_width: z.number().optional().describe("Viewport width in px"), viewport_height: z.number().optional().describe("Viewport height in px"), }, - src/tools/interceptors.ts:140-181 (registration)MCP tool registration via server.tool() with name "interceptor_browser_launch", description, input schema, and async handler that calls interceptorManager.activate("browser", ...).
server.tool( "interceptor_browser_launch", "Launch cloakbrowser (stealth Chromium) with proxy flags and SPKI certificate trust. Built-in source-level fingerprint patches + humanize mode. Driven via Playwright — locator-based tools replace CDP.", { url: z.string().optional().describe("URL to open (default: about:blank)"), headless: z.boolean().optional().default(false).describe("Run headless (default: false)"), humanize: z.boolean().optional().default(true).describe("Enable cloakbrowser's humanize mode (default: true)"), human_preset: z.enum(["default", "careful"]).optional().default("default") .describe("Human behavior preset"), timezone: z.string().optional().describe("IANA timezone, e.g. 'America/New_York'"), locale: z.string().optional().describe("BCP 47 locale, e.g. 'en-US'"), viewport_width: z.number().optional().describe("Viewport width in px"), viewport_height: z.number().optional().describe("Viewport height in px"), }, async ({ url, headless, humanize, human_preset, timezone, locale, viewport_width, viewport_height }) => { try { const proxyInfo = requireProxy(); const viewport = (viewport_width && viewport_height) ? { width: viewport_width, height: viewport_height } : undefined; const result = await interceptorManager.activate("browser", { ...proxyInfo, url, headless, humanize, humanPreset: human_preset, timezone, locale, viewport, }); return { content: [{ type: "text", text: JSON.stringify({ status: "success", ...result }), }], }; } catch (e) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", error: errorToString(e) }) }] }; } }, ); - src/tools/interceptors.ts:37-50 (helper)requireProxy() helper — ensures proxy is running and returns proxy port, cert PEM, and cert fingerprint needed by the browser launch handler.
function requireProxy(): { proxyPort: number; certPem: string; certFingerprint: string } { if (!proxyManager.isRunning()) { throw new Error("Proxy is not running. Start it first with proxy_start."); } const cert = proxyManager.getCert(); if (!cert) { throw new Error("No certificate available. Start the proxy first."); } return { proxyPort: proxyManager.getPort()!, certPem: cert.cert, certFingerprint: cert.fingerprint, }; } - src/interceptors/manager.ts:32-43 (registration)InterceptorManager.activate() — dispatches to the registered BrowserInterceptor's activate() method, which is the actual handler.
/** Activate a specific interceptor. */ async activate(interceptorId: string, options: ActivateOptions): Promise<ActivateResult> { const interceptor = this.interceptors.get(interceptorId); if (!interceptor) { throw new Error(`Interceptor '${interceptorId}' not found. Available: ${[...this.interceptors.keys()].join(", ")}`); } const activable = await interceptor.isActivable(); if (!activable) { throw new Error(`Interceptor '${interceptorId}' is not activable. Required tooling may be missing.`); } return interceptor.activate(options); }