From e9e99629a2dffb99c45336a5b3a304d972f6f0e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Apr 2026 11:11:05 +0000 Subject: [PATCH 1/3] fix: correct Claude Desktop auto-config for both pkg and node modes - pkg binary: uses the installed binary path as command - node/dev mode: uses npx -y @clashcontrol/mcp-server - Previously used process.execPath which pointed to node binary itself, resulting in a broken config entry https://claude.ai/code/session_01XEvUykWcLc452uxGWPb1mb --- smart-bridge.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/smart-bridge.js b/smart-bridge.js index e2816d1..96cb01b 100644 --- a/smart-bridge.js +++ b/smart-bridge.js @@ -87,7 +87,18 @@ function getClaudeConfigPath() { function configureClaude() { const configPath = getClaudeConfigPath(); - const binaryPath = process.pkg ? getInstallPath() : process.execPath; + + // Determine the right command + args for Claude Desktop to spawn us + let command, args; + if (process.pkg) { + // Running as compiled binary — use the installed binary path directly + command = getInstallPath(); + args = ['--mcp']; + } else { + // Running via node — use npx so it works without knowing the script path + command = 'npx'; + args = ['-y', '@clashcontrol/mcp-server']; + } let config = {}; try { @@ -98,17 +109,14 @@ function configureClaude() { if (!config.mcpServers) config.mcpServers = {}; - // Already configured — check if path still matches + // Already configured with the same command — skip if (config.mcpServers.clashcontrol) { const existing = config.mcpServers.clashcontrol; - if (existing.command === binaryPath) return; // already correct + if (existing.command === command) return; } // Add or update the clashcontrol entry - config.mcpServers.clashcontrol = { - command: binaryPath, - args: ['--mcp'] - }; + config.mcpServers.clashcontrol = { command, args }; try { fs.mkdirSync(path.dirname(configPath), { recursive: true }); From fbb5302460f429ded4d286fd388c116ac6f935f4 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Apr 2026 11:13:31 +0000 Subject: [PATCH 2/3] fix: use node + script path instead of unpublished npx package The npm package @clashcontrol/mcp-server isn't published yet. When running via node (non-pkg), use process.execPath + absolute path to smart-bridge.js instead of npx. https://claude.ai/code/session_01XEvUykWcLc452uxGWPb1mb --- smart-bridge.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smart-bridge.js b/smart-bridge.js index 96cb01b..0f05511 100644 --- a/smart-bridge.js +++ b/smart-bridge.js @@ -95,9 +95,9 @@ function configureClaude() { command = getInstallPath(); args = ['--mcp']; } else { - // Running via node — use npx so it works without knowing the script path - command = 'npx'; - args = ['-y', '@clashcontrol/mcp-server']; + // Running via node — use node + absolute path to this script + command = process.execPath; + args = [path.resolve(__dirname, 'smart-bridge.js'), '--mcp']; } let config = {}; From 5169083536439d26337a39cbd52f721959c561ce Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Apr 2026 11:29:35 +0000 Subject: [PATCH 3/3] fix: move MCP SDK requires to top level so pkg can bundle them The compiled binary crashed with "Cannot find module '@modelcontextprotocol/sdk/server/mcp.js'" because pkg can't trace require() calls inside conditional function bodies. Fix: move requires to top-level imports. Also change pkg config from assets to scripts for .js files so they're properly compiled into the binary, and add tools.js to assets. https://claude.ai/code/session_01XEvUykWcLc452uxGWPb1mb --- package.json | 9 +++++++-- smart-bridge.js | 7 +++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index a8ecdc6..00aa714 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,14 @@ "zod": "^3.25.0" }, "pkg": { + "scripts": [ + "node_modules/@modelcontextprotocol/sdk/**/*.js", + "node_modules/zod/**/*.js" + ], "assets": [ - "node_modules/@modelcontextprotocol/sdk/**/*", - "node_modules/zod/**/*" + "node_modules/@modelcontextprotocol/sdk/**/*.json", + "node_modules/zod/**/*.json", + "tools.js" ] }, "license": "MIT" diff --git a/smart-bridge.js b/smart-bridge.js index 0f05511..9bb3265 100644 --- a/smart-bridge.js +++ b/smart-bridge.js @@ -21,6 +21,9 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); const { spawn } = require('child_process'); +const { McpServer } = require('@modelcontextprotocol/sdk/server/mcp.js'); +const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js'); +const { z } = require('zod'); const VERSION = require('./package.json').version; const WS_PORT = 19802; @@ -427,10 +430,6 @@ function startRestServer() { // ── MCP Server (Claude Desktop) ────────────────────────────────── async function startMcpServer() { - const { McpServer } = require('@modelcontextprotocol/sdk/server/mcp.js'); - const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js'); - const { z } = require('zod'); - const mcp = new McpServer({ name: 'ClashControl', version: VERSION }, { instructions: MCP_INSTRUCTIONS }); registerMcpTools(mcp, z, sendToBrowser);