Skip to content

fix(windows): add qmd.cmd launcher that invokes node/bun directly#561

Open
OthmanAdi wants to merge 1 commit intotobi:mainfrom
OthmanAdi:fix/windows-mcp-stdio-spawn
Open

fix(windows): add qmd.cmd launcher that invokes node/bun directly#561
OthmanAdi wants to merge 1 commit intotobi:mainfrom
OthmanAdi:fix/windows-mcp-stdio-spawn

Conversation

@OthmanAdi
Copy link
Copy Markdown

Problem

On Windows, the npm-generated qmd.cmd wrapper calls /bin/sh to run bin/qmd. When MCP clients (e.g. Claude Code, Cursor, or any tool using Node.js child_process.spawn()) start qmd as a stdio subprocess, /bin/sh is not reliably available — Git for Windows is often absent from the subprocess PATH even when present in interactive shells.

The result: qmd mcp silently fails to start when configured as an MCP stdio server. No error is shown to the user; the MCP client simply never sees the server.

Example broken config (fails on Windows via Node.js spawn):

{
  "mcpServers": {
    "qmd": { "command": "qmd", "args": ["mcp"] }
  }
}

Fix

Add bin/qmd.cmd: a native CMD launcher that mirrors the runtime-detection logic already in bin/qmd (checks package-lock.jsonnode, bun.lock / bun.lockbbun, fallback → node) without requiring a POSIX shell.

npm uses a hand-crafted qmd.cmd over its auto-generated wrapper when both share the same base name — so this file is picked up automatically on npm install -g with no changes to package.json.

Verification

Tested via Node.js spawnSync (exactly how MCP clients spawn the server):

const r = spawnSync('cmd.exe', ['/c', 'qmd.cmd', '--help'], { encoding: 'utf8' });
// stdout: "qmd — Quick Markdown Search\n\nUsage:\n  qmd <command> [options]..."
// status: 0

MCP stdio handshake works end-to-end after this change.

Related

Similar in spirit to #555 (USERPROFILE fallback for Windows HOME resolution).

The npm-generated qmd.cmd wrapper calls /bin/sh to run bin/qmd.
When MCP clients (e.g. Claude Code) spawn qmd as a stdio subprocess
via Node.js child_process.spawn(), /bin/sh is not reliably available
— Git for Windows is often absent from the subprocess PATH even when
present in interactive shells. This causes the MCP server to fail
silently with no error output.

Add bin/qmd.cmd: a native CMD launcher that mirrors the runtime-
detection logic in bin/qmd (bun.lock → bun, package-lock.json → node,
fallback → node) without requiring a POSIX shell. npm uses a
hand-crafted qmd.cmd over its auto-generated wrapper when both share
the same base name, so this file is picked up automatically on
"npm install -g".

Verified: Node.js spawnSync('cmd.exe', ['/c', 'qmd.cmd', 'mcp'])
returns exit 0 and correct MCP JSON-RPC response.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant