Repository navigation
dcd mcp install can't find code or claude on Windows (.cmd shims) #281
Description
dcd mcp install vscode reports that code isn't on PATH on Windows, even when code works in the user's terminal. dcd mcp install claude-code fails the same way. This affects at least the npm-installed CLI running under Node.
Found by the review bot on #280 (commit e83ae64). The code is the same on dev.
Cause
runTool in src/commands/mcp.ts calls spawnSync without a shell:
Lines 42 to 47 in e83ae64
| /** Run another tool's CLI without a shell. Undefined when it isn't installed. */ | |
| function runTool(command: string, args: string[]): { ok: boolean; output: string } | undefined { | |
| const result = spawnSync(command, args, { encoding: 'utf8' }); | |
| if ((result.error as NodeJS.ErrnoException | undefined)?.code === 'ENOENT') return undefined; | |
| return { ok: result.status === 0, output: `${result.stdout ?? ''}${result.stderr ?? ''}`.trim() }; | |
| } |
On Windows, VS Code's command line exists only as ...\Microsoft VS Code\bin\code.cmd. Without a shell, Node's spawnSync searches PATH for .com and .exe files and skips .cmd. So spawnSync('code', ...) fails with ENOENT, runTool returns undefined, and the user sees "The code command isn't on PATH".
Recent Node versions also refuse to spawn a .cmd file unless you pass shell: true (CVE-2024-27980), so finding the file isn't enough on its own.
npm installs Claude Code as claude.cmd, so the claude mcp remove / claude mcp add calls hit the same problem:
Lines 77 to 82 in e83ae64
| const removed = runTool('claude', ['mcp', 'remove', '--scope', 'user', SERVER_NAME]); | |
| if (!removed) { | |
| throw new CliError(`The claude command isn't on PATH. Run this where it is:\n ${shellLine('claude', add)}`); | |
| } | |
| const added = runTool('claude', add)!; |
Scope
- Affected: anyone who installed
dcdwith npm on Windows. - Not checked yet: whether the bun-compiled binary (
install.ps1) resolves.cmddifferently.
Windows is a supported platform: there's install.ps1, and src/utils/mcp-install.ts handles win32 when it builds config paths.
Possible fixes
- On
win32, trycode.cmd/claude.cmd. Because of the CVE change this probably still needs a shell to launch them. - On
win32, spawn withshell: true(throughcmd.exe). If we do this, quote the JSON argument fromvscodeAddArgscarefully, becausecmdwill reparse it.
Done when
-
dcd mcp install vscodeanddcd mcp install claude-codework on Windows with an npm-installed CLI. - The bun-compiled binary is checked as well.
- The JSON argument passed to
code --add-mcpreaches VS Code unchanged.
Activity