diff --git a/README.md b/README.md index 437233389..1590f5c8c 100644 --- a/README.md +++ b/README.md @@ -428,6 +428,10 @@ The Chrome DevTools MCP server supports the following configuration option: Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp. - **Type:** array +- **`--ignoreDefaultChromeArg`/ `--ignore-default-chrome-arg`** + Explicitly disable default arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp. + - **Type:** array + - **`--categoryEmulation`/ `--category-emulation`** Set to false to exclude tools related to emulation. - **Type:** boolean diff --git a/src/browser.ts b/src/browser.ts index e7dffd8db..628007f6b 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -142,7 +142,8 @@ interface McpLaunchOptions { width: number; height: number; }; - args?: string[]; + chromeArgs?: string[]; + ignoreDefaultChromeArgs?: string[]; devtools: boolean; } @@ -167,9 +168,12 @@ export async function launch(options: McpLaunchOptions): Promise { } const args: LaunchOptions['args'] = [ - ...(options.args ?? []), + ...(options.chromeArgs ?? []), '--hide-crash-restore-bubble', ]; + const ignoreDefaultArgs: LaunchOptions['ignoreDefaultArgs'] = + options.ignoreDefaultChromeArgs ?? false; + if (headless) { args.push('--screen-info={3840x2160}'); } @@ -194,6 +198,7 @@ export async function launch(options: McpLaunchOptions): Promise { pipe: true, headless, args, + ignoreDefaultArgs: ignoreDefaultArgs, acceptInsecureCerts: options.acceptInsecureCerts, handleDevToolsAsPage: true, }); diff --git a/src/cli.ts b/src/cli.ts index e1a623e78..f3f8071f6 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -168,6 +168,11 @@ export const cliOptions = { describe: 'Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.', }, + ignoreDefaultChromeArg: { + type: 'array', + describe: + 'Explicitly disable default arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.', + }, categoryEmulation: { type: 'boolean', default: true, @@ -229,6 +234,10 @@ export function parseArguments(version: string, argv = process.argv) { `$0 --chrome-arg='--no-sandbox' --chrome-arg='--disable-setuid-sandbox'`, 'Launch Chrome without sandboxes. Use with caution.', ], + [ + `$0 --ignore-default-chrome-arg='--disable-extensions'`, + 'Disable the default arguments provided by Puppeteer. Use with caution.', + ], ['$0 --no-category-emulation', 'Disable tools in the emulation category'], [ '$0 --no-category-performance', diff --git a/src/main.ts b/src/main.ts index ab6ee3019..049214d54 100644 --- a/src/main.ts +++ b/src/main.ts @@ -54,9 +54,12 @@ server.server.setRequestHandler(SetLevelRequestSchema, () => { let context: McpContext; async function getContext(): Promise { - const extraArgs: string[] = (args.chromeArg ?? []).map(String); + const chromeArgs: string[] = (args.chromeArg ?? []).map(String); + const ignoreDefaultChromeArgs: string[] = ( + args.ignoreDefaultChromeArg ?? [] + ).map(String); if (args.proxyServer) { - extraArgs.push(`--proxy-server=${args.proxyServer}`); + chromeArgs.push(`--proxy-server=${args.proxyServer}`); } const devtools = args.experimentalDevtools ?? false; const browser = @@ -78,7 +81,8 @@ async function getContext(): Promise { userDataDir: args.userDataDir, logFile, viewport: args.viewport, - args: extraArgs, + chromeArgs, + ignoreDefaultChromeArgs, acceptInsecureCerts: args.acceptInsecureCerts, devtools, }); diff --git a/tests/browser.test.ts b/tests/browser.test.ts index 45c09a3c2..aad6eec9c 100644 --- a/tests/browser.test.ts +++ b/tests/browser.test.ts @@ -82,7 +82,7 @@ describe('browser', () => { userDataDir: folderPath, executablePath: executablePath(), devtools: false, - args: ['--remote-debugging-port=0'], + chromeArgs: ['--remote-debugging-port=0'], }); try { const connectedBrowser = await ensureBrowserConnected({ diff --git a/tests/cli.test.ts b/tests/cli.test.ts index 1312e630b..c5f966cf7 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -143,6 +143,30 @@ describe('cli args parsing', () => { }); }); + it('parses ignore chrome args', async () => { + const args = parseArguments('1.0.0', [ + 'node', + 'main.js', + `--ignore-default-chrome-arg='--disable-extensions'`, + `--ignore-default-chrome-arg='--disable-cancel-all-touches'`, + ]); + assert.deepStrictEqual(args, { + ...defaultArgs, + _: [], + headless: false, + $0: 'npx chrome-devtools-mcp@latest', + channel: 'stable', + 'ignore-default-chrome-arg': [ + '--disable-extensions', + '--disable-cancel-all-touches', + ], + ignoreDefaultChromeArg: [ + '--disable-extensions', + '--disable-cancel-all-touches', + ], + }); + }); + it('parses wsEndpoint with ws:// protocol', async () => { const args = parseArguments('1.0.0', [ 'node',