fix(mcp): cross-platform launcher for Windows/macOS/Linux#18
Open
guoyucode wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Claude Code Weixin MCP plugin startup flow to work cross-platform (Windows/macOS/Linux) by replacing the /bin/sh wrapper approach with a Node.js-based launcher that finds bun, installs deps, and starts server.ts over stdio.
Changes:
- Add a cross-platform Node.js launcher (
plugins/weixin/mcp-launch.cjs) to locatebun, runbun install, and spawnbun server.ts. - Update the Claude MCP configuration (
plugins/weixin/.mcp.json) to invokenodewith the launcher script.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| plugins/weixin/mcp-launch.cjs | New Node-based launcher that bootstraps bun deps and starts the MCP server process. |
| plugins/weixin/.mcp.json | Switch MCP startup command from /bin/sh wrapper to node launcher for Windows compatibility. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+47
to
+56
| // Step 1: install dependencies (idempotent, near-instant on no-op). | ||
| const install = spawnSync(bun, ["install", "--no-summary"], { | ||
| cwd: root, | ||
| stdio: ["ignore", "inherit", "inherit"], | ||
| }); | ||
| if (install.status !== 0) { | ||
| process.stderr.write( | ||
| `[weixin] bun install failed (exit ${install.status ?? "?"})\n`, | ||
| ); | ||
| process.exit(install.status ?? 1); |
Comment on lines
+69
to
+76
| process.on("SIGINT", () => forward("SIGINT")); | ||
| process.on("SIGTERM", () => forward("SIGTERM")); | ||
| process.on("SIGHUP", () => forward("SIGHUP")); | ||
|
|
||
| child.on("exit", (code, signal) => { | ||
| if (signal) { | ||
| process.kill(process.pid, signal); | ||
| return; |
Replace the shell wrapper in .mcp.json (currently `bash -c "..."`) with a Node.js launcher script (mcp-launch.cjs). Windows typically has no POSIX shell on PATH, so the previous config failed to start the MCP server entirely on Windows: the bun process was never spawned and WeChat messages were never delivered to Claude Code (the 'Listening for channel messages from ...' banner only confirms channel registration, not that the server actually runs). The launcher preserves the macOS PATH fallback introduced in qufei1993#14 (~/.bun/bin, ~/.volta/bin) and extends it to Windows by also looking for bun.exe under the same directories. It also redirects bun install output to stderr so non-protocol lines like "Saved lockfile" cannot corrupt the MCP JSON-RPC stream over stdout. .mcp.json cannot branch on OS, so we centralize the discovery + spawn logic in one CommonJS file that runs on all three platforms.
0124b70 to
2b25b2f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
plugins/weixin/.mcp.json(currentlybash -c "...") with a Node.js launcher (mcp-launch.cjs) so the plugin works on Windows in addition to macOS and Linux.~/.bun/bin,~/.volta/bin) and extends it to Windows (bun.exeunder the same dirs).Background
PR #14 fixed macOS GUI launches by wrapping the command in a POSIX shell that prepends bun install dirs to PATH (later evolved into the current
bash -cform). However:Listening for channel messages from: plugin:weixin@cc-weixinbanner is misleading — it only confirms channel registration, not that the server actually runs. So the failure is silent: no error surfaces to the user, the banner says everything is fine, and messages just disappear..mcp.jsondoesn't support per-OS branching, so a singlecommandmust work on all three OSes.Changes
plugins/weixin/mcp-launch.cjs(~90 lines, CommonJS for max compat):bunvia PATH first, then fall back to~/.bun/bin/bun(.exe)and~/.volta/bin/bun(.exe).bun install --no-summarywith stdout redirected to stderr (fd 2) so non-protocol output likeSaved lockfilecannot corrupt the MCP JSON-RPC stream over stdout. SurfacesspawnSyncerrors (e.g. ENOENT when bun isn't found) in the failure message.bun server.tswithcwd = __dirname, inheriting stdio so the host can speak MCP over stdin/stdout.128 + signumcode instead of re-raising the signal (which would re-enter our own listeners and hang the launcher).plugins/weixin/.mcp.json:command:bash→nodeargs: shell-script string →["${CLAUDE_PLUGIN_ROOT}/mcp-launch.cjs"]Trade-off
Introduces a Node.js dependency for the launcher itself. Bun cannot bootstrap itself when not on PATH, but Node.js is broadly preinstalled on developer machines (and trivially added if missing), so this is a pragmatic choice. Open to feedback if the maintainer prefers a pure-bun launcher (e.g. a small Rust/Go binary, or platform-specific shell scripts), but those add more friction than this single CommonJS file.
Testing
Verified locally on Windows 11 + PowerShell (where the previous shell-wrapper config fails silently):
(stdout stays empty — confirmed by piping
1>stdout.log 2>stderr.logand checkingstdout.logis zero bytes whilestderr.logcontains the lines above.)After replacing
.mcp.jsonand restarting Claude Code, WeChat messages are delivered as expected. Without this fix, the same setup on Windows shows the connection banner but never delivers any message.macOS / Linux behavior should be unchanged — the launcher's discovery list is a superset of the previous PATH prepend, and stdout/stderr semantics are equivalent to the existing
1>&2redirect.Out of scope
.codex-mcp.json— Codex uses a separatestart-codex.shflow that already handles cross-platform concerns differently.Review feedback addressed
Both Copilot review comments addressed in the latest force-push:
bun installstdout redirected to stderr (fd 2);install.errornow included in the failure message so users see the underlying cause (e.g.ENOENTwhen bun isn't found) instead of just an exit code.process.exit(128 + signum)directly.