Back to skills
SkillHub ClubBuild MobileFull StackBackendDesigner

devtools

This skill helps launch and configure the Chrome DevTools MCP server, giving Claude visual access to a live browser for debugging and automation. Use when the user asks to set up browser debugging, launch Chrome with DevTools, configure chrome-devtools-mcp, see what my app looks like, take screenshots of my web application, check the browser console, debug console errors, inspect network requests, analyse API responses, measure Core Web Vitals or page performance, run a Lighthouse audit, test button clicks or form submissions, automate browser interactions, fill out forms programmatically, simulate user actions, emulate mobile devices or slow networks, capture DOM snapshots, execute JavaScript in the browser, or troubleshoot Chrome DevTools MCP connection issues. Supports Windows, Linux, and WSL2 environments.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
38
Hot score
90
Updated
March 20, 2026
Overall rating
C2.9
Composite score
2.9
Best-practice grade
F37.6

Install command

npx @skill-hub/cli install henkisdabro-wookstar-claude-code-plugins-devtools

Repository

henkisdabro/wookstar-claude-code-plugins

Skill path: plugins/developer/skills/devtools

This skill helps launch and configure the Chrome DevTools MCP server, giving Claude visual access to a live browser for debugging and automation. Use when the user asks to set up browser debugging, launch Chrome with DevTools, configure chrome-devtools-mcp, see what my app looks like, take screenshots of my web application, check the browser console, debug console errors, inspect network requests, analyse API responses, measure Core Web Vitals or page performance, run a Lighthouse audit, test button clicks or form submissions, automate browser interactions, fill out forms programmatically, simulate user actions, emulate mobile devices or slow networks, capture DOM snapshots, execute JavaScript in the browser, or troubleshoot Chrome DevTools MCP connection issues. Supports Windows, Linux, and WSL2 environments.

Open repository

Best for

Primary workflow: Build Mobile.

Technical facets: Full Stack, Backend, Designer, Mobile, Testing, Integration.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: henkisdabro.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install devtools into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/henkisdabro/wookstar-claude-code-plugins before adding devtools to shared team environments
  • Use devtools for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: devtools
description: This skill helps launch and configure the Chrome DevTools MCP server, giving Claude visual access to a live browser for debugging and automation. Use when the user asks to set up browser debugging, launch Chrome with DevTools, configure chrome-devtools-mcp, see what my app looks like, take screenshots of my web application, check the browser console, debug console errors, inspect network requests, analyse API responses, measure Core Web Vitals or page performance, run a Lighthouse audit, test button clicks or form submissions, automate browser interactions, fill out forms programmatically, simulate user actions, emulate mobile devices or slow networks, capture DOM snapshots, execute JavaScript in the browser, or troubleshoot Chrome DevTools MCP connection issues. Supports Windows, Linux, and WSL2 environments.
---

# Chrome DevTools MCP

**GitHub Repository:** https://github.com/ChromeDevTools/chrome-devtools-mcp

Without browser access, Claude is "coding blindfolded" - making changes without seeing results. The Chrome DevTools MCP server provides **26 specialised tools** across these categories:

| Category | Capabilities |
|----------|--------------|
| **Visual Inspection** | Take screenshots, capture DOM snapshots, see rendered output |
| **Console & Logging** | Read console messages, catch JavaScript errors, debug issues |
| **Network Analysis** | Inspect API requests/responses, analyse headers, debug fetch calls |
| **Performance** | Record traces, measure Core Web Vitals (LCP, CLS, TBT), identify bottlenecks |
| **User Simulation** | Click elements, fill forms, drag-and-drop, handle dialogs |
| **Device Emulation** | Simulate mobile viewports, throttle CPU/network, test responsive design |

## Quick Start Workflow

Execute these steps in order:

### Step 1: Detect Environment

```bash
bash scripts/detect_environment.sh
```

Returns one of: `windows`, `linux`, or `wsl2`

### Step 2: Verify Chrome Installation

```bash
bash scripts/check_chrome.sh <environment>
```

Outputs `status:installed` or `status:not_installed`. If not installed, see [references/chrome-installation.md](references/chrome-installation.md) for installation options.

**IMPORTANT:** Do not proceed until Chrome is installed and verified.

### Step 3: Check MCP Server Status

```bash
claude mcp list | grep -i chrome
```

If not installed:

```bash
claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --browserUrl http://127.0.0.1:9222
```

For advanced configuration options and alternative connection methods, see [references/mcp-configuration.md](references/mcp-configuration.md).

### Step 4: Detect Running Dev Server

```bash
bash scripts/detect_dev_server.sh
```

Checks ports 5173, 5174, 5175, 3000, 3001, 8080, and 8000. If no dev server is running and one is needed, offer to start it.

### Step 5: Launch Chrome with Debugging

```bash
bash scripts/launch_chrome.sh <environment> <url> [headed]
```

- `<environment>`: `windows`, `linux`, or `wsl2`
- `<url>`: Target URL (e.g., `http://localhost:5173`)
- `[headed]`: Optional - pass `headed` for visible browser, omit for headless (default)

### Step 6: Verify Connection

```bash
curl -s http://127.0.0.1:9222/json/version
```

Once connected, test with the `mcp__chrome-devtools__list_pages` tool.

## Quick Troubleshooting

| Issue | Solution |
|-------|----------|
| "Target closed" error | Close all Chrome instances, restart with debugging |
| Module not found | Clear npm cache: `rm -rf ~/.npm/_npx && npm cache clean --force` |
| Connection refused | Ensure Chrome launched with `--remote-debugging-port=9222` |
| Port already in use | Kill existing Chrome or use different port |
| Chrome won't start in sandbox | Use `--browserUrl` to connect to manually-started Chrome |
| WebDriver sign-in blocked | Use `--autoConnect` to connect to your normal browser session |

For detailed troubleshooting steps, see [references/troubleshooting.md](references/troubleshooting.md).

## References

- **Chrome Installation:** [references/chrome-installation.md](references/chrome-installation.md) - platform-specific installation options
- **MCP Configuration:** [references/mcp-configuration.md](references/mcp-configuration.md) - all configuration flags, JSON examples, connection methods, platform commands, and known limitations
- **Troubleshooting:** [references/troubleshooting.md](references/troubleshooting.md) - detailed error resolution, debugging with logs, and recovery scripts


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/chrome-installation.md

```markdown
# Chrome Installation

If Chrome is not detected by `scripts/check_chrome.sh`, install it using one of these methods.

## Linux / WSL2

**Option 1: Direct download (recommended)**

```bash
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -y ./google-chrome-stable_current_amd64.deb
```

**Option 2: Add Google's repository**

```bash
# Add signing key
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg

# Add repository
echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list

# Install
sudo apt update
sudo apt install -y google-chrome-stable
```

**Option 3: Chromium (open-source alternative)**

```bash
sudo apt update
sudo apt install -y chromium-browser
```

## Windows

**Option 1: Download from Google**
Visit https://www.google.com/chrome/ and run the installer.

**Option 2: Using winget**

```powershell
winget install Google.Chrome
```

**Option 3: Using Chocolatey**

```powershell
choco install googlechrome
```

**Option 4: PowerShell direct download**

```powershell
$installer = "$env:TEMP\chrome_installer.exe"
Invoke-WebRequest -Uri "https://dl.google.com/chrome/install/latest/chrome_installer.exe" -OutFile $installer
Start-Process -FilePath $installer -Args "/silent /install" -Wait
Remove-Item $installer
```

## Verify Installation

After installation, verify with:

```bash
bash scripts/check_chrome.sh <environment>
```

```

### references/mcp-configuration.md

```markdown
# Chrome DevTools MCP Configuration Reference

**GitHub Repository:** https://github.com/ChromeDevTools/chrome-devtools-mcp

## Quick Install

```bash
claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --browserUrl http://127.0.0.1:9222
```

## Configuration Flags

All flags can be passed via the `args` array in `.mcp.json`:

| Flag | Description | Default |
|------|-------------|---------|
| `--browserUrl`, `-u` | Connect to running Chrome (e.g., `http://127.0.0.1:9222`) | - |
| `--autoConnect` | Auto-connect to Chrome 145+ with remote debugging enabled | `false` |
| `--headless` | Run in headless (no UI) mode | `false` |
| `--isolated` | Use temporary user-data-dir, auto-cleaned on close | `false` |
| `--channel` | Chrome channel: `stable`, `canary`, `beta`, `dev` | `stable` |
| `--viewport` | Initial viewport size (e.g., `1280x720`, max `3840x2160` headless) | - |
| `--executablePath`, `-e` | Path to custom Chrome executable | - |
| `--userDataDir` | Custom user data directory | `~/.cache/chrome-devtools-mcp/chrome-profile` |
| `--wsEndpoint`, `-w` | WebSocket endpoint (alternative to `--browserUrl`) | - |
| `--wsHeaders` | Custom WebSocket headers as JSON (use with `--wsEndpoint`) | - |
| `--proxyServer` | Proxy server for Chrome | - |
| `--acceptInsecureCerts` | Ignore self-signed/expired certificate errors | `false` |
| `--chromeArg` | Additional Chrome launch arguments (array) | - |
| `--logFile` | Debug log file path (set `DEBUG=*` for verbose) | - |
| `--categoryEmulation` | Include emulation tools | `true` |
| `--categoryPerformance` | Include performance tools | `true` |
| `--categoryNetwork` | Include network tools | `true` |

## Configuration Examples

### Basic Configuration

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--browserUrl",
        "http://127.0.0.1:9222"
      ]
    }
  }
}
```

### Headless with Isolated Profile

Best for CI/CD or automated testing - uses a temporary profile that's cleaned up automatically:

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--headless",
        "--isolated"
      ]
    }
  }
}
```

### Custom Viewport for Mobile Testing

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--browserUrl=http://127.0.0.1:9222",
        "--viewport=390x844"
      ]
    }
  }
}
```

### Using Chrome Canary/Beta

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--channel=canary",
        "--headless",
        "--isolated"
      ]
    }
  }
}
```

### With Debug Logging

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--browserUrl=http://127.0.0.1:9222",
        "--logFile=/tmp/chrome-devtools-mcp.log"
      ],
      "env": {
        "DEBUG": "*"
      }
    }
  }
}
```

### WebSocket Connection with Auth Headers

For connecting to remote Chrome instances with authentication:

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--wsEndpoint=ws://127.0.0.1:9222/devtools/browser/<id>",
        "--wsHeaders={\"Authorization\":\"Bearer YOUR_TOKEN\"}"
      ]
    }
  }
}
```

To get the WebSocket endpoint, visit `http://127.0.0.1:9222/json/version` and look for `webSocketDebuggerUrl`.

## Connection Methods

### Method 1: Manual Connection (Recommended)

Start Chrome yourself with remote debugging, then connect via `--browserUrl`. This is the approach used in the Quick Start Workflow.

**When to use:**

- Running Claude in a sandboxed environment
- Need full control over Chrome launch options
- Working with self-signed certificates

### Method 2: Auto-Connect (Chrome 145+)

Let chrome-devtools-mcp automatically connect to a running Chrome instance.

**Step 1:** Enable remote debugging in Chrome:

1. Navigate to `chrome://inspect/#remote-debugging`
2. Follow the dialog to allow debugging connections

**Step 2:** Configure MCP with `--autoConnect`:

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["chrome-devtools-mcp@latest", "--autoConnect"]
    }
  }
}
```

**When to use:**

- Sharing state between manual testing and Claude-driven testing
- Avoiding WebDriver sign-in blocks (some sites block automated browsers)
- Want Chrome to prompt for permission before Claude connects

### Method 3: Let MCP Launch Chrome

If you omit `--browserUrl` and `--autoConnect`, the MCP server will launch its own Chrome instance.

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["chrome-devtools-mcp@latest", "--headless", "--isolated"]
    }
  }
}
```

**When to use:**

- Fully automated workflows
- No need to maintain browser state
- CI/CD pipelines

## User Data Directory

By default, chrome-devtools-mcp uses a persistent profile at:

- **Linux/macOS:** `$HOME/.cache/chrome-devtools-mcp/chrome-profile-$CHANNEL`
- **Windows:** `%HOMEPATH%/.cache/chrome-devtools-mcp/chrome-profile-$CHANNEL`

This profile is shared across all MCP sessions, preserving cookies, local storage, and login state.

Use `--isolated` for a fresh, temporary profile that's automatically cleaned up when the browser closes.

## Platform-Specific Launch Commands

### WSL2 / Linux

```bash
# Headless
google-chrome --headless --remote-debugging-port=9222 --no-first-run --user-data-dir=/tmp/chrome-mcp http://localhost:5173 &

# Headed
google-chrome --remote-debugging-port=9222 --no-first-run --user-data-dir=/tmp/chrome-mcp http://localhost:5173 &
```

### Windows (CMD/PowerShell)

```cmd
REM Headless
start chrome.exe --headless --remote-debugging-port=9222 --no-first-run --user-data-dir=%TEMP%\chrome-mcp http://localhost:5173

REM Headed
start chrome.exe --remote-debugging-port=9222 --no-first-run --user-data-dir=%TEMP%\chrome-mcp http://localhost:5173
```

## Known Limitations

### Operating System Sandboxes

Some MCP clients sandbox the server using macOS Seatbelt or Linux containers. In sandboxed environments, chrome-devtools-mcp cannot start Chrome (which requires its own sandbox permissions).

**Workarounds:**

1. Disable sandboxing for chrome-devtools-mcp in your MCP client
2. Use `--browserUrl` to connect to a Chrome instance started outside the sandbox

### Security Considerations

The remote debugging port exposes your browser to any application on your machine. When debugging is enabled:

- Avoid browsing sensitive sites (banking, email with sensitive data)
- Use `--isolated` for a separate profile
- Close Chrome when done debugging

```

### references/troubleshooting.md

```markdown
# Chrome DevTools MCP Troubleshooting Guide

## General Tips

1. **Test MCP server independently:**
   ```bash
   npx chrome-devtools-mcp@latest --help
   ```

2. **Ensure npm/node versions match:**
   Make sure the MCP client uses the same npm and node version as the terminal.

3. **Use --yes flag for npx:**
   When configuring MCP client, use `--yes` to auto-accept installation prompts:
   ```bash
   npx --yes chrome-devtools-mcp@latest
   ```

4. **Check IDE output logs:**
   If the client is an IDE, look for specific errors in the Output pane.

## Debugging with Logs

### Enable Debug Mode

Start the MCP server with debugging enabled:

```bash
DEBUG=* npx chrome-devtools-mcp@latest --log-file=/tmp/chrome-devtools-mcp.log
```

### Debug Configuration in .mcp.json

```json
{
  "mcpServers": {
    "chrome-devtools": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "chrome-devtools-mcp@latest",
        "--log-file",
        "/tmp/chrome-devtools-mcp.log"
      ],
      "env": {
        "DEBUG": "*"
      }
    }
  }
}
```

### View Logs

```bash
# Follow log file in real-time
tail -f /tmp/chrome-devtools-mcp.log

# View last 50 lines
tail -50 /tmp/chrome-devtools-mcp.log
```

## Specific Problems

### Error: `Cannot find module ...` (ERR_MODULE_NOT_FOUND)

**Cause:** Non-supported Node version or corrupted npm/npx cache.

**Solution:**
```bash
# Clear npx cache (NOTE: may remove other npx executables)
rm -rf ~/.npm/_npx

# Clear npm cache
npm cache clean --force

# Reinstall
npx chrome-devtools-mcp@latest --help
```

### Error: "Target closed"

**Cause:** Browser could not be started or closed unexpectedly.

**Solutions:**
1. Close all existing Chrome instances:
   ```bash
   # Linux/WSL2
   pkill -f chrome

   # Windows
   taskkill /F /IM chrome.exe
   ```

2. Ensure latest stable Chrome is installed

3. Check system meets Chrome requirements: https://support.google.com/chrome/a/answer/7100626

4. Restart Chrome with debugging:
   ```bash
   google-chrome --headless --remote-debugging-port=9222 --no-first-run --user-data-dir=/tmp/chrome-mcp &
   ```

### Error: Connection Refused

**Cause:** Chrome not running with remote debugging enabled.

**Solutions:**
1. Verify Chrome is running with debugging:
   ```bash
   curl -s http://127.0.0.1:9222/json/version
   ```

2. Check if port 9222 is in use:
   ```bash
   # Linux/WSL2
   ss -tuln | grep 9222
   lsof -i :9222

   # Windows (PowerShell)
   netstat -ano | findstr 9222
   ```

3. Kill process using the port and restart Chrome:
   ```bash
   fuser -k 9222/tcp
   ```

### Error: Port Already in Use

**Cause:** Another process (often previous Chrome instance) is using port 9222.

**Solution:**
```bash
# Find and kill process on port
fuser -k 9222/tcp

# Or use different port
google-chrome --remote-debugging-port=9223 ...

# Update MCP config to match
claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --browserUrl http://127.0.0.1:9223
```

### WSL2: Remote Debugging Between VM and Host

**Cause:** Host header validation blocks connections from VM to host Chrome.

**Solution:** Tunnel the port over SSH:

```bash
# In WSL2, run:
ssh -N -L 127.0.0.1:9222:127.0.0.1:9222 <user>@<host-ip>

# Then configure MCP to connect to localhost
claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --browserUrl http://127.0.0.1:9222
```

### Chrome Won't Start in Headless Mode

**Cause:** Missing dependencies or sandbox issues.

**Solutions:**

1. Install missing dependencies (Linux):
   ```bash
   sudo apt install -y \
     libnss3 \
     libnspr4 \
     libatk1.0-0 \
     libatk-bridge2.0-0 \
     libcups2 \
     libdrm2 \
     libxkbcommon0 \
     libxcomposite1 \
     libxdamage1 \
     libxfixes3 \
     libxrandr2 \
     libgbm1 \
     libasound2
   ```

2. Try with sandbox disabled (testing only):
   ```bash
   google-chrome --headless --no-sandbox --remote-debugging-port=9222 ...
   ```

### MCP Server Not Responding

**Diagnostic steps:**

1. Check if server is running:
   ```bash
   pgrep -f chrome-devtools-mcp
   ```

2. Check Claude MCP status:
   ```bash
   claude mcp list
   ```

3. Remove and re-add MCP server:
   ```bash
   claude mcp remove chrome-devtools
   claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --browserUrl http://127.0.0.1:9222
   ```

4. Restart Claude Code session

## Verification Commands

### Check Chrome is Listening

```bash
curl -s http://127.0.0.1:9222/json/version
```

Expected output:
```json
{
   "Browser": "Chrome/xxx.x.xxxx.xx",
   "Protocol-Version": "1.3",
   ...
}
```

### List Available Pages

```bash
curl -s http://127.0.0.1:9222/json/list
```

### Check MCP Configuration

```bash
claude mcp list
cat ~/.mcp.json
```

## Quick Recovery Script

If everything is broken, run this to reset:

```bash
#!/bin/bash
# Reset Chrome DevTools MCP setup

# Kill all Chrome
pkill -9 -f chrome || true

# Clear temp data
rm -rf /tmp/chrome-mcp

# Clear npx cache
rm -rf ~/.npm/_npx

# Remove MCP config
claude mcp remove chrome-devtools 2>/dev/null || true

# Wait
sleep 2

# Start fresh Chrome
google-chrome --headless --remote-debugging-port=9222 --no-first-run --user-data-dir=/tmp/chrome-mcp &

# Wait for startup
sleep 3

# Re-add MCP
claude mcp add chrome-devtools -- npx chrome-devtools-mcp@latest --browserUrl http://127.0.0.1:9222

echo "Done. Restart Claude Code session."
```

## Resources

- **GitHub Repository:** https://github.com/ChromeDevTools/chrome-devtools-mcp
- **Chrome DevTools Protocol:** https://chromedevtools.github.io/devtools-protocol/
- **Chrome System Requirements:** https://support.google.com/chrome/a/answer/7100626

```

### scripts/detect_environment.sh

```bash
#!/bin/bash
# Detect the current operating environment: windows, linux, or wsl2

detect_environment() {
    # Check for WSL2 first (most specific)
    if grep -qiE "(microsoft|wsl)" /proc/version 2>/dev/null; then
        echo "wsl2"
        return 0
    fi

    # Check for Windows (Git Bash, MSYS, Cygwin)
    if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]] || [[ -n "$WINDIR" ]]; then
        echo "windows"
        return 0
    fi

    # Check uname for additional Windows detection
    case "$(uname -s)" in
        MINGW*|MSYS*|CYGWIN*)
            echo "windows"
            return 0
            ;;
        Linux)
            # Defensive fallback: re-check WSL in case the initial /proc/version check
            # at the top was skipped (e.g. uname returned Linux before /proc was mounted)
            if [[ -f /proc/version ]] && grep -qiE "(microsoft|wsl)" /proc/version; then
                echo "wsl2"
            else
                echo "linux"
            fi
            return 0
            ;;
        Darwin)
            echo "macos"
            return 0
            ;;
        *)
            echo "unknown"
            return 1
            ;;
    esac
}

# Run detection
detect_environment

```

### scripts/check_chrome.sh

```bash
#!/bin/bash
# Check if Chrome is installed for the given environment
# Usage: check_chrome.sh <environment>
# Returns: 0 if installed, 1 if not installed

ENVIRONMENT="${1:-linux}"

check_chrome_linux() {
    # Check common Chrome binary names
    if command -v google-chrome &>/dev/null; then
        echo "status:installed"
        echo "path:$(which google-chrome)"
        echo "version:$(google-chrome --version 2>/dev/null)"
        return 0
    elif command -v google-chrome-stable &>/dev/null; then
        echo "status:installed"
        echo "path:$(which google-chrome-stable)"
        echo "version:$(google-chrome-stable --version 2>/dev/null)"
        return 0
    elif command -v chromium-browser &>/dev/null; then
        echo "status:installed"
        echo "path:$(which chromium-browser)"
        echo "version:$(chromium-browser --version 2>/dev/null)"
        return 0
    elif command -v chromium &>/dev/null; then
        echo "status:installed"
        echo "path:$(which chromium)"
        echo "version:$(chromium --version 2>/dev/null)"
        return 0
    fi

    echo "status:not_installed"
    echo ""
    echo "============================================"
    echo "  CHROME NOT FOUND - Installation Required"
    echo "============================================"
    echo ""
    echo "Option 1: Download and install directly (recommended)"
    echo "  wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
    echo "  sudo apt install -y ./google-chrome-stable_current_amd64.deb"
    echo ""
    echo "Option 2: Add Google's repository first"
    echo "  # Add Google's signing key"
    echo "  wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/google-chrome.gpg"
    echo ""
    echo "  # Add the repository"
    echo "  echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list"
    echo ""
    echo "  # Install Chrome"
    echo "  sudo apt update"
    echo "  sudo apt install -y google-chrome-stable"
    echo ""
    echo "Option 3: Install Chromium (open-source alternative)"
    echo "  sudo apt update"
    echo "  sudo apt install -y chromium-browser"
    echo ""
    echo "After installation, run this check again to verify."
    return 1
}

check_chrome_windows() {
    # Check common Windows Chrome paths (from WSL2)
    CHROME_PATHS=(
        "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
        "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    )

    for path in "${CHROME_PATHS[@]}"; do
        if [[ -f "$path" ]]; then
            echo "status:installed"
            echo "path:$path"
            # Try to get version
            "$path" --version 2>/dev/null || true
            return 0
        fi
    done

    # Check Windows environment variables if running natively
    if [[ -n "$LOCALAPPDATA" ]]; then
        local win_path="$LOCALAPPDATA/Google/Chrome/Application/chrome.exe"
        if [[ -f "$win_path" ]]; then
            echo "status:installed"
            echo "path:$win_path"
            return 0
        fi
    fi

    # Try which/where for PATH-based detection
    if command -v chrome.exe &>/dev/null; then
        echo "status:installed"
        echo "path:$(which chrome.exe)"
        return 0
    fi

    echo "status:not_installed"
    echo ""
    echo "============================================"
    echo "  CHROME NOT FOUND - Installation Required"
    echo "============================================"
    echo ""
    echo "Option 1: Download from Google (recommended)"
    echo "  Visit: https://www.google.com/chrome/"
    echo "  Download and run the installer"
    echo ""
    echo "Option 2: Using winget (Windows Package Manager)"
    echo "  winget install Google.Chrome"
    echo ""
    echo "Option 3: Using Chocolatey"
    echo "  choco install googlechrome"
    echo ""
    echo "Option 4: Using PowerShell (direct download)"
    echo '  $installer = "$env:TEMP\chrome_installer.exe"'
    echo '  Invoke-WebRequest -Uri "https://dl.google.com/chrome/install/latest/chrome_installer.exe" -OutFile $installer'
    echo '  Start-Process -FilePath $installer -Args "/silent /install" -Wait'
    echo '  Remove-Item $installer'
    echo ""
    echo "After installation, run this check again to verify."
    return 1
}

# Main execution
echo "Checking Chrome installation for environment: $ENVIRONMENT"
echo ""

case "$ENVIRONMENT" in
    linux|wsl2)
        check_chrome_linux
        ;;
    windows)
        check_chrome_windows
        ;;
    *)
        echo "Unknown environment: $ENVIRONMENT"
        echo "Supported: linux, wsl2, windows"
        exit 1
        ;;
esac

```

### scripts/detect_dev_server.sh

```bash
#!/bin/bash
# Detect running development servers on common ports
# Returns the first available dev server URL or "none"

COMMON_PORTS=(5173 5174 5175 3000 3001 8080 8000 4200 4000)

check_port() {
    local port=$1

    # Try curl first (most reliable)
    if curl -s --max-time 1 "http://localhost:$port" &>/dev/null; then
        return 0
    fi

    # Fallback to checking if something is listening
    if command -v ss &>/dev/null; then
        if ss -tuln | grep -q ":$port "; then
            return 0
        fi
    elif command -v netstat &>/dev/null; then
        if netstat -tuln | grep -q ":$port "; then
            return 0
        fi
    elif command -v lsof &>/dev/null; then
        if lsof -i :$port &>/dev/null; then
            return 0
        fi
    fi

    return 1
}

get_process_on_port() {
    local port=$1

    if command -v lsof &>/dev/null; then
        lsof -i :$port -sTCP:LISTEN 2>/dev/null | tail -1 | awk '{print $1}'
    elif command -v ss &>/dev/null; then
        ss -tulnp | grep ":$port " | grep -oP 'users:\(\("\K[^"]+' 2>/dev/null
    fi
}

echo "Checking for running dev servers..."
echo ""

FOUND_SERVERS=()

for port in "${COMMON_PORTS[@]}"; do
    if check_port $port; then
        process=$(get_process_on_port $port)
        FOUND_SERVERS+=("$port")
        echo "  [FOUND] http://localhost:$port (process: ${process:-unknown})"
    fi
done

echo ""

if [[ ${#FOUND_SERVERS[@]} -eq 0 ]]; then
    echo "result:none"
    echo ""
    echo "No dev servers detected. To start one:"
    echo "  Vite:    npm run dev"
    echo "  Next.js: npm run dev"
    echo "  CRA:     npm start"
else
    # Return the first found server (usually the most common dev port)
    echo "result:http://localhost:${FOUND_SERVERS[0]}"
fi

```

### scripts/launch_chrome.sh

```bash
#!/bin/bash
# Launch Chrome with remote debugging enabled
# Usage: launch_chrome.sh <environment> <url> [headed]
# Arguments:
#   environment: linux, wsl2, or windows
#   url: Target URL (e.g., http://localhost:5173)
#   headed: Optional - pass "headed" for visible browser, omit for headless

ENVIRONMENT="${1:-linux}"
URL="${2:-http://localhost:5173}"
MODE="${3:-headless}"

DEBUG_PORT=9222
USER_DATA_DIR="/tmp/chrome-mcp"

# Determine headless flag
if [[ "$MODE" == "headed" ]]; then
    HEADLESS_FLAG=""
else
    HEADLESS_FLAG="--headless"
fi

# Kill any existing Chrome debug sessions
kill_existing_chrome() {
    echo "Checking for existing Chrome debug sessions on port $DEBUG_PORT..."

    # Check if port is in use
    if lsof -i :$DEBUG_PORT &>/dev/null || ss -tuln | grep -q ":$DEBUG_PORT "; then
        echo "Port $DEBUG_PORT is in use. Attempting to free it..."

        # Try to kill Chrome processes using that port
        if command -v fuser &>/dev/null; then
            fuser -k $DEBUG_PORT/tcp 2>/dev/null || true
        fi

        sleep 1
    fi
}

launch_linux() {
    local chrome_bin=""

    # Find Chrome binary
    if command -v google-chrome &>/dev/null; then
        chrome_bin="google-chrome"
    elif command -v google-chrome-stable &>/dev/null; then
        chrome_bin="google-chrome-stable"
    elif command -v chromium-browser &>/dev/null; then
        chrome_bin="chromium-browser"
    elif command -v chromium &>/dev/null; then
        chrome_bin="chromium"
    else
        echo "ERROR: Chrome not found. Install with:"
        echo "  wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
        echo "  sudo apt install -y ./google-chrome-stable_current_amd64.deb"
        exit 1
    fi

    kill_existing_chrome

    echo "Launching Chrome ($chrome_bin) in ${MODE} mode..."
    echo "  URL: $URL"
    echo "  Debug port: $DEBUG_PORT"
    echo "  User data dir: $USER_DATA_DIR"

    # Launch Chrome
    $chrome_bin $HEADLESS_FLAG \
        --remote-debugging-port=$DEBUG_PORT \
        --no-first-run \
        --disable-background-timer-throttling \
        --disable-backgrounding-occluded-windows \
        --disable-renderer-backgrounding \
        --user-data-dir="$USER_DATA_DIR" \
        "$URL" &

    CHROME_PID=$!
    echo ""
    echo "Chrome launched with PID: $CHROME_PID"

    # Wait a moment and verify
    sleep 2
    if curl -s "http://127.0.0.1:$DEBUG_PORT/json/version" &>/dev/null; then
        echo "Chrome DevTools available at: http://127.0.0.1:$DEBUG_PORT"
        curl -s "http://127.0.0.1:$DEBUG_PORT/json/version" | head -5
    else
        echo "WARNING: Chrome may not be ready yet. Check with:"
        echo "  curl -s http://127.0.0.1:$DEBUG_PORT/json/version"
    fi
}

launch_windows() {
    # Find Chrome executable
    local chrome_exe=""

    CHROME_PATHS=(
        "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
        "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    )

    for path in "${CHROME_PATHS[@]}"; do
        if [[ -f "$path" ]]; then
            chrome_exe="$path"
            break
        fi
    done

    if [[ -z "$chrome_exe" ]]; then
        echo "ERROR: Chrome not found at standard Windows paths"
        exit 1
    fi

    echo "Launching Chrome ($chrome_exe) in ${MODE} mode..."
    echo "  URL: $URL"
    echo "  Debug port: $DEBUG_PORT"

    # Use Windows temp directory
    WIN_USER_DATA_DIR="%TEMP%\\chrome-mcp"

    # Launch via cmd.exe for proper Windows execution
    cmd.exe /c start "" "$chrome_exe" $HEADLESS_FLAG \
        --remote-debugging-port=$DEBUG_PORT \
        --no-first-run \
        --user-data-dir="$WIN_USER_DATA_DIR" \
        "$URL"

    echo ""
    echo "Chrome launched. DevTools should be available at: http://127.0.0.1:$DEBUG_PORT"
}

case "$ENVIRONMENT" in
    linux|wsl2)
        launch_linux
        ;;
    windows)
        launch_windows
        ;;
    *)
        echo "Unknown environment: $ENVIRONMENT"
        echo "Supported: linux, wsl2, windows"
        exit 1
        ;;
esac

```

devtools | SkillHub