From 173a8c6154a84f588c8a58dedad44c2d26d2683e Mon Sep 17 00:00:00 2001 From: yubingjiaocn Date: Sun, 22 Jun 2025 08:40:38 +0000 Subject: [PATCH 1/3] fix: Handle -- separator in command arguments to prevent timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/bin/mcp-proxy.ts | 51 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/bin/mcp-proxy.ts b/src/bin/mcp-proxy.ts index c643501..f23f64f 100644 --- a/src/bin/mcp-proxy.ts +++ b/src/bin/mcp-proxy.ts @@ -6,7 +6,6 @@ import { EventSource } from "eventsource"; import { setTimeout } from "node:timers"; import util from "node:util"; import yargs from "yargs"; -import { hideBin } from "yargs/helpers"; import { InMemoryEventStore } from "../InMemoryEventStore.js"; import { proxyServer } from "../proxyServer.js"; @@ -20,17 +19,34 @@ if (!("EventSource" in global)) { global.EventSource = EventSource; } -const argv = await yargs(hideBin(process.argv)) +// Handle the -- separator properly +const processArgs = process.argv.slice(2); // Remove 'node' and script name +const doubleDashIndex = processArgs.indexOf("--"); + +let mcpProxyArgs: string[]; +let commandAndArgs: string[]; + +if (doubleDashIndex !== -1) { + // Split at -- separator + mcpProxyArgs = processArgs.slice(0, doubleDashIndex); + commandAndArgs = processArgs.slice(doubleDashIndex + 1); +} else { + // No -- separator, use traditional parsing + mcpProxyArgs = processArgs; + commandAndArgs = []; +} + +const argv = await yargs(mcpProxyArgs) .scriptName("mcp-proxy") - .command("$0 [args...]", "Run a command with MCP arguments") + .command("$0 [command] [args...]", "Run a command with MCP arguments") .positional("command", { - demandOption: true, + demandOption: doubleDashIndex === -1, // Only required if no -- separator describe: "The command to run", type: "string", }) .positional("args", { array: true, - describe: "The arguments to pass to the command", + describe: "The arguments to pass to the command", type: "string", }) .env("MCP_PROXY") @@ -73,10 +89,31 @@ const argv = await yargs(hideBin(process.argv)) .help() .parseAsync(); +// Determine the final command and args +let finalCommand: string; +let finalArgs: string[] | undefined; + +if (doubleDashIndex !== -1) { + // When using --, command comes from yargs parsing (before --) + // and args come from after -- separator + if (!argv.command) { + throw new Error("No command specified before -- separator"); + } + finalCommand = argv.command; + finalArgs = commandAndArgs; // Everything after -- becomes arguments +} else { + // Use command and args from yargs parsing + if (!argv.command) { + throw new Error("No command specified"); + } + finalCommand = argv.command; + finalArgs = argv.args; +} + const connect = async (client: Client) => { const transport = new StdioClientTransport({ - args: argv.args, - command: argv.command, + args: finalArgs, + command: finalCommand, env: process.env as Record, onEvent: (event) => { if (argv.debug) { From e049182aab39bb83942c29e10ba47d86c0350167 Mon Sep 17 00:00:00 2001 From: yubingjiaocn Date: Mon, 23 Jun 2025 08:15:45 +0000 Subject: [PATCH 2/3] fix: use "populate--" to handle command args --- src/bin/mcp-proxy.ts | 48 ++++++++++---------------------------------- 1 file changed, 11 insertions(+), 37 deletions(-) diff --git a/src/bin/mcp-proxy.ts b/src/bin/mcp-proxy.ts index f23f64f..c5ec6d7 100644 --- a/src/bin/mcp-proxy.ts +++ b/src/bin/mcp-proxy.ts @@ -19,28 +19,11 @@ if (!("EventSource" in global)) { global.EventSource = EventSource; } -// Handle the -- separator properly -const processArgs = process.argv.slice(2); // Remove 'node' and script name -const doubleDashIndex = processArgs.indexOf("--"); - -let mcpProxyArgs: string[]; -let commandAndArgs: string[]; - -if (doubleDashIndex !== -1) { - // Split at -- separator - mcpProxyArgs = processArgs.slice(0, doubleDashIndex); - commandAndArgs = processArgs.slice(doubleDashIndex + 1); -} else { - // No -- separator, use traditional parsing - mcpProxyArgs = processArgs; - commandAndArgs = []; -} - -const argv = await yargs(mcpProxyArgs) +const argv = await yargs(process.argv.slice(2)) .scriptName("mcp-proxy") .command("$0 [command] [args...]", "Run a command with MCP arguments") .positional("command", { - demandOption: doubleDashIndex === -1, // Only required if no -- separator + demandOption: true, describe: "The command to run", type: "string", }) @@ -50,6 +33,9 @@ const argv = await yargs(mcpProxyArgs) type: "string", }) .env("MCP_PROXY") + .parserConfiguration({ + "populate--": true + }) .options({ debug: { default: false, @@ -90,26 +76,14 @@ const argv = await yargs(mcpProxyArgs) .parseAsync(); // Determine the final command and args -let finalCommand: string; -let finalArgs: string[] | undefined; - -if (doubleDashIndex !== -1) { - // When using --, command comes from yargs parsing (before --) - // and args come from after -- separator - if (!argv.command) { - throw new Error("No command specified before -- separator"); - } - finalCommand = argv.command; - finalArgs = commandAndArgs; // Everything after -- becomes arguments -} else { - // Use command and args from yargs parsing - if (!argv.command) { - throw new Error("No command specified"); - } - finalCommand = argv.command; - finalArgs = argv.args; +if (!argv.command) { + throw new Error("No command specified"); } +const finalCommand = argv.command; +// If -- separator was used, args after -- are in argv["--"], otherwise use parsed args +const finalArgs = (argv["--"] as string[]) || argv.args; + const connect = async (client: Client) => { const transport = new StdioClientTransport({ args: finalArgs, From e64ac2c4f677ca754e6cd28cda6d8e449644ce7a Mon Sep 17 00:00:00 2001 From: yubingjiaocn Date: Tue, 1 Jul 2025 02:42:36 +0000 Subject: [PATCH 3/3] fix: revert hidebin removal --- src/bin/mcp-proxy.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bin/mcp-proxy.ts b/src/bin/mcp-proxy.ts index c5ec6d7..ecb4793 100644 --- a/src/bin/mcp-proxy.ts +++ b/src/bin/mcp-proxy.ts @@ -6,6 +6,7 @@ import { EventSource } from "eventsource"; import { setTimeout } from "node:timers"; import util from "node:util"; import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; import { InMemoryEventStore } from "../InMemoryEventStore.js"; import { proxyServer } from "../proxyServer.js"; @@ -19,9 +20,9 @@ if (!("EventSource" in global)) { global.EventSource = EventSource; } -const argv = await yargs(process.argv.slice(2)) +const argv = await yargs(hideBin(process.argv)) .scriptName("mcp-proxy") - .command("$0 [command] [args...]", "Run a command with MCP arguments") + .command("$0 [args...]", "Run a command with MCP arguments") .positional("command", { demandOption: true, describe: "The command to run", @@ -29,7 +30,7 @@ const argv = await yargs(process.argv.slice(2)) }) .positional("args", { array: true, - describe: "The arguments to pass to the command", + describe: "The arguments to pass to the command", type: "string", }) .env("MCP_PROXY")