Public/Invoke-McpTool.ps1
|
function Invoke-McpTool { <# .SYNOPSIS Calls a tool on an MCP server and returns a PowerShell-friendly result. .DESCRIPTION Sends tools/call. By default text content is flattened: JSON text becomes objects, other text stays a string, and non-text blocks are dropped. structuredContent is preferred when present. Errors are returned as strings by default so an LLM tool loop can see and recover from them; use -ThrowOnError to raise exceptions instead. A server process dying mid-call always throws. .PARAMETER Server Session name. .PARAMETER Name Tool name. .PARAMETER Arguments Tool arguments matching the tool's inputSchema. .PARAMETER Raw Return the unmodified tools/call result (content[], isError, structuredContent). .PARAMETER ThrowOnError Throw on JSON-RPC errors and on results with isError = true. .PARAMETER TimeoutSec Per-call timeout; defaults to the session's RequestTimeoutSec. .EXAMPLE Invoke-McpTool -Server everything -Name echo -Arguments @{ message = 'hi' } #> [CmdletBinding()] param( [Parameter(Mandatory, Position = 0, ValueFromPipelineByPropertyName)] [string]$Server, [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)] [string]$Name, [Parameter(Position = 2)] [System.Collections.IDictionary]$Arguments, [switch]$Raw, [switch]$ThrowOnError, [int]$TimeoutSec ) process { $session = Get-McpSession -Server $Server $params = [ordered]@{ name = $Name arguments = if ($null -ne $Arguments) { $Arguments } else { @{} } } $response = Send-McpRequest -Session $session -Method 'tools/call' -Params $params -TimeoutSec $TimeoutSec -Raw if ($response.ContainsKey('error')) { $rpcError = $response['error'] $message = "MCP error $($rpcError.code): $($rpcError.message)" if ($ThrowOnError) { throw (New-McpError -ErrorId 'McpProtocolError' -Category InvalidOperation -TargetObject $rpcError -Message $message) } return $message } $result = $response['result'] if ($result -is [System.Collections.IDictionary] -and $result['resultType'] -and $result['resultType'] -ne 'complete') { throw (New-McpError -ErrorId 'McpUnsupportedResult' -Category NotImplemented -TargetObject $result ` -Message "Tool '$Name' returned resultType '$($result['resultType'])'; PSMcpClient supports only 'complete' results.") } $isError = $result -is [System.Collections.IDictionary] -and $result['isError'] -eq $true $content = if ($Raw) { $result } else { ConvertFrom-McpContent -Result $result } if ($isError -and $ThrowOnError) { $flattened = if ($Raw) { ConvertFrom-McpContent -Result $result } else { $content } $text = if ($flattened -is [string]) { $flattened } elseif ($null -ne $flattened) { ConvertTo-Json -InputObject $flattened -Compress -Depth 20 } else { '(no content)' } throw (New-McpError -ErrorId 'McpToolError' -Category InvalidResult -TargetObject $result ` -Message "Tool '$Name' on server '$Server' reported an error: $text") } $content } } |