browsing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBrowsing with Chrome Direct
直接控制Chrome浏览
Overview
概述
Control Chrome via DevTools Protocol using the MCP tool. Single unified interface with auto-starting Chrome.
use_browserAnnounce: "I'm using the browsing skill to control Chrome."
通过 MCP工具,利用DevTools Protocol控制Chrome。提供统一的单一界面,可自动启动Chrome。
use_browser声明:“我正在使用浏览技能来控制Chrome。”
When to Use
适用场景
Use this when:
- Controlling authenticated sessions
- Managing multiple tabs in running browser
- Playwright MCP unavailable or excessive
Use Playwright MCP when:
- Need fresh browser instances
- Generating screenshots/PDFs
- Prefer higher-level abstractions
在以下场景使用本工具:
- 控制已认证的会话
- 管理运行中浏览器的多个标签页
- Playwright MCP不可用或过于冗余时
在以下场景使用Playwright MCP:
- 需要全新的浏览器实例
- 生成截图/PDF
- 偏好更高层级的抽象封装
Auto-Capture
自动捕获
Every DOM action (navigate, click, type, select, eval, keyboard_press) automatically saves:
- — viewport screenshot
{prefix}.png - — page content as structured markdown
{prefix}.md - — full rendered DOM
{prefix}.html - — browser console messages
{prefix}-console.txt
Files are saved to the session directory with sequential prefixes (001-navigate, 002-click, etc.). You must check these before using extract or screenshot actions.
每一次DOM操作(导航、点击、输入、选择、执行脚本、按键)都会自动保存以下文件:
- —— 视口截图
{prefix}.png - —— 结构化Markdown格式的页面内容
{prefix}.md - —— 完整的渲染后DOM
{prefix}.html - —— 浏览器控制台消息
{prefix}-console.txt
文件会以连续前缀(如001-navigate、002-click等)保存到会话目录中。在执行提取或截图操作前,你必须先查看这些文件。
The use_browser Tool
use_browser工具
Single MCP tool with action-based interface. Chrome auto-starts on first use.
Parameters:
- (required): Operation to perform
action - (optional): Tab to operate on (default: 0)
tab_index - (optional): CSS selector for element operations
selector - (optional): Action-specific data
payload - (optional): Timeout in ms for await operations (default: 5000)
timeout
基于动作的单一MCP工具。首次使用时会自动启动Chrome。
参数:
- (必填):要执行的操作
action - (可选):要操作的标签页索引(默认值:0)
tab_index - (可选):元素操作使用的CSS选择器
selector - (可选):操作专属数据
payload - (可选):等待操作的超时时间(单位:毫秒,默认值:5000)
timeout
Actions Reference
操作参考
Navigation
导航
-
navigate: Navigate to URL
- : URL string
payload - Example:
{action: "navigate", payload: "https://example.com"}
-
await_element: Wait for element to appear
- : CSS selector
selector - : Max wait time in ms
timeout - Example:
{action: "await_element", selector: ".loaded", timeout: 10000}
-
await_text: Wait for text to appear
- : Text to wait for
payload - Example:
{action: "await_text", payload: "Welcome"}
-
navigate:导航到指定URL
- :URL字符串
payload - 示例:
{action: "navigate", payload: "https://example.com"}
-
await_element:等待元素出现
- :CSS选择器
selector - :最长等待时间(毫秒)
timeout - 示例:
{action: "await_element", selector: ".loaded", timeout: 10000}
-
await_text:等待文本出现
- :要等待的文本
payload - 示例:
{action: "await_text", payload: "Welcome"}
Interaction
交互
-
click: Click element
- : CSS selector
selector - Example:
{action: "click", selector: "button.submit"}
-
type: Type text into input (appendto submit)
\n- : CSS selector
selector - : Text to type
payload - Example:
{action: "type", selector: "#email", payload: "user@example.com\n"}
-
select: Select dropdown option
- : CSS selector
selector - : Option value(s)
payload - Example:
{action: "select", selector: "select[name=state]", payload: "CA"}
-
click:点击元素
- :CSS选择器
selector - 示例:
{action: "click", selector: "button.submit"}
-
type:在输入框中输入文本(追加可提交表单)
\n- :CSS选择器
selector - :要输入的文本
payload - 示例:
{action: "type", selector: "#email", payload: "user@example.com\n"}
-
select:选择下拉菜单选项
- :CSS选择器
selector - :选项值
payload - 示例:
{action: "select", selector: "select[name=state]", payload: "CA"}
Extraction
内容提取
-
extract: Get page content
- : Format ('markdown'|'text'|'html')
payload - : Optional - limit to element
selector - Example:
{action: "extract", payload: "markdown"} - Example:
{action: "extract", payload: "text", selector: "h1"}
-
attr: Get element attribute
- : CSS selector
selector - : Attribute name
payload - Example:
{action: "attr", selector: "a.download", payload: "href"}
-
eval: Execute JavaScript
- : JavaScript code
payload - Example:
{action: "eval", payload: "document.title"}
-
extract:获取页面内容
- :格式选项('markdown'|'text'|'html')
payload - :可选 - 限制提取范围到指定元素
selector - 示例:
{action: "extract", payload: "markdown"} - 示例:
{action: "extract", payload: "text", selector: "h1"}
-
attr:获取元素属性
- :CSS选择器
selector - :属性名称
payload - 示例:
{action: "attr", selector: "a.download", payload: "href"}
-
eval:执行JavaScript代码
- :JavaScript代码
payload - 示例:
{action: "eval", payload: "document.title"}
Export
导出
- screenshot: Capture screenshot of a specific element
- : Filename
payload - : Optional - screenshot specific element
selector - Viewport screenshots are auto-captured after every DOM action. Use this only when you need a specific element.
- Example:
{action: "screenshot", payload: "/tmp/chart.png", selector: ".chart"}
- screenshot:捕获特定元素的截图
- :文件名
payload - :可选 - 仅截图特定元素
selector - 每次DOM操作后会自动捕获视口截图。仅当你需要特定元素的截图时才使用此操作。
- 示例:
{action: "screenshot", payload: "/tmp/chart.png", selector: ".chart"}
Tab Management
标签页管理
-
list_tabs: List all open tabs
- Example:
{action: "list_tabs"}
- Example:
-
new_tab: Create new tab
- Example:
{action: "new_tab"}
- Example:
-
close_tab: Close tab
- : Tab to close
tab_index - Example:
{action: "close_tab", tab_index: 2}
-
list_tabs:列出所有打开的标签页
- 示例:
{action: "list_tabs"}
- 示例:
-
new_tab:新建标签页
- 示例:
{action: "new_tab"}
- 示例:
-
close_tab:关闭标签页
- :要关闭的标签页索引
tab_index - 示例:
{action: "close_tab", tab_index: 2}
Browser Mode Control
浏览器模式控制
-
show_browser: Make browser window visible (headed mode)
- Example:
{action: "show_browser"} - ⚠️ WARNING: Restarts Chrome, reloads pages via GET, loses POST state
- Example:
-
hide_browser: Switch to headless mode (invisible browser)
- Example:
{action: "hide_browser"} - ⚠️ WARNING: Restarts Chrome, reloads pages via GET, loses POST state
- Example:
-
browser_mode: Check current browser mode and profile
- Example:
{action: "browser_mode"} - Returns:
{"headless": true|false, "mode": "headless"|"headed", "running": true|false, "profile": "name", "profileDir": "/path"}
- Example:
-
show_browser:显示浏览器窗口(有头模式)
- 示例:
{action: "show_browser"} - ⚠️ 警告:会重启Chrome,通过GET请求重新加载页面,POST状态会丢失
- 示例:
-
hide_browser:切换到无头模式(不可见浏览器)
- 示例:
{action: "hide_browser"} - ⚠️ 警告:会重启Chrome,通过GET请求重新加载页面,POST状态会丢失
- 示例:
-
browser_mode:检查当前浏览器模式和配置文件
- 示例:
{action: "browser_mode"} - 返回结果:
{"headless": true|false, "mode": "headless"|"headed", "running": true|false, "profile": "name", "profileDir": "/path"}
- 示例:
Profile Management
配置文件管理
-
set_profile: Change Chrome profile (must kill Chrome first)
- Example:
{action: "set_profile", "payload": "browser-user"} - ⚠️ WARNING: Chrome must be stopped first
- Example:
-
get_profile: Get current profile name and directory
- Example:
{action: "get_profile"} - Returns:
{"profile": "name", "profileDir": "/path"}
- Example:
Default behavior: Chrome starts in headless mode with "superpowers-chrome" profile.
Critical caveats when toggling modes:
- Chrome must restart - Cannot switch headless/headed mode on running Chrome
- Pages reload via GET - All open tabs are reopened with GET requests
- POST state is lost - Form submissions, POST results, and POST-based navigation will be lost
- Session state is lost - Any client-side state (JavaScript variables, etc.) is cleared
- Cookies/auth may persist - Uses same user data directory, so logged-in sessions may survive
When to use headed mode:
- Debugging visual rendering issues
- Demonstrating browser behavior to user
- Testing features that only work with visible browser
- Debugging issues that don't reproduce in headless mode
When to stay in headless mode (default):
- All other cases - faster, cleaner, less intrusive
- Screenshots work perfectly in headless mode
- Most automation works identically in both modes
Profile management:
Profiles store persistent browser data (cookies, localStorage, extensions, auth sessions).
Profile locations:
- macOS:
~/Library/Caches/superpowers/browser-profiles/{name}/ - Linux:
~/.cache/superpowers/browser-profiles/{name}/ - Windows:
%LOCALAPPDATA%/superpowers/browser-profiles/{name}/
When to use separate profiles:
- Default profile ("superpowers-chrome"): General automation, shared sessions
- Agent-specific profiles: Isolate different agents' browser state
- Example: browser-user agent uses "browser-user" profile
- Task-specific profiles: Testing with different user contexts
- Example: "test-logged-in" vs "test-logged-out"
Profile data persists across:
- Chrome restarts
- Mode toggles (headless ↔ headed)
- System reboots (data is in cache directory)
To use a different profile:
- Kill Chrome if running:
await chromeLib.killChrome() - Set profile:
{action: "set_profile", "payload": "my-profile"} - Start Chrome: Next navigate/action will use new profile
-
set_profile:切换Chrome配置文件(必须先关闭Chrome)
- 示例:
{action: "set_profile", "payload": "browser-user"} - ⚠️ 警告:必须先停止Chrome
- 示例:
-
get_profile:获取当前配置文件名称和目录
- 示例:
{action: "get_profile"} - 返回结果:
{"profile": "name", "profileDir": "/path"}
- 示例:
默认行为:Chrome会以无头模式启动,使用**"superpowers-chrome"配置文件**。
切换模式的重要注意事项:
- Chrome必须重启 - 无法在运行中的Chrome上切换无头/有头模式
- 页面通过GET重新加载 - 所有打开的标签页都会通过GET请求重新打开
- POST状态丢失 - 表单提交、POST请求结果以及基于POST的导航状态都会丢失
- 会话状态丢失 - 所有客户端状态(如JavaScript变量等)都会被清除
- Cookie/认证信息可能保留 - 使用相同的用户数据目录,因此已登录的会话可能会保留
何时使用有头模式:
- 调试视觉渲染问题
- 向用户演示浏览器行为
- 测试仅在可见浏览器中生效的功能
- 调试在无头模式下无法复现的问题
何时保持无头模式(默认):
- 其他所有场景 - 速度更快、更简洁、干扰更少
- 无头模式下截图功能完全正常
- 大多数自动化操作在两种模式下表现一致
配置文件管理说明:
配置文件用于存储持久化的浏览器数据(Cookie、localStorage、扩展程序、认证会话)。
配置文件位置:
- macOS:
~/Library/Caches/superpowers/browser-profiles/{name}/ - Linux:
~/.cache/superpowers/browser-profiles/{name}/ - Windows:
%LOCALAPPDATA%/superpowers/browser-profiles/{name}/
何时使用独立配置文件:
- 默认配置文件("superpowers-chrome"):通用自动化、共享会话
- Agent专属配置文件:隔离不同Agent的浏览器状态
- 示例:browser-user agent使用"browser-user"配置文件
- 任务专属配置文件:在不同用户上下文下进行测试
- 示例:"test-logged-in" vs "test-logged-out"
配置文件数据在以下场景中会保留:
- Chrome重启
- 模式切换(无头↔有头)
- 系统重启(数据存储在缓存目录中)
如何使用不同的配置文件:
- 如果Chrome正在运行,先关闭它:
await chromeLib.killChrome() - 设置配置文件:
{action: "set_profile", "payload": "my-profile"} - 启动Chrome:下一次导航或操作会使用新的配置文件
Quick Start Pattern
快速入门示例
Navigate and extract:
{action: "navigate", payload: "https://example.com"}
{action: "await_element", selector: "h1"}
{action: "extract", payload: "text", selector: "h1"}导航并提取内容:
{action: "navigate", payload: "https://example.com"}
{action: "await_element", selector: "h1"}
{action: "extract", payload: "text", selector: "h1"}Common Patterns
常见使用模式
Fill and Submit Form
填写并提交表单
{action: "navigate", payload: "https://example.com/login"}
{action: "await_element", selector: "input[name=email]"}
{action: "type", selector: "input[name=email]", payload: "user@example.com"}
{action: "type", selector: "input[name=password]", payload: "pass123\n"}
{action: "await_text", payload: "Welcome"}The at the end of the password submits the form.
\n{action: "navigate", payload: "https://example.com/login"}
{action: "await_element", selector: "input[name=email]"}
{action: "type", selector: "input[name=email]", payload: "user@example.com"}
{action: "type", selector: "input[name=password]", payload: "pass123\n"}
{action: "await_text", payload: "Welcome"}密码末尾的会自动提交表单。
\nMulti-Tab Workflow
多标签页工作流
{action: "list_tabs"}
{action: "click", tab_index: 2, selector: "a.email"}
{action: "await_element", tab_index: 2, selector: ".content"}
{action: "extract", tab_index: 2, payload: "text", selector: ".amount"}{action: "list_tabs"}
{action: "click", tab_index: 2, selector: "a.email"}
{action: "await_element", tab_index: 2, selector: ".content"}
{action: "extract", tab_index: 2, payload: "text", selector: ".amount"}Dynamic Content
动态内容处理
{action: "navigate", payload: "https://example.com"}
{action: "type", selector: "input[name=q]", payload: "query"}
{action: "click", selector: "button.search"}
{action: "await_element", selector: ".results"}
{action: "extract", payload: "text", selector: ".result-title"}{action: "navigate", payload: "https://example.com"}
{action: "type", selector: "input[name=q]", payload: "query"}
{action: "click", selector: "button.search"}
{action: "await_element", selector: ".results"}
{action: "extract", payload: "text", selector: ".result-title"}Get Link Attribute
获取链接属性
{action: "navigate", payload: "https://example.com"}
{action: "await_element", selector: "a.download"}
{action: "attr", selector: "a.download", payload: "href"}{action: "navigate", payload: "https://example.com"}
{action: "await_element", selector: "a.download"}
{action: "attr", selector: "a.download", payload: "href"}Execute JavaScript
执行JavaScript代码
{action: "eval", payload: "document.querySelectorAll('a').length"}
{action: "eval", payload: "Array.from(document.querySelectorAll('a')).map(a => a.href)"}{action: "eval", payload: "document.querySelectorAll('a').length"}
{action: "eval", payload: "Array.from(document.querySelectorAll('a')).map(a => a.href)"}Resize Viewport (Responsive Testing)
调整视口大小(响应式测试)
Use to resize the browser window for testing responsive layouts:
eval{action: "eval", payload: "window.resizeTo(375, 812); 'Resized to mobile'"}
{action: "eval", payload: "window.resizeTo(768, 1024); 'Resized to tablet'"}
{action: "eval", payload: "window.resizeTo(1920, 1080); 'Resized to desktop'"}Note: This resizes the window, not device emulation. It won't change:
- Device pixel ratio (retina displays)
- Touch events
- User-Agent string
For most responsive testing, window resize is sufficient.
使用调整浏览器窗口大小,以测试响应式布局:
eval{action: "eval", payload: "window.resizeTo(375, 812); 'Resized to mobile'"}
{action: "eval", payload: "window.resizeTo(768, 1024); 'Resized to tablet'"}
{action: "eval", payload: "window.resizeTo(1920, 1080); 'Resized to desktop'"}注意:此操作仅调整窗口大小,并非设备模拟。不会改变以下内容:
- 设备像素比(视网膜显示屏)
- 触摸事件
- User-Agent字符串
对于大多数响应式测试,调整窗口大小已足够。
Clear Cookies
清除Cookie
Use to clear cookies accessible to JavaScript:
eval{action: "eval", payload: "document.cookie.split(';').forEach(c => { document.cookie = c.trim().split('=')[0] + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/'; }); 'Cookies cleared'"}Note: This clears cookies accessible to JavaScript. It won't clear:
- httpOnly cookies (server-side only)
- Cookies from other domains
For most logout/reset scenarios, this is sufficient.
使用清除JavaScript可访问的Cookie:
eval{action: "eval", payload: "document.cookie.split(';').forEach(c => { document.cookie = c.trim().split('=')[0] + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/'; }); 'Cookies cleared'"}注意:此操作仅清除JavaScript可访问的Cookie,无法清除:
- httpOnly Cookie(仅服务器端可访问)
- 其他域名的Cookie
对于大多数登出/重置场景,此操作已足够。
Scroll Page
滚动页面
{action: "eval", payload: "window.scrollTo(0, document.body.scrollHeight); 'Scrolled to bottom'"}
{action: "eval", payload: "window.scrollTo(0, 0); 'Scrolled to top'"}
{action: "eval", payload: "document.querySelector('.target').scrollIntoView(); 'Scrolled to element'"}{action: "eval", payload: "window.scrollTo(0, document.body.scrollHeight); 'Scrolled to bottom'"}
{action: "eval", payload: "window.scrollTo(0, 0); 'Scrolled to top'"}
{action: "eval", payload: "document.querySelector('.target').scrollIntoView(); 'Scrolled to element'"}Tips
技巧提示
Always wait before interaction:
Don't click or fill immediately after navigate - pages need time to load.
// BAD - might fail if page slow
{action: "navigate", payload: "https://example.com"}
{action: "click", selector: "button"} // May fail!
// GOOD - wait first
{action: "navigate", payload: "https://example.com"}
{action: "await_element", selector: "button"}
{action: "click", selector: "button"}Use specific selectors:
Avoid generic selectors that match multiple elements.
// BAD - matches first button
{action: "click", selector: "button"}
// GOOD - specific
{action: "click", selector: "button[type=submit]"}
{action: "click", selector: "#login-button"}Submit forms with \n:
Append newline to text to submit forms automatically.
{action: "type", selector: "#search", payload: "query\n"}Check content first:
Extract page content to verify selectors before building workflow.
{action: "extract", payload: "html"}交互前务必等待:
不要在导航后立即点击或填写内容——页面需要加载时间。
// 错误示例 - 如果页面加载缓慢可能失败
{action: "navigate", payload: "https://example.com"}
{action: "click", selector: "button"} // 可能失败!
// 正确示例 - 先等待
{action: "navigate", payload: "https://example.com"}
{action: "await_element", selector: "button"}
{action: "click", selector: "button"}使用特定的选择器:
避免使用会匹配多个元素的通用选择器。
// 错误示例 - 匹配第一个按钮
{action: "click", selector: "button"}
// 正确示例 - 特定选择器
{action: "click", selector: "button[type=submit]"}
{action: "click", selector: "#login-button"}用\n提交表单:
在文本末尾追加换行符可自动提交表单。
{action: "type", selector: "#search", payload: "query\n"}先检查内容:
在构建工作流前,先提取页面内容以验证选择器是否正确。
{action: "extract", payload: "html"}Troubleshooting
故障排除
Element not found:
- Use before interaction
await_element - Verify selector with action using 'html' format
extract
Timeout errors:
- Increase timeout: for slow pages
{timeout: 30000} - Wait for specific element instead of text
Tab index out of range:
- Use to get current indices
list_tabs - Tab indices change when tabs close
eval returns :
[object Object]- Use for complex objects:
JSON.stringify(){action: "eval", payload: "JSON.stringify({name: 'test'})"} - For async functions:
{action: "eval", payload: "JSON.stringify(await yourAsyncFunction())"}
元素未找到:
- 交互前使用等待
await_element - 使用操作并选择'html'格式来验证选择器
extract
超时错误:
- 增加超时时间:对于加载缓慢的页面,设置
{timeout: 30000} - 等待特定元素而非文本
标签页索引超出范围:
- 使用获取当前标签页索引
list_tabs - 关闭标签页后,标签页索引会发生变化
eval返回:
[object Object]- 对于复杂对象,使用:
JSON.stringify(){action: "eval", payload: "JSON.stringify({name: 'test'})"} - 对于异步函数:
{action: "eval", payload: "JSON.stringify(await yourAsyncFunction())"}
Test Automation (Advanced)
测试自动化(进阶)
<details>
<summary>Click to expand test automation guidance</summary>
When building test automation, you have two approaches:
<details>
<summary>点击展开测试自动化指南</summary>
构建测试自动化时,有两种方法:
Approach 1: use_browser MCP (Simple Tests)
方法1:use_browser MCP(简单测试)
Best for: Single-step tests, direct Claude control during conversation
json
{"action": "navigate", "payload": "https://app.com"}
{"action": "click", "selector": "#test-button"}
{"action": "eval", "payload": "JSON.stringify({passed: document.querySelector('.success') !== null})"}最适合:单步测试、对话过程中由Claude直接控制
json
{"action": "navigate", payload: "https://app.com"}
{"action": "click", selector: "#test-button"}
{"action": "eval", payload: "JSON.stringify({passed: document.querySelector('.success') !== null})"}Approach 2: chrome-ws CLI (Complex Tests)
方法2:chrome-ws CLI(复杂测试)
Best for: Multi-step test suites, standalone automation scripts
Key insight: is the reference implementation showing proper Chrome DevTools Protocol usage. When doesn't work as expected, examine how handles the same operation.
chrome-wsuse_browserchrome-wsbash
undefined最适合:多步测试套件、独立自动化脚本
关键提示:是展示正确Chrome DevTools Protocol用法的参考实现。当无法按预期工作时,查看如何处理相同操作。
chrome-wsuse_browserchrome-wsbash
undefinedExample: Automated form testing
示例:自动化表单测试
./chrome-ws navigate 0 "https://app.com/form"
./chrome-ws fill 0 "#email" "test@example.com"
./chrome-ws click 0 "button[type=submit]"
./chrome-ws wait-text 0 "Success"
undefined./chrome-ws navigate 0 "https://app.com/form"
./chrome-ws fill 0 "#email" "test@example.com"
./chrome-ws click 0 "button[type=submit]"
./chrome-ws wait-text 0 "Success"
undefinedWhen use_browser Fails
当use_browser失效时
- Check chrome-ws source code - It shows the correct CDP pattern
- Use chrome-ws to verify - Test the same operation via CLI
- Adapt the pattern - Apply the working CDP approach to use_browser
- 查看chrome-ws源代码 - 它展示了正确的CDP模式
- 用chrome-ws验证 - 通过CLI测试相同操作
- 适配模式 - 将可行的CDP方法应用到use_browser中
Common Test Automation Patterns
常见测试自动化模式
- Form validation: Fill forms, check error states
- UI state testing: Click elements, verify DOM changes
- Performance testing: Measure load times, capture metrics
- Screenshot comparison: Capture before/after states
- 表单验证:填写表单,检查错误状态
- UI状态测试:点击元素,验证DOM变化
- 性能测试:测量加载时间,捕获指标
- 截图对比:捕获操作前后的状态
Advanced Usage
进阶用法
For command-line usage outside Claude Code, see COMMANDLINE-USAGE.md.
For detailed examples, see EXAMPLES.md.
如需在Claude Code之外使用命令行,请查看COMMANDLINE-USAGE.md。
如需详细示例,请查看EXAMPLES.md。
Protocol Reference
协议参考
Full CDP documentation: https://chromedevtools.github.io/devtools-protocol/