Browser Bridge connects to a real browser through a Chrome extension, providing structured web page operation and extraction capabilities. It does not stuff the entire raw HTML of a page directly into the model; instead, it executes JavaScript in the browser, then returns structured results, DOM change summaries, and briefly appearing prompt text.
Usage positioning
Browser Bridge is a standalone skill. It only describes its own installation method, command interface, and usage patterns.
Confirm three things before use:
- Python dependencies and the Chrome extension are already installed.
python <skill-dir>/scripts/browser.py tabsYou can see the browser tab.- When executing commands frequently, start the resident master first, to avoid waiting for the extension to reconnect on every CLI call.
Architecture
CLI (browser.py) -> Python (TMWebDriver) <-WebSocket-> Chrome 扩展 <-CDP/scripting-> 浏览器 Tab
- The Python WebSocket server runs on
ws://127.0.0.1:18765。 - The Chrome extension connects to the server and forwards commands to the browser tab.
- JavaScript executes in the page context; if CSP blocks execution, it falls back to CDP.
- The returned result is structured JSON, not raw HTML.
One-time installation
Install dependencies before first use:
pip install bs4 simple-websocket-server bottle requests
Then install the Chrome extension:
- Open Chrome's
chrome://extensions/。 - Enable "Developer mode / 开发者模式".
- Click "Load unpacked / 加载已解压的扩展程序", and select
<skill-dir>/assets/extension/。 - Open any web page to verify: you should see a green
ljq_driver: connectedmarker in the lower right corner.
CLI reference
All commands automatically start the bridge server on their first call. The CLI is located at:
<skill-dir>/scripts/browser.py
Below, <skill-dir> refers to the directory containing this SKILL.md .
Recommended: start a resident master
If you directly call browser.py exec ...repeatedly, each short-lived CLI process may restart the bridge server and wait for the Chrome extension to reconnect, usually adding several seconds of cold-start time. When operating the browser frequently, start it separately first:
python <skill-dir>/scripts/browser_master.py
Keep this process running. Afterward, use browser.py exec、scan、tabs and other commands normally; they will automatically forward through http://127.0.0.1:18766/link to the resident master.
When you only need the JS return value and do not need DOM diff and toast capture, add exec to --no-monitor:
python <skill-dir>/scripts/browser.py exec --no-monitor "document.title"
exec: execute JavaScript in the browser
This is the most commonly used main command. Directly write JavaScript to query or manipulate the DOM. The system captures return values, DOM changes, and brief text that appears during execution, such as toast, notification, and loading copy.
python <skill-dir>/scripts/browser.py exec "<javascript>"
Parameters:
--tab <id>: specify the tab.--no-monitor: skip DOM diff, faster.--wait <selector>: wait before execution until the CSS selector appears, suitable for SPAs.--wait-ms <ms>:--waitmaximum wait time, default10000。--timeout <s>: execution timeout in seconds, default15。
Example:
# 获取页面标题
python <skill-dir>/scripts/browser.py exec "document.title"
# 点击元素并查看页面变化
python <skill-dir>/scripts/browser.py exec "document.querySelector('.submit-btn').click()"
# 抽取结构化数据
python <skill-dir>/scripts/browser.py exec "Array.from(document.querySelectorAll('.item')).map(e=>({name:e.querySelector('.name')?.textContent,price:e.querySelector('.price')?.textContent}))"
# 填写表单字段,并触发 React/Vue 绑定
python <skill-dir>/scripts/browser.py exec "const e=document.querySelector('#email');e.value='u@x.com';e.dispatchEvent(new Event('input',{bubbles:true}))"
# 向下滚动
python <skill-dir>/scripts/browser.py exec "window.scrollBy(0,800)"
# 等待元素出现后再交互
python <skill-dir>/scripts/browser.py exec --wait ".loaded" "return document.querySelector('.loaded').textContent"
# 长时间操作
python <skill-dir>/scripts/browser.py exec --timeout 30 "await fetch('/api/slow'); return 'done'"
Returned fields:
status:successorfailed。js_return: the JavaScript return value; DOM elements are intelligently processed intoouterHTML。diff: DOM change summary, explaining which elements appeared or changed.transients: text that briefly appeared during execution, such as toast or loading.newTabs: new tabs opened during execution.tab_id: the tab ID to execute in.error: error message on failure.reloaded: whether the page reloaded during execution.suggestion: a hint given when there is no obvious page change.
scan: get simplified page content
Use when a page overview is needed. HTML is simplified spatially and semantically: sidebar, floating ads, occluded elements, and invisible content are removed; repeated lists are truncated to 3 items; non-semantic attributes are deleted.
python <skill-dir>/scripts/browser.py scan # 简化 HTML + tab 列表
python <skill-dir>/scripts/browser.py scan --tabs-only # 只返回 tab 列表,不返回 HTML
python <skill-dir>/scripts/browser.py scan --text-only # 只返回文本,token 最少
python <skill-dir>/scripts/browser.py scan --size-only # 只返回内容大小,用于确认页面是否渲染
python <skill-dir>/scripts/browser.py scan --tab <id> # 扫描指定 tab
python <skill-dir>/scripts/browser.py scan --wait ".result-card" # 等待 SPA 内容出现
Returned fields:
status:successorerror。html: simplified HTML;tabs-onlyorsize-onlyis not returned.url/tab_id: current tab info.sessions: list of id, url, and title for all tabs.size: content character count, only returned bysize-only.msg: error message on failure.
tabs: list all browser tabs
python <skill-dir>/scripts/browser.py tabs
# -> {"status":"success","sessions":[{"id":"123","url":"https://...","title":"..."},...]}
navigate: open a URL
Navigate the current tab and wait for the page to finish loading, up to 30 seconds.
python <skill-dir>/scripts/browser.py navigate "https://example.com"
python <skill-dir>/scripts/browser.py navigate "https://example.com" --no-wait # 跳过加载等待
Returns:
{"status":"success","navigated_to":"https://...","loaded":true}
back: go back
python <skill-dir>/scripts/browser.py back
forward: go forward
python <skill-dir>/scripts/browser.py forward
reload: reload the current page
python <skill-dir>/scripts/browser.py reload
newtab: open a new tab
python <skill-dir>/scripts/browser.py newtab
python <skill-dir>/scripts/browser.py newtab "https://example.com"
The return will include as much as possible tab_id and tab, which can then be passed directly to --tab。
close: close a tab
python <skill-dir>/scripts/browser.py close
python <skill-dir>/scripts/browser.py close <tab_id>
switch: switch tabs by URL fragment
python <skill-dir>/scripts/browser.py switch "github"
# -> {"status":"success","session_id":"456"}
When multiple tabs match at the same time, the first one is selected by default. When precise selection is needed, first use tabs to view the IDs of all tabs.
screenshot: take a screenshot
Capture a PNG image of the current tab via Chrome DevTools Protocol.
python <skill-dir>/scripts/browser.py screenshot
python <skill-dir>/scripts/browser.py screenshot page.png
Returns:
{"status":"success","filepath":"/tmp/screenshot_1714650000.png"}
evidence: export rendered component evidence
Used for design system extraction and component restoration. For small, detail-sensitive components such as switch, slider, tabs, select, menu, dialog, command input, date picker, and chart, screenshots alone are unreliable.evidence captures the rendered component structure from a real browser tab.
python <skill-dir>/scripts/browser.py evidence 'button[role="switch"]' --name Switch --out component-evidence/switch
python <skill-dir>/scripts/browser.py evidence '[data-slot="switch"]' --name Switch --index 0 --depth 4
python <skill-dir>/scripts/browser.py evidence '.tabs-root' --name Tabs --wait '.tabs-root' --wait-ms 8000
Parameters:
--name <name>: component name, used for metadata and the output directory.--out <dir>: output directory, defaultcomponent-evidence/<name>。--index <n>: selector match index, default0。--depth <n>: descendant structure depth, default4。--tab <id>: specify the tab.--wait <selector>/--wait-ms <ms>: wait for the SPA to render the component.--all-styles: capture all computed styles instead of a trimmed UI style set.
Output files:
component-evidence/<name>/
README.md
metadata.json
dom.html
attributes.json
class-list.txt
box-model.json
computed-styles.json
anatomy.json
screenshot.png
page.png
Treat this evidence as the authoritative source for component structure. When translating the component into source code, preserve meaningful role、aria-*、data-state、data-size、data-slot, dimensions, transforms, and state class names.evidence When it is unavailable, first ask the caller for the copied rendered DOM, class list, or source code, then mark detail-sensitive components as verified.
Further reference
Usage patterns, SPA extraction examples, a research quick-reference, and troubleshooting notes are in reference.md. Read grok.mdwhen operating Grok. Read these references only when the command documentation is not enough.