1. 与 chrome-devtools-mcp 兼容,能直接作为 --executablePath 启动目标。
  2. 可控性高:安装在 /opt,通过固定入口 /usr/local/bin/ungoogled-chromium,升级与回滚路径清晰。
  3. 可隔离会话:日常浏览、--remote-debugging-port=9222、MCP --userDataDir 可以拆分,互不污染。
  4. 隐私侧更干净:默认不依赖 Google 服务,减少背景干扰项,适合自动化与排障场景。
  5. 在本机桌面环境可稳定跑 headful 调试,遇到会话环境变量缺失时可通过包装脚本补齐。

目标

  1. 部署ungoogled-chromium到系统级合适目录(/opt)
  2. 添加桌面启动器并固定到任务栏(GNOME favorites)
  3. 配置 CDP MCP(Claude Code / Codex 的 chrome-devtools-mcp)

前置检查

whoami
id
echo "$XDG_CURRENT_DESKTOP"

关键结果:

  • 当前用户:dev
  • 属于 sudo 组,且可无密码 sudo(sudo -n true 成功)
  • 桌面环境:zorin:GNOME

过程细节

1) 安装到 /opt(系统级)

SRC="/home/dev/Downloads/ungoogled-chromium-146.0.7680.71-1-x86_64_linux"
VER="146.0.7680.71"
DST="/opt/ungoogled-chromium-$VER"
LINK="/opt/ungoogled-chromium"

sudo install -d -m 0755 "$DST"
sudo rsync -a --delete "$SRC/" "$DST/"
sudo chown -R root:root "$DST"
sudo ln -sfn "$DST" "$LINK"

说明:

  • 使用版本目录 + 稳定软链方案,便于后续升级回滚。
  • 最终主路径固定为:/opt/ungoogled-chromium。

2) 创建启动命令(普通模式 + CDP 模式)

创建 /usr/local/bin/ungoogled-chromium:

#!/usr/bin/env bash
exec /opt/ungoogled-chromium/chrome-wrapper "$@"

创建 /usr/local/bin/ungoogled-chromium-cdp:

#!/usr/bin/env bash
PROFILE_DIR="${HOME}/.config/ungoogled-chromium-cdp"
mkdir -p "$PROFILE_DIR"
exec /opt/ungoogled-chromium/chrome-wrapper \
  --remote-debugging-address=127.0.0.1 \
  --remote-debugging-port=9222 \
  --user-data-dir="$PROFILE_DIR" \
  --no-first-run \
  "$@"

用途:

  • ungoogled-chromium:日常浏览。
  • ungoogled-chromium-cdp:用于本机 CDP 调试(127.0.0.1:9222)。

浏览器版本

/usr/local/bin/ungoogled-chromium --version

输出:Chromium 146.0.7680.71 custom

3) 创建桌面启动器并加入任务栏

系统桌面项目录在本机不存在,先创建:

sudo install -d -m 0755 /usr/local/share/applications

创建桌面文件:

  • /usr/local/share/applications/ungoogled-chromium.desktop
  • /usr/local/share/applications/ungoogled-chromium-cdp.desktop

/usr/local/share/applications/ungoogled-chromium.desktop 内容:

[Desktop Entry]
Version=1.0
Type=Application
Name=Ungoogled Chromium
Comment=Browse the Web
Exec=/usr/local/bin/ungoogled-chromium %U
Terminal=false
Icon=/opt/ungoogled-chromium/product_logo_48.png
Categories=Network;WebBrowser;
MimeType=text/html;text/xml;application/xhtml_xml;x-scheme-handler/http;x-scheme-handler/https;
StartupNotify=true
StartupWMClass=chromium

/usr/local/share/applications/ungoogled-chromium-cdp.desktop 内容:

[Desktop Entry]
Version=1.0
Type=Application
Name=Ungoogled Chromium (CDP 9222)
Comment=Ungoogled Chromium with remote debugging on 127.0.0.1:9222
Exec=/usr/local/bin/ungoogled-chromium-cdp %U
Terminal=false
Icon=/opt/ungoogled-chromium/product_logo_48.png
Categories=Network;WebBrowser;Development;
StartupNotify=true
StartupWMClass=chromium

无痕模式

如果希望点击桌面启动器后直接以无痕模式启动,可在对应 desktop 文件的 Exec= 行中追加 --incognito。

例如普通启动器可改为:Exec=/usr/local/bin/ungoogled-chromium --incognito %U

若确实需要,CDP 启动器同理可写成:Exec=/usr/local/bin/ungoogled-chromium-cdp --incognito %U

提示

若出现“窗口不与任务栏图标合并”,通常是窗口被识别为另一个 desktop id(例如 chromium-devel.desktop)。优先检查启动入口与 desktop 文件 id 是否一致。

刷新桌面数据库:

sudo update-desktop-database /usr/local/share/applications

将普通启动器固定到 GNOME 任务栏(favorites):

gsettings get org.gnome.shell favorite-apps
gsettings set org.gnome.shell favorite-apps "[..., 'ungoogled-chromium.desktop']"

任务栏固定确认

gsettings get org.gnome.shell favorite-apps

关键结果包含: ungoogled-chromium.desktop

4) 配置 Claude Code CDP MCP

先确认 CLI 可用:

which claude
claude mcp list

添加用户级 MCP(全项目可用):

claude mcp add -s user chrome-devtools -- \
  npx -y chrome-devtools-mcp@latest \
  --executablePath /usr/local/bin/ungoogled-chromium \
  --userDataDir /home/dev/.config/ungoogled-chromium-mcp

说明:

  • 绑定到刚安装的 ungoogled-chromium 启动入口。
  • 使用独立 userDataDir,避免污染其它浏览器配置。

Claude Code CDP MCP 状态

claude mcp get chrome-devtools
claude mcp list

关键结果:

  • chrome-devtools 状态:✓ Connected
  • 已写入配置文件:/home/dev/.claude.json

5) 配置 Codex CDP MCP

这里直接给出最终验证可用的 Codex 配置。先为当前 Codex CLI 增加 chrome-devtools:

codex mcp add chrome-devtools -- \
  npx -y chrome-devtools-mcp@latest \
  --executablePath /usr/local/bin/ungoogled-chromium \
  --userDataDir /home/dev/.config/ungoogled-chromium-mcp

然后在 ~/.codex/config.toml 中为该条目补充环境变量:

[mcp_servers.chrome-devtools.env]
DISPLAY = ":0"
WAYLAND_DISPLAY = "wayland-0"
XDG_SESSION_TYPE = "wayland"
XDG_RUNTIME_DIR = "/run/user/1000"
DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/user/1000/bus"

说明:

  • codex mcp add 负责写入 command / args,config.toml 中的 env 用于补齐 Codex MCP 子进程缺失的桌面会话变量。
  • XAUTHORITY 不建议写死到 config.toml,因为 Wayland/Xwayland 认证文件名会随登录会话变化;更稳妥的做法是配合后文修复章节中的浏览器启动脚本动态探测。
  • 最终效果是:Codex 侧 chrome-devtools 使用独立 userDataDir,并在可用的图形会话环境下稳定拉起 headful 的 ungoogled-chromium。

查询:

codex mcp list
codex mcp get chrome-devtools --json

关键结果:

  • Codex 已存在 MCP 条目:chrome-devtools
  • 类型:stdio
  • command/args 指向本机 ungoogled-chromium 启动路径
  • env 中包含 DISPLAY、WAYLAND_DISPLAY、XDG_SESSION_TYPE、XDG_RUNTIME_DIR、DBUS_SESSION_BUS_ADDRESS
  • 配置位置:/home/dev/.codex/config.toml 中 [mcp_servers.chrome-devtools] 与 [mcp_servers.chrome-devtools.env]

使用方式

  • 普通启动:应用菜单搜索 Ungoogled Chromium,或命令 ungoogled-chromium
  • CDP 启动:应用菜单搜索 Ungoogled Chromium (CDP 9222),或命令 ungoogled-chromium-cdp
  • Claude Code 中使用 CDP MCP:直接在 Claude Code 中调用 chrome-devtools 工具即可
  • Codex 中使用 CDP MCP:新开一个 Codex 会话后可直接调用 chrome-devtools MCP 工具

补充:192.168.114.3 通过 SSH 反向转发复用本机 CDP(不改 chromium-cdp 监听地址)

场景与原则

  • 本机(192.168.114.4)继续保持 /usr/local/bin/ungoogled-chromium-cdp 监听 127.0.0.1:9222,不改成 0.0.0.0
  • 在本机执行 ssh 192.168.114.3 时,自动建立 RemoteForward
  • 这样 192.168.114.3 上的 127.0.0.1:9222 会映射到本机 127.0.0.1:9222

1) 修改本机 ~/.ssh/config

在 Host 192.168.114.3 段追加:

Host 192.168.114.3
    User van
    ExitOnForwardFailure yes
    ServerAliveInterval 30
    ServerAliveCountMax 3
    RemoteForward 127.0.0.1:9222 127.0.0.1:9222

说明:

  • RemoteForward 127.0.0.1:9222 127.0.0.1:9222:把“本机 CDP 9222”映射到“远端 114.3 的本地 9222”
  • 连接 114.3 后隧道生效,断开后自动释放

2) 在 192.168.114.3 验证隧道

先从本机连接:

ssh 192.168.114.3

然后在 192.168.114.3 的 shell 里验证:

curl -sS http://127.0.0.1:9222/json/version

关键结果应包含:

  • Browser: Chrome/146.0.7680.71
  • webSocketDebuggerUrl: ws://127.0.0.1:9222/devtools/browser/...

3) 配置 192.168.114.3 的 Claude Code / Codex MCP

过程说明

192.168.114.3 上直接 npx 访问 npm registry 曾出现 EAI_AGAIN。
最终做法:给 MCP 子进程显式加代理环境变量(HTTP_PROXY / HTTPS_PROXY / ALL_PROXY / NO_PROXY)。

Claude Code:

claude mcp add -s user chrome-devtools -- \
  npx -y chrome-devtools-mcp@latest \
  --browser-url http://127.0.0.1:9222

然后在 ~/.claude.json 的 mcpServers.chrome-devtools.env 写入:

{
  "HTTP_PROXY": "http://192.168.114.9:7890",
  "HTTPS_PROXY": "http://192.168.114.9:7890",
  "ALL_PROXY": "socks5://192.168.114.9:7890",
  "NO_PROXY": "127.0.0.1,localhost,192.168.114.0/24,192.168.3.0/24"
}

Codex:

codex mcp add \
  --env HTTP_PROXY=http://192.168.114.9:7890 \
  --env HTTPS_PROXY=http://192.168.114.9:7890 \
  --env ALL_PROXY=socks5://192.168.114.9:7890 \
  --env NO_PROXY=127.0.0.1,localhost,192.168.114.0/24,192.168.3.0/24 \
  chrome-devtools -- \
  npx -y chrome-devtools-mcp@latest \
  --browser-url http://127.0.0.1:9222

4) 实测结果

192.168.114.3 上状态:

claude mcp get chrome-devtools
codex mcp get chrome-devtools --json

关键结果:

  • Claude Code:Status: ✓ Connected
  • Codex:transport.args 为 --browser-url http://127.0.0.1:9222
  • Codex/Claude 的 MCP env 均包含代理变量

192.168.114.3 上实际执行(Codex 通过 CDP MCP 打开页面):

codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check -C /home/van \
  "使用 chrome-devtools MCP 打开 https://www.baidu.com ,并返回页面标题与最终 URL。"

返回:

  • 页面标题:百度一下,你就知道
  • 最终 URL:https://www.baidu.com/

5) 注意事项

  • RemoteForward 9222 同时只能被一个 SSH 连接占用;若出现 remote port forwarding failed for listen port 9222,先断开已有占用会话再重连
  • 该方案不暴露局域网监听端口,CDP 仍只绑定在本机 loopback,安全性高于直接开放 0.0.0.0:9222

补充:Codex 使用 ungoogled-chromium 的 CDP MCP 修复过程

问题现象

在 Codex 中调用 chrome-devtools 时,最初报错:

Missing X server to start the headful browser.
Either set headless to true or use xvfb-run to run your Puppeteer script.

后续出现:

Protocol error (Target.setDiscoverTargets): Target closed

诊断过程(关键步骤)

  1. 对比 Claude Code 与 Codex 的 MCP 启动参数,确认两边 command/args 一致,均为:
npx -y chrome-devtools-mcp@latest \
  --executablePath /usr/local/bin/ungoogled-chromium \
  --userDataDir /home/dev/.config/ungoogled-chromium-mcp
  1. 对比 MCP 进程环境变量(/proc/<pid>/environ):

    • Claude 侧包含:DISPLAY、WAYLAND_DISPLAY、XDG_RUNTIME_DIR、XAUTHORITY、DBUS_SESSION_BUS_ADDRESS
    • Codex 侧仅有:HOME、PATH、USER 等最小变量
  2. 用最小环境复现实验验证:

    • 缺少 XDG_RUNTIME_DIR 时,Chromium 无法初始化 Wayland 平台并退出
    • 解释了 Codex 侧“Target closed”的根因是浏览器进程启动后很快退出

过程说明

中间尝试安装 xvfb 做旁路验证(可执行),但最终确认不是主因;核心问题是 Codex MCP 进程环境变量被裁剪。

1) 增强 /usr/local/bin/ungoogled-chromium 启动脚本兜底

将启动脚本改为在缺省环境下自动补齐桌面会话变量(DISPLAY、WAYLAND_DISPLAY、XDG_SESSION_TYPE、XDG_RUNTIME_DIR,并动态探测 XAUTHORITY,补 DBUS_SESSION_BUS_ADDRESS):

#!/usr/bin/env bash

uid="$(id -u)"
: "${DISPLAY:=:0}"
: "${WAYLAND_DISPLAY:=wayland-0}"
: "${XDG_SESSION_TYPE:=wayland}"
: "${XDG_RUNTIME_DIR:=/run/user/${uid}}"

if [ -z "${XAUTHORITY:-}" ]; then
	latest_auth="$(ls -t /run/user/${uid}/.mutter-Xwaylandauth.* 2>/dev/null | head -n 1)"
	if [ -n "${latest_auth}" ]; then
		export XAUTHORITY="${latest_auth}"
	fi
fi

if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && [ -S "/run/user/${uid}/bus" ]; then
	export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${uid}/bus"
fi

export DISPLAY WAYLAND_DISPLAY XDG_SESSION_TYPE XDG_RUNTIME_DIR
exec /opt/ungoogled-chromium/chrome-wrapper "$@"

结论

  • Codex 侧故障不是 MCP 参数本身错误,而是 MCP 子进程环境变量不完整导致 Chromium 启动失败。
  • 通过“启动脚本兜底 + Codex MCP env 显式补齐”后,Codex 使用 ungoogled-chromium 的 CDP MCP 已恢复可用。
  • 当前配置默认使用 --userDataDir /home/dev/.config/ungoogled-chromium-mcp 的独立浏览器上下文;若要“附着到已打开的桌面浏览器窗口”,需改为连接该实例的 remote debugging endpoint(例如 --browser-url 模式)。

回滚(可选)

claude mcp remove -s user chrome-devtools
codex mcp remove chrome-devtools
sudo rm -f /usr/local/share/applications/ungoogled-chromium.desktop
sudo rm -f /usr/local/share/applications/ungoogled-chromium-cdp.desktop
sudo rm -f /usr/local/bin/ungoogled-chromium /usr/local/bin/ungoogled-chromium-cdp
sudo rm -f /opt/ungoogled-chromium
sudo rm -rf /opt/ungoogled-chromium-146.0.7680.71