diff --git a/packages/mcp-gateway/src/sharedGateway.test.ts b/packages/mcp-gateway/src/sharedGateway.test.ts index a55eddab4c5bc..79f2d7ffd8ebc 100644 --- a/packages/mcp-gateway/src/sharedGateway.test.ts +++ b/packages/mcp-gateway/src/sharedGateway.test.ts @@ -672,10 +672,17 @@ describe("shared MCP gateway", () => { T3_MCP_GRANTS: "{}", }, }); + let stderr = ""; + transport.stderr?.on("data", (chunk: Buffer) => { + stderr += chunk.toString(); + }); cleanup.push(() => client.close()); await client.connect(transport); const changed = Promise.withResolvers(); client.setNotificationHandler(ToolListChangedNotificationSchema, () => changed.resolve()); + // A launcher that cannot move the session exits; fail with its reason instead of waiting. + // oxlint-disable-next-line unicorn/prefer-add-event-listener -- MCP Client exposes an onclose callback rather than a DOM event API. + client.onclose = () => changed.reject(new Error(`Launcher exited: ${stderr.trim()}`)); expect((await client.listTools()).tools.length).toBeGreaterThan(0); await first!.close(); diff --git a/packages/mcp-gateway/src/sharedLauncher.ts b/packages/mcp-gateway/src/sharedLauncher.ts index 8e2fe558b498a..532ff1d209a72 100644 --- a/packages/mcp-gateway/src/sharedLauncher.ts +++ b/packages/mcp-gateway/src/sharedLauncher.ts @@ -39,9 +39,9 @@ export function launchSharedOwner( }, }, ); - const timeout = AbortSignal.timeout(15_000); + // Startup waits on no peer, so it always ends in ready, an error, or an exit. A deadline would + // only kill a healthy owner a loaded machine starts slowly; a stuck launcher is its host's to end. const cleanup = () => { - timeout.removeEventListener("abort", onTimeout); child.off("error", fail); child.off("exit", onExit); child.off("message", onMessage); @@ -52,7 +52,6 @@ export function launchSharedOwner( if (child.connected) child.disconnect(); reject(error); }; - const onTimeout = () => fail(new Error("Timed out starting the shared MCP gateway owner.")); const onExit = (code: number | null) => fail(new Error(`Shared MCP gateway owner exited before startup (code ${code}).`)); const onMessage = (value: unknown) => { @@ -66,7 +65,6 @@ export function launchSharedOwner( resolve(child); } }; - timeout.addEventListener("abort", onTimeout, { once: true }); child.once("error", fail); child.once("exit", onExit); child.on("message", onMessage);