1. 为什么 WSL2 里的 AI 找不到 Windows 的 Chrome
很多人现在的开发环境是这样的:代码放在 WSL2 里,AI agent 也跑在 WSL2 里,但日常用的浏览器还是 Windows 桌面上的 Chrome。这个组合本身没问题,问题出在“浏览器接管”这一步。
chrome-devtools-mcp 是一个让 AI 通过 Chrome DevTools Protocol 直接操作浏览器的 MCP 服务端。它的默认行为是:在本地环境里自己去找一个 Chrome 拉起来。放在纯 Linux 或者纯 Windows 环境里,这套逻辑没问题。但放在 WSL2 里,它会在 Linux 文件系统里找 Chrome,结果要么找不到,要么拉起来一个没有图形界面的残缺实例,要么 MCP 进程启动了但始终连不上 Windows 那边真正在跑的浏览器。
我试过直接让 MCP 自己找浏览器,日志里反复出现连接超时,排查半天才发现它根本没意识到浏览器在另一个操作系统里。WSL2 虽然和 Windows 共享内核,但网络命名空间、文件系统、进程空间都是隔离的,AI 在 WSL2 里看到的localhost和 Windows 的localhost不是一回事。
更稳的思路不是让工具自己去猜浏览器在哪,而是把链路拆开,各管一段:
Windows 侧手动启动一个专门给调试用的 Chrome,固定远程调试端口,使用独立的 user-data-dir;WSL2 侧的 chrome-devtools-mcp 只负责通过--browser-url连过去,不负责启动浏览器。
这样职责清晰:Windows 管浏览器进程,WSL2 管 AI 和 MCP 服务端,中间靠一个 HTTP 调试端口通信。出问题时也能快速定位是浏览器没起来、端口不通、还是 MCP 配置写错了。
这套方案适合谁?适合在 WSL2 里跑 Codex、Cline、Claude Code 等 AI 编码工具,同时希望 AI 能直接打开页面、读 Console、看 Network、做截图和表单操作的开发者。下面从环境确认开始,一步步给出可复制的配置。
2. 前置确认:Node 版本、WSL 网络模式与 Chrome 安装
开始配之前,先把三个前提确认清楚,否则后面报错会很难判断是哪一层的问题。
第一,Windows 侧已经安装 Google Chrome。chrome-devtools-mcp 官方明确支持的是 Google Chrome 和 Chrome for Testing。为了减少变量,下面统一按 Google Chrome 来写,路径默认在C:\Program Files\Google\Chrome\Application\chrome.exe。如果你用的是其他 Chromium 内核浏览器,参数逻辑类似,但路径和部分行为可能有差异。
第二,WSL2 里有可用的 Node.js、npm、npx。按当前 README,chrome-devtools-mcp 要求 Node.js 为 20.19 或更高的维护中 LTS。先在 WSL2 里执行:
node -v npm -v npx -y chrome-devtools-mcp@latest --help如果node -v低于 20.19,先升级 Node。如果npx这条命令报错,先别继续配浏览器,把 Node 环境理顺再说。这一步能跑通,说明 MCP 服务端本身在 WSL2 里是可执行的。
第三,确认当前 WSL2 走的是 mirrored 还是 NAT 网络模式。这个决定了后面写127.0.0.1还是 Windows 宿主机 IP。
如果你用的是 mirrored 模式,WSL2 一般可以直接访问 Windows 侧的127.0.0.1:
curl http://127.0.0.1:9922/json/version如果你还是 NAT 模式,就需要先查 Windows 宿主机 IP:
ip route show | grep -i default | awk '{ print $3 }'后面的地址都改成http://<Windows宿主机IP>:9922。
如果你打算切到 mirrored,可以在 Windows 用户目录下的.wslconfig里写:
[wsl2] networkingMode=mirrored保存后执行wsl --shutdown,然后重新打开 WSL。mirrored 模式下 WSL2 和 Windows 共享网络接口,访问127.0.0.1就能直达 Windows 侧服务,配置会简单很多。但要注意,切换网络模式后所有依赖 IP 的配置都要重新确认。
这三件事确认完,再往下走。很多人卡住不是因为 MCP 配置错,而是 Node 版本不够或者网络模式没搞清,导致后面每一步都在猜。
3. 可复制配置:Windows 启动调试 Chrome + WSL2 配置 MCP
这一节是核心,分两步:先在 Windows 上启动一个专门给调试用的 Chrome,再在 WSL2 里配置 chrome-devtools-mcp 和 Codex。
3.1 Windows 侧启动调试 Chrome
Chrome 官方从 Chrome 136 开始收紧了远程调试开关的规则:如果你对默认数据目录启用--remote-debugging-port或--remote-debugging-pipe,这些开关不会生效。要让远程调试真正打开,必须同时指定一个非默认的--user-data-dir。
所以现在不要再用这种旧命令:
chrome.exe --remote-debugging-port=9922它在新版本 Chrome 里很可能根本不起作用。正确做法是单独起一个专门给调试用的 Chrome 实例。
PowerShell 用下面这条:
& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` --remote-debugging-port=9922 ` --user-data-dir="$env:TEMP\chrome-devtools-mcp-profile"如果你习惯用 cmd,对应命令是:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9922 --user-data-dir="%TEMP%\chrome-devtools-mcp-profile"如果你的 Chrome 不在默认路径,把可执行文件路径换成你自己的实际位置,其他参数不要删。长期用的话,最省事的做法是做一个 Windows 快捷方式,目标写成:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9922 --user-data-dir="%TEMP%\chrome-devtools-mcp-profile"这个 Chrome 最好只给 AI 和调试用,不要和日常浏览混用。独立 user-data-dir 的好处是:不会污染你的日常书签和登录态,也不会因为日常 Chrome 已经在运行而导致调试实例启动失败。
3.2 WSL2 侧配置 chrome-devtools-mcp
浏览器启动后,先不要急着配 Codex。先在 WSL2 里确认调试端口真的通了。Chrome DevTools Protocol 官方文档里明确提到,远程调试启动后可以访问/json/version,返回内容里会带webSocketDebuggerUrl。
mirrored 模式直接测:
curl http://127.0.0.1:9922/json/versionNAT 模式先查宿主机 IP 再测:
HOST_IP=$(ip route show | grep -i default | awk '{ print $3 }') curl "http://${HOST_IP}:9922/json/version"如果返回 JSON 且里面有webSocketDebuggerUrl,说明浏览器这边已经准备好了。如果这一步不通,先别碰 MCP,问题还停留在浏览器或网络层。
确认端口通之后,配置 MCP。很多 AI 客户端都支持标准 MCP JSON 配置,写法类似这样:
{ "mcpServers": { "chrome-devtools": { "command": "npx", "args": [ "-y", "chrome-devtools-mcp@latest", "--browser-url=http://127.0.0.1:9922" ] } } }如果你现在走的是 NAT,就把地址改成http://<Windows宿主机IP>:9922。这里真正关键的就一个参数:--browser-url=http://127.0.0.1:9922。它的意思很直接:不要自己去找浏览器,直接连这个已经开好的 Chrome。
3.3 Codex 侧配置
如果你用的是 Codex,最直接的方式有两种:直接改~/.codex/config.toml,或者用codex mcp add加进去。
config.toml通常在~/.codex/config.toml,对大多数人来说实际路径就是/home/<你的用户名>/.codex/config.toml。最直接的配置可以写成:
[mcp_servers.chrome-devtools] command = "npx" args = ["chrome-devtools-mcp@latest", "--browser-url=http://127.0.0.1:9922"]如果你是 NAT 模式,就把地址改成宿主机 IP。有些环境下,npx 第一次运行包时会弹确认。如果你碰到 Codex 一直卡在启动 MCP,或者日志看起来像是在等确认,可以改成:
[mcp_servers.chrome-devtools] command = "npx" args = ["-y", "chrome-devtools-mcp@latest", "--browser-url=http://127.0.0.1:9922"]如果你不想手改文件,也可以直接在 WSL2 里执行:
codex mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --browser-url=http://127.0.0.1:9922执行完以后,最好再打开~/.codex/config.toml看一眼,确认已经写进去。三件套要写全:Base URL 是http://127.0.0.1:9922,Key 这里不需要,Model ID 由 Codex 自身配置决定,MCP 只负责浏览器连接。
4. 验证请求:从 curl 到 AI 实际操控页面
配置写完不代表通了,建议按下面顺序验证,不要一上来就给 AI 下复杂任务。
第一步,确认包本身能跑起来:
npx -y chrome-devtools-mcp@latest --help能打印帮助信息,说明 MCP 服务端在 WSL2 里可执行。
第二步,确认调试端口还通着:
curl http://127.0.0.1:9922/json/version返回内容里应该有Browser、Protocol-Version、webSocketDebuggerUrl等字段。如果这一步失败,回到第 3 节检查 Chrome 启动参数和网络模式。
第三步,重启 Codex,或者让你的 AI 客户端重新加载 MCP 配置。很多客户端不会热加载 MCP,改完config.toml必须重启进程。
第四步,给 AI 一个很简单的任务,比如:
打开 https://example.com,查看 Console 是否有报错,再检查一下 Network 请求。这个阶段先看两件事:AI 能不能把页面打开,AI 能不能拿到浏览器里的调试信息。这两件事通了,后面的点击、截图、表单、性能分析基本就是顺着往下做。
如果 AI 能打开页面但拿不到 Console,检查一下是不是连到了错误的 target。Chrome 调试端口会暴露多个 page target,MCP 需要选对当前活动标签页。如果 AI 完全没反应,看 Codex 日志里 MCP 是否启动成功,常见的是 npx 卡在第一次下载。
验证通过后,你可以让 AI 做更复杂的操作,比如:
打开 https://example.com,截图保存到 /tmp/example.png,然后读取页面标题。截图能落盘、标题能返回,说明整条链路从 WSL2 到 Windows Chrome 已经完全打通。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
这一节对照真实报错来排查。不同报错对应不同层的问题,不要混在一起猜。
报错一:401 Unauthorized
如果你在 MCP 配置里加了额外的认证头,或者客户端要求 API Key,但 chrome-devtools-mcp 本身不需要 Key。401 通常出现在你同时配置了其他需要鉴权的 MCP 服务端,或者把 TaoToken 的 API Key 误填到了浏览器 MCP 里。检查config.toml里[mcp_servers.chrome-devtools]这一段,只保留command和args,不要加env里的 Key。
报错二:local proxy failed或连接被拒绝
这是 WSL2 网络层最典型的报错。原因通常是:Chrome 没启动、端口没监听、或者 WSL2 和 Windows 网络不通。按顺序检查:
# 1. Windows 侧确认端口在监听 netstat -ano | findstr 9922 # 2. WSL2 侧确认能访问 curl -v http://127.0.0.1:9922/json/version如果 Windows 侧netstat没有输出,说明 Chrome 没按带参数的命令启动,或者被已有 Chrome 实例拦截了。先关掉所有 Chrome,再用独立 user-data-dir 启动。
报错三:reading choices或 JSON 解析失败
这个报错通常出现在 MCP 客户端读取服务端返回时。chrome-devtools-mcp 启动后会输出 JSON-RPC 消息,如果 npx 在第一次运行时输出了额外的下载日志,会污染 stdout,导致客户端解析失败。解决办法是在 args 里加-y,并确保 npx 缓存已经预热:
npx -y chrome-devtools-mcp@latest --help先手动跑一次,让包下载完成,再重启 Codex。
报错四:OAuth相关报错
chrome-devtools-mcp 本身不走 OAuth。如果你看到 OAuth 报错,大概率是 Codex 或其他 MCP 客户端在尝试认证另一个服务端。检查config.toml里是否有多个[mcp_servers.*],逐个确认哪个需要 OAuth、哪个不需要。浏览器 MCP 只需要--browser-url。
报错五:Codex 启动但 MCP 没加载
先看~/.codex/config.toml路径是不是写对了,TOML 语法有没有写错,改完配置后 Codex 是否已经重启,npx 是否卡在第一次安装确认。可以用codex mcp list查看当前已注册的 MCP 服务端。
如果端口换了,配置也要一起跟着改。比如你 Windows 上启动的是--remote-debugging-port=9922,那 WSL2 里的 curl、--browser-url、Codex 的config.toml都必须写 9922。不要一边启动 9922,一边配置 9222。
还有一点要单独提醒:WSL 的确可以从 Linux 命令行直接启动 Windows 程序,但在这个问题上,更稳的方式还是 Windows 负责启动 Chrome,WSL2 负责运行 AI 和 MCP,chrome-devtools-mcp 只负责连接。这样职责清楚,问题也更好定位。
6. 接入 TaoToken:让 Codex 的模型调用与浏览器控制各司其职
浏览器链路打通后,Codex 本身还需要一个稳定的模型调用入口。TaoToken 提供 OpenAI 兼容的 API 接入,适合在 WSL2 里给 Codex、Cline 等工具做模型后端。它的 API 地址是https://taotoken.net/api,不附加 UTM 参数,直接用于配置。
在 Codex 的配置里,模型调用和 MCP 浏览器控制是两套独立配置。模型侧配置 API Key 和 Base URL,MCP 侧只配--browser-url。两者不要混在一起,否则排查时会互相干扰。
如果你用的是 Codex,可以在~/.codex/config.toml里同时保留模型配置和 MCP 配置:
model = "gpt-4o" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" [mcp_servers.chrome-devtools] command = "npx" args = ["-y", "chrome-devtools-mcp@latest", "--browser-url=http://127.0.0.1:9922"]然后在 WSL2 里设置环境变量:
export TAOTOKEN_API_KEY="你的Key"Key 可以在 TaoToken 控制台的 API Keys 页面创建:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
配置完成后,Codex 用 TaoToken 做模型推理,chrome-devtools-mcp 用--browser-url连 Windows Chrome,两条链路互不依赖。模型侧出问题看 API Key 和 Base URL,浏览器侧出问题看端口和网络模式。
如果你更习惯用图形界面调试模型对话,可以打开模型对话页面直接测试:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
对于长期在 WSL2 里跑编码 Agent 的场景,Coding Plan 提供了更稳定的调用额度:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
接入文档里有完整的 Base URL 和参数说明:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
如果你用的是 Claude Code 或 Anthropic 兼容客户端,接入方式参考:https://taotoken.net/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite
整个链路的核心思路就一句话:Windows 管浏览器,WSL2 管 AI,TaoToken 管模型调用,chrome-devtools-mcp 只负责连接已经存在的浏览器。把这几件事拆开以后,配置会清楚很多,排障也会轻松很多。