<# Self-check for the crg-mcp plugin. Drives crg.cmd exactly the way the PI-Desktop MCP host does — `cmd /c crg.cmd` with piped stdio and cwd = this folder — then reports the MCP handshake, the tool list, and one real tool call. Run it from PowerShell: powershell -NoProfile -ExecutionPolicy Bypass -File .\selfcheck.ps1 #> $ErrorActionPreference = 'Stop' $dir = Split-Path -Parent $MyInvocation.MyCommand.Path # Mirror the host's minimal environment plus the manifest's env block. foreach ($k in 'PATH', 'SystemRoot', 'TEMP', 'TMP') { if (-not (Test-Path "Env:$k")) { Write-Warning "missing $k in ambient env" } } $psi = New-Object System.Diagnostics.ProcessStartInfo $psi.FileName = 'cmd.exe' $psi.Arguments = '/c crg.cmd' $psi.WorkingDirectory = $dir $psi.RedirectStandardInput = $true $psi.RedirectStandardOutput = $true $psi.RedirectStandardError = $true $psi.UseShellExecute = $false $psi.StandardOutputEncoding = [System.Text.Encoding]::UTF8 $proc = [System.Diagnostics.Process]::Start($psi) function Send($obj) { $proc.StandardInput.WriteLine(($obj | ConvertTo-Json -Compress -Depth 8)) $proc.StandardInput.Flush() } function ReadLine([int]$waitSeconds = 25) { $task = $proc.StandardOutput.ReadLineAsync() if ($task.Wait([TimeSpan]::FromSeconds($waitSeconds))) { return $task.Result } return $null } Send @{ jsonrpc = '2.0'; id = 1; method = 'initialize' params = @{ protocolVersion = '2025-06-18' capabilities = @{} clientInfo = @{ name = 'crg-selfcheck'; version = '1' } } } $initLine = ReadLine 40 if (-not $initLine) { Write-Host 'HANDSHAKE FAILED: no stdout from crg.cmd' -ForegroundColor Red Write-Host '--- stderr ---' Write-Host $proc.StandardError.ReadToEnd() try { $proc.Kill() } catch { } exit 1 } $init = $initLine | ConvertFrom-Json Write-Host ("HANDSHAKE OK server={0} {1}" -f $init.result.serverInfo.name, $init.result.serverInfo.version) -ForegroundColor Green Send @{ jsonrpc = '2.0'; method = 'notifications/initialized'; params = @{} } Send @{ jsonrpc = '2.0'; id = 2; method = 'tools/list'; params = @{} } $toolsLine = ReadLine if (-not $toolsLine) { Write-Host 'tools/list returned nothing' -ForegroundColor Red try { $proc.Kill() } catch { } exit 1 } $tools = ($toolsLine | ConvertFrom-Json).result.tools Write-Host ("TOOLS: {0}" -f $tools.Count) -ForegroundColor Green foreach ($t in $tools) { Write-Host (" plugin_crg_mcp_crg_{0}" -f $t.name) } Send @{ jsonrpc = '2.0'; id = 3; method = 'tools/call' params = @{ name = 'list_graph_stats_tool'; arguments = @{} } } $callLine = ReadLine 40 if ($callLine) { $call = $callLine | ConvertFrom-Json if ($call.result) { $text = $call.result.content[0].text Write-Host 'TOOL CALL OK' -ForegroundColor Green Write-Host (' ' + ($text -split "`n")[0..3] -join ' | ') } else { Write-Host ("TOOL CALL ERROR: {0}" -f ($call | ConvertTo-Json -Compress -Depth 6)) -ForegroundColor Red } } else { Write-Host 'TOOL CALL: no response' -ForegroundColor Red } try { $proc.Kill() } catch { }