{"id":49529300,"url":"https://github.com/pigochu/wsl-chrome-bridge","last_synced_at":"2026-05-02T05:48:27.535Z","repository":{"id":350828374,"uuid":"1203341944","full_name":"pigochu/wsl-chrome-bridge","owner":"pigochu","description":"Bridge chrome-devtools-mcp/playwright-mcp in WSL2 to Windows Chrome","archived":false,"fork":false,"pushed_at":"2026-05-01T01:59:10.000Z","size":240,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-02T05:47:53.941Z","etag":null,"topics":["ai-agent","cdp","chrome","chrome-devtools-mcp","mcp","playwright-mcp","remote-debugging","wsl"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pigochu.png","metadata":{"files":{"readme":"README-zh.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-07T00:38:12.000Z","updated_at":"2026-05-01T01:57:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pigochu/wsl-chrome-bridge","commit_stats":null,"previous_names":["pigochu/wsl-chrome-bridge"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/pigochu/wsl-chrome-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pigochu%2Fwsl-chrome-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pigochu%2Fwsl-chrome-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pigochu%2Fwsl-chrome-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pigochu%2Fwsl-chrome-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pigochu","download_url":"https://codeload.github.com/pigochu/wsl-chrome-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pigochu%2Fwsl-chrome-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32524565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T01:12:54.858Z","status":"online","status_checked_at":"2026-05-02T02:00:05.923Z","response_time":132,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","cdp","chrome","chrome-devtools-mcp","mcp","playwright-mcp","remote-debugging","wsl"],"created_at":"2026-05-02T05:48:26.898Z","updated_at":"2026-05-02T05:48:27.528Z","avatar_url":"https://github.com/pigochu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wsl-chrome-bridge\n\n本專案主要提供一支 CLI `wsl-chrome-bridge`。\n\n在 [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) 眼中，`wsl-chrome-bridge` 將會是一個可執行的 Chrome。\n`wsl-chrome-bridge` 會在 WSL 端提供 DevTools 連線入口，並把 CDP 訊息橋接到 Windows Chrome。\n\n原有 `chrome-devtools-mcp` 的設定方式，只需調整 `--executablePath` 並增加特定參數，即可讓 WSL 下的 Agent 調用 Windows Chrome，且無須做任何系統層級的設定(如 portproxy 轉發 , WSL2 Mirrored Mode)。\n\n此構想是看到 [wsl-chrome-mcp](https://github.com/477174/wsl-chrome-mcp) 實作方式是利用 `powershell` 繞過限制，但由於此專案是以 MCP Server 方式提供服務，但我想繼續使用比較多人維護的 `chrome-devtools-mcp`，所以才寫了本專案作為橋接手段。\n\n## 0.2.0 重大變更（支援 Playwright）\n\n`0.2.0` 新增對 `playwright-mcp` 的支援，並且調整多項 bridge 參數行為與設定方式。\n\n若你是從 `0.1.0` 升級，請先閱讀升級說明文件：[UPGRADE-zh.md](./UPGRADE-zh.md)。\n\n## 專案特色\n\n- 👍 **使用原 MCP 工具**：`wsl-chrome-bridge` 並非取代 `chrome-devtools-mcp` 或 `playwright-mcp`，而是讓你在 WSL2 內沿用原有工具操作 Windows Chrome。\n- ⚡ **無須系統級設定**：不需要設定 WSL Mirrored Mode、portproxy，也不用安裝額外繞路工具。\n- ⚙️ **設定門檻低**：通常只要在原有 MCP 設定中調整 `--executablePath` 與少量參數即可運作。\n- 🛡️ **統一退出行為**：`chrome-devtools-mcp` 與 `playwright-mcp` 退出時對於 Chrome 的關閉行為完全不同，本專案會將這兩種退出行為做一致化處理。\n    - 🖥️ headed 模式下，若 MCP 退出，Windows Chrome 視窗仍保持。\n    - 🤖 headless 模式下，若 MCP 退出，處於背景執行的 Windows Chrome 行程會被自動銷毀。\n\n## 基本運作方式\n\n```text\n[Chrome DevTools MCP]             [Playwright MCP]\n         |                              |\n      stdio pipe           remote-debugging-port/stdio pipe\n         |                              |\n         +------[wsl-chrome-bridge]-----+\n                         |\n            PowerShell websocket relay\n                         |\n                 [Windows Chrome]\n```\n\nwsl-chrome-bridge 會：\n\n- 接收 `chrome-devtools-mcp` 與 `playwright-mcp` 傳入的 Chrome 啟動參數\n- 啟動 Windows Chrome（透過PowerShell）\n- 在 `chrome-devtools-mcp` 模式下，透過 stdio pipe（OS pipe）接收/回傳 CDP 訊息\n- 在 `playwright-mcp` 模式下，於本機建立對應 port 的 WebSocket proxy 後轉發 CDP 訊息\n- 透過 PowerShell WebSocket relay 雙向轉發 CDP 訊息到 Windows Chrome\n\n\u003e [!NOTE]\n\u003e 我們在實測中觀察到，近期 `playwright-mcp` 版本可能改以 `--remote-debugging-pipe` 啟動 Chrome（官方 release note 未明確標註變更版本，可能介於 `0.0.71`～`0.0.72`）。為保留舊版相容性，bridge 仍同時支援 remote-debugging-port 與 pipe 兩種上游連線模式。\n\n\n## 使用環境需求\n- Windows 11 安裝最新版 chrome。\n- Windows 11 需要有 powershell.exe 可供 WSL2 執行。\n- WSL2 需要有 Node 20+\n\n\n## 安裝與使用方式\n\n### 安裝方式\n\n於 WSL 環境下用以下方式擇一安裝 :\n\n1. 透過 `npm install -g wsl-chrome-bridge` 安裝。\n2. 下載原始碼後自行編譯，再以 `npm link` 安裝：\n\n```bash\ngit clone https://github.com/pigochu/wsl-chrome-bridge.git\ncd wsl-chrome-bridge\nnpm install\nnpm run build\nnpm link\n```\n\n### 使用方式 (以 codex 為例子)\n\n1. 找出 wsl-chrome-bridge 實際位置 , 假設是 `/home/pigochu/.local/share/mise/shims/wsl-chrome-bridge`。\n2. 設定檔撰寫，如以下範例 `.codex/config.toml`。\n\n`chrome-devtools-mcp` 最小可運作設定：\n\n```toml\n[sandbox_workspace_write]\nnetwork_access = true\n\n[mcp_servers.chrome-devtools]\ncommand = \"npx\"\nargs = [\n    \"-y\",\n    \"chrome-devtools-mcp@latest\",\n    \"--executablePath\",\n    \"/home/pigochu/.local/share/mise/shims/wsl-chrome-bridge\"\n]\nenabled = true\n```\n\n這是最小可運作設定。`wsl-chrome-bridge` 會啟動 Windows Chrome，並為 `chrome-devtools-mcp` 橋接 CDP 流量，不需要額外 bridge 專用參數。\n\n`playwright-mcp` 最小可運作設定（含 sandbox）：\n\n```toml\n[sandbox_workspace_write]\nnetwork_access = true\n\n[mcp_servers.playwright]\ncommand = \"npx\"\nargs = [\n    \"-y\",\n    \"@playwright/mcp@latest\",\n    \"--browser\",\n    \"chrome\",\n    \"--sandbox\",\n    \"--executable-path\",\n    \"/home/pigochu/.local/share/mise/shims/wsl-chrome-bridge\"\n]\nenabled = true\n\n[mcp_servers.playwright.env]\nDISPLAY = \":9999\"\n```\n\n在 bridge + Windows 系統 Chrome 的情境下，加上 `--browser chrome` 可避免常見的上游 `--no-sandbox` 警告行為，並維持 Playwright 啟動行為穩定。\n\n\u003e [!NOTE]\n\u003e FAQ 章節有介紹 `--executablePath` 的路徑尋找的方式。\n\u003e 其他設定寫法可參考 `agent-config-sample/.codex/`。\n\n## FAQ\n\n### Q1. `--executablePath` 如何找\n\n`chrome-devtools-mcp` 的 `--executablePath` 必須是「檔案路徑」，不能只填指令名（例如 `wsl-chrome-bridge`）。\n\n#### 情境 A: 未使用 Node 版本管理工具（僅系統 Node）\n\n這種情境下，通常就是用 `command` 找出絕對路徑再填入設定：\n\n```bash\ncommand -v wsl-chrome-bridge\n```\n\n把輸出結果直接填進 `--executablePath`。\n\n#### 情境 B: 使用 mise 管理多版本 Node（建議做法）\n\n若你使用 [mise](https://mise.jdx.dev/) 且可能切換多個 Node 版本，不建議把 `command -v` 找到的版本化路徑（例如 `.../installs/node/\u003cversion\u003e/bin/...`）直接寫死在設定檔。\n\n建議改用 mise shim 固定入口：\n\n如以下命令所印出的絕對路徑\n```bash\necho $HOME/.local/share/mise/shims/wsl-chrome-bridge\n```\n或直接檢查：\n\n```bash\nls -la ~/.local/share/mise/shims/wsl-chrome-bridge\n```\n\n#### 差異總結\n\n- 不使用版本管理工具時，透過 `command -v` 找絕對路徑是可行且直接的方法。\n- 使用 mise 多版本 Node 時，建議使用 `/home/\u003cuser\u003e/.local/share/mise/shims/wsl-chrome-bridge`，避免 Node 版本切換後路徑失效。\n\n### Q2. 為什麼 Playwright 需要設定 `DISPLAY`\n\n在 WSL/Linux 環境下，`playwright-mcp` 啟動瀏覽器時會先判斷圖形顯示環境。  \n若 `DISPLAY` 沒有設定，Playwright 通常會改成 headless 行為（即使你沒有手動指定 `--headless`）。\n\n而這個判斷是在 bridge 之前就完成，所以 `wsl-chrome-bridge` 無法在後段覆蓋該決策。  \n如果你希望在 Windows 看到實際 Chrome 視窗，請於 MCP `env` 額外設定 `DISPLAY`（例如 `DISPLAY=:999`）。\n\n### Q3. 上游 MCP 結束時，Headless 與非 Headless 行為\n\n`wsl-chrome-bridge` 在上游 MCP（例如 `chrome-devtools-mcp` / `playwright-mcp`）結束時，採用以下生命週期策略：\n\n- 若 Chrome 是以 headless 啟動，通常是為了進行自動測試，測試完畢大概就沒用了，因此 bridge 一律會結束背景 Chrome 行程，以防 Windows 端殘留背景 Chrome。\n- 若 Chrome 不是以 headless 啟動（headed / non-headless），通常是用戶想看到畫面結果或參與實際操作，bridge 一律保留該 Chrome 行程，這樣用戶的 Chrome 視窗還在，下次重新啟動 AI 助手時，也能接著使用原本開啟的 Chrome。\n\n上述的行為是刻意設計的，因為原生 `chrome-devtools-mcp` 與 `playwright-mcp` 的行為是不同的，如下：\n- `chrome-devtools-mcp` 不論是 headed 或 headless 都不會主動關閉 Chrome。\n- `playwright-mcp` 不論是 headed 或 headless 都會主動關閉 Chrome。\n\n而 `wsl-chrome-bridge` 統一了兩者的不一致。 \n\n### Q4. 為什麼 Playwright 可能出現 `--no-sandbox` 警告\n\n`playwright-mcp` 若未明確指定 browser channel，可能會產生含 `--no-sandbox` 的啟動參數。  \n在有視窗的 Chrome 中，會看到這類警告列：\n`你正在使用不受支援的命令列標幟: --no-sandbox`\n\n建議在 Playwright MCP args 明確加入：\n\n```text\n--browser chrome\n```\n\n這樣在常見 bridge 設定下可避免上游傳入 `--no-sandbox`。\n\n\n### Q5. `--user-data-dir` 說明\n\n`wsl-chrome-bridge` 現在支援上游 MCP 直接傳入 `--user-data-dir` / `--userDataDir`。\n\nPlaywright 可能會把原本的 Windows 風格路徑先 resolve 成 Linux 路徑，並在本地先建立一個空目錄再交給 bridge。  \nbridge 目前會檢查該路徑，且僅在「空目錄」時才會安全刪除；非空目錄不會刪除。\n\n`chrome-devtools-mcp` 一般不會有這個本地空目錄副作用。\n\n另外，bridge 只會把「Windows 風格」的 user-data-dir 傳給 Windows Chrome。像 `/cwd/%TEMP%\\\\...` 這種被 resolve 過的形式會先嘗試還原。\n\n若上游沒有送出 `--user-data-dir`，或送出的值最後無法還原為 Windows 風格路徑（被過濾），bridge 會自動使用預設值：\n\n```text\n%TEMP%\\wsl-chrome-bridge\\profile-default\n```\n\n這可確保 Windows Chrome 啟動時一律有可用的 profile 目錄，避免因未帶 profile 導致的啟動行為差異。\n\n為了避免 Playwright 差異，並統一 `chrome-devtools-mcp` / `playwright-mcp` 的設定風格，建議優先使用：\n\n```toml\nWSL_CHROME_BRIDGE_USER_DATA_DIR = \"%TEMP%\\\\wsl-chrome-bridge\\\\chrome-profile-xxx\"\n```\n\n`--user-data-dir` 仍可使用，但建議把 `WSL_CHROME_BRIDGE_USER_DATA_DIR` 當成預設寫法。\n\n\n## 設定參數重要說明\n\n- `--user-data-dir` / `--userDataDir` : 僅當最終值為 Windows 風格（包含 `%TEMP%\\\\...` 還原成功）才會帶入啟動參數。\n- 若 `--user-data-dir` 未提供，或被過濾（非 Windows 風格），bridge 會回退到 `%TEMP%\\\\wsl-chrome-bridge\\\\profile-default`。\n- `playwright-mcp --browser chrome` : 建議搭配 bridge 使用，可避免上游送出 `--no-sandbox` 警告列。\n\n## 環境變數重要說明\n\n- `WSL_CHROME_BRIDGE_USER_DATA_DIR=%TEMP%\\\\...` : 建議預設使用。可固定指定 Windows Chrome profile 路徑，且優先於上游 `--user-data-dir`，可避開 Playwright 本地空目錄副作用，並統一兩種 MCP 設定風格。\n- `WSL_CHROME_BRIDGE_EXECUTABLE_PATH=C:\\\\...` : 可選環境變數，用於覆蓋 Windows Chrome 的執行檔路徑。\n- `WSL_CHROME_BRIDGE_REMOTE_DEBUG_PORT=9222` : 以環境變數指定 Windows Chrome debug port。若都沒指定，bridge 改為隨機 port，不再固定 9222。\n- bridge 會在 Windows 端先探測 port 可用性。若是固定 port 模式且該 port 已被占用，會在啟動前直接報錯。\n- `WSL_CHROME_BRIDGE_DEBUG_FILE=/tmp/xxx.log` : 以環境變數指定 bridge debug log 輸出路徑。\n- `WSL_CHROME_BRIDGE_DEBUG_LEVEL=all|important` : 可選 debug 詳細度。`important`（預設）只記錄 session / 開頁導覽 / 斷線相關的重要 method 與錯誤回應；`all` 會記錄全部 CDP relay 訊息。\n- `WSL_CHROME_BRIDGE_DEBUG_RAW_DIR=/tmp/wsl-chrome-bridge-raw` : 以環境變數指定 raw CDP 內容輸出目錄。每筆 request/response/event 會獨立寫入一個 `raw-\u003ctimestamp\u003e.log` 檔案，且 `WSL_CHROME_BRIDGE_DEBUG_FILE` 的 relay log 會包含對應的 `rawPath`。\n\n## 已確認無法使用的參數\n\n以下列表為搭配本程式確定無法使用 `chrome-devtools-mcp` 原始參數\n\n- `--browser-url` : 這是遠端連線設定，一旦啟用就會讓 `chrome-devtools-mcp` 走 remote mode 而非 pipe mode，無法與 `wsl-chrome-bridge` 配合。\n\n\n\u003e 其他 `chrome-devtools-mcp` 提供的原始參數未必全部能使用，本程式尚在開發中，也沒有完全測試過所有原始參數，故只列出目前已經測試過的。\n\n## For Developer\n\n開發者可參考 bridge 連線生命週期與恢復策略文件：\n\n- [docs/BRIDGE_CONNECTION_LIFECYCLE-zh.md](./docs/BRIDGE_CONNECTION_LIFECYCLE-zh.md)\n\n### 開發時所用技術棧：\n\n- Node 24\n- TypeScript v6\n- Commander v14\n- ws v8.20\n- 測試框架: Vitest v4.1\n\n### 安裝與建置\n\n```bash\nnpm install\nnpm run build\n```\n\n### 本地測試\n\n```bash\nnpm test\n```\n\n測試分成兩層：\n\n- 單元測試：路徑轉換、參數標準化、bridge 啟動規劃\n- 情境測試：CLI 對 bridge runner 的參數傳遞整合\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpigochu%2Fwsl-chrome-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpigochu%2Fwsl-chrome-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpigochu%2Fwsl-chrome-bridge/lists"}