Skill: qinthqod/fox-chrome-devtools-mcp (version 1.0.0)

--- name: fox-chrome-devtools-mcp description: "Chrome DevTools MCP — Google's official browser automation and testing server. Control Chrome via Puppeteer through MCP protocol: click, fill forms, navigate, screenshot, performance traces, network inspection, console debugging. Use for browser testing, web automation, performance analysis, UI testing, form filling, and visual regression." homepage: https://github.com/ChromeDevTools/chrome-devtools-mcp license: Apache-2.0 compatibility: Node.js v20.19+, Chrome/Chromium metadata: {"openclaw": {"emoji": "🌐", "requires": {"env": []}, "homepage": "https://github.com/ChromeDevTools/chrome-devtools-mcp"}} --- # 🌐 Chrome DevTools MCP Google's official Chrome DevTools MCP server — gives AI agents full control of a live Chrome browser via Puppeteer and the Chrome DevTools Protocol. ## Features - **Input automation** — click, drag, fill forms, hover, press keys, upload files, handle dialogs - **Navigation** — open/close/switch pages, wait for elements/network idle - **Screenshots & snapshots** — capture page state visually and as DOM - **Performance traces** — record and analyze Chrome performance traces with insights - **Network inspection** — list/inspect network requests and responses - **Console debugging** — read console messages with source-mapped stack traces - **Device emulation** — emulate mobile devices, resize viewport - **Form automation** — fill multiple form fields at once ## Requirements - Node.js v20.19+ (already available in OpenClaw) - Chrome/Chromium browser ## Quick Start ### Install & verify ```bash npx -y chrome-devtools-mcp@latest --help ``` ### Start the MCP server ```bash # Standard (launches Chrome automatically) npx -y chrome-devtools-mcp@latest # Headless mode (for servers) npx -y chrome-devtools-mcp@latest --headless # Connect to existing Chrome (must be started with --remote-debugging-port=9222) npx -y chrome-devtools-mcp@latest --browser-url=http://127.0.0.1:9222 # Disable telemetry npx -y chrome-devtools-mcp@latest --no-usage-statistics --no-performance-crux ``` ### OpenClaw MCP Integration Add to your `openclaw.json` under MCP servers: ```json { "mcp": { "servers": { "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp@latest", "--headless", "--no-usage-statistics"] } } } } ``` Or use the setup script: ```bash python3 {baseDir}/scripts/setup_chrome_mcp.py setup python3 {baseDir}/scripts/setup_chrome_mcp.py status python3 {baseDir}/scripts/setup_chrome_mcp.py test ``` ## Tool Reference ### Input Automation (8 tools) | Tool | Description | Key Params | |------|-------------|------------| | `click` | Click an element | `uid` (required), `dblClick` | | `drag` | Drag element onto another | `from_uid`, `to_uid` | | `fill` | Type text into input/textarea/select | `uid`, `value` | | `fill_form` | Fill multiple form elements at once | `elements[]` | | `handle_dialog` | Accept/dismiss browser dialogs | `action` (accept/dismiss) | | `hover` | Hover over element | `uid` | | `press_key` | Press keyboard key | `key` | | `upload_file` | Upload file to input | `uid`, `paths[]` | ### Navigation (6 tools) | Tool | Description | Key Params | |------|-------------|------------| | `navigate_page` | Go to URL | `url` | | `new_page` | Open new tab | `url` | | `close_page` | Close current tab | — | | `list_pages` | List all open tabs | — | | `select_page` | Switch to tab | `index` | | `wait_for` | Wait for element/network | `event`, `uid`, `timeout` | ### Debugging (5 tools) | Tool | Description | |------|-------------| | `take_screenshot` | Capture page as image | | `take_snapshot` | Get DOM/accessibility snapshot | | `evaluate_script` | Run JavaScript in page | | `list_console_messages` | Get console log entries | | `get_console_message` | Get specific console message | ### Performance (3 tools) | Tool | Description | |------|-------------| | `performance_start_trace` | Begin performance recording | | `performance_stop_trace` | Stop and get trace data | | `performance_analyze_insight` | AI analysis of trace | ### Network (2 tools) | Tool | Description | |------|-------------| | `list_network_requests` | List all network requests | | `get_network_request` | Get request/response details | ### Emulation (2 tools) | Tool | Description | |------|-------------| | `emulate` | Emulate device (mobile, tablet) | | `resize_page` | Change viewport size | ## Common Workflows ### Test a webpage 1. `navigate_page` → URL 2. `take_snapshot` → get element UIDs 3. `click`/`fill` → interact with elements 4. `take_screenshot` → capture result ### Performance audit 1. `navigate_page` → URL 2. `performance_start_trace` 3. Interact with page 4. `performance_stop_trace` 5. `performance_analyze_insight` ### Form testing 1. `navigate_page` → form URL 2. `take_snapshot` → identify form fields 3. `fill_form` → fill all fields at once 4. `click` → submit button 5. `take_screenshot` → verify result ## Privacy Notes - Google collects usage statistics by default — disable with `--no-usage-statistics` - Performance tools may send trace URLs to Google CrUX API — disable with `--no-performance-crux` - Avoid sharing sensitive data in browser sessions

path: _meta.json
content: ownerId: kn78vyxbj9m9gk197mbwc6a6bh816qev
slug: chrome-devtools-mcp
version: 1.0.0
publishedAt: 1771639489991

path: scripts/setup_chrome_mcp.py
content: #!/usr/bin/env python3
"""Chrome DevTools MCP — Setup, status check, and test script.

Usage:
    setup_chrome_mcp.py setup    # Install and configure
    setup_chrome_mcp.py status   # Check if working
    setup_chrome_mcp.py test     # Run a quick browser test
"""

import json, os, subprocess, sys


def run(cmd, capture=True, timeout=30):
    try:
        r = subprocess.run(cmd, shell=True, capture_output=capture, text=True, timeout=timeout)
        return r.returncode, r.stdout.strip() if capture else "", r.stderr.strip() if capture else ""
    except subprocess.TimeoutExpired:
        return 1, "", "timeout"
    except Exception as e:
        return 1, "", str(e)


def setup():
    """Install chrome-devtools-mcp and configure for OpenClaw."""
    print("🌐 Setting up Chrome DevTools MCP...")

    # Check Node.js
    code, out, _ = run("node --version")
    if code != 0:
        print("❌ Node.js not found. Required v20.19+")
        return False
    print(f"✅ Node.js: {out}")

    # Check npx
    code, out, _ = run("npx --version")
    if code != 0:
        print("❌ npx not found")
        return False
    print(f"✅ npx: {out}")

    # Pre-cache the package
    print("📦 Installing chrome-devtools-mcp...")
    code, out, err = run("npx -y chrome-devtools-mcp@latest --help", timeout=60)
    if code == 0:
        print("✅ chrome-devtools-mcp installed")
    else:
        # --help may not be supported, check if binary exists
        code2, out2, _ = run("npm list -g chrome-devtools-mcp 2>/dev/null || echo 'not global'")
        print(f"⚠️  Package cached (--help may not be supported): {err[:100]}")

    # Check for Chrome/Chromium
    chrome_paths = [
        "/usr/bin/google-chrome",
        "/usr/bin/chromium",
        "/usr/bin/chromium-browser",
        os.path.expanduser("~/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome"),
    ]
    chrome_found = None
    for p in chrome_paths:
        if os.path.exists(p):
            chrome_found = p
            break

    if chrome_found:
        print(f"✅ Chrome found: {chrome_found}")
    else:
        print("⚠️  No Chrome/Chromium found. MCP server will try to download one.")

    print("\n📋 MCP Configuration for openclaw.json:")
    config = {
        "mcp": {
            "servers": {
                "chrome-devtools": {
                    "command": "npx",
                    "args": ["-y", "chrome-devtools-mcp@latest", "--headless", "--no-usage-statistics"]
                }
            }
        }
    }
    print(json.dumps(config, indent=2))

    print("\n✅ Setup complete. Add the config above to openclaw.json to enable.")
    return True


def status():
    """Check if chrome-devtools-mcp is available."""
    print("🔍 Chrome DevTools MCP Status\n")

    # Node
    code, out, _ = run("node --version")
    print(f"{'✅' if code == 0 else '❌'} Node.js: {out if code == 0 else 'not found'}")

    # npx
    code, out, _ = run("npx --version")
    print(f"{'✅' if code == 0 else '❌'} npx: {out if code == 0 else 'not found'}")

    # Chrome
    chrome_paths = [
        "/usr/bin/google-chrome",
        "/usr/bin/chromium",
        "/usr/bin/chromium-browser",
        os.path.expanduser("~/.cache/ms-playwright/chromium-1208/chrome-linux64/chrome"),
    ]
    chrome_found = None
    for p in chrome_paths:
        if os.path.exists(p):
            chrome_found = p
            break
    print(f"{'✅' if chrome_found else '⚠️ '} Chrome: {chrome_found or 'not found locally'}")

    # Check if MCP config exists in openclaw.json
    config_path = os.path.expanduser("~/.openclaw/openclaw.json")
    if os.path.exists(config_path):
        with open(config_path) as f:
            config = json.load(f)
        mcp_servers = config.get("mcp", {}).get("servers", {})
        if "chrome-devtools" in mcp_servers:
            print("✅ MCP server configured in openclaw.json")
        else:
            print("⚠️  MCP server NOT configured in openclaw.json — run setup")
    else:
        print("⚠️  openclaw.json not found")


def test():
    """Quick test — start MCP server and verify it responds."""
    print("🧪 Testing Chrome DevTools MCP...\n")

    # Try starting with --headless
    print("Starting MCP server (headless)...")
    proc = subprocess.Popen(
        ["npx", "-y", "chrome-devtools-mcp@latest", "--headless", "--no-usage-statistics"],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
    )

    import time
    time.sleep(5)

    if proc.poll() is not None:
        _, err = proc.communicate()
        print(f"❌ Server exited immediately: {err[:200]}")
        return False

    print("✅ MCP server started successfully (headless mode)")
    print("   Server is running and accepting MCP connections")

    proc.terminate()
    try:
        proc.wait(timeout=5)
    except:
        proc.kill()

    print("✅ Server shut down cleanly")
    return True


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: setup_chrome_mcp.py [setup|status|test]")
        sys.exit(1)

    cmd = sys.argv[1]
    if cmd == "setup":
        setup()
    elif cmd == "status":
        status()
    elif cmd == "test":
        test()
    else:
        print(f"Unknown command: {cmd}")
        sys.exit(1)


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)