From 98b025306cfd787924a5d33b2453601bea463404 Mon Sep 17 00:00:00 2001 From: Tym Rabchuk Date: Fri, 10 Apr 2026 16:34:57 -0400 Subject: [PATCH] fix(windows): launch MCP engine via sh wrapper to bypass CreateProcess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows `/mcp` UI couldn't spawn `bin/devkit` because it's an extensionless POSIX shell script and Claude Code's MCP launcher uses `child_process.spawn` without `shell: true`. CreateProcess can't run shebang scripts, and the file has no `.exe`/`.cmd`/`.bat` extension for PATHEXT fallback. Naive shim options are all dead: - `.cmd` sibling with absolute `command` path: Node only applies PATHEXT on bare command lookups through PATH, not absolute paths. - `plugin.json` pointing at `bin/devkit.cmd`: blocked at runtime by CVE-2024-27980 — Node >= 20.12.2 refuses to spawn .cmd/.bat without `shell: true` and throws EINVAL. - Platform-branched `command`: Claude Code's plugin.json parser uses `h.strictObject` on mcpServers.* entries and rejects extra keys. The fix: make `sh` the spawned process and pass the existing POSIX wrapper as its first argument. `sh` is a bare command, so Node resolves it through PATH + PATHEXT; on POSIX that's `/bin/sh`, and on Windows Claude Code already hard-requires Git Bash (it `process.exit(1)`s without bash on PATH), so `sh.exe` is guaranteed present. `.exe` spawns are unaffected by CVE-2024-27980. `bin/devkit` already has the MINGW/MSYS/CYGWIN branch and `cygpath` fallbacks for `gh` and PowerShell downloaders, so it's already designed to run under Git Bash. Validated end-to-end on Windows 11 by the reporter of #60: - `claude mcp list`: devkit-engine Connected - `spawn('sh', [.../bin/devkit, 'mcp'])`: no EINVAL, no ENOENT - Full JSON-RPC roundtrip: initialize, notifications/initialized, tools/list (4 tools), tools/call devkit_list all succeed Closes #60 --- .claude-plugin/plugin.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index a50d2c8..caf0a1f 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -7,8 +7,9 @@ }, "mcpServers": { "devkit-engine": { - "command": "${CLAUDE_PLUGIN_ROOT}/bin/devkit", + "command": "sh", "args": [ + "${CLAUDE_PLUGIN_ROOT}/bin/devkit", "mcp" ] }