episodic-memory
Semantic search for Claude Code and Codex conversations. Remember past discussions, decisions, and patterns.
Direct browser control via Chrome DevTools Protocol. Two modes available: Skill Mode - CLI tool for Claude Code agents (browsing skill) MCP Mode - Ultra-lightweight MCP server for any MCP client
> /plugin marketplace add obra/superpowers-chrome> /plugin install superpowers-chrome@superpowers-chrome-dev
Repo: obra/superpowers-chrome
What's inside
Direct browser control via Chrome DevTools Protocol. Two modes available:
browsing skill)0, 1, 2) instead of WebSocket URLschrome-ws start works on macOS, Linux, Windows/plugin marketplace add obra/superpowers-marketplace
/plugin install superpowers-chrome@superpowers-marketplace
# Find your plugin installation path (varies by marketplace and version)
# Common locations:
# ~/.claude/plugins/cache/superpowers-marketplace/superpowers-chrome/<version>/skills/browsing
# ~/.claude/plugins/cache/superpowers-chrome/skills/browsing
cd ~/.claude/plugins/cache/superpowers-marketplace/superpowers-chrome/*/skills/browsing
./chrome-ws start # Launch Chrome
./chrome-ws new "https://example.com" # Create tab
./chrome-ws navigate 0 "https://google.com"
./chrome-ws fill 0 "textarea[name=q]" "test"
./chrome-ws click 0 "button[name=btnK]"
Port allocation: Chrome gets a dynamically allocated port (range 9222-12111) to avoid conflicts. Port assignment is persisted per profile in ~/.cache/superpowers/browser-profiles/{name}.meta.json. Override with --port=N flag or CHROME_WS_PORT env var. Multiple profiles can run in parallel on different ports.
Parallel MCPs on one host (3.0+): the bridge auto-disambiguates the default profile. The first MCP claims superpowers-chrome:9222, the next silently falls through to superpowers-chrome-2:9223, then -3:9224, etc., each driving its own Chrome with its own profile dir. To intentionally share a Chrome between processes (e.g., a chrome-ws CLI session + a Claude MCP attaching to it), set a fixed profile via CHROME_WS_PROFILE=name (env var) or call {action: "set_profile", payload: "name"} at runtime โ explicit profiles share rather than disambiguate.
Windows tip: The tooling defaults to 127.0.0.1 for DevTools traffic. Override via CHROME_WS_HOST / CHROME_WS_PORT or --port=N if you forward Chrome elsewhere.
Linux/WSL2 tip: For headed mode (visible browser), the MCP server needs the DISPLAY environment variable. If show_browser doesn't work, configure "env": {"DISPLAY": ":0"} in your MCP server config. See mcp/README.md for details. Running as root or inside a container is detected automatically and disables Chrome's sandbox; on a headless box add CHROME_EXTRA_ARGS="--headless=new --disable-gpu".
Custom Chrome flags: Set CHROME_EXTRA_ARGS to a whitespace-separated list of flags that will be appended to the Chrome command line on launch. Useful for headless containers that need software WebGL:
CHROME_EXTRA_ARGS="--use-gl=angle --use-angle=swiftshader-webgl --enable-unsafe-swiftshader"
node skills/browsing/chrome-ws start launched Chrome with remote debugging enabled on a fresh Windows 11 Pro install.node skills/browsing/chrome-ws tabs and node skills/browsing/chrome-ws navigate 0 https://example.com confirmed CLI control with the IPv4 default binding.codex exec -c "mcp_servers.superpowers-chrome.enabled=true" "List Chrome tabs via MCP to verify the Windows override patch." listed the Example Domain tab through the MCP server, demonstrating that the overrides also work through Codex.start (auto-detects platform)tabs, new, closenavigate, wait-for, wait-textclick, fill, selecteval, extract, attr, htmlscreenshot, markdownraw (full CDP access)Pages that open JavaScript dialogs (alert, confirm, prompt, beforeunload), WebUSB/Bluetooth/Serial/HID device choosers, HTTP basic-auth challenges, or permission prompts (camera, microphone, notifications, geolocation, clipboard) no longer wedge the connection. The dialog is surfaced as a synthetic page response and the agent interacts with it using the existing click and type actions against a small dialog::* selector grammar.
While a dialog is open, any page-targeted action (extract, screenshot, eval, attr, click <real-selector>, etc.) returns a clear refusal with the dialog content and instructions:
Page is behind a dialog. Handle dialog::accept or dialog::dismiss first.
# Dialog: confirm
Tab origin: https://example.com
> Are you sure you want to leave?
Buttons:
- dialog::accept (OK)
- dialog::dismiss (Cancel)
To interact:
click selector="dialog::accept"
click selector="dialog::dismiss"
Browser-targeted actions (list_tabs, new_tab, close_tab, etc.) pass through unaffected.
| Selector | Purpose |
|---|---|
click dialog::accept | OK / Grant / Provide credentials, depending on dialog kind |
click dialog::dismiss | Cancel / Deny |
type dialog::prompt <value> | Stage prompt text; commit on dialog::accept |
click dialog::device[id="โฆ"] | Pick a device in the chooser (USB, BT, Serial, HID) |
type dialog::username <value> / type dialog::password <value> | Basic-auth credentials |
# 1. Page on load: alert('Saved!')
extract payload=text
# โ refused with synthetic dialog markdown
# 2. Dismiss
click selector="dialog::accept"
# 3. Page is interactive again
extract payload=text
# โ returns the page text
Permission prompts (getUserMedia, Notification.requestPermission, geolocation, clipboard) are caught by a document_start JS-API shim and surfaced through the same flow.
See docs/superpowers/specs/2026-05-13-dialog-handling-design.md for the full design.
Ultra-lightweight MCP server with a single use_browser tool. Perfect for minimal context usage with automatic page captures.
Option 1: NPX from GitHub (Recommended)
{
"mcpServers": {
"chrome": {
"command": "npx",
"args": [
"github:obra/superpowers-chrome"
]
}
}
}
Option 1b: NPX with Headless Mode
{
"mcpServers": {
"chrome": {
"command": "npx",
"args": [
"github:obra/superpowers-chrome",
"--headless"
]
}
}
}
Option 2: Git Clone + Local Path (Current)
git clone https://github.com/obra/superpowers-chrome.git
cd superpowers-chrome/mcp && npm install && npm run build
{
"mcpServers": {
"chrome": {
"command": "node",
"args": [
"/path/to/superpowers-chrome/mcp/dist/index.js"
]
}
}
}
DOM-changing actions (navigate, click, type, select, eval) automatically capture:
Response format:
โ https://example.com (capture #001)
Size: 1200ร765
Snapshot: /tmp/chrome-session-123/001-navigate-456/
Resources: page.html, page.md, screenshot.png, console-log.txt
DOM:
Example Domain
Interactive: 0 buttons, 0 inputs, 1 links
Layout: body
{
"action": "navigate",
"payload": "https://example.com"
}
Get help: {"action": "help"} - Returns complete documentation
See mcp/README.md for complete documentation.
Use Skill Mode when:
Use MCP Mode when:
Use Playwright MCP when:
MIT
.claude-plugin/
marketplace.json
plugin.json
.gitignore
.private-journal/
2025-11-01/
17-52-44-883761.embedding
17-52-44-883761.md
18-38-02-377659.embedding
18-38-02-377659.md
19-03-08-260343.embedding
19-03-08-260343.md
agents/
browser-user.md
biome.json
CHANGELOG.md
CLAUDE.md
docs/
cdp/
autoattach-popup-timing.md
flatten-mode.md
headless-variants.md
INDEX.md
navigation-listener-race.md
per-session-id-counters.md
target-lifecycle.md
superpowers/
plans/
2026-05-05-post-c5-followup.md
2026-05-06-bug-fixes-after-manual-test.md
2026-05-13-dialog-handling.md
2026-05-22-mcp-schema-reshape.md
specs/
2026-05-05-post-c5-followup-design.md
2026-05-13-dialog-handling-design.md
TESTING-INSTRUCTIONS.md
LICENSE
mcp/
.gitignore
CHANGELOG.md
dist/
index.d.ts
index.d.ts.map
index.js
index.js.map
payload.d.ts
payload.d.ts.map
payload.js
payload.js.map
package-lock.json
package.json
README.md
src/
index.ts
payload.ts
tsconfig.json
package-lock.json
package.json
README.md
scripts/
check-bundle-fresh.sh
skills/
browsing/
.gitignore
chrome-ws
chrome-ws-lib.js
COMMANDLINE-USAGE.md
EXAMPLES.md
host-override.js
lib/
browser-bridge.js
browser-session.js
capture.js
cdp-router.js
cdp-utils.js
chrome-launcher-helpers.js
chrome-process.js
console-logging.js
cookies.js
dialogs-render.js
dialogs-router.js
dialogs.js
element-selector.js
evaluation.js
extraction.js
file-upload.js
html-diff.js
key-definitions.js
keyboard-input.js
mouse.js
navigation.js
page-scripts/
dom-summary.js
markdown.js
permission-shim.js
page-session.js
profile-lock.js
screenshot.js
select-option.js
session-state.js
tabs.js
viewport.js
websocket-client.js
package.json
README.md
SKILL.md
test-chrome-args.js
test-cookies.js
test-e2e.sh
test-extract.sh
test-interact.sh
test-navigate.sh
test-raw.sh
test-tabs.sh
test-viewport.js
test-wait.sh
test/
test-harness.js
test-headless-toggle.cjs
test-issue-18-pid.cjs
test-issue-19-fullpage.cjs
test-issue-20-hidpi.cjs
test-profiles.cjs
test-xdg-cache.cjs
array-guards.test.mjs
bundle-drift.test.mjs
bundle-loads.test.mjs
cli-dispatch.test.mjs
dialogs-wiring.test.mjs
dialogs.smoke.test.mjs
element-selector.test.mjs
evaluate-await-promise.test.mjs
fixtures/
popup-opener.html
popup-with-confirm.html
host-lifecycle.test.mjs
lib/
_helpers.mjs
_helpers.test.mjs
browser-bridge.test.mjs
browser-session.test.mjs
capture.test.mjs
cdp-router.test.mjs
chrome-launcher-helpers.test.mjs
chrome-process.test.mjs
chrome-ws-lib-bridge.test.mjs
cli-close-numeric.test.mjs
console-logging.test.mjs
cookies.test.mjs
dialogs-render.test.mjs
dialogs-router.test.mjs
dialogs.test.mjs
evaluation.test.mjs
extraction.test.mjs
file-upload.test.mjs
find-pid-on-port-guard.test.mjs
fixtures/
dialog-alert.md
dialog-basic-auth-no-realm.md
dialog-basic-auth.md
dialog-beforeunload.md
dialog-confirm.md
dialog-device-chooser-0.md
dialog-device-chooser-1.md
dialog-device-chooser-many.md
dialog-permission.md
dialog-prompt-default.md
dialog-prompt.md
html-diff.test.mjs
key-definitions.test.mjs
keyboard-input.test.mjs
mouse.test.mjs
navigation.test.mjs
page-scripts/
dom-summary.test.mjs
markdown.test.mjs
page-session.test.mjs
profile-lock.test.mjs
screenshot-exec-safety.test.mjs
screenshot.test.mjs
select-option.test.mjs
session-state.test.mjs
tabs.test.mjs
viewport.test.mjs
websocket-client-no-compression.test.mjs
mcp-error-flag.test.mjs
mcp-postel-fixes.test.mjs
mcp-schema.test.mjs
payload-normalization.test.mjs
popup-dialog-integration.test.mjs
schema-collapse.test.mjs
session-isolation.test.mjs
smoke.test.mjs
tests/
scenarios/
01-smoke.md
02-action-libs.md
03-dialog-confirm.md
04-popup-dialog.md
05-popup-form-fill.md
06-failure-modes.md
07-cli-smoke.md
08-mouse-keyboard-extras.md
09-file-upload-and-console.md
10-dialog-kinds-extras.md
11-browser-actions.md
12-iframes-https.md
13-multi-tab-and-service-worker.md
14-recovery.md
README.mdSemantic search for Claude Code and Codex conversations. Remember past discussions, decisions, and patterns.
Experimental skills for Claude Code Superpowers - new techniques and tools under active development.
FAQ
superpowers-chrome is a Claude Code plugin with 1 hand-picked skill for automation work, indexed on Flowy. Install it with the command on its page. It includes browsing. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.