/web-bridge
Control a real browser via CDP — navigate, click, type, screenshot, and extract web content. No Chrome extension required.
$ npx -y skills add AgenticMatrix/coderix --skill web-bridge --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/web-bridge
Context preview
The summary Claude sees to decide when to auto-load this skill.
Control a real browser via CDP — navigate, click, type, screenshot, and extract web content. No Chrome extension required.
SKILL.md
web-bridge.SKILL.mdname: web-bridge
description: Control a real browser via CDP — navigate, click, type, screenshot, and extract web content. No Chrome extension required.
version: "2.1"
triggers: [web-bridge, webbridge, browser control, browser automation, CDP, chrome devtools, 截图, 浏览器操作, 网页自动化]
tools: [bash]
tags: [browser, automation, web]
author: Coderix
Web Bridge — Browser Automation via CDP
Control a real Chrome/Edge browser from the AI agent. **No extension installation needed.** All data stays local.
Quick Start
Start the bridge server (one command)
node ~/.coderix/skills/web-bridge/bridge-server.cjs
The server auto-detects Chrome/Edge, launches it with remote debugging, and listens on port **9223**. You'll see `BRIDGE_READY port=9223` when ready.
If Chrome is already running with `--remote-debugging-port=9222`, the server connects to it instead of launching a new one.
Make a request
curl -s -X POST http://127.0.0.1:9223/cmd \
-H 'Content-Type: application/json' \
-d '{"action":"navigate","params":{"url":"https://example.com"}}'All commands go to `POST /cmd` with JSON body `{"action":"...", "params":{...}}`.
Sessions
Add `"session":"name"` to the request body to isolate tabs for multi-task workflows. Each session tracks its own set of tabs.
# Start a task in its own session
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"navigate","params":{"url":"https://example.com","new_tab":true},"session":"research"}'
# Later actions in the same session automatically use the right tab
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"snapshot","session":"research"}'
# Close all tabs in a session when done (session name optional if active)
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"close_session","session":"research"}'
# Or close the last active session without naming it
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"close_session"}'Without a session, all operations use the first available tab.
Health check
curl -s http://127.0.0.1:9223/
# {"status":"ok","version":"Chrome/150...","uptime_seconds":120,"extensionConnected":false,"mode":"cdp","port":9223,"cdpPort":9222}Server options
| Flag | Description | |------|-------------| | `--port 9223` | Listen port (default: 9223) | | `--cdp-port 9222` | CDP debug port (default: 9222) | | `--browser-path /path/to/chrome` | Custom browser binary | | `--headless` | Run browser headless | | `--no-auto-launch` | Don't auto-launch browser (connect to existing) |
Operations Reference
Browser Lifecycle
| Action | Params | Notes | |--------|--------|-------| | `status` | — | Returns `{connected, debugPort, version, tabCount, uptime_seconds, sessionCount, sessions}` |
Tab Management
| Action | Params | Returns | |--------|--------|---------| | `get_tabs` | — | `[{id, url, title, active, sessions}]` | | `new_tab` | `url` (optional) | `{created: true, tabId}` | | `close_tab` | `tab_id` (required) | `{closed: true}` | | `close_session` | — (session from body, optional if active) | `{closed: N}` — closes all tabs in session | | `switch_tab` | `tab_id` (required) | `{switched: true}` | | `find_tab` | `url` or `active` (bool) | `{id, url, title}` — match by hostname, or find the active tab |
Page Interaction
| Action | Key Params | Notes | |--------|-----------|-------| | `navigate` | `url` (required), `new_tab` (bool) | Navigate current tab or open new one | | `snapshot` | — | Returns accessibility tree with `@e` refs for interactive elements | | `screenshot` | `format`, `quality`, `full_page`, `selector`, `tab_id`, `path` | Writes to `~/.coderix/screenshots/` (or `path` if given), returns `{path, sizeBytes, mimeType}` | | `click` | `selector` (CSS or `@e` ref), or `x`+`y` | Supports `@e` refs from snapshot | | `mouse_click` | `selector` (required) | Real mouse events at element center via `getBoxModel` | | `fill` | `selector`, `value` | Clear-and-insert. Works on `<input>`, `<textarea>`, `[contenteditable]` | | `type` | `text`, `selector` (optional) | Simple text insertion without clearing | | `send_keys` | `keys` (e.g. `"Enter"`, `"Mod+A"`, `"Shift+Tab"`), `repeat` | Full keyboard dispatch with modifier support | | `scroll` | `amount` (default 500) | Positive=down | | `extract` | `selector` (optional) | Returns `{content, length}` | | `evaluate` | `script` (required) | Supports async/await, returns `{type, value}` |
Advanced
| Action | Key Params | Notes | |--------|-----------|-------| | `upload` | `selector`, `files` (string array) | Sets files on `<input type=file>` | | `save_as_pdf` | `paper_format`, `landscape`, `scale`, `print_background`, `path` | Writes to `~/.coderix/pdfs/` (or `path` if given), returns `{path, sizeBytes, mimeType}` | | `network` | `cmd`: `start`/`stop`/`list`/`detail`, `filter`, `requestId` | HTTP request capture | | `cdp` | `method` (e.g. `"Page.captureScreenshot"`), `params` | Raw CDP method passthrough |
Using `@e` refs from snapshot
`snapshot` returns interactive elements with `@e` refs based on semantic role/name. Use them directly with `click` / `fill` / `mouse_click` — they survive CSS class hash changes that break manually-written selectors.
# Get a snapshot
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"snapshot"}'
# Click a button by ref
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"click","params":{"selector":"@e1"}}'
# Fill a textbox by ref
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"fill","params":{"selector":"@e3","value":"hello"}}'Screenshots: read the returned path
The server writes the image to disk and returns `{path, format, sizeBytes, mimeType}`. Use the `Read` tool to view it.
# Default — PNG, full viewport
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"screenshot","params":{}}'
# Full-page
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"Read more
name: web-bridge description: Control a real browser via CDP — navigate, click, type, screenshot, and extract web content. No Chrome extension required. version: "2.1" triggers: [web-bridge, webbridge, browser control, browser automation, CDP, chrome devtools, 截图, 浏览器操作, 网页自动化] tools: [bash] tags: [browser, automation, web] author: Coderix
Web Bridge — Browser Automation via CDP
Control a real Chrome/Edge browser from the AI agent. **No extension installation needed.** All data stays local.
Quick Start
Start the bridge server (one command)
node ~/.coderix/skills/web-bridge/bridge-server.cjs
The server auto-detects Chrome/Edge, launches it with remote debugging, and listens on port **9223**. You'll see `BRIDGE_READY port=9223` when ready.
If Chrome is already running with `--remote-debugging-port=9222`, the server connects to it instead of launching a new one.
Make a request
curl -s -X POST http://127.0.0.1:9223/cmd \
-H 'Content-Type: application/json' \
-d '{"action":"navigate","params":{"url":"https://example.com"}}'All commands go to `POST /cmd` with JSON body `{"action":"...", "params":{...}}`.
Sessions
Add `"session":"name"` to the request body to isolate tabs for multi-task workflows. Each session tracks its own set of tabs.
# Start a task in its own session
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"navigate","params":{"url":"https://example.com","new_tab":true},"session":"research"}'
# Later actions in the same session automatically use the right tab
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"snapshot","session":"research"}'
# Close all tabs in a session when done (session name optional if active)
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"close_session","session":"research"}'
# Or close the last active session without naming it
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"close_session"}'Without a session, all operations use the first available tab.
Health check
curl -s http://127.0.0.1:9223/
# {"status":"ok","version":"Chrome/150...","uptime_seconds":120,"extensionConnected":false,"mode":"cdp","port":9223,"cdpPort":9222}Server options
| Flag | Description | |------|-------------| | `--port 9223` | Listen port (default: 9223) | | `--cdp-port 9222` | CDP debug port (default: 9222) | | `--browser-path /path/to/chrome` | Custom browser binary | | `--headless` | Run browser headless | | `--no-auto-launch` | Don't auto-launch browser (connect to existing) |
Operations Reference
Browser Lifecycle
| Action | Params | Notes | |--------|--------|-------| | `status` | — | Returns `{connected, debugPort, version, tabCount, uptime_seconds, sessionCount, sessions}` |
Tab Management
| Action | Params | Returns | |--------|--------|---------| | `get_tabs` | — | `[{id, url, title, active, sessions}]` | | `new_tab` | `url` (optional) | `{created: true, tabId}` | | `close_tab` | `tab_id` (required) | `{closed: true}` | | `close_session` | — (session from body, optional if active) | `{closed: N}` — closes all tabs in session | | `switch_tab` | `tab_id` (required) | `{switched: true}` | | `find_tab` | `url` or `active` (bool) | `{id, url, title}` — match by hostname, or find the active tab |
Page Interaction
| Action | Key Params | Notes | |--------|-----------|-------| | `navigate` | `url` (required), `new_tab` (bool) | Navigate current tab or open new one | | `snapshot` | — | Returns accessibility tree with `@e` refs for interactive elements | | `screenshot` | `format`, `quality`, `full_page`, `selector`, `tab_id`, `path` | Writes to `~/.coderix/screenshots/` (or `path` if given), returns `{path, sizeBytes, mimeType}` | | `click` | `selector` (CSS or `@e` ref), or `x`+`y` | Supports `@e` refs from snapshot | | `mouse_click` | `selector` (required) | Real mouse events at element center via `getBoxModel` | | `fill` | `selector`, `value` | Clear-and-insert. Works on `<input>`, `<textarea>`, `[contenteditable]` | | `type` | `text`, `selector` (optional) | Simple text insertion without clearing | | `send_keys` | `keys` (e.g. `"Enter"`, `"Mod+A"`, `"Shift+Tab"`), `repeat` | Full keyboard dispatch with modifier support | | `scroll` | `amount` (default 500) | Positive=down | | `extract` | `selector` (optional) | Returns `{content, length}` | | `evaluate` | `script` (required) | Supports async/await, returns `{type, value}` |
Advanced
| Action | Key Params | Notes | |--------|-----------|-------| | `upload` | `selector`, `files` (string array) | Sets files on `<input type=file>` | | `save_as_pdf` | `paper_format`, `landscape`, `scale`, `print_background`, `path` | Writes to `~/.coderix/pdfs/` (or `path` if given), returns `{path, sizeBytes, mimeType}` | | `network` | `cmd`: `start`/`stop`/`list`/`detail`, `filter`, `requestId` | HTTP request capture | | `cdp` | `method` (e.g. `"Page.captureScreenshot"`), `params` | Raw CDP method passthrough |
Using `@e` refs from snapshot
`snapshot` returns interactive elements with `@e` refs based on semantic role/name. Use them directly with `click` / `fill` / `mouse_click` — they survive CSS class hash changes that break manually-written selectors.
# Get a snapshot
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"snapshot"}'
# Click a button by ref
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"click","params":{"selector":"@e1"}}'
# Fill a textbox by ref
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"fill","params":{"selector":"@e3","value":"hello"}}'Screenshots: read the returned path
The server writes the image to disk and returns `{path, format, sizeBytes, mimeType}`. Use the `Read` tool to view it.
# Default — PNG, full viewport
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"screenshot","params":{}}'
# Full-page
curl -s -X POST http://127.0.0.1:9223/cmd \
-d '{"action":"An open-source AI coding agent for the terminal and desktop — a project for research and learning. Desktop Terminal Coderix is an AI coding agent that runs in your terminal or as a desktop app.

