Description of the bug
Since v1.8.0, when --log-file is set, the puppeteerLogger function in src/utils/logger.js unconditionally writes all puppeteer:protocol:SEND and puppeteer:protocol:RECV messages to the log file, regardless of the DEBUG environment variable. This is a regression introduced by #2562 ("refactor: replace debug with NodeJS native").
In v1.7.0, logger.js used the debug npm package. The saveLogsToFile() function called debug.enable() with the user's DEBUG namespaces + mcp:log, so only explicitly enabled namespaces were written to the file.
In v1.8.0+, puppeteerLogger() has a branching bug — when logFileStream is truthy (i.e. --log-file is set), it returns a write function unconditionally without checking util.debuglog(prefix).enabled or DEBUG:
// v1.8.0+ src/utils/logger.js
export const puppeteerLogger = (prefix) => {
if (logFileStream) {
// ALWAYS returns a logger — DEBUG is never checked
return (...args) => {
logFileStream.write(`${new Date().toISOString()} ${prefix} ${util.format(...args)}\n`);
};
}
// DEBUG is only checked when there is NO log file
const dbg = util.debuglog(prefix);
return dbg.enabled
? (...args) => { dbg('%s %s', new Date().toISOString(), util.format(...args)); }
: undefined;
};
The result: every CDP wire message (network requests, responses, DOM events, accessibility tree queries, etc.) is written to disk. In real-world use, this produces gigabytes of log files, compared to kilobytes previously for the same amount of traffic.
Reproduction
Testing identical operations on v1.7.0 vs v1.9.0 with DEBUG=mcp:log (should exclude puppeteer:*):
- Configure MCP with
--log-file /path/to/log and DEBUG=mcp:log
- Truncate the log file
- Reload the MCP server
- Call
list_pages, then navigate_page to https://example.com, then take_snapshot
- Count log lines by namespace
Results:
|
v1.7.0 |
v1.9.0 |
| Total lines |
26 |
209 |
puppeteer:* lines |
0 |
174 |
mcp:log lines |
16 |
17 |
DEBUG respected? |
Yes |
No |
v1.7.0 correctly writes only mcp:log entries. v1.9.0 dumps 174 additional puppeteer:protocol:SEND/RECV lines containing full CDP JSON payloads (accessibility trees, network events, etc.) despite DEBUG=mcp:log.
Expectation
puppeteerLogger should respect DEBUG namespace filtering when writing to --log-file, matching v1.7.0 behavior:
DEBUG unset → only mcp:log lines in the log file
DEBUG=mcp:log → only mcp:log lines
DEBUG=puppeteer:* → puppeteer lines included (opt-in)
DEBUG=* → everything (explicit user choice)
A minimal fix would be to check util.debuglog(prefix).enabled before returning a file-writing logger:
export const puppeteerLogger = (prefix) => {
const dbg = util.debuglog(prefix);
if (!dbg.enabled) return undefined;
if (logFileStream) {
return (...args) => {
logFileStream.write(`${new Date().toISOString()} ${prefix} ${util.format(...args)}\n`);
};
}
return (...args) => {
dbg('%s %s', new Date().toISOString(), util.format(...args));
};
};
MCP configuration
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": [
"-y",
"chrome-devtools-mcp@latest",
"--log-file",
"/path/to/chrome-devtools-mcp.log"
],
"env": {
"DEBUG": "mcp:log"
}
}
}
}
Chrome DevTools MCP version
v1.8.0 and v1.9.0 affected; v1.7.0 works correctly
Chrome version
Chromium 150.0.7871.181
Coding agent version
Cursor 3.18.9
Model version
No response
Chat log
No response
Node version
v24.19.0
Operating system
Linux
Extra checklist
Description of the bug
Since v1.8.0, when --log-file is set, the puppeteerLogger function in src/utils/logger.js unconditionally writes all puppeteer:protocol:SEND and puppeteer:protocol:RECV messages to the log file, regardless of the DEBUG environment variable. This is a regression introduced by #2562 ("refactor: replace debug with NodeJS native").
In v1.7.0, logger.js used the debug npm package. The saveLogsToFile() function called debug.enable() with the user's DEBUG namespaces + mcp:log, so only explicitly enabled namespaces were written to the file.
In v1.8.0+, puppeteerLogger() has a branching bug — when logFileStream is truthy (i.e. --log-file is set), it returns a write function unconditionally without checking util.debuglog(prefix).enabled or DEBUG:
The result: every CDP wire message (network requests, responses, DOM events, accessibility tree queries, etc.) is written to disk. In real-world use, this produces gigabytes of log files, compared to kilobytes previously for the same amount of traffic.
Reproduction
Testing identical operations on v1.7.0 vs v1.9.0 with
DEBUG=mcp:log(should excludepuppeteer:*):--log-file /path/to/logandDEBUG=mcp:loglist_pages, thennavigate_pagetohttps://example.com, thentake_snapshotResults:
puppeteer:*linesmcp:loglinesDEBUGrespected?v1.7.0 correctly writes only
mcp:logentries. v1.9.0 dumps 174 additionalpuppeteer:protocol:SEND/RECVlines containing full CDP JSON payloads (accessibility trees, network events, etc.) despiteDEBUG=mcp:log.Expectation
puppeteerLoggershould respectDEBUGnamespace filtering when writing to--log-file, matching v1.7.0 behavior:DEBUGunset → onlymcp:loglines in the log fileDEBUG=mcp:log→ onlymcp:loglinesDEBUG=puppeteer:*→ puppeteer lines included (opt-in)DEBUG=*→ everything (explicit user choice)A minimal fix would be to check
util.debuglog(prefix).enabledbefore returning a file-writing logger:MCP configuration
{ "mcpServers": { "chrome-devtools": { "command": "npx", "args": [ "-y", "chrome-devtools-mcp@latest", "--log-file", "/path/to/chrome-devtools-mcp.log" ], "env": { "DEBUG": "mcp:log" } } } }Chrome DevTools MCP version
v1.8.0 and v1.9.0 affected; v1.7.0 works correctly
Chrome version
Chromium 150.0.7871.181
Coding agent version
Cursor 3.18.9
Model version
No response
Chat log
No response
Node version
v24.19.0
Operating system
Linux
Extra checklist