Skip to content
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

<!-- END AUTO GENERATED OPTIONS -->

Pass them via the `args` property in the JSON configuration. For example:
Expand Down Expand Up @@ -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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need an explicit example in the readme, let's remove it and rely on the CLI docs and --help examples.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


```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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this into troubleshooting.md

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

> 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
Expand Down
6 changes: 6 additions & 0 deletions src/McpContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
11 changes: 11 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's clarify that this is for screenshots taken by take_screenshot if no format is supplied to the tool call.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

choices: ['png', 'jpeg', 'webp'] as const,
default: 'png',
},
} satisfies Record<string, YargsOptions>;

export function parseArguments(version: string, argv = process.argv) {
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ async function getContext(): Promise<McpContext> {
context = await McpContext.from(browser, logger, {
experimentalDevToolsDebugging: devtools,
experimentalIncludeAllPages: args.experimentalIncludeAllPages,
screenshotFormat: args.screenshotFormat as 'png' | 'jpeg' | 'webp',
});
}
return context;
Expand Down
4 changes: 4 additions & 0 deletions src/tools/ToolDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Schema extends zod.ZodRawShape>(
Expand Down
13 changes: 8 additions & 5 deletions src/tools/screenshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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'),
});
}
Expand Down
2 changes: 2 additions & 0 deletions tests/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down