diff --git a/src/McpAggregator.Core/Services/ConnectionManager.cs b/src/McpAggregator.Core/Services/ConnectionManager.cs index a4d3a0e..8ccb134 100644 --- a/src/McpAggregator.Core/Services/ConnectionManager.cs +++ b/src/McpAggregator.Core/Services/ConnectionManager.cs @@ -113,6 +113,12 @@ public async Task ExecuteWithRetryAsync( client = await GetClientAsync(serverName, ct); return await operation(client, ct); } + catch (Exception ex) when (ex is not OperationCanceledException and not AggregatorException) + { + _logger.LogError(ex, "Non-retryable error executing operation on '{Server}': {ExType}: {ExMessage}", + serverName, ex.GetType().FullName, ex.Message); + throw; + } } private static bool ShouldRetry(Exception ex) diff --git a/src/McpAggregator.Core/Tools/ToolProxyHandler.cs b/src/McpAggregator.Core/Tools/ToolProxyHandler.cs index 0169c03..bff9f9d 100644 --- a/src/McpAggregator.Core/Tools/ToolProxyHandler.cs +++ b/src/McpAggregator.Core/Tools/ToolProxyHandler.cs @@ -24,6 +24,24 @@ public ToolProxyHandler( _logger = logger; } + private void LogCallToolResult(string toolName, string serverName, CallToolResult result) + { + var contentSummary = string.Join(", ", result.Content + .GroupBy(b => b.Type ?? "unknown") + .Select(g => $"{g.Key}:{g.Count()}")); + + _logger.LogDebug( + "Tool '{Tool}' on '{Server}' returned IsError={IsError}, content=[{Content}]", + toolName, serverName, result.IsError, contentSummary); + + if (result.IsError is null) + { + _logger.LogDebug( + "Tool '{Tool}' on '{Server}' has IsError=null (downstream did not set error flag explicitly)", + toolName, serverName); + } + } + public async Task InvokeAsync( string serverName, string toolName, @@ -46,22 +64,33 @@ public async Task InvokeAsync( var result = await _connectionManager.ExecuteWithRetryAsync(serverName, async (client, token) => await client.CallToolAsync(toolName, args, cancellationToken: token), cts.Token); - var textContent = result.Content - .OfType() - .Select(c => c.Text) - .ToList(); + LogCallToolResult(toolName, serverName, result); + + var parts = new List(); + + foreach (var block in result.Content) + { + if (block is TextContentBlock text) + { + parts.Add(text.Text); + } + else + { + parts.Add($"[{block.Type ?? "unknown"} content block]"); + } + } - if (textContent.Count == 0) + if (parts.Count == 0) { if (result.IsError ?? false) { - _logger.LogWarning("Tool '{Tool}' on '{Server}' returned error with no text content", toolName, serverName); + _logger.LogWarning("Tool '{Tool}' on '{Server}' returned error with no content blocks", toolName, serverName); throw new ToolExecutionException(serverName, toolName, "No error details provided"); } - return "Tool completed with no text content."; + return "Tool completed with no content."; } - var response = string.Join("\n", textContent); + var response = string.Join("\n", parts); if (result.IsError ?? false) {