From b91b8d41b2bafa333226056dc427de0cf7bae60f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 Aug 2025 12:33:24 +0000 Subject: [PATCH 1/4] Initial plan From 68133fd987e5f71eb858ed4ad98e1fd8c67f642b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 Aug 2025 12:49:09 +0000 Subject: [PATCH 2/4] Add IEnumerable support to JsonSerializerContext Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com> --- .../McpJsonUtilities.cs | 1 + .../McpJsonUtilitiesTests.cs | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/ModelContextProtocol.Core/McpJsonUtilities.cs b/src/ModelContextProtocol.Core/McpJsonUtilities.cs index 21e2468d9..8bc9e21b0 100644 --- a/src/ModelContextProtocol.Core/McpJsonUtilities.cs +++ b/src/ModelContextProtocol.Core/McpJsonUtilities.cs @@ -146,6 +146,7 @@ internal static bool IsValidMcpToolSchema(JsonElement element) [JsonSerializable(typeof(AudioContentBlock))] [JsonSerializable(typeof(EmbeddedResourceBlock))] [JsonSerializable(typeof(ResourceLinkBlock))] + [JsonSerializable(typeof(IEnumerable))] [JsonSerializable(typeof(PromptReference))] [JsonSerializable(typeof(ResourceTemplateReference))] [JsonSerializable(typeof(BlobResourceContents))] diff --git a/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs b/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs index e0af61eed..02ea2d2c6 100644 --- a/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs +++ b/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs @@ -1,6 +1,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; +using ModelContextProtocol.Protocol; namespace ModelContextProtocol.Tests; @@ -43,6 +44,37 @@ public static void DefaultOptions_UnknownEnumHandling() } } + [Fact] + public static void DefaultOptions_CanSerializeIEnumerableOfContentBlock() + { + var options = McpJsonUtilities.DefaultOptions; + + // Create an IEnumerable with different content types + IEnumerable contentBlocks = new List + { + new TextContentBlock { Text = "Hello World" }, + new TextContentBlock { Text = "Test message" } + }; + + // Should not throw NotSupportedException + string json = JsonSerializer.Serialize(contentBlocks, options); + + Assert.NotNull(json); + Assert.Contains("Hello World", json); + Assert.Contains("Test message", json); + Assert.Contains("\"type\":\"text\"", json); + + // Should also be able to deserialize back + var deserialized = JsonSerializer.Deserialize(json, options); + Assert.NotNull(deserialized); + Assert.Equal(2, deserialized.Length); + Assert.All(deserialized, cb => Assert.Equal("text", cb.Type)); + + var textBlocks = deserialized.Cast().ToArray(); + Assert.Equal("Hello World", textBlocks[0].Text); + Assert.Equal("Test message", textBlocks[1].Text); + } + public enum EnumWithoutAnnotation { A = 1, B = 2, C = 3 } [JsonConverter(typeof(JsonStringEnumConverter))] From 09f2f52a8ac435d157edf521912990a66ef36efc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:32:52 +0000 Subject: [PATCH 3/4] Add ContentBlock[] to JsonSerializerContext for AOT compatibility Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- src/ModelContextProtocol.Core/McpJsonUtilities.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ModelContextProtocol.Core/McpJsonUtilities.cs b/src/ModelContextProtocol.Core/McpJsonUtilities.cs index 8bc9e21b0..60470ea53 100644 --- a/src/ModelContextProtocol.Core/McpJsonUtilities.cs +++ b/src/ModelContextProtocol.Core/McpJsonUtilities.cs @@ -141,6 +141,7 @@ internal static bool IsValidMcpToolSchema(JsonElement element) // MCP Content [JsonSerializable(typeof(ContentBlock))] + [JsonSerializable(typeof(ContentBlock[]))] [JsonSerializable(typeof(TextContentBlock))] [JsonSerializable(typeof(ImageContentBlock))] [JsonSerializable(typeof(AudioContentBlock))] From dd42d166f0ed0f2c19d3b523906f0f7b11bba601 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:44:52 +0000 Subject: [PATCH 4/4] Remove ContentBlock[] from JsonSerializerContext and fix test to use IEnumerable consistently Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> --- src/ModelContextProtocol.Core/McpJsonUtilities.cs | 1 - .../ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ModelContextProtocol.Core/McpJsonUtilities.cs b/src/ModelContextProtocol.Core/McpJsonUtilities.cs index 60470ea53..8bc9e21b0 100644 --- a/src/ModelContextProtocol.Core/McpJsonUtilities.cs +++ b/src/ModelContextProtocol.Core/McpJsonUtilities.cs @@ -141,7 +141,6 @@ internal static bool IsValidMcpToolSchema(JsonElement element) // MCP Content [JsonSerializable(typeof(ContentBlock))] - [JsonSerializable(typeof(ContentBlock[]))] [JsonSerializable(typeof(TextContentBlock))] [JsonSerializable(typeof(ImageContentBlock))] [JsonSerializable(typeof(AudioContentBlock))] diff --git a/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs b/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs index 02ea2d2c6..cc55746fe 100644 --- a/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs +++ b/tests/ModelContextProtocol.Tests/McpJsonUtilitiesTests.cs @@ -65,12 +65,13 @@ public static void DefaultOptions_CanSerializeIEnumerableOfContentBlock() Assert.Contains("\"type\":\"text\"", json); // Should also be able to deserialize back - var deserialized = JsonSerializer.Deserialize(json, options); + var deserialized = JsonSerializer.Deserialize>(json, options); Assert.NotNull(deserialized); - Assert.Equal(2, deserialized.Length); - Assert.All(deserialized, cb => Assert.Equal("text", cb.Type)); + var deserializedList = deserialized.ToList(); + Assert.Equal(2, deserializedList.Count); + Assert.All(deserializedList, cb => Assert.Equal("text", cb.Type)); - var textBlocks = deserialized.Cast().ToArray(); + var textBlocks = deserializedList.Cast().ToArray(); Assert.Equal("Hello World", textBlocks[0].Text); Assert.Equal("Test message", textBlocks[1].Text); }