OpenCode in Chrome
opencode-chrome
Give your local opencode agent full control of a real browser — clicks, types, screenshots, all via real CDP Input events that bypass bot detection.
62 MCP tools · MV3 Chrome extension + Node.js bridge · chrome.debugger API for full CDP access
What it does
opencode-chrome is a Chrome/Edge extension that exposes 62 browser automation tools to any MCP-compatible agent (like opencode, Claude Code, etc.) over a localhost WebSocket. Every form interaction uses the CDP Input domain — real mouse and keyboard events at the browser level — so LinkedIn and other anti-bot sites can't detect automation.
Used in production to add 5/5 CI/CD skills to linkedin.com/in/anton-petnitsky and publish a v0.6.0 announcement post — both through CDP Input, not JS element.click().
Related MCP server: chrome-devtools-mcp
Architecture
┌─────────────────────┐ WS 127.0.0.1:8766 ┌──────────────────┐ stdio MCP ┌──────────┐
│ Chrome Extension │ ◄───────────────────────────► │ bridge.mjs │ ◄──────────────────► │ opencode │
│ (MV3, debugger API)│ │ (Node.js) │ └──────────┘
└─────────────────────┘ └──────────────────┘
│
│ CDP :9223
▼
┌──────────┐
│ Edge │
└──────────┘Extension — MV3 service worker, uses
chrome.debuggerfor full CDP (no need for--remote-debugging-porton default profile)Bridge — WS server (for the extension) + MCP stdio server (for the agent), token-authenticated
Token — auto-generated on first run, stored in
~/.opencode-chrome/token(chmod 600)
Quick start
1. Start the bridge
node bridge/bridge.mjs
# [bridge] listening on ws://127.0.0.1:8766
# [bridge] token: a1b2c3d4... (also saved to ~/.opencode-chrome/token)2. Start Edge with the extension
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" \
--user-data-dir=D:\Projects\opencode-chrome\.edge-profile \
--profile-directory=Default \
--remote-debugging-port=9223 \
--load-extension=D:\Projects\opencode-chrome\extension \
--no-first-run --no-default-browser-check \
https://www.linkedin.com/in/anton-petnitsky/(Edge is used because Chrome 151+ blocks CDP on default profile but Edge allows --load-extension. Use Chrome if you have a custom --user-data-dir.)
3. Auto-setup (recommended)
Instead of steps 1+2 manually, just run:
node scripts/auto.mjsThis script:
Starts the bridge if not running
Starts Edge with the extension
Auto-sets the extension token via CDP
chrome.storage.sync.setWaits for the extension to connect
Runs
tabs_listto confirm everything works
4. Auto-recovery (optional)
For long-running sessions, run the watchdog in another terminal:
node scripts/watchdog.mjsThis monitors bridge (port 8766) and Edge (port 9223), auto-restarts them if they die.
62 MCP tools
All tools use CDP Input domain for mouse/keyboard (bypasses bot detection) and chrome.debugger for everything else.
Navigation (9)
chrome_tabs_list, chrome_tab_open, chrome_tab_navigate, chrome_tab_close, chrome_tab_switch, chrome_tab_wait_load, chrome_tab_back, chrome_tab_forward, chrome_tab_refresh
Mouse (7) — all real CDP Input events
chrome_click (selector), chrome_click_coords (x,y), chrome_hover, chrome_double_click, chrome_right_click, chrome_scroll, chrome_drag_and_drop
Keyboard (3) — real CDP Input
chrome_fill (selector + text), chrome_type (focused element), chrome_press_key (Enter, Tab, etc.)
Select (1)
chrome_select (dropdown by value or text)
Reading (6)
chrome_read (title + url + text), chrome_get_text, chrome_get_attribute, chrome_get_all_links, chrome_find_elements, chrome_eval (run JS)
Screenshots / PDF (4)
chrome_screenshot (image block), chrome_full_page_screenshot, chrome_element_screenshot, chrome_save_pdf
Extraction (4)
chrome_get_page_source, chrome_get_element_html, chrome_extract_table, chrome_get_computed_style
Waiting (2)
chrome_wait_for_element, chrome_wait_and_retry
Composite (2)
chrome_click_and_wait, chrome_fill_and_submit
Monitoring (1)
chrome_console
Advanced (5)
chrome_upload_file, chrome_iframe_list, chrome_iframe_eval, chrome_shadow_query, chrome_batch, chrome_if_exists
Cookies / Storage (4)
chrome_cookies_get, chrome_cookie_set, chrome_local_storage, chrome_export_session
Emulation (5)
chrome_set_viewport, chrome_set_user_agent, chrome_set_geolocation, chrome_set_timezone, chrome_emulate_network
v0.6.0 Anti-bot realism (4) — bypass LinkedIn et al.
chrome_click_in_shadow — pierces shadow DOM (artdeco-* web components)
chrome_hover_and_reveal — hover + wait for hidden edit buttons
chrome_human_type — realistic typing with jitter (50-150ms/char) and optional typo simulation
chrome_scroll_to_element — smooth-scroll to target
Helper scripts
Script | Purpose |
| One-command setup: start bridge + Edge + set token + verify |
| Auto-restart bridge/Edge if they crash |
| Copy post text to clipboard + open LinkedIn sharebox |
| Check that 5/5 CI/CD skills are still on LinkedIn profile |
v0.6.0 changes
Extension: 4 new anti-bot tools (
click_in_shadow,hover_and_reveal,human_type,scroll_to_element)Bridge: was stuck at v0.1.0 (25 tools), now exposes all 62 tools via MCP. Added
askExtensionWithRetry()for MV3 service worker lifecycle resilienceBackground SW:
chrome.alarmskeepalive every 24s, ping/pong every 20s,onStartuphandlerauto.mjs: full one-command setup
post_linkedin.mjs: clipboard + sharebox helper
verify_skills.mjs: profile skill checker
Why CDP Input (not JS .click())?
LinkedIn, Cloudflare, and most modern sites detect element.click() because:
The event has
isTrusted: falseNo real mouse trajectory
Instant timing
chrome.debugger + Input.dispatchMouseEvent creates events with isTrusted: true — the browser itself dispatches them — which bypasses these checks. The extension only uses JS element.click() for reading (not visible to users) and never for form interaction.
Anti-bot features
LinkedIn's "About" section edit button is the only thing in this codebase that can't be automated. The button is rendered dynamically after a 2-3 second hover, only when the page detects a trusted mouse, and its click handler checks event.isTrusted. The v0.6.0 hover_and_reveal waits the right time, but LinkedIn's JS still blocks the synthetic click. This is a known limitation.
Workaround: copy-paste the text from D:\Documents\Desktop\linkedin_pending_cicd_2026-08-22.md into the About section manually (1-2 minutes).
MV3 service worker lifecycle
MV3 kills idle service workers after ~30 seconds. The extension uses chrome.alarms (every 24s) to keep itself alive, and the bridge's askExtensionWithRetry waits and retries when the SW reconnects. Expect occasional 2-3 second delays on long-running sessions.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Control a real browser from AI agents: navigate, click, type, screenshot, read the page.
Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceLets AI coding agents control and inspect a live Chrome browser via MCP, providing Chrome DevTools capabilities for automation, debugging, and performance analysis.6 npmApache 2.0
- AlicenseNot gradedqualityDmaintenanceLets coding agents control and inspect a live Chrome browser via MCP, providing Chrome DevTools capabilities for automation, debugging, and performance analysis.1,737,496 npmApache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables coding agents to control and inspect a live Chrome browser via MCP, providing Chrome DevTools capabilities for automation, debugging, and performance analysis.1,737,496 npmApache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to control and inspect a live Chrome browser via MCP, including performance tracing, network and console debugging, screenshots, and reliable Puppeteer-based automation.1,737,496 npmApache 2.0