From e6fb13531ede15bcabf585347ed7e2c037276a0d Mon Sep 17 00:00:00 2001 From: Marc Andreu Date: Fri, 21 Nov 2025 11:03:33 +0900 Subject: [PATCH 1/3] feat: add default screenshot format configuration and update related functionality --- README.md | 36 ++++++++++++++++++++++++++++++++++++ src/McpContext.ts | 6 ++++++ src/cli.ts | 11 +++++++++++ src/main.ts | 1 + src/tools/ToolDefinition.ts | 4 ++++ src/tools/screenshot.ts | 13 ++++++++----- tests/cli.test.ts | 2 ++ 7 files changed, 68 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 07f598be..662cd60a 100644 --- a/README.md +++ b/README.md @@ -383,6 +383,12 @@ The Chrome DevTools MCP server supports the following configuration option: - **Type:** boolean - **Default:** `true` +- **`--screenshot-format`** + Default image format for screenshots. Options: png, jpeg, webp. Default is png. + - **Type:** string + - **Choices:** `png`, `jpeg`, `webp` + - **Default:** `png` + Pass them via the `args` property in the JSON configuration. For example: @@ -424,6 +430,36 @@ You can connect directly to a Chrome WebSocket endpoint and include custom heade To get the WebSocket endpoint from a running Chrome instance, visit `http://127.0.0.1:9222/json/version` and look for the `webSocketDebuggerUrl` field. +### Configuring default screenshot format + +You can set a default image format for all screenshots using the `--screenshot-format` option. The default is PNG. You can change it to JPEG or WebP if needed: + +```json +{ + "mcpServers": { + "chrome-devtools": { + "command": "npx", + "args": [ + "chrome-devtools-mcp@latest", + "--screenshot-format=jpeg" + ] + } + } +} +``` + +When configured, the `take_screenshot` tool will use this format by default unless explicitly overridden by passing a `format` parameter. Supported formats are `png`, `jpeg`, and `webp`. + +> [!TIP] +> PNG is the default format as it provides lossless screenshots. JPEG typically produces smaller file sizes than PNG, which improves performance when working with screenshots. WebP offers the best compression while maintaining quality. + +> [!NOTE] +> **Claude Code users**: If you experience issues with screenshots not displaying correctly, you can work around this by: +> 1. Setting the default format to JPEG in your configuration (recommended): Add `--screenshot-format=jpeg` to your MCP server args +> 2. Explicitly passing `jpeg` as the format parameter in all `take_screenshot()` calls: `take_screenshot(format="jpeg")` +> +> This workaround is needed until the issue is resolved on Claude Code's side. + You can also run `npx chrome-devtools-mcp@latest --help` to see all available configuration options. ## Concepts diff --git a/src/McpContext.ts b/src/McpContext.ts index 1c3c988d..bfa56d1f 100644 --- a/src/McpContext.ts +++ b/src/McpContext.ts @@ -49,6 +49,8 @@ interface McpContextOptions { experimentalDevToolsDebugging: boolean; // Whether all page-like targets are exposed as pages. experimentalIncludeAllPages?: boolean; + // Default screenshot format. + screenshotFormat?: 'png' | 'jpeg' | 'webp'; } const DEFAULT_TIMEOUT = 5_000; @@ -292,6 +294,10 @@ export class McpContext implements Context { this.#dialog = undefined; } + getDefaultScreenshotFormat(): 'png' | 'jpeg' | 'webp' { + return this.#options.screenshotFormat ?? 'png'; + } + getSelectedPage(): Page { const page = this.#selectedPage; if (!page) { diff --git a/src/cli.ts b/src/cli.ts index 5ce8673e..d08f5f71 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -160,6 +160,13 @@ export const cliOptions = { default: true, describe: 'Set to false to exclude tools related to network.', }, + screenshotFormat: { + type: 'string', + describe: + 'Default image format for screenshots. Options: png, jpeg, webp. Default is png.', + choices: ['png', 'jpeg', 'webp'] as const, + default: 'png', + }, } satisfies Record; export function parseArguments(version: string, argv = process.argv) { @@ -212,6 +219,10 @@ export function parseArguments(version: string, argv = process.argv) { 'Disable tools in the performance category', ], ['$0 --no-category-network', 'Disable tools in the network category'], + [ + '$0 --screenshot-format jpeg', + 'Set default screenshot format to JPEG (overrides PNG default)', + ], ]); return yargsInstance diff --git a/src/main.ts b/src/main.ts index 153b6f5d..77662726 100644 --- a/src/main.ts +++ b/src/main.ts @@ -86,6 +86,7 @@ async function getContext(): Promise { context = await McpContext.from(browser, logger, { experimentalDevToolsDebugging: devtools, experimentalIncludeAllPages: args.experimentalIncludeAllPages, + screenshotFormat: args.screenshotFormat as 'png' | 'jpeg' | 'webp', }); } return context; diff --git a/src/tools/ToolDefinition.ts b/src/tools/ToolDefinition.ts index 8acebb56..ad44a3ad 100644 --- a/src/tools/ToolDefinition.ts +++ b/src/tools/ToolDefinition.ts @@ -120,6 +120,10 @@ export type Context = Readonly<{ * Returns a reqid for a cdpRequestId. */ resolveCdpElementId(cdpBackendNodeId: number): string | undefined; + /** + * Returns the configured default screenshot format. + */ + getDefaultScreenshotFormat(): 'png' | 'jpeg' | 'webp'; }>; export function defineTool( diff --git a/src/tools/screenshot.ts b/src/tools/screenshot.ts index d8d3dfcf..3eb0ead7 100644 --- a/src/tools/screenshot.ts +++ b/src/tools/screenshot.ts @@ -21,8 +21,8 @@ export const screenshot = defineTool({ schema: { format: zod .enum(['png', 'jpeg', 'webp']) - .default('png') - .describe('Type of format to save the screenshot as. Default is "png"'), + .optional() + .describe('Type of format to save the screenshot as. If not specified, uses the configured default format.'), quality: zod .number() .min(0) @@ -62,8 +62,11 @@ export const screenshot = defineTool({ pageOrHandle = context.getSelectedPage(); } + // Use configured default format if not specified in request + const format = request.params.format ?? context.getDefaultScreenshotFormat(); + const screenshot = await pageOrHandle.screenshot({ - type: request.params.format, + type: format, fullPage: request.params.fullPage, quality: request.params.quality, optimizeForSpeed: true, // Bonus: optimize encoding for speed @@ -89,12 +92,12 @@ export const screenshot = defineTool({ } else if (screenshot.length >= 2_000_000) { const {filename} = await context.saveTemporaryFile( screenshot, - `image/${request.params.format}`, + `image/${format}`, ); response.appendResponseLine(`Saved screenshot to ${filename}.`); } else { response.attachImage({ - mimeType: `image/${request.params.format}`, + mimeType: `image/${format}`, data: Buffer.from(screenshot).toString('base64'), }); } diff --git a/tests/cli.test.ts b/tests/cli.test.ts index 19502e28..01837eff 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -16,6 +16,8 @@ describe('cli args parsing', () => { categoryPerformance: true, 'category-network': true, categoryNetwork: true, + 'screenshot-format': 'png', + screenshotFormat: 'png', }; it('parses with default args', async () => { From b5e211f73a7386f7ab9058b413d2e904c466ef12 Mon Sep 17 00:00:00 2001 From: Marc Andreu Date: Sun, 23 Nov 2025 16:49:28 +0900 Subject: [PATCH 2/3] fix: update screenshot format configuration and troubleshooting notes for Claude Code --- README.md | 32 +------------------------------- docs/troubleshooting.md | 9 +++++++++ src/cli.ts | 2 +- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 662cd60a..afd7cdd8 100644 --- a/README.md +++ b/README.md @@ -430,37 +430,7 @@ You can connect directly to a Chrome WebSocket endpoint and include custom heade To get the WebSocket endpoint from a running Chrome instance, visit `http://127.0.0.1:9222/json/version` and look for the `webSocketDebuggerUrl` field. -### Configuring default screenshot format - -You can set a default image format for all screenshots using the `--screenshot-format` option. The default is PNG. You can change it to JPEG or WebP if needed: - -```json -{ - "mcpServers": { - "chrome-devtools": { - "command": "npx", - "args": [ - "chrome-devtools-mcp@latest", - "--screenshot-format=jpeg" - ] - } - } -} -``` - -When configured, the `take_screenshot` tool will use this format by default unless explicitly overridden by passing a `format` parameter. Supported formats are `png`, `jpeg`, and `webp`. - -> [!TIP] -> PNG is the default format as it provides lossless screenshots. JPEG typically produces smaller file sizes than PNG, which improves performance when working with screenshots. WebP offers the best compression while maintaining quality. - -> [!NOTE] -> **Claude Code users**: If you experience issues with screenshots not displaying correctly, you can work around this by: -> 1. Setting the default format to JPEG in your configuration (recommended): Add `--screenshot-format=jpeg` to your MCP server args -> 2. Explicitly passing `jpeg` as the format parameter in all `take_screenshot()` calls: `take_screenshot(format="jpeg")` -> -> This workaround is needed until the issue is resolved on Claude Code's side. - -You can also run `npx chrome-devtools-mcp@latest --help` to see all available configuration options. +You can run `npx chrome-devtools-mcp@latest --help` to see all available configuration options. ## Concepts diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 7fc62eac..d03509e9 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -38,3 +38,12 @@ ssh -N -L 127.0.0.1:9222:127.0.0.1:9222 @ Point the MCP connection inside the VM to `http://127.0.0.1:9222` and DevTools will reach the host browser without triggering the Host validation. + +### Screenshots not displaying correctly in Claude Code + +If you experience issues with screenshots not displaying correctly in Claude Code, you can work around this by: + +1. Setting the default format to JPEG in your configuration (recommended): Add `--screenshot-format=jpeg` to your MCP server args +2. Explicitly passing `jpeg` as the format parameter in all `take_screenshot()` calls: `take_screenshot(format="jpeg")` + +This workaround is needed until the issue is resolved on Claude Code's side. diff --git a/src/cli.ts b/src/cli.ts index d08f5f71..4f9543ec 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -163,7 +163,7 @@ export const cliOptions = { screenshotFormat: { type: 'string', describe: - 'Default image format for screenshots. Options: png, jpeg, webp. Default is png.', + 'Default image format for screenshots taken by take_screenshot when no format parameter is provided. Options: png, jpeg, webp. Default is png.', choices: ['png', 'jpeg', 'webp'] as const, default: 'png', }, From 3f65e761721ab1ba1dae10d9962f5991b4b77df9 Mon Sep 17 00:00:00 2001 From: Marc Andreu Date: Mon, 24 Nov 2025 20:53:27 +0900 Subject: [PATCH 3/3] style: format code for better readability in screenshot tool --- src/tools/screenshot.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/tools/screenshot.ts b/src/tools/screenshot.ts index e29b6b56..c1c2247a 100644 --- a/src/tools/screenshot.ts +++ b/src/tools/screenshot.ts @@ -22,7 +22,9 @@ export const screenshot = defineTool({ format: zod .enum(['png', 'jpeg', 'webp']) .optional() - .describe('Type of format to save the screenshot as. If not specified, uses the configured default format.'), + .describe( + 'Type of format to save the screenshot as. If not specified, uses the configured default format.', + ), quality: zod .number() .min(0) @@ -63,12 +65,13 @@ export const screenshot = defineTool({ } // Use configured default format if not specified in request - const format = request.params.format ?? context.getDefaultScreenshotFormat(); + const format = + request.params.format ?? context.getDefaultScreenshotFormat(); const screenshot = await pageOrHandle.screenshot({ type: format, fullPage: request.params.fullPage, - quality, + quality: request.params.quality, optimizeForSpeed: true, // Bonus: optimize encoding for speed });