From 4bfa2457be8ab8411bf4a81692ca2336c489efb3 Mon Sep 17 00:00:00 2001 From: Sundeep Gottipati Date: Tue, 18 Nov 2025 19:28:34 -0800 Subject: [PATCH 1/6] Add Dockerfile for MCP registry support This Dockerfile enables the chrome-devtools-mcp server to be used with Docker-based MCP registries. It: - Uses Node.js 22 LTS with Chrome dependencies - Installs Chrome Stable for Puppeteer - Builds the TypeScript project - Runs as non-root user for security - Exposes the MCP server via stdio --- Dockerfile | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..d3e2c1efc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,60 @@ +# Build stage +FROM node:22-bookworm-slim AS builder + +WORKDIR /app + +# Copy all source files +COPY . . + +# Install all dependencies (including dev dependencies for building) +RUN npm ci + +# Build the TypeScript project +RUN npm run build + +# Runtime stage +FROM node:22-bookworm-slim + +# Install Chromium and dependencies +RUN apt-get update && apt-get install -y \ + chromium \ + fonts-liberation \ + libasound2 \ + libatk-bridge2.0-0 \ + libatk1.0-0 \ + libatspi2.0-0 \ + libcups2 \ + libdbus-1-3 \ + libdrm2 \ + libgbm1 \ + libgtk-3-0 \ + libnspr4 \ + libnss3 \ + libwayland-client0 \ + libxcomposite1 \ + libxdamage1 \ + libxfixes3 \ + libxkbcommon0 \ + libxrandr2 \ + xdg-utils \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +# Copy built files and node_modules from builder stage +COPY --from=builder /app/build ./build +COPY --from=builder /app/node_modules ./node_modules + +# Set environment to tell Puppeteer where Chromium is installed +ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium + +# Run as non-root user for security +RUN groupadd -r mcpuser && useradd -r -g mcpuser -G audio,video mcpuser \ + && mkdir -p /home/mcpuser/Downloads \ + && chown -R mcpuser:mcpuser /home/mcpuser \ + && chown -R mcpuser:mcpuser /app + +USER mcpuser + +# Expose MCP server via stdio +ENTRYPOINT ["node", "build/src/index.js"] From 6203a267f3fce271cc3b076eb66754c1fa16b31a Mon Sep 17 00:00:00 2001 From: Sundeep Gottipati Date: Tue, 18 Nov 2025 20:02:48 -0800 Subject: [PATCH 2/6] Add entrypoint script to support optional BROWSER_URL The entrypoint script checks if BROWSER_URL environment variable is set and only passes --browserUrl flag if it's provided. This allows the MCP registry to support optional browser connection without template issues. Default behavior (no BROWSER_URL): Launches Chrome in headless mode With BROWSER_URL: Connects to existing Chrome instance --- Dockerfile | 8 ++++++-- docker-entrypoint.sh | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index d3e2c1efc..5b45dab63 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,6 +45,10 @@ WORKDIR /app COPY --from=builder /app/build ./build COPY --from=builder /app/node_modules ./node_modules +# Copy entrypoint script +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + # Set environment to tell Puppeteer where Chromium is installed ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium @@ -56,5 +60,5 @@ RUN groupadd -r mcpuser && useradd -r -g mcpuser -G audio,video mcpuser \ USER mcpuser -# Expose MCP server via stdio -ENTRYPOINT ["node", "build/src/index.js"] +# Use entrypoint script that handles optional BROWSER_URL +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 000000000..078a5ea24 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e + +# Build command with optional arguments +CMD="node build/src/index.js" + +# Add browserUrl if BROWSER_URL is set and not empty +if [ -n "$BROWSER_URL" ]; then + CMD="$CMD --browserUrl $BROWSER_URL" +fi + +# Execute the command +exec $CMD "$@" From 5206c902280080b12b56a663c85b913d9e2ac54a Mon Sep 17 00:00:00 2001 From: Sundeep Gottipati Date: Tue, 18 Nov 2025 20:03:51 -0800 Subject: [PATCH 3/6] Add support for all Chrome DevTools configuration options Extended entrypoint script to support all configuration options via environment variables: Connection Options: - BROWSER_URL: Connect to existing Chrome via HTTP - WS_ENDPOINT: Connect via WebSocket - WS_HEADERS: Custom headers for WebSocket (JSON) Browser Launch Options: - HEADLESS: true/false (default: true) - VIEWPORT: WIDTHxHEIGHT (default: 1280x720) - ISOLATED: true/false for temporary profile - CHANNEL: stable/canary/beta/dev - EXECUTABLE_PATH: Custom Chrome path - PROXY_SERVER: Proxy configuration - ACCEPT_INSECURE_CERTS: true/false Feature Toggles: - CATEGORY_EMULATION: true/false (default: true) - CATEGORY_PERFORMANCE: true/false (default: true) - CATEGORY_NETWORK: true/false (default: true) Debugging: - LOG_FILE: Path for debug logs --- docker-entrypoint.sh | 61 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 078a5ea24..2e47bbc27 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -4,10 +4,69 @@ set -e # Build command with optional arguments CMD="node build/src/index.js" -# Add browserUrl if BROWSER_URL is set and not empty +# Connection Options if [ -n "$BROWSER_URL" ]; then CMD="$CMD --browserUrl $BROWSER_URL" fi +if [ -n "$WS_ENDPOINT" ]; then + CMD="$CMD --wsEndpoint $WS_ENDPOINT" +fi + +if [ -n "$WS_HEADERS" ]; then + CMD="$CMD --wsHeaders '$WS_HEADERS'" +fi + +# Browser Launch Options +if [ -n "$HEADLESS" ]; then + if [ "$HEADLESS" = "false" ]; then + CMD="$CMD --no-headless" + else + CMD="$CMD --headless" + fi +fi + +if [ -n "$VIEWPORT" ]; then + CMD="$CMD --viewport $VIEWPORT" +fi + +if [ -n "$ISOLATED" ] && [ "$ISOLATED" = "true" ]; then + CMD="$CMD --isolated" +fi + +if [ -n "$CHANNEL" ]; then + CMD="$CMD --channel $CHANNEL" +fi + +if [ -n "$EXECUTABLE_PATH" ]; then + CMD="$CMD --executablePath $EXECUTABLE_PATH" +fi + +if [ -n "$PROXY_SERVER" ]; then + CMD="$CMD --proxyServer $PROXY_SERVER" +fi + +if [ -n "$ACCEPT_INSECURE_CERTS" ] && [ "$ACCEPT_INSECURE_CERTS" = "true" ]; then + CMD="$CMD --acceptInsecureCerts" +fi + +# Feature Toggles +if [ -n "$CATEGORY_EMULATION" ] && [ "$CATEGORY_EMULATION" = "false" ]; then + CMD="$CMD --no-category-emulation" +fi + +if [ -n "$CATEGORY_PERFORMANCE" ] && [ "$CATEGORY_PERFORMANCE" = "false" ]; then + CMD="$CMD --no-category-performance" +fi + +if [ -n "$CATEGORY_NETWORK" ] && [ "$CATEGORY_NETWORK" = "false" ]; then + CMD="$CMD --no-category-network" +fi + +# Debugging +if [ -n "$LOG_FILE" ]; then + CMD="$CMD --logFile $LOG_FILE" +fi + # Execute the command exec $CMD "$@" From 9fae624c71401125c6548d1e375a2e10d4afea50 Mon Sep 17 00:00:00 2001 From: Sundeep Gottipati Date: Tue, 18 Nov 2025 20:18:42 -0800 Subject: [PATCH 4/6] Remove entrypoint script, use direct node entrypoint Removed the custom entrypoint script since the MCP registry doesn't support conditional command-line argument passing. The server will auto-launch Chrome with default settings (headless, 1280x720). Users who need custom Chrome configurations can build and run the server outside the registry using the standard npx approach with command-line flags. --- Dockerfile | 8 ++--- docker-entrypoint.sh | 72 -------------------------------------------- 2 files changed, 2 insertions(+), 78 deletions(-) delete mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 5b45dab63..d3e2c1efc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,10 +45,6 @@ WORKDIR /app COPY --from=builder /app/build ./build COPY --from=builder /app/node_modules ./node_modules -# Copy entrypoint script -COPY docker-entrypoint.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-entrypoint.sh - # Set environment to tell Puppeteer where Chromium is installed ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium @@ -60,5 +56,5 @@ RUN groupadd -r mcpuser && useradd -r -g mcpuser -G audio,video mcpuser \ USER mcpuser -# Use entrypoint script that handles optional BROWSER_URL -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +# Expose MCP server via stdio +ENTRYPOINT ["node", "build/src/index.js"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100644 index 2e47bbc27..000000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -set -e - -# Build command with optional arguments -CMD="node build/src/index.js" - -# Connection Options -if [ -n "$BROWSER_URL" ]; then - CMD="$CMD --browserUrl $BROWSER_URL" -fi - -if [ -n "$WS_ENDPOINT" ]; then - CMD="$CMD --wsEndpoint $WS_ENDPOINT" -fi - -if [ -n "$WS_HEADERS" ]; then - CMD="$CMD --wsHeaders '$WS_HEADERS'" -fi - -# Browser Launch Options -if [ -n "$HEADLESS" ]; then - if [ "$HEADLESS" = "false" ]; then - CMD="$CMD --no-headless" - else - CMD="$CMD --headless" - fi -fi - -if [ -n "$VIEWPORT" ]; then - CMD="$CMD --viewport $VIEWPORT" -fi - -if [ -n "$ISOLATED" ] && [ "$ISOLATED" = "true" ]; then - CMD="$CMD --isolated" -fi - -if [ -n "$CHANNEL" ]; then - CMD="$CMD --channel $CHANNEL" -fi - -if [ -n "$EXECUTABLE_PATH" ]; then - CMD="$CMD --executablePath $EXECUTABLE_PATH" -fi - -if [ -n "$PROXY_SERVER" ]; then - CMD="$CMD --proxyServer $PROXY_SERVER" -fi - -if [ -n "$ACCEPT_INSECURE_CERTS" ] && [ "$ACCEPT_INSECURE_CERTS" = "true" ]; then - CMD="$CMD --acceptInsecureCerts" -fi - -# Feature Toggles -if [ -n "$CATEGORY_EMULATION" ] && [ "$CATEGORY_EMULATION" = "false" ]; then - CMD="$CMD --no-category-emulation" -fi - -if [ -n "$CATEGORY_PERFORMANCE" ] && [ "$CATEGORY_PERFORMANCE" = "false" ]; then - CMD="$CMD --no-category-performance" -fi - -if [ -n "$CATEGORY_NETWORK" ] && [ "$CATEGORY_NETWORK" = "false" ]; then - CMD="$CMD --no-category-network" -fi - -# Debugging -if [ -n "$LOG_FILE" ]; then - CMD="$CMD --logFile $LOG_FILE" -fi - -# Execute the command -exec $CMD "$@" From d546a5d332c5de8c654e926ee99a9dd758cea46c Mon Sep 17 00:00:00 2001 From: Sundeep Gottipati Date: Tue, 18 Nov 2025 20:19:04 -0800 Subject: [PATCH 5/6] Add entrypoint script for optional connection flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simple entrypoint script that converts environment variables to command-line flags only when set: - BROWSER_URL → --browserUrl - WS_ENDPOINT → --wsEndpoint - WS_HEADERS → --wsHeaders This allows the server.yaml to pass these as env vars without causing build errors when they're empty. --- Dockerfile | 8 ++++++-- docker-entrypoint.sh | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index d3e2c1efc..521589916 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,6 +45,10 @@ WORKDIR /app COPY --from=builder /app/build ./build COPY --from=builder /app/node_modules ./node_modules +# Copy entrypoint script +COPY docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + # Set environment to tell Puppeteer where Chromium is installed ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium @@ -56,5 +60,5 @@ RUN groupadd -r mcpuser && useradd -r -g mcpuser -G audio,video mcpuser \ USER mcpuser -# Expose MCP server via stdio -ENTRYPOINT ["node", "build/src/index.js"] +# Use entrypoint script that handles optional connection flags +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 000000000..93dd1d6b5 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -e + +# Build command with optional connection arguments +CMD="node build/src/index.js" + +# Add browserUrl if BROWSER_URL is set and not empty +if [ -n "$BROWSER_URL" ]; then + CMD="$CMD --browserUrl $BROWSER_URL" +fi + +# Add wsEndpoint if WS_ENDPOINT is set and not empty +if [ -n "$WS_ENDPOINT" ]; then + CMD="$CMD --wsEndpoint $WS_ENDPOINT" +fi + +# Add wsHeaders if WS_HEADERS is set and not empty +if [ -n "$WS_HEADERS" ]; then + CMD="$CMD --wsHeaders '$WS_HEADERS'" +fi + +# Execute the command with any additional arguments +exec $CMD "$@" From 78a3c3df78f711b7dfcf7076e645016296beec71 Mon Sep 17 00:00:00 2001 From: Sundeep Gottipati Date: Tue, 18 Nov 2025 20:23:09 -0800 Subject: [PATCH 6/6] Remove entrypoint script - use direct node entrypoint --- Dockerfile | 8 ++------ docker-entrypoint.sh | 23 ----------------------- 2 files changed, 2 insertions(+), 29 deletions(-) delete mode 100644 docker-entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 521589916..d3e2c1efc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -45,10 +45,6 @@ WORKDIR /app COPY --from=builder /app/build ./build COPY --from=builder /app/node_modules ./node_modules -# Copy entrypoint script -COPY docker-entrypoint.sh /usr/local/bin/ -RUN chmod +x /usr/local/bin/docker-entrypoint.sh - # Set environment to tell Puppeteer where Chromium is installed ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium @@ -60,5 +56,5 @@ RUN groupadd -r mcpuser && useradd -r -g mcpuser -G audio,video mcpuser \ USER mcpuser -# Use entrypoint script that handles optional connection flags -ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +# Expose MCP server via stdio +ENTRYPOINT ["node", "build/src/index.js"] diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100644 index 93dd1d6b5..000000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -set -e - -# Build command with optional connection arguments -CMD="node build/src/index.js" - -# Add browserUrl if BROWSER_URL is set and not empty -if [ -n "$BROWSER_URL" ]; then - CMD="$CMD --browserUrl $BROWSER_URL" -fi - -# Add wsEndpoint if WS_ENDPOINT is set and not empty -if [ -n "$WS_ENDPOINT" ]; then - CMD="$CMD --wsEndpoint $WS_ENDPOINT" -fi - -# Add wsHeaders if WS_HEADERS is set and not empty -if [ -n "$WS_HEADERS" ]; then - CMD="$CMD --wsHeaders '$WS_HEADERS'" -fi - -# Execute the command with any additional arguments -exec $CMD "$@"