diff --git a/Public/Invoke-HandleRequest.ps1 b/Public/Invoke-HandleRequest.ps1 index bd66346..0a41d74 100644 --- a/Public/Invoke-HandleRequest.ps1 +++ b/Public/Invoke-HandleRequest.ps1 @@ -44,8 +44,69 @@ function Invoke-HandleRequest { $toolName = $request.params.name $targetArgs = $request.params.arguments | ConvertTo-Json -Depth 10 | ConvertFrom-Json -Depth 10 -AsHashtable + # Derive the set of allowed tool names from the configured tools list JSON. + $allowedToolNames = @() + try { + $parsedTools = $toolsListJson | ConvertFrom-Json -Depth 10 + + if ($parsedTools -is [System.Array]) { + # Expecting an array of tool objects with a 'name' property. + $allowedToolNames = $parsedTools | ForEach-Object { $_.name } | Where-Object { $_ } + } + elseif ($parsedTools -ne $null) { + # Handle object shapes like @{ tools = @(@{ name = "..." }, ...) } or a single tool object. + if ($parsedTools.PSObject.Properties.Name -contains 'tools' -and $parsedTools.tools) { + $allowedToolNames = $parsedTools.tools | ForEach-Object { $_.name } | Where-Object { $_ } + } + elseif ($parsedTools.PSObject.Properties.Name -contains 'name') { + $allowedToolNames = @($parsedTools.name) | Where-Object { $_ } + } + } + } + catch { + # If parsing fails, leave $allowedToolNames empty to avoid executing arbitrary tools. + $allowedToolNames = @() + } + + # Validate that the requested tool name is in the allowed list. + if (-not ($allowedToolNames -and ($allowedToolNames -contains $toolName))) { + $errorResponse = [ordered]@{ + jsonrpc = "2.0" + id = $request.id + error = @{ + code = -32602 + message = "Invalid or unauthorized tool name: '$toolName'." + } + } + + return ($errorResponse | ConvertTo-Json -Depth 10 -Compress) + } $result = & $toolName @targetArgs + $resultText = if ($null -eq $result) { + "" + } + elseif ($result -is [string]) { + $result + } + elseif ($result -is [ValueType]) { + $result.ToString() + } + else { + try { + $result | ConvertTo-Json -Depth 100 + } + catch { + # Fallback to a safer string representation if JSON serialization fails + try { + $result | Out-String + } + catch { + $result.ToString() + } + } + } + # Log structured data Write-Log -LogEntry @{ RequestId = $request.id @@ -63,7 +124,7 @@ function Invoke-HandleRequest { content = @( [ordered]@{ type = "text" - text = $result | Out-String + text = $resultText } ) isError = $false