{"slug": "show-hn-turbo-browser-mcp-batch-forms-dom-deltas-and-submit-guards-for-mcp", "title": "Show HN: Turbo-Browser-MCP – Batch forms, DOM deltas and submit guards for MCP", "summary": "A developer released turbo-browser-mcp, a Playwright-based Model Context Protocol server that consolidates 25-33 fine-grained browser primitives into 10 batched tools to cut token use and multi-turn latency in LLM browser automation. Benchmarks run in headless Chromium with OpenAI o200k_base tokenization (tiktoken 0.14.0) show a dense 140-button UI snapshot at 1,135 tokens versus 18,654 for HTML (93.9% savings), a 10-field form completed in 1 turn at 811 tokens versus 11 turns and 12,197 direct tokens (7x faster, 93.4% direct savings), and a 48 KiB PDF upload at 85 tokens versus 44,728 tokens inline Base64 (99.8% saved). The server ships delta DOM snapshots, single-turn React/Shadow DOM/iframe form prefill, disk-path file uploads, parallel tab sessions, network blocking presets and a default human-in-the-loop Submit guard.", "body_md": "`turbo-browser-mcp` is a Playwright-based Model Context Protocol (MCP) server built to cut LLM token waste and multi-turn latency in browser automation. It consolidates 25-33 fine-grained browser primitives into **10 batched tools** featuring delta DOM snapshots, single-turn React/Shadow DOM/iframe form prefill, direct disk file uploads (no Base64 in context), parallel tab sessions, network blocking presets, and a default human-in-the-loop Submit guard.\n\nAll figures below come from [`benchmarks/benchmark.mjs`](https://github.com/Tthanh2k6/turbo-browser-mcp/blob/main/benchmarks/benchmark.mjs) (`npm run benchmark`) running headless Chromium locally with exact OpenAI `o200k_base` tokenization (`tiktoken 0.14.0`):\n\n| Capability | Typical Baseline | `turbo-browser-mcp` | Speed / Turn Gain | Token Savings ( `o200k_base` ) | \n|---|---|---|---|---|\n| **Dense UI Snapshot** (140-btn SaaS console) | `18,654` tok HTML /`3,568` tok full ARIA | **`1,135` tok** compact (`28 ms` ) | `1` call | **`93.9%` vs HTML** (`68.2%` vs ARIA) | \n| **Post-Click Delta Snapshot** (`onlyChanged: true` ) | `3,582` tok full ARIA rescan | **`56` tok** changed lines (`18 ms` ) | `1` call | **`98.4%` vs ARIA** (`99.7%` vs HTML) | \n| **10-Field Complex Form + Snapshot** (`smart_fill_form` ) | `11` turns (`574 ms` ,`12,197` dir /`72,614` cum tok) | **`1` turn** (`82 ms` ,**`811` tok** ) | **`7x` faster** ,`11 -> 1` turns | **`93.4%` direct / `98.9%` cumulative** | \n| **48 KiB PDF Upload** (`49,152` bytes) | `44,728` tok inline Base64 tool arg | **`85` tok** disk path (`68 ms` ) | Zero Base64 generation | **`99.8%` saved** | \n| **6-Step Interactive UI Flow** (`batch_actions` ) | `6` turns (`411 ms` ,`955` dir /`3,162` cum tok) | **`1` turn** (`357 ms` ,**`406` tok** ) | **`1.15x` faster** ,`6 -> 1` turns | **`57.5%` direct / `87.2%` cumulative** | \n| **Open 6 Tabs Concurrently** (`open_many` ) | `6` turns sequential (`998 ms` ) | **`1` turn** batched (`420 ms` ) | **`2.38x` faster** ,`6x` fewer turns | `5` fewer prompt replays | \n| **Heavy Media Load** (`preset: \"turbo\"` ,`304 KiB` assets) | `252 ms` ,`9` media requests (`304 KiB` ) | **`165 ms`** ,` 0` media requests (`0 KiB` ) | **`1.53x` faster** | **`100%` media bandwidth cut** | \n| **Article Markdown Scraping** (`extract_clean_text` ) | `3,595` tok raw HTML (`10,844` chars) | **`156` tok** clean Markdown (`641` chars) | Clean reader output | **`95.7%` saved** | \n| **Diagnostics Triage** (`page_diagnostics` errors-only) | `3,460` tok unfiltered (`32` req /`26` console) | **`601` tok** default errors (`2` req /`6` console) | Zero noise scrolling | **`82.6%` saved** | \n| **Static MCP Tool Schema** (every turn overhead) | `3,917` tok Playwright /`6,737` tok DevTools | **`3,010` tok** stripped (`3,314` full w/ annotations) | `10` tools vs`25` /`33` | **`23.2%` vs Playwright / `55.3%` vs DevTools** | \n\n**Note on latency vs LLM inference turns:** Eliminating `10` round-trips on a 10-field form saves both `7x` in browser execution (`574 ms -> 82 ms`) and `10` separate LLM inference round-trips (`2-5s` per turn in agent loops) plus `~71,800` replayed history tokens.\n\nStandard MCP servers charge an LLM round-trip for every snapshot, field fill, `<select>` choice, upload, and verification check. Each turn re-sends the growing conversation history back into the model.\n\n```\nsequenceDiagram\n    autonumber\n    participant Agent as LLM Agent\n    participant Std as Standard MCP (Playwright / DevTools)\n    participant Turbo as turbo-browser-mcp\n\n    Note over Agent,Std: Standard MCP (12+ LLM turns, full ARIA tree + history replay each step)\n    Agent->>Std: 1. snapshot() -> full ARIA (~3,568 tok)\n    loop Repeats 10+ times across fields, selects, checkboxes, upload\n        Agent->>Std: fill / select_option / click\n        Std-->>Agent: full ARIA or confirmation re-added to history\n    end\n    Agent->>Std: 12. upload inline or click chooser\n\n    Note over Agent,Turbo: turbo-browser-mcp (2 LLM turns total, delta & inline snapshot)\n    Agent->>Turbo: 1. inspect_compact(mode: \"forms\") -> compact refs (1,135 tok)\n    Agent->>Turbo: 2. smart_fill_form(fields: [...10 fields + disk PDF...], returnSnapshot: true)\n    Turbo-->>Agent: Filled 10 fields + guarded before Submit + inline snapshot (811 tok)\n```\n\n- **4 connection modes (`--mode auto|cdp|persistent|launch`):**  - `auto` (default): probes`--cdp http://127.0.0.1:9222` first so agents can reuse an existing signed-in browser session, then falls back to launching Chromium.\n  - `cdp` : attach directly to a running Chromium/Chrome/Edge remote debugging port.\n  - `persistent` : launch with a reusable`--user-data-dir` profile across runs.\n  - `launch` : start a clean browser session (`--headless` by default, or`--headed` ).\n- **Auto binary discovery (`src/playwright-loader.mjs`):** checks` playwright-core` cache revisions across Windows, macOS, and Linux, system installs of Google Chrome, Microsoft Edge, Brave, and Chromium, or an explicit`--executable <path>` .\n- **Per-tab isolation (`tabs_batch`):** open tabs inside named` isolatedContext` sandboxes with separate cookies and storage, batch-open up to 10 concurrent URLs (`open_many` ), activate, reload, go`back` /`forward` ,`resize` viewport, and emulate`colorScheme` ,`media` ,`reducedMotion` ,`contrast` ,`forcedColors` , or custom`userAgent` .\n\n- **Snapshot modes:**`interactive` ,`forms` ,`article` , and`all` .\n- **Cross-boundary traversal:** flattens main frame DOM, child iframes (`includeFrames` ,`frameIdx` ), and open Shadow DOM. Injects an init script hooking`Element.prototype.attachShadow` (`WeakMap` +`WeakRef` /`FinalizationRegistry` +`window.__tbmGetShadowRoot` ) to keep post-init closed Shadow roots inspectable and guarded, traverses`<slot>`` assignedNodes({ flatten: true })` , and supports Form-Associated Custom Elements.\n- **Token controls:**`onlyChanged: true` emits only elements added or changed since the prior snapshot;`query` filters by regex or substring;`boxes: true` adds`[box=x,y,w,h]` only when needed;`maxChars` caps payload size;`savePath` writes full output to disk.\n\nPrefills an entire form in one MCP call while flushing microtasks and macrotasks between controlled inputs:\n\n- **Standard & framework inputs:** text, email, password, number, date, textarea,`<input type=\"range\">` , checkboxes, radio groups (`check` ,`not` ,`overwrite` ). Triggers React-controlled state updates via native property setters and synthetic events.\n- **Selects & custom widgets:**`<select>` and`<select multiple>` (`option` /`values` ), ARIA comboboxes, ARIA switches,`contenteditable` rich editors, and Gmail compose dialogs (`gmail: { to, subject, body }` ).\n- **Frame & wildcard targeting:** target specific iframes via`frameIdx` , or set`all: true` to populate matching controls across frames.\n- **Direct disk uploads:** pass`file` or`files` paths directly to Playwright`setInputFiles` without loading binary files or Base64 strings into LLM context.\n- **Atomic verification:** pass`returnSnapshot: true` to inspect the updated form state in the same tool response.\n\n- **`act_fast` actions:**`click` ,`dblclick` ,`hover` ,`focus` ,`clear` ,`fill` ,`type` (`slowly` ,`delayMs` ,`submit` ),`select` ,`check` ,`uncheck` ,`drag` ,`drop` (`file` ,`files` , or custom MIME`dropData` ),`press` (`key` +`modifiers` :`Alt` ,`Control` ,`ControlOrMeta` ,`Meta` ,`Shift` ),`scroll` (`dx` ,`dy` ),`wait` (`ms` ,`state` ,`loadState` ,`text` ,`textGone` ,`url` ), and`upload` .\n- **Targeting options:** compact`[eN]`` ref` , CSS`selector` , visible`text` ,`label` , or viewport`(x, y)` coordinates, with`button` (`left` ,`right` ,`middle` ) and`frameIdx` .\n- **`batch_actions`:** runs an ordered list of DOM actions and nested` smart_fill_form` steps in one MCP call, stopping safely if blocked by the Submit guard or optionally continuing on step errors (`continueOnError` ).\n\n- **`extract_clean_text`:** extracts readable plain text or compact Markdown (` format: \"text\" | \"markdown\"` ) from main/article containers and iframes, stripped of script and style noise.\n- **`evaluate_js`:** runs JS expressions or`(el, arg)` element functions in any frame (`frameIdx` ) with JSON-serialized results and optional`savePath` export.\n- **`capture_page`:** full-page or element-scoped screenshots (` png` or`jpeg` with`quality` ,`css` or`device` scale, optional`returnImage` ) and PDF generation saved to a confined`savePath` .\n\n- **`network_session` presets:**`turbo` ,`no-images` ,`no-media` , and`clean` (unblock all), alongside custom`blockResources` and`blockUrls` patterns.\n- **Session & storage management:** read/write/clear browser`cookies` ,`localStorage` /`sessionStorage` , and export or reload full Playwright`storageState` JSON files (`saveStorageStatePath` ,`loadStorageStatePath` ).\n- **`page_diagnostics`:** defaults to errors-only (` level: \"errors\"` ,`statusFilter: \"errors\"` ) to surface failures cleanly without flooding context, while supporting`all` ,`includeStatic` ,`urlFilter` , deep request/response inspection (`reqId` +`part` ), completed downloads, and dialog auto-handling (`dialogPolicy` :`accept` /`dismiss` ).\n\nRun the benchmark suite yourself with Chromium and Playwright installed:\n\n```\nnpm run benchmark\n```\n\n**Environment & methodology:** Headless Chromium via `playwright-core`, counting exact OpenAI `o200k_base` tokens via Python `tiktoken` (`approx-bpe` fallback if `tiktoken` is unavailable). Cumulative workflow tokens model standard chat-history replay across \n\n| Scenario | Raw HTML | Full Playwright ARIA | `turbo-browser-mcp` Output | Saved vs ARIA | Saved vs HTML | \n|---|---|---|---|---|---|\n| **140-Button SaaS Console** (`inspect_compact` ) | `61,010` chars (`18,654` tok) | `12,771` chars (`3,568` tok) | **`3,968` chars (`1,135` tok)** | **`68.2%`** | **` 93.9%`** | \n| **Post-Click Delta** (`onlyChanged: true` ) | `61,010` chars (`18,654` tok) | `12,825` chars (`3,582` tok) | **`168` chars (`56` tok)** | **`98.4%`** | **` 99.7%`** | \n| **Article Markdown Extraction** (`extract_clean_text` ) | `10,844` chars (`3,595` tok) | n/a | **`641` chars (`156` tok)** | n/a | **`95.7%`** | \n| **Diagnostics Filter** (`32` reqs,`26` console logs) | `9,651` chars (`3,460` tok,`all` ) | n/a | **`1,761` chars (`601` tok, `errors`)** | n/a | **` 82.6%`** | \n\n| Scenario | Step-by-Step Baseline | `turbo-browser-mcp` | Execution Speedup | Token Savings | \n|---|---|---|---|---|\n| **10-Field Complex Form + Verify** (`smart_fill_form` ) | `11` turns,`574 ms` ,`12,197` direct /`72,614` cum tok | **`1` turn** ,**`82 ms`** ,**` 811` tok** (`filled=10` ) | **`7x` faster** | **`93.4%` dir / `98.9%` cum** | \n| **48 KiB PDF Upload** (`49,152` bytes via`file` ) | `65,679` chars (`44,728` tok) Base64 payload | **`263` chars (`85` tok)** disk path (`68 ms` ) | Zero LLM Base64 encode | **`99.8%`** | \n| **6-Step UI Flow** (`batch_actions` ) | `6` turns,`411 ms` ,`955` dir /`3,162` cum tok | **`1` turn** ,**`357 ms`** ,**` 406` tok** | **`1.15x` faster** | **`57.5%` dir / `87.2%` cum** | \n| **Open 6 Tabs** (`tabs_batch`` open_many` ,`60 ms` TTFB) | `6` turns sequential (`998 ms` ) | **`1` turn** batched (`420 ms` ) | **`2.38x` faster** (`6 -> 1` turns) | Eliminates `5` turns | \n| **Heavy Media Load** (`8x32 KiB` imgs +`48 KiB` font) | `252 ms` ,`9` media hits (`304 KiB` ) | **`165 ms`** ,` 0` media hits (`0 KiB` ) | **`1.53x` faster** | **`100%` media saved** | \n\nMeasured against installed MCP JSON schemas on disk (compact parameter schemas without `annotations`):\n\n| MCP Server | Tool Count | Compact Schema Chars | Exact `o200k_base` Tokens | Savings with `turbo-browser-mcp` | \n|---|---|---|---|---|\n| `turbo-browser-mcp` | **`10`** (` 14,186` full /`12,796` compact) | **`12,796`** | **` 3,010`** (` 3,314` full w/ annotations) | Baseline ( `10` tools) | \n| `@playwright/mcp` | `25` | `18,457` | `3,917` | **`23.2%` fewer static tokens** | \n| `chrome-devtools-mcp` | `33` | `30,252` | `6,737` | **`55.3%` fewer static tokens** | \n\n| Feature | `turbo-browser-mcp` | `@playwright/mcp` | `chrome-devtools-mcp` | \n|---|---|---|---|\n| **Tool Surface Size** | **10 batched tools** | 25 granular tools | 33 granular tools | \n| **Delta Snapshots (`onlyChanged`)** | Built-in | Full tree every snapshot | Full tree every snapshot | \n| **Closed Shadow DOM Hook** | Post-init `attachShadow` hook +`<slot>` flattening | Open Shadow DOM | CDP / standard DOM access | \n| **Single-Call Smart Form + Contenteditable** | Yes (React, Shadow DOM, iframe, Gmail, ranges) | Multi-turn fill + separate select calls | Basic `fill_form` | \n| **Disk File Upload (Zero Base64)** | Native `file` /`files` path in`smart_fill_form` &`act_fast` | Dedicated `browser_file_upload` turn | Dedicated `upload_file` turn | \n| **Default Human-in-the-Loop Submit Guard** | Yes ( `allowSubmit=false` , form/iframe/Enter hooks) | No | No | \n| **Parallel `open_many` + `isolatedContext`** | Single batched call | Separate sequential tab calls | Separate page calls | \n| **One-Call `turbo` Media Blocker** | Built-in ( `turbo` ,`no-images` ,`no-media` ) | Manual JS / routing | Network emulation | \n| **Performance / Heap Profiling** | Not included | Not included | **Trace, Lighthouse, Heap Snapshot** | \n\n**When to keep Chrome DevTools MCP alongside `turbo-browser-mcp`:** `chrome-devtools-mcp` provides Lighthouse audits, performance trace analysis, CSS computed style panels, and V8 heap snapshots. `turbo-browser-mcp` focuses on fast multi-step UI automation, forms, and scraping with minimal token overhead.\n\n| Capability | `turbo-browser-mcp` | `@playwright/mcp` | `chrome-devtools-mcp` | \n|---|---|---|---|\n| Multi-tab open, list, switch, resize, emulate | `tabs_batch` | `browser_tabs` ,`browser_navigate` ,`browser_resize` , ... | `new_page` ,`list_pages` ,`select_page` ,`resize_page` , ... | \n| DOM / accessibility inspection | `inspect_compact` | `browser_snapshot` | `take_snapshot` | \n| Multi-field form & upload | `smart_fill_form` | `browser_fill_form` +`browser_select_option` +`browser_file_upload` | `fill_form` +`upload_file` | \n| Click, type, drag, press, scroll, wait | `act_fast` | `browser_click` ,`browser_type` ,`browser_drag` , ... | `click` ,`type_text` ,`drag` ,`press_key` ,`wait_for` | \n| Multi-step sequential macro | `batch_actions` | `browser_run_code_unsafe` or N tool calls | N separate tool calls | \n| Clean article extraction | `extract_clean_text` | `browser_evaluate` custom JS | `evaluate_script` custom JS | \n| Frame/element JS evaluation | `evaluate_js` | `browser_evaluate` | `evaluate_script` | \n| Errors, network & console triage | `page_diagnostics` | `browser_console_messages` ,`browser_network_requests` | `list_console_messages` ,`list_network_requests` , ... | \n| Screenshots & PDF export | `capture_page` | `browser_take_screenshot` | `take_screenshot` | \n| Blocking presets, cookies & storage | `network_session` | `browser_evaluate` + context config | Partial via `evaluate_script` /`emulate` | \n\n1. **Human-in-the-loop Submit Guard (`allowSubmit=false` by default):**  - `smart_fill_form` (`stopBeforeSubmit: true` ),`act_fast` , and`batch_actions` inspect matching elements, W3C AccName labels (`isSafeSubmitter` ), implicit HTML form Enter submissions, key chords (`Shift+Enter` ,`Enter+Shift` ),`HTMLFormElement.prototype.submit` /`requestSubmit` , and same-origin iframe`contentWindow` /`contentDocument` proxies.\n  - Final actions resembling `Submit` ,`Publish` ,`Send` ,`Post` ,`Apply` ,`Confirm` , or payment triggers are blocked unless`allowSubmit: true` is explicitly passed or`--allow-submit` is enabled at startup.\n  - Trade-off: pre-existing closed Shadow roots on already-open CDP tabs (attached before the init script ran) or strict cross-origin sandboxed frames fall back to Playwright frame handles, coordinate actions, and keyboard input.\n2. **Workspace Path Confinement (`TURBO_BROWSER_SAVE_ROOT`):**  - File outputs (` savePath` ,`saveStorageStatePath` ) and state inputs (`loadStorageStatePath` ) are strictly confined to the current working directory or`TURBO_BROWSER_SAVE_ROOT` .\n  - Lexical checks, `lstatSync` /`readlinkSync` symlink verification, and`realpathSync` validation block`..` traversal, UNC network paths, dangling symlinks, cyclic symlinks, and Windows junctions before reading or writing.\n3. File outputs (\n\n| Tool | Purpose | Key Parameters | \n|---|---|---|\n| `tabs_batch` | Ordered tab & browser lifecycle | `operations[]` (`list` ,`open` ,`open_many` ,`navigate` ,`activate` ,`resize` ,`emulate` ,`reload` ,`back` ,`forward` ,`close` ,`close_browser` ),`isolatedContext` ,`concurrency` (1-10) | \n| `inspect_compact` | Token-capped element/form/article snapshot | `mode` (`interactive` ,`forms` ,`article` ,`all` ),`onlyChanged` ,`query` ,`boxes` ,`maxChars` ,`includeFrames` ,`savePath` | \n| `smart_fill_form` | Batch form, editor & disk file prefill | `fields[]` (`ref` ,`selector` ,`value` ,`option` ,`values` ,`check` ,`not` ,`keys` ,`file` ,`files` ,`frameIdx` ,`all` ),`gmail` ,`overwrite` ,`stopBeforeSubmit` ,`returnSnapshot` | \n| `act_fast` | Single targeted page action | `action` (`16` actions),`ref` /`selector` /`text` /`label` /`(x, y)` ,`modifiers` ,`dropData` ,`allowSubmit` ,`returnSnapshot` | \n| `batch_actions` | Ordered chain of actions + form steps | `steps[]` ,`continueOnError` ,`allowSubmit` ,`returnSnapshot` ,`snapshotMaxChars` | \n| `extract_clean_text` | Clean text or compact Markdown reader | `format` (`text` ,`markdown` ),`selector` ,`includeFrames` ,`maxChars` ,`savePath` | \n| `evaluate_js` | Scoped JS expression or `(el, arg)` call | `expression` ,`arg` ,`frameIdx` ,`ref` /`selector` /`text` ,`savePath` | \n| `page_diagnostics` | Console, network, downloads & dialogs | `level` (`errors` ,`all` ),`statusFilter` (`errors` ,`all` ),`includeStatic` ,`urlFilter` ,`reqId` ,`part` ,`dialogPolicy` ,`clear` ,`savePath` | \n| `capture_page` | PNG/JPEG screenshots & PDF export | `mode` (`screenshot` ,`pdf` ),`type` ,`quality` ,`fullPage` ,`scale` (`css` ,`device` ),`ref` /`selector` /`text` ,`returnImage` ,`savePath` | \n| `network_session` | Resource blockers, cookies & storage | `preset` (`turbo` ,`no-images` ,`no-media` ,`clean` ),`blockResources` ,`blockUrls` ,`cookieAction` ,`storageAction` ,`loadStorageStatePath` ,`saveStorageStatePath` | \n\n```\n{\n  \"name\": \"smart_fill_form\",\n  \"arguments\": {\n    \"fields\": [\n      { \"selector\": \"#full_name\", \"value\": \"Alex Nguyen\" },\n      { \"selector\": \"#email\", \"value\": \"alex@example.com\" },\n      { \"selector\": \"#country\", \"option\": \"United States\" },\n      { \"selector\": \"#skills\", \"values\": [\"TypeScript\", \"Playwright\"] },\n      { \"selector\": \"#agree_terms\", \"check\": true },\n      { \"selector\": \"#resume_pdf\", \"file\": \"./assets/resume.pdf\" }\n    ],\n    \"stopBeforeSubmit\": true,\n    \"returnSnapshot\": true\n  }\n}\n{\n  \"name\": \"inspect_compact\",\n  \"arguments\": {\n    \"mode\": \"interactive\",\n    \"onlyChanged\": true,\n    \"maxChars\": 3000\n  }\n}\n{\n  \"name\": \"tabs_batch\",\n  \"arguments\": {\n    \"operations\": [\n      { \"action\": \"open\", \"url\": \"https://example.com/app\", \"isolatedContext\": \"acct-a\" },\n      { \"action\": \"open_many\", \"urls\": [\"https://example.com/docs\", \"https://example.com/pricing\"], \"concurrency\": 4 }\n    ]\n  }\n}\ngit clone https://github.com/Tthanh2k6/turbo-browser-mcp.git\ncd turbo-browser-mcp\nnpm install\nnpm run doctor\n```\n\nIf you need Playwright's bundled Chromium (or have no system Chrome/Edge/Brave installed):\n\n```\nnpx playwright-core install chromium\n```\n\nUsing local clone:\n\n```\n{\n  \"mcpServers\": {\n    \"turbo-browser\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/turbo-browser-mcp/src/index.mjs\"],\n      \"env\": {\n        \"TURBO_BROWSER_SAVE_ROOT\": \"/absolute/path/to/allowed/workspace\"\n      }\n    }\n  }\n}\n```\n\nUsing `npx` / binary entrypoint:\n\n```\n{\n  \"mcpServers\": {\n    \"turbo-browser\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"turbo-browser-mcp\"]\n    }\n  }\n}\n```\n\n| CLI Flag | Environment Variable | Default | Description | \n|---|---|---|---|\n| `--mode <auto\\|cdp\\|persistent\\|launch>` | `TURBO_BROWSER_MODE` | `auto` | Connection strategy ( `cdp` first then launch in`auto` ) | \n| `--cdp <url>` | `TURBO_BROWSER_CDP_URL` | `http://127.0.0.1:9222` | Chrome DevTools Protocol HTTP endpoint | \n| `--user-data-dir <path>` | `TURBO_BROWSER_USER_DATA_DIR` | `\"\"` | Persistent profile directory path | \n| `--executable <path>` | - | auto-detected | Custom Chromium, Chrome, Edge, or Brave executable | \n| `--timeout <ms>` | `TURBO_BROWSER_TIMEOUT_MS` | `15000` | Default Playwright action/navigation timeout in ms | \n| `--headless` /`--headed` | `TURBO_BROWSER_HEADLESS` | `true` (headless) | Run headless or visible browser window ( `\"false\"` for headed) | \n| `--allow-submit` | - | `false` | Disable default Submit/Publish confirmation guard | \n| `--doctor` | - | - | Print Node, Playwright, Chromium, and CDP diagnostics as JSON | \n| `--version` /`-v` | - | - | Print server version ( `0.4.0` ) | \n| `--help` /`-h` | - | - | Print CLI usage summary | \n| - | `TURBO_BROWSER_SAVE_ROOT` | `process.cwd()` | Root directory confining `savePath` and`storageState` files | \n| - | `PLAYWRIGHT_CORE_PATH` | auto-resolved | Explicit path to `playwright-core/index.mjs` | \n\n**Tip - Reusing your logged-in Chrome tabs:** Enable remote debugging on port `9222` (via `chrome://inspect/#remote-debugging` or launching Chrome with `--remote-debugging-port=9222`). In default `--mode auto`, `turbo-browser-mcp` attaches to your open tabs directly instead of launching a fresh unauthenticated browser.\n\n```\nnpm test            # 405 passing tests across 85 suites (25 test files under test/*.test.mjs)\nnpm run doctor      # Environment check for Node, Playwright, Chromium, and CDP\nnpm run benchmark   # Local Chromium speed & exact o200k_base token benchmark\n```\n\nTested automatically on GitHub Actions (`ubuntu-latest`) across **Node 20** and **Node 22**.", "url": "https://wpnews.pro/news/show-hn-turbo-browser-mcp-batch-forms-dom-deltas-and-submit-guards-for-mcp", "canonical_source": "https://github.com/Tthanh2k6/turbo-browser-mcp", "published_at": "2026-11-15 04:09:11+00:00", "updated_at": "2026-11-15 04:22:48.372547+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "agent-protocols", "ai-infrastructure"], "entities": ["turbo-browser-mcp", "Playwright", "Model Context Protocol", "OpenAI", "tiktoken", "Chromium"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-turbo-browser-mcp-batch-forms-dom-deltas-and-submit-guards-for-mcp", "markdown": "https://wpnews.pro/news/show-hn-turbo-browser-mcp-batch-forms-dom-deltas-and-submit-guards-for-mcp.md", "text": "https://wpnews.pro/news/show-hn-turbo-browser-mcp-batch-forms-dom-deltas-and-submit-guards-for-mcp.txt", "jsonld": "https://wpnews.pro/news/show-hn-turbo-browser-mcp-batch-forms-dom-deltas-and-submit-guards-for-mcp.jsonld"}}