diff --git a/src/ModelContextProtocol/Client/McpClientExtensions.cs b/src/ModelContextProtocol/Client/McpClientExtensions.cs index f11f0295..1a5c57cc 100644 --- a/src/ModelContextProtocol/Client/McpClientExtensions.cs +++ b/src/ModelContextProtocol/Client/McpClientExtensions.cs @@ -485,7 +485,7 @@ public static Task SetLoggingLevel(this IMcpClient client, LoggingLevel level, C Throw.IfNull(client); return client.SendRequestAsync( - CreateRequest("logging/setLevel", new() { ["level"] = level.ToJsonValue() }), + CreateRequest("logging/setLevel", new() { ["level"] = level }), cancellationToken); } @@ -514,22 +514,6 @@ private static JsonRpcRequest CreateRequest(string method, Dictionary "debug", - LoggingLevel.Info => "info", - LoggingLevel.Notice => "notice", - LoggingLevel.Warning => "warning", - LoggingLevel.Error => "error", - LoggingLevel.Critical => "critical", - LoggingLevel.Alert => "alert", - LoggingLevel.Emergency => "emergency", - _ => throw new ArgumentOutOfRangeException(nameof(level)) - }; - } - /// Provides an AI function that calls a tool through . private sealed class McpAIFunction(IMcpClient client, Tool tool) : AIFunction { diff --git a/src/ModelContextProtocol/Protocol/Types/ContextInclusion.cs b/src/ModelContextProtocol/Protocol/Types/ContextInclusion.cs index 50fbc3de..a513e4d7 100644 --- a/src/ModelContextProtocol/Protocol/Types/ContextInclusion.cs +++ b/src/ModelContextProtocol/Protocol/Types/ContextInclusion.cs @@ -1,23 +1,29 @@ -namespace ModelContextProtocol.Protocol.Types; +using System.Text.Json.Serialization; + +namespace ModelContextProtocol.Protocol.Types; /// /// A request to include context from one or more MCP servers (including the caller), to be attached to the prompt. /// See the schema for details /// +[JsonConverter(typeof(JsonStringEnumConverter))] public enum ContextInclusion { /// /// No context should be included. /// + [JsonStringEnumMemberName("none")] None, /// /// Include context from the server that sent the request. /// + [JsonStringEnumMemberName("thisServer")] ThisServer, /// /// Include context from all servers that the client is connected to. /// + [JsonStringEnumMemberName("allServers")] AllServers } diff --git a/src/ModelContextProtocol/Protocol/Types/LoggingLevel.cs b/src/ModelContextProtocol/Protocol/Types/LoggingLevel.cs index 4e603e69..df8c4c75 100644 --- a/src/ModelContextProtocol/Protocol/Types/LoggingLevel.cs +++ b/src/ModelContextProtocol/Protocol/Types/LoggingLevel.cs @@ -7,37 +7,38 @@ namespace ModelContextProtocol.Protocol.Types; /// These map to syslog message severities, as specified in RFC-5424: /// https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1 /// +[JsonConverter(typeof(JsonStringEnumConverter))] public enum LoggingLevel { /// Detailed debug information, typically only valuable to developers. - [JsonPropertyName("debug")] + [JsonStringEnumMemberName("debug")] Debug, /// Normal operational messages that require no action. - [JsonPropertyName("info")] + [JsonStringEnumMemberName("info")] Info, /// Normal but significant events that might deserve attention. - [JsonPropertyName("notice")] + [JsonStringEnumMemberName("notice")] Notice, /// Warning conditions that don't represent an error but indicate potential issues. - [JsonPropertyName("warning")] + [JsonStringEnumMemberName("warning")] Warning, /// Error conditions that should be addressed but don't require immediate action. - [JsonPropertyName("error")] + [JsonStringEnumMemberName("error")] Error, /// Critical conditions that require immediate attention. - [JsonPropertyName("critical")] + [JsonStringEnumMemberName("critical")] Critical, /// Action must be taken immediately to address the condition. - [JsonPropertyName("alert")] + [JsonStringEnumMemberName("alert")] Alert, /// System is unusable and requires immediate attention. - [JsonPropertyName("emergency")] + [JsonStringEnumMemberName("emergency")] Emergency } \ No newline at end of file diff --git a/src/ModelContextProtocol/Protocol/Types/Role.cs b/src/ModelContextProtocol/Protocol/Types/Role.cs index a8266a05..91c9899a 100644 --- a/src/ModelContextProtocol/Protocol/Types/Role.cs +++ b/src/ModelContextProtocol/Protocol/Types/Role.cs @@ -6,17 +6,18 @@ namespace ModelContextProtocol.Protocol.Types; /// Represents the type of role in the conversation. /// See the schema for details /// +[JsonConverter(typeof(JsonStringEnumConverter))] public enum Role { /// /// Corresponds to the user in the conversation. /// - [JsonPropertyName("user")] + [JsonStringEnumMemberName("user")] User, /// /// Corresponds to the AI in the conversation. /// - [JsonPropertyName("assistant")] + [JsonStringEnumMemberName("assistant")] Assistant } \ No newline at end of file diff --git a/tests/ModelContextProtocol.Tests/Protocol/ProtocolTypeTests.cs b/tests/ModelContextProtocol.Tests/Protocol/ProtocolTypeTests.cs index a5c4c6a3..81264336 100644 --- a/tests/ModelContextProtocol.Tests/Protocol/ProtocolTypeTests.cs +++ b/tests/ModelContextProtocol.Tests/Protocol/ProtocolTypeTests.cs @@ -1,4 +1,5 @@ using ModelContextProtocol.Protocol.Types; +using ModelContextProtocol.Utils.Json; using System.Text.Json; namespace ModelContextProtocol.Tests.Protocol; @@ -51,4 +52,41 @@ public static void ToolInputSchema_AcceptsValidSchemaDocuments(string validSchem Assert.True(JsonElement.DeepEquals(document.RootElement, tool.InputSchema)); } + + [Theory] + [InlineData(Role.User, "\"user\"")] + [InlineData(Role.Assistant, "\"assistant\"")] + public static void SerializeRole_ShouldBeCamelCased(Role role, string expectedValue) + { + var actualValue = JsonSerializer.Serialize(role); + + Assert.Equal(expectedValue, actualValue); + } + + [Theory] + [InlineData(LoggingLevel.Debug, "\"debug\"")] + [InlineData(LoggingLevel.Info, "\"info\"")] + [InlineData(LoggingLevel.Notice, "\"notice\"")] + [InlineData(LoggingLevel.Warning, "\"warning\"")] + [InlineData(LoggingLevel.Error, "\"error\"")] + [InlineData(LoggingLevel.Critical, "\"critical\"")] + [InlineData(LoggingLevel.Alert, "\"alert\"")] + [InlineData(LoggingLevel.Emergency, "\"emergency\"")] + public static void SerializeLoggingLevel_ShouldBeCamelCased(LoggingLevel level, string expectedValue) + { + var actualValue = JsonSerializer.Serialize(level); + + Assert.Equal(expectedValue, actualValue); + } + + [Theory] + [InlineData(ContextInclusion.None, "\"none\"")] + [InlineData(ContextInclusion.ThisServer, "\"thisServer\"")] + [InlineData(ContextInclusion.AllServers, "\"allServers\"")] + public static void ContextInclusion_ShouldBeCamelCased(ContextInclusion level, string expectedValue) + { + var actualValue = JsonSerializer.Serialize(level); + + Assert.Equal(expectedValue, actualValue); + } }