Skip to content

Commit 216b159

Browse files
committed
feat(mcp): wire chrome-devtools-mcp for Claude Code via nix+just
Add a Model Context Protocol server that gives Claude (and other MCP clients) real Chrome-DevTools access — evaluate_script, console capture, take_screenshot, network inspection, etc. — against Playwright's nix-provided Chrome-for-Testing. Targets headless Linux. Wiring: - .mcp.json at repo root registers a "chrome-devtools" server that shells out via `nix develop --command just mcp-chrome-devtools`. Claude Code starts outside the devshell, so the nix-develop wrapper is mandatory — it bridges into the devshell where KOLU_CHROME_EXECUTABLE is set and npx/node are on PATH. - justfile gains a `mcp-chrome-devtools` recipe that execs `npx -y chrome-devtools-mcp@latest` with --headless, --isolated, and --executable-path pinned to the resolved chrome binary. Keeps command complexity out of .mcp.json. - shell.nix computes the chrome path at Nix eval time by reading playwright-driver's browsers.json (idiom from wiki.nixos.org/wiki/Playwright) — fails loud on layout change, warm `nix develop` eval stays at ~0.2s. Telemetry: chrome-devtools-mcp sends usage stats to Google by default (and trace URLs to Chrome CrUX for performance traces). Left on for the prototype; add `--no-usage-statistics --no-performance-crux` to the just recipe if that's unwanted.
1 parent 547cd9e commit 216b159

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

.mcp.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mcpServers": {
3+
"chrome-devtools": {
4+
"command": "nix",
5+
"args": ["develop", "--command", "just", "mcp-chrome-devtools"]
6+
}
7+
}
8+
}

justfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ fmt:
9595
fmt-check:
9696
{{ nix_shell }} sh -c 'prettier --check --cache --ignore-unknown . && nixpkgs-fmt --check *.nix nix/**/*.nix'
9797

98+
# Launch chrome-devtools-mcp server over stdio — wired up via .mcp.json.
99+
# Drives Playwright's nix-provided Chrome-for-Testing (headless, isolated
100+
# profile). Claude Code starts outside the devshell, so .mcp.json wraps
101+
# this with `nix develop --command just mcp-chrome-devtools`.
102+
mcp-chrome-devtools:
103+
{{ nix_shell }} sh -c 'exec npx -y chrome-devtools-mcp@latest --headless=true --isolated=true --executable-path="$KOLU_CHROME_EXECUTABLE"'
104+
98105
# Nix build (server + client)
99106
build:
100107
nix build

shell.nix

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
{ pkgs ? import ./nix/nixpkgs.nix { } }:
33
let
44
packages = import ./default.nix { inherit pkgs; };
5+
6+
# Chrome-for-Testing path for chrome-devtools-mcp (see .mcp.json). Pulled
7+
# from playwright-driver's browsers.json at eval time so the chromium-N
8+
# revision tracks whatever nixpkgs pins — fails loud here if layout changes
9+
# instead of silently at MCP startup. Idiom from https://wiki.nixos.org/wiki/Playwright.
10+
playwrightBrowsers = (builtins.fromJSON
11+
(builtins.readFile "${pkgs.playwright-driver}/browsers.json")).browsers;
12+
chromiumRev = (builtins.head
13+
(builtins.filter (b: b.name == "chromium") playwrightBrowsers)).revision;
14+
koluChromeExecutable =
15+
"${pkgs.playwright-driver.browsers}/chromium-${chromiumRev}/chrome-linux64/chrome";
516
in
617
pkgs.mkShell {
718
name = "kolu-shell";
@@ -11,6 +22,7 @@ pkgs.mkShell {
1122
KOLU_COMMIT_HASH = "dev";
1223
PLAYWRIGHT_BROWSERS_PATH = "${pkgs.playwright-driver.browsers}";
1324
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "1";
25+
KOLU_CHROME_EXECUTABLE = koluChromeExecutable;
1426
};
1527

1628
shellHook = ''

0 commit comments

Comments
 (0)