browsing by obra/superpowers-chrome
npx skills add https://github.com/obra/superpowers-chrome --skill browsing使用 use_browser MCP 工具通过 DevTools 协议控制 Chrome。单一的统一接口,可自动启动 Chrome。
声明: "我正在使用浏览技能来控制 Chrome。"
在以下情况下使用此方式:
在以下情况下使用 Playwright MCP:
每次 DOM 操作(导航、点击、输入、选择、执行脚本、键盘按键)都会自动保存:
{前缀}.png — 视口屏幕截图{前缀}.md — 页面内容,以结构化 Markdown 格式保存{前缀}.html — 完整的渲染后 DOM{前缀}-console.txt — 浏览器控制台消息广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
文件保存到会话目录,使用顺序前缀(001-navigate、002-click 等)。在使用提取或屏幕截图操作之前,必须检查这些文件。
单一的 MCP 工具,提供基于操作的接口。Chrome 在首次使用时自动启动。
参数:
action(必需):要执行的操作tab_index(可选):要操作的标签页索引(默认:0)selector(可选):用于元素操作的 CSS 选择器payload(可选):特定于操作的数据timeout(可选):等待操作超时时间(毫秒)(默认:5000)payload:URL 字符串{action: "navigate", payload: "https://example.com"}selector:CSS 选择器timeout:最大等待时间(毫秒){action: "await_element", selector: ".loaded", timeout: 10000}payload:要等待的文本{action: "await_text", payload: "Welcome"}selector:CSS 选择器{action: "click", selector: "button.submit"}\n 以提交)
selector:CSS 选择器payload:要输入的文本{action: "type", selector: "#email", payload: "user@example.com\n"}selector:CSS 选择器payload:选项值{action: "select", selector: "select[name=state]", payload: "CA"}payload:格式('markdown'|'text'|'html')selector:可选 - 限制在特定元素内{action: "extract", payload: "markdown"}{action: "extract", payload: "text", selector: "h1"}selector:CSS 选择器payload:属性名称{action: "attr", selector: "a.download", payload: "href"}payload:JavaScript 代码{action: "eval", payload: "document.title"}payload:文件名selector:可选 - 截取特定元素{action: "screenshot", payload: "/tmp/chart.png", selector: ".chart"}{action: "list_tabs"}{action: "new_tab"}tab_index:要关闭的标签页索引{action: "close_tab", tab_index: 2}{action: "show_browser"}{action: "hide_browser"}{action: "browser_mode"}{"headless": true|false, "mode": "headless"|"headed", "running": true|false, "port": 9222, "profile": "name", "profileDir": "/path"}{action: "set_profile", "payload": "browser-user"}{action: "get_profile"}{"profile": "name", "profileDir": "/path"}默认行为:Chrome 以无头模式启动,使用 "superpowers-chrome" 配置文件,在动态分配的端口(范围 9222-12111)上运行。可通过 CHROME_WS_PORT 环境变量或 MCP --port=N 标志覆盖。
切换模式时的关键注意事项:
何时使用有头模式:
何时保持在无头模式(默认):
配置文件管理:配置文件存储持久的浏览器数据(Cookie、localStorage、扩展程序、认证会话)。
配置文件位置:
~/Library/Caches/superpowers/browser-profiles/{name}/~/.cache/superpowers/browser-profiles/{name}/%LOCALAPPDATA%/superpowers/browser-profiles/{name}/何时使用单独的配置文件:
配置文件数据在以下情况中持续存在:
要使用不同的配置文件:
await chromeLib.killChrome(){action: "set_profile", "payload": "my-profile"}导航并提取:
{action: "navigate", payload: "https://example.com"}
{action: "await_element", selector: "h1"}
{action: "extract", payload: "text", selector: "h1"}
{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"}
密码末尾的 \n 用于提交表单。
{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: "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: "await_element", selector: "a.download"}
{action: "attr", selector: "a.download", payload: "href"}
{action: "eval", payload: "document.querySelectorAll('a').length"}
{action: "eval", payload: "Array.from(document.querySelectorAll('a')).map(a => a.href)"}
使用 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'"}
注意:这调整的是窗口大小,而不是设备模拟。它不会改变:
对于大多数响应式测试,调整窗口大小就足够了。
使用 eval 清除 JavaScript 可访问的 Cookie:
{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。它不会清除:
对于大多数登出/重置场景,这已经足够了。
{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: "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"}
找不到元素:
await_elementextract 操作验证选择器超时错误:
{timeout: 30000} 用于慢速页面标签页索引超出范围:
list_tabs 获取当前索引eval 返回 [object Object]:
JSON.stringify():{action: "eval", payload: "JSON.stringify({name: 'test'})"}{action: "eval", payload: "JSON.stringify(await yourAsyncFunction())"}构建测试自动化时,您有两种方法:
最适合:单步测试、对话期间直接由 Claude 控制
{"action": "navigate", "payload": "https://app.com"}
{"action": "click", "selector": "#test-button"}
{"action": "eval", "payload": "JSON.stringify({passed: document.querySelector('.success') !== null})"}
最适合:多步测试套件、独立的自动化脚本
关键见解:chrome-ws 是展示正确 Chrome DevTools 协议使用方式的参考实现。当 use_browser 未按预期工作时,检查 chrome-ws 如何处理相同的操作。
# 示例:自动化表单测试
./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"
有关在 Claude Code 之外使用命令行的信息,请参阅 COMMANDLINE-USAGE.md。
有关详细示例,请参阅 EXAMPLES.md。
每周安装数
155
仓库
GitHub 星标数
219
首次出现
2026年1月29日
安全审计
安装于
opencode149
codex146
gemini-cli139
github-copilot138
kimi-cli137
amp137
Control Chrome via DevTools Protocol using the use_browser MCP tool. Single unified interface with auto-starting Chrome.
Announce: "I'm using the browsing skill to control Chrome."
Use this when:
Use Playwright MCP when:
Every DOM action (navigate, click, type, select, eval, keyboard_press) automatically saves:
{prefix}.png — viewport screenshot{prefix}.md — page content as structured markdown{prefix}.html — full rendered DOM{prefix}-console.txt — browser console messagesFiles are saved to the session directory with sequential prefixes (001-navigate, 002-click, etc.). You must check these before using extract or screenshot actions.
Single MCP tool with action-based interface. Chrome auto-starts on first use.
Parameters:
action (required): Operation to performtab_index (optional): Tab to operate on (default: 0)selector (optional): CSS selector for element operationspayload (optional): Action-specific datatimeout (optional): Timeout in ms for await operations (default: 5000)navigate : Navigate to URL
payload: URL string{action: "navigate", payload: "https://example.com"}await_element : Wait for element to appear
selector: CSS selectortimeout: Max wait time in ms{action: "await_element", selector: ".loaded", timeout: 10000}await_text : Wait for text to appear
payload: Text to wait for{action: "await_text", payload: "Welcome"}click : Click element
selector: CSS selector{action: "click", selector: "button.submit"}type : Type text into input (append \n to submit)
selector: CSS selectorpayload: Text to type{action: "type", selector: "#email", payload: "user@example.com\n"}select : Select dropdown option
selector: CSS selectorextract : Get page content
payload: Format ('markdown'|'text'|'html')selector: Optional - limit to element{action: "extract", payload: "markdown"}{action: "extract", payload: "text", selector: "h1"}attr : Get element attribute
selector: CSS selectorpayload: Attribute name{action: "attr", selector: "a.download", payload: "href"}: Execute JavaScript
payload: Filenameselector: Optional - screenshot specific element{action: "screenshot", payload: "/tmp/chart.png", selector: ".chart"}list_tabs : List all open tabs
{action: "list_tabs"}new_tab : Create new tab
{action: "new_tab"}close_tab : Close tab
tab_index: Tab to close{action: "close_tab", tab_index: 2}show_browser : Make browser window visible (headed mode)
{action: "show_browser"}hide_browser : Switch to headless mode (invisible browser)
{action: "hide_browser"}browser_mode : Check current browser mode, port, and profile
{action: "browser_mode"}{"headless": true|false, "mode": "headless"|"headed", "running": true|false, "port": 9222, "profile": "name", "profileDir": "/path"}set_profile : Change Chrome profile (must kill Chrome first)
{action: "set_profile", "payload": "browser-user"}get_profile : Get current profile name and directory
{action: "get_profile"}{"profile": "name", "profileDir": "/path"}Default behavior : Chrome starts in headless mode with "superpowers-chrome" profile on a dynamically allocated port (range 9222-12111). Override with CHROME_WS_PORT env var or MCP --port=N flag.
Critical caveats when toggling modes :
When to use headed mode :
When to stay in headless mode (default):
Profile management : Profiles store persistent browser data (cookies, localStorage, extensions, auth sessions).
Profile locations :
~/Library/Caches/superpowers/browser-profiles/{name}/~/.cache/superpowers/browser-profiles/{name}/%LOCALAPPDATA%/superpowers/browser-profiles/{name}/When to use separate profiles :
Profile data persists across :
To use a different profile :
await chromeLib.killChrome(){action: "set_profile", "payload": "my-profile"}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/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 \n at the end of the password submits the form.
{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: "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: "await_element", selector: "a.download"}
{action: "attr", selector: "a.download", payload: "href"}
{action: "eval", payload: "document.querySelectorAll('a').length"}
{action: "eval", payload: "Array.from(document.querySelectorAll('a')).map(a => a.href)"}
Use eval to resize the browser window for testing responsive layouts:
{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:
For most responsive testing, window resize is sufficient.
Use eval to clear cookies accessible to JavaScript:
{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:
For most logout/reset scenarios, this is sufficient.
{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'"}
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"}
Element not found:
await_element before interactionextract action using 'html' formatTimeout errors:
{timeout: 30000} for slow pagesTab index out of range:
list_tabs to get current indiceseval returns[object Object]:
JSON.stringify() for complex objects: {action: "eval", payload: "JSON.stringify({name: 'test'})"}{action: "eval", payload: "JSON.stringify(await yourAsyncFunction())"}When building test automation, you have two approaches:
Best for: Single-step tests, direct Claude control during conversation
{"action": "navigate", "payload": "https://app.com"}
{"action": "click", "selector": "#test-button"}
{"action": "eval", "payload": "JSON.stringify({passed: document.querySelector('.success') !== null})"}
Best for: Multi-step test suites, standalone automation scripts
Key insight : chrome-ws is the reference implementation showing proper Chrome DevTools Protocol usage. When use_browser doesn't work as expected, examine how chrome-ws handles the same operation.
# Example: 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"
For command-line usage outside Claude Code, see COMMANDLINE-USAGE.md.
For detailed examples, see EXAMPLES.md.
Full CDP documentation: https://chromedevtools.github.io/devtools-protocol/
Weekly Installs
155
Repository
GitHub Stars
219
First Seen
Jan 29, 2026
Security Audits
Gen Agent Trust HubFailSocketPassSnykFail
Installed on
opencode149
codex146
gemini-cli139
github-copilot138
kimi-cli137
amp137
通过 LiteLLM 代理让 Claude Code 对接 GitHub Copilot 运行 | 高级变通方案指南
36,300 周安装
payload: Option value(s){action: "select", selector: "select[name=state]", payload: "CA"}payload: JavaScript code{action: "eval", payload: "document.title"}