{ config, pkgs, lib, ... }: let # Wrapper to launch Chromium on Wayland, scale=1, DevTools debugging on 127.0.0.1:9222 chromiumWaylandWrapper = pkgs.writeShellScriptBin "chromium-mcp" '' exec ${pkgs.ungoogled-chromium}/bin/chromium \ --ozone-platform=wayland \ --enable-features=UseOzonePlatform \ --force-device-scale-factor=1 \ --remote-debugging-address=127.0.0.1 \ --remote-debugging-port=9222 \ "$@" ''; in { # Tools: Chromium, Node (for MCP server), our wrapper environment.systemPackages = [ pkgs.ungoogled-chromium pkgs.nodejs_22 # 25.05 ships Node 22 LTS; works great for MCP servers chromiumWaylandWrapper ]; # Where Codex CLI reads config; we make it system-wide environment.variables.CODEX_HOME = "/etc/codex"; # Codex CLI MCP config: wires Chrome DevTools MCP to the local DevTools port environment.etc."codex/config.toml".text = '' [mcp_servers.chrome-devtools] command = "npx" args = [ # "-y", "chrome-devtools-mcp@latest", "--browserUrl=http://127.0.0.1:9222" "-y", "chrome-devtools-mcp@latest", # Tell MCP exactly which Chromium to launch (Nix store path) "--executablePath=${pkgs.ungoogled-chromium}/bin/chromium", # Make every run use a temporary profile (no shared state) "--isolated=true", # Headful by default on Wayland "--headless=true", # Pass Chromium flags for Wayland + scale "--chromeArg=--ozone-platform=wayland", "--chromeArg=--enable-features=UseOzonePlatform", "--chromeArg=--force-device-scale-factor=1" ] startup_timeout_sec = 30 tool_timeout_sec = 120 ''; # No firewall opening: binding to 127.0.0.1 only # networking.firewall.allowedTCPPorts = [ 9222 ]; }