From 327b51589abc021f25c1cba9fa19a8d4f4a49ed6 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Mon, 25 May 2026 22:27:09 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20resolve=206=20test=20failures=20?= =?UTF-8?q?=E2=80=94=20timeouts=20and=20window=5Flist=20syntax?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - audio.ts: increase Add-Type C# compilation timeout to 60s - system.ts: increase WMI query timeout to 45s - service.ts: batch WMI lookups (single query instead of per-service), 45s timeout - power.ts: increase powercfg timeout to 30s - window.ts: fix .Where() syntax to pipe-based Where-Object - shell.ts: unref terminal session child processes so MCP server can exit cleanly Test results: 36/36 passed (12 skipped — destructive/interactive) Authored-by: Moko Consulting --- src/shell.ts | 6 ++++++ src/tools/audio.ts | 2 +- src/tools/power.ts | 4 ++-- src/tools/service.ts | 7 ++++--- src/tools/system.ts | 2 +- src/tools/window.ts | 2 +- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/shell.ts b/src/shell.ts index 5a0062e..015f9e2 100644 --- a/src/shell.ts +++ b/src/shell.ts @@ -182,7 +182,13 @@ export function startSession(shell: 'pwsh' | 'cmd' | 'bash' | 'python' | 'node' const proc = spawn(executable, args, { stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true, + detached: false, }); + // Don't let terminal sessions prevent the MCP server from exiting + proc.unref(); + (proc.stdout as any)?.unref?.(); + (proc.stderr as any)?.unref?.(); + (proc.stdin as any)?.unref?.(); const session: TerminalSession = { pid: proc.pid!, diff --git a/src/tools/audio.ts b/src/tools/audio.ts index 07e2a52..49746b7 100644 --- a/src/tools/audio.ts +++ b/src/tools/audio.ts @@ -100,7 +100,7 @@ $device = (Get-CimInstance Win32_SoundDevice | Where-Object { $_.Status -eq 'OK' device = $device } | ConvertTo-Json -Compress`; - const result = await runPowerShell(ps); + const result = await runPowerShell(ps, { timeout: 60000 }); if (result.exitCode !== 0) { return { content: [{ type: 'text', text: `Error: ${result.stderr}` }], isError: true }; } diff --git a/src/tools/power.ts b/src/tools/power.ts index 03a6bda..00c55d1 100644 --- a/src/tools/power.ts +++ b/src/tools/power.ts @@ -38,7 +38,7 @@ $dcSleep = (powercfg /query SCHEME_CURRENT SUB_SLEEP STANDBYIDLE 2>$null | Selec SleepTimeout_DC = if ($dcSleep) { "$([math]::Floor($dcSleep / 60))m" } else { 'Never' } } | ConvertTo-Json -Compress`; - const result = await runPowerShell(ps, { timeout: 10000 }); + const result = await runPowerShell(ps, { timeout: 30000 }); if (result.exitCode !== 0) { return { content: [{ type: 'text', text: `Error: ${result.stderr}` }], isError: true }; } @@ -113,7 +113,7 @@ $dcSleep = (powercfg /query SCHEME_CURRENT SUB_SLEEP STANDBYIDLE 2>$null | Selec break; } - const result = await runPowerShell(ps, { timeout: 10000 }); + const result = await runPowerShell(ps, { timeout: 30000 }); return { content: [{ type: 'text', text: result.stdout || result.stderr }], isError: result.exitCode !== 0, diff --git a/src/tools/service.ts b/src/tools/service.ts index a69453e..5a90a29 100644 --- a/src/tools/service.ts +++ b/src/tools/service.ts @@ -27,18 +27,19 @@ export function registerServiceTools(server: McpServer): void { : ''; const ps = ` +$wmiCache = @{} +Get-CimInstance Win32_Service -ErrorAction SilentlyContinue | ForEach-Object { $wmiCache[$_.Name] = $_.Description } Get-Service ${filterClause} ${statusClause} | Sort-Object DisplayName | ForEach-Object { - $wmi = Get-CimInstance Win32_Service -Filter "Name='$($_.Name)'" -ErrorAction SilentlyContinue [PSCustomObject]@{ Name = $_.Name DisplayName = $_.DisplayName Status = $_.Status.ToString() StartType = $_.StartType.ToString() - Description = if ($wmi) { $wmi.Description } else { '' } + Description = if ($wmiCache[$_.Name]) { $wmiCache[$_.Name] } else { '' } } } | ConvertTo-Json -Depth 3 -Compress`; - const result = await runPowerShell(ps, { timeout: 20000 }); + const result = await runPowerShell(ps, { timeout: 45000 }); if (result.exitCode !== 0) { return { content: [{ type: 'text', text: `Error: ${result.stderr}` }], isError: true }; } diff --git a/src/tools/system.ts b/src/tools/system.ts index 89b4877..b177c14 100644 --- a/src/tools/system.ts +++ b/src/tools/system.ts @@ -56,7 +56,7 @@ $uptime = (Get-Date) - $os.LastBootUpTime Uptime = "$($uptime.Days)d $($uptime.Hours)h $($uptime.Minutes)m" } | ConvertTo-Json -Depth 4 -Compress`; - const result = await runPowerShell(ps, { timeout: 15000 }); + const result = await runPowerShell(ps, { timeout: 45000 }); if (result.exitCode !== 0) { return { content: [{ type: 'text', text: `Error: ${result.stderr}` }], isError: true }; } diff --git a/src/tools/window.ts b/src/tools/window.ts index 745b027..7c8d789 100644 --- a/src/tools/window.ts +++ b/src/tools/window.ts @@ -53,7 +53,7 @@ export function registerWindowTools(server: McpServer): void { }, async ({ filter }) => { const filterClause = filter - ? `.Where({ $_.Title -like '*${filter.replace(/'/g, "''")}*' })` + ? `| Where-Object { $_.Title -like '*${filter.replace(/'/g, "''")}*' }` : ''; const ps = `