说明

使用的是官方订阅则只需要把对应的开关配置打开即可。使用的是三方 API 则需要修改 codex 配置,因为三方 API 过不了 codex 操作浏览器的权限校验。本文最后有回滚命。

问题复现

本次内置浏览器在设置已开启、服务已启动的情况下,仍返回 Local browser use is disabled in Work settings。之后接入 Chrome DevTools MCP,成功打开产品地址并读取登录页;用户登录后,又成功读取用量大盘、密钥管理与调用日志。

这证明替代连接已经可用,不代表内置浏览器的授权故障已经修复。不要仅根据这句报错就反复安装浏览器或扩大系统权限。

图解:确认你打开的是哪个设置

图 1:应用内的浏览器开关

 

路径是应用自己的「设置 → 浏览器」。截图顶部的「让 ChatGPT 控制内置浏览器」已经开启。它与 macOS 系统设置、Chrome 扩展设置是不同入口。开关已开启但工具仍报禁用时,应继续检查授权与工具连接。

图 2:Chrome 扩展连接状态

 

「电脑操控 → Google Chrome」中的绿色状态表示扩展已安装。此扩展连接与本文后续的 Chrome DevTools MCP 是两种方案,安装 MCP 不要求先安装该扩展。

图 3:macOS 录屏权限

 

这是系统的「隐私与安全性 → 录屏与系统录音」,不是应用浏览器总开关。截图中相关权限已经开启;它不能单独证明浏览器会话授权成功。无需为解决此错误给无关应用增加权限。

先对症:根据你的报错选择方案

你看到的

需要检查的方向

跳到

Local browser use is disabled in Work settings

浏览器开关、会话授权、认证模式或组织限制;需日志进一步区分

替代方案

MCP 起不来、handshaking with MCP server failed

启动超时、命令路径、包下载、运行时版本或缓存错误

缓存排查

pageId: Invalid input: expected number

缺少有效数字页面 ID,或调用参数与当前工具 schema 不符

调用顺序

配置写了但毫无反应

配置未加载、文件位置不对或服务启动失败

重启

第一条不能单独用来判断根因。先确认图 1 的开关,再看日志中是否有明确的认证拒绝原因。界面显示开启、日志显示服务就绪,与当前会话获准操作浏览器并不等价。

决定性证据在日志里:

sqlite3 -readonly "$HOME/.codex/logs_2.sqlite" \ "SELECT datetime(ts,'unixepoch','localtime'), substr(feedback_log_body,1,120) FROM logs WHERE feedback_log_body LIKE '%remote control%' ORDER BY ts DESC LIMIT 3;"

只有当前时间附近明确出现 remote control requires ChatGPT authentication; API key auth is not supported,才能将本次拒绝归因于该连接不支持 API key 认证。不要公开 auth.json 的完整内容,也不要把某次日志结论推广到所有浏览器工具。没有这条证据时,保留根因未定的结论。

使用普通只读连接能正常读取 SQLite 的预写日志(WAL);正在更新的数据库不宜加 immutable=1,否则可能漏看尚未合并的数据。数据库表结构可能随应用版本改变,查询报列不存在时先检查 .schema logs。

两个查日志的坑,踩了就会判断反:

  • ts 列单位是秒。按毫秒换算会把当前报错显示成 1970 年,误以为是历史遗留。

  • curl 不读 PAC。直连 curl https://chatgpt.com/... 返回 000 很像网络故障,但 App 内部走 PAC 代理,行为不同。要测连通性必须显式指定代理。

方案 A:接入 Chrome DevTools MCP

如果内置浏览器暂时无法使用,可以单独配置 Chrome DevTools MCP。本次环境已验证其导航、页面读取和截图功能;其他能力仍以当前版本实际暴露的工具为准。此方案不要求修改现有模型供应商配置。

1. 备份加写配置

TS=$(date +%Y%m%d%H%M%S) cp -p ~/.codex/config.toml "$HOME/.codex/config.toml.bak-$TS" echo "备份时间戳: $TS"

在 ~/.codex/config.toml 追加:

[mcp_servers.chrome-devtools] 
command = "npx" 
args = ["-y", "chrome-devtools-mcp@latest"] 
startup_timeout_sec = 120

两点别漏:

  • startup_timeout_sec = 120 用于给首次下载和启动留出时间,属于排障建议,不是所有环境都必须设置的值。

  • 不要写 type = "stdio"。这是无效字段,日志会报 mcp_servers.chrome-devtools.type is ignored。

2. 仅在出现缓存错误时处理 npx 缓存

如果启动输出明确出现以下错误,再检查缓存目录:

npm error ENOTEMPTY: directory not empty, rename '.../_npx/15c61037b1978c83/node_modules/chrome-devtools-mcp' -> '.../.chrome-devtools-mcp-GVqCnf84'

残留的中间目录让 npx 无法原子替换。处理:

find ~/.npm/_npx -maxdepth 3 -name '.chrome-devtools-mcp-*' # 确认对应进程已停止后,将命中的单个缓存目录移到废纸篓。 # 不要直接删除整个 ~/.npm,也不要照抄占位路径执行。

3. 脱离 Codex 先跑通

先在 App 之外验证下载与启动。独立运行成功只能缩小排查范围;应用内仍可能存在环境变量、命令路径、版本或权限差异。

npm view chrome-devtools-mcp version --fetch-timeout=20000 cd /tmp && printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}' \ | npx -y chrome-devtools-mcp@latest 2>/tmp/cdp-err.log | head -c 600

期望看到 serverInfo 带 Chrome DevTools MCP server。macOS 自带 shell 没有 timeout 命令;--fetch-timeout 只限制 npm 网络请求,不能代替整个 MCP 进程的执行超时。该探针只检查初始化,不是完整交互验证。

4. 验证

端到端拉起 Chrome:

cd /tmp && { \ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}'; \ sleep 1; \ printf '%s\n' '{"jsonrpc":"2.0","method":"notifications/initialized"}'; \ printf '%s\n' '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"new_page","arguments":{"url":"https://example.com"}}}'; \ sleep 30; \ } | npx -y chrome-devtools-mcp@latest --isolated 2>/dev/null | tail -3

两个判断上的坑:

  • 先取得页面 ID。 调用 list_pages,已有页面就使用返回的数字 ID;没有适用页面再调用 new_page。是否要求 pageId 以当前工具 schema 为准。本次连接实际先用 list_pages 获得页面 1,再导航成功。

  • 工具层的校验错误不在 JSON-RPC 的 error 字段里,而是放在 result.content (可能带 isError)。只检查 error 会把失败误判成成功,要同时看 isError 和正文 里有没有 validation error。

参考资料

Logo

更多推荐