Bug Description
The commandExistsSync function in lib/mcp/util.js incorrectly executes Windows-specific code on macOS, resulting in the creation of a file named nul (Windows null device) in the working directory.
Environment
- OS: macOS (Darwin 24.6.0)
- firebase-tools version: 14.15.2 (globally installed via npm)
- Node.js: v22.x
- Context: Using Firebase MCP server with Claude Code CLI
Steps to Reproduce
- Install firebase-tools globally:
npm install -g firebase-tools
- Use Firebase MCP server (e.g., via Claude Code or any MCP-compatible client)
- The MCP server periodically checks for command availability
- A file named
nul appears in the working directory
Expected Behavior
On macOS/Linux, the function should execute:
which "command" > /dev/null 2> /dev/null
Actual Behavior
On macOS, the function executes the Windows branch:
where "command" > nul 2> nul
This results in:
/bin/sh: where: command not found error
- A file named
nul created in the working directory containing the error message
Root Cause
File: lib/mcp/util.js (lines 42-49)
function commandExistsSync(command) {
try {
const isWindows = (0, os_1.platform)() === "win32";
const commandToCheck = isWindows
? `where "${command}" > nul 2> nul`
: `which "${command}" > /dev/null 2> /dev/null`;
(0, child_process_1.execSync)(commandToCheck);
return true;
}
catch (error) {
return false;
}
}
The platform detection os_1.platform() === "win32" appears to fail or return an unexpected value in certain execution contexts (possibly related to how the MCP server is spawned).
Evidence
Contents of the nul file created on macOS:
/bin/sh: where: command not found
Simultaneously, firebase-debug.log is created with API calls showing empty project IDs:
GET https://serviceusage.googleapis.com/v1/projects//services/firebaseappdistribution.googleapis.com
Suggested Fix
Consider one of the following approaches:
- Add defensive check for platform detection:
const platform = os_1.platform();
const isWindows = platform === "win32" || platform === "windows";
-
Use a cross-platform library like command-exists npm package
-
Add fallback logic if the first command fails:
function commandExistsSync(command) {
const commands = [
`which "${command}" > /dev/null 2> /dev/null`,
`where "${command}" > nul 2> nul`,
`command -v "${command}" > /dev/null 2> /dev/null`
];
// Try each until one succeeds
}
Workaround
Add nul to .gitignore:
# Firebase MCP bug artifact
nul
Additional Context
This bug is triggered whenever the Firebase MCP server initializes or checks for tool availability, causing repeated file creation.
Bug Description
The
commandExistsSyncfunction inlib/mcp/util.jsincorrectly executes Windows-specific code on macOS, resulting in the creation of a file namednul(Windows null device) in the working directory.Environment
Steps to Reproduce
npm install -g firebase-toolsnulappears in the working directoryExpected Behavior
On macOS/Linux, the function should execute:
Actual Behavior
On macOS, the function executes the Windows branch:
This results in:
/bin/sh: where: command not founderrornulcreated in the working directory containing the error messageRoot Cause
File:
lib/mcp/util.js(lines 42-49)The platform detection
os_1.platform() === "win32"appears to fail or return an unexpected value in certain execution contexts (possibly related to how the MCP server is spawned).Evidence
Contents of the
nulfile created on macOS:Simultaneously,
firebase-debug.logis created with API calls showing empty project IDs:Suggested Fix
Consider one of the following approaches:
Use a cross-platform library like
command-existsnpm packageAdd fallback logic if the first command fails:
Workaround
Add
nulto.gitignore:Additional Context
This bug is triggered whenever the Firebase MCP server initializes or checks for tool availability, causing repeated file creation.