Enable .NET SDK code analyzers (#41)

This commit is contained in:
Stephen Toub 2025-03-08 11:18:09 -05:00 • committed by GitHub
commit 587e05f057
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 301 additions and 151 deletions

View file

@ -1,8 +1,8 @@
namespace McpDotNet.Client;
using McpDotNet.Protocol.Messages;
using McpDotNet.Protocol.Messages;
using McpDotNet.Protocol.Types;
namespace McpDotNet.Client;
/// <summary>
/// Represents an instance of the MCP client connecting to a specific server.
/// Use PingAsync, ListToolsAsync and CallToolAsync instead of SendRequestAsync for common operations.

View file

@ -55,7 +55,7 @@ internal class McpClient : McpJsonRpcEndpoint, IMcpClient
throw new McpClientException("Sampling handler not configured");
}
return await SamplingHandler(request, CancellationTokenSource?.Token ?? CancellationToken.None);
return await SamplingHandler(request, CancellationTokenSource?.Token ?? CancellationToken.None).ConfigureAwait(false);
});
}
if (options.Capabilities?.Roots != null)
@ -69,7 +69,7 @@ internal class McpClient : McpJsonRpcEndpoint, IMcpClient
_logger.RootsHandlerNotConfigured(EndpointName);
throw new McpClientException("Roots handler not configured");
}
return await RootsHandler(request, CancellationTokenSource?.Token ?? CancellationToken.None);
return await RootsHandler(request, CancellationTokenSource?.Token ?? CancellationToken.None).ConfigureAwait(false);
});
}
}

View file

@ -10,6 +10,13 @@ public class McpClientException : Exception
/// </summary>
public int? ErrorCode { get; }
/// <summary>
/// Initializes a new instance of the <see cref="McpClientException"/> class.
/// </summary>
public McpClientException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="McpClientException"/> class with a specified error message.
/// </summary>

View file

@ -81,7 +81,7 @@ public class McpClientFactory
var transport = _transportFactoryMethod(config);
var client = _clientFactoryMethod(transport, config, _clientOptions);
await client.ConnectAsync(cancellationToken);
await client.ConnectAsync(cancellationToken).ConfigureAwait(false);
_logger.ClientCreated(endpointName);
@ -97,29 +97,36 @@ public class McpClientFactory
var options = string.Join(", ", config.TransportOptions?.Select(kv => $"{kv.Key}={kv.Value}") ?? []);
_logger.CreatingTransport(endpointName, config.TransportType, options);
return config.TransportType.ToLowerInvariant() switch
if (string.Equals(config.TransportType, TransportTypes.StdIo, StringComparison.OrdinalIgnoreCase))
{
TransportTypes.StdIo => new StdioClientTransport(new StdioClientTransportOptions
return new StdioClientTransport(new StdioClientTransportOptions
{
Command = GetCommand(config),
Arguments = config.TransportOptions?.GetValueOrDefault("arguments")?.Split(' '),
WorkingDirectory = config.TransportOptions?.GetValueOrDefault("workingDirectory"),
EnvironmentVariables = config.TransportOptions?
.Where(kv => kv.Key.StartsWith("env:"))
.Where(kv => kv.Key.StartsWith("env:", StringComparison.Ordinal))
.ToDictionary(kv => kv.Key.Substring(4), kv => kv.Value)
}, config, _loggerFactory),
TransportTypes.Sse or "http" => new SseClientTransport(
}, config, _loggerFactory);
}
if (string.Equals(config.TransportType, TransportTypes.Sse, StringComparison.OrdinalIgnoreCase) ||
string.Equals(config.TransportType, "http", StringComparison.OrdinalIgnoreCase))
{
return new SseClientTransport(
new SseClientTransportOptions
{
ConnectionTimeout = TimeSpan.FromSeconds(ParseOrDefault(config.TransportOptions, "connectionTimeout", 30)),
MaxReconnectAttempts = ParseOrDefault(config.TransportOptions, "maxReconnectAttempts", 3),
ReconnectDelay = TimeSpan.FromSeconds(ParseOrDefault(config.TransportOptions, "reconnectDelay", 5)),
AdditionalHeaders = config.TransportOptions?
.Where(kv => kv.Key.StartsWith("header."))
.Where(kv => kv.Key.StartsWith("header.", StringComparison.Ordinal))
.ToDictionary(kv => kv.Key.Substring(7), kv => kv.Value)
}, config, _loggerFactory),
_ => throw new ArgumentException($"Unsupported transport type '{config.TransportType}'.", nameof(config))
};
}, config, _loggerFactory);
}
throw new ArgumentException($"Unsupported transport type '{config.TransportType}'.", nameof(config));
}
private static int ParseOrDefault(Dictionary<string, string>? options, string key, int defaultValue)