From b946cc19f4ce307f399f7e72601362c64eb89572 Mon Sep 17 00:00:00 2001 From: 1357310795 <1357310795@qq.com> Date: Fri, 25 Apr 2025 12:14:56 +0800 Subject: [PATCH 1/3] Add SchemaCreateOptions in McpServerToolCreateOptions --- .../Server/AIFunctionMcpServerTool.cs | 1 + .../Server/McpServerToolCreateOptions.cs | 10 +++++++++ .../Server/McpServerToolTests.cs | 21 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/ModelContextProtocol/Server/AIFunctionMcpServerTool.cs b/src/ModelContextProtocol/Server/AIFunctionMcpServerTool.cs index 562a8476c..658075c41 100644 --- a/src/ModelContextProtocol/Server/AIFunctionMcpServerTool.cs +++ b/src/ModelContextProtocol/Server/AIFunctionMcpServerTool.cs @@ -151,6 +151,7 @@ private static AIFunctionFactoryOptions CreateAIFunctionFactoryOptions( return null; } }, + JsonSchemaCreateOptions = options?.SchemaCreateOptions, }; /// Creates an that wraps the specified . diff --git a/src/ModelContextProtocol/Server/McpServerToolCreateOptions.cs b/src/ModelContextProtocol/Server/McpServerToolCreateOptions.cs index ed7a49f10..14fcb7cd7 100644 --- a/src/ModelContextProtocol/Server/McpServerToolCreateOptions.cs +++ b/src/ModelContextProtocol/Server/McpServerToolCreateOptions.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.AI; using ModelContextProtocol.Utils.Json; using System.ComponentModel; using System.Text.Json; @@ -132,6 +133,14 @@ public sealed class McpServerToolCreateOptions /// public JsonSerializerOptions? SerializerOptions { get; set; } + /// + /// Gets or sets the JSON schema options when creating from a method. + /// + /// + /// Defaults to if left unspecified. + /// + public AIJsonSchemaCreateOptions? SchemaCreateOptions { get; set; } + /// /// Creates a shallow clone of the current instance. /// @@ -147,5 +156,6 @@ internal McpServerToolCreateOptions Clone() => OpenWorld = OpenWorld, ReadOnly = ReadOnly, SerializerOptions = SerializerOptions, + SchemaCreateOptions = SchemaCreateOptions, }; } diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs index 4c42ba242..28bc62cf5 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs @@ -355,6 +355,27 @@ public async Task CanReturnCallToolResponse() Assert.Equal("image", result.Content[1].Type); } + [Fact] + public async Task SupportsSchemaCreateOptions() + { + AIJsonSchemaCreateOptions schemaCreateOptions = new () + { + RequireAllProperties = false + }; + + McpServerTool tool = McpServerTool.Create((int num1, int num2 = 42) => + { + return num2.ToString(); + }, new() { SchemaCreateOptions = schemaCreateOptions }); + + Assert.Collection( + tool.ProtocolTool.InputSchema.GetProperty("required").EnumerateArray().Select(x => x.GetString()), + [ + x => Assert.Equal("num1", x), + ] + ); + } + private sealed class MyService; private class DisposableToolType : IDisposable From 4fb1c69b412d07c7d61e55017209b3ffa2564655 Mon Sep 17 00:00:00 2001 From: 1357310795 <1357310795@qq.com> Date: Fri, 25 Apr 2025 21:03:42 +0800 Subject: [PATCH 2/3] Use TransformSchemaNode for SchemaCreateOptions testing --- .../Server/McpServerToolTests.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs index 28bc62cf5..efd5028b2 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerToolTests.cs @@ -360,19 +360,21 @@ public async Task SupportsSchemaCreateOptions() { AIJsonSchemaCreateOptions schemaCreateOptions = new () { - RequireAllProperties = false + TransformSchemaNode = (context, node) => + { + node["text"] = "1234"; + return node; + }, }; - McpServerTool tool = McpServerTool.Create((int num1, int num2 = 42) => + McpServerTool tool = McpServerTool.Create((int num, string str) => { - return num2.ToString(); + return "42"; }, new() { SchemaCreateOptions = schemaCreateOptions }); - Assert.Collection( - tool.ProtocolTool.InputSchema.GetProperty("required").EnumerateArray().Select(x => x.GetString()), - [ - x => Assert.Equal("num1", x), - ] + Assert.All( + tool.ProtocolTool.InputSchema.GetProperty("properties").EnumerateObject(), + x => Assert.True(x.Value.TryGetProperty("text", out JsonElement value) && value.ToString() == "1234") ); } From a4edcb6e2ea4b2d6e8b950ec2b3d5bde0ee832d9 Mon Sep 17 00:00:00 2001 From: 1357310795 <1357310795@qq.com> Date: Fri, 25 Apr 2025 21:19:26 +0800 Subject: [PATCH 3/3] Add SchemaCreateOptions in McpServerPromptCreateOptions also --- .../Server/AIFunctionMcpServerPrompt.cs | 1 + .../Server/McpServerPromptCreateOptions.cs | 10 +++++++ .../Server/McpServerPromptTests.cs | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/src/ModelContextProtocol/Server/AIFunctionMcpServerPrompt.cs b/src/ModelContextProtocol/Server/AIFunctionMcpServerPrompt.cs index b1671b906..404038035 100644 --- a/src/ModelContextProtocol/Server/AIFunctionMcpServerPrompt.cs +++ b/src/ModelContextProtocol/Server/AIFunctionMcpServerPrompt.cs @@ -130,6 +130,7 @@ private static AIFunctionFactoryOptions CreateAIFunctionFactoryOptions( return null; } }, + JsonSchemaCreateOptions = options?.SchemaCreateOptions, }; /// Creates an that wraps the specified . diff --git a/src/ModelContextProtocol/Server/McpServerPromptCreateOptions.cs b/src/ModelContextProtocol/Server/McpServerPromptCreateOptions.cs index 40ef66211..17f6dfd9d 100644 --- a/src/ModelContextProtocol/Server/McpServerPromptCreateOptions.cs +++ b/src/ModelContextProtocol/Server/McpServerPromptCreateOptions.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.AI; using ModelContextProtocol.Utils.Json; using System.ComponentModel; using System.Text.Json; @@ -55,6 +56,14 @@ public sealed class McpServerPromptCreateOptions /// public JsonSerializerOptions? SerializerOptions { get; set; } + /// + /// Gets or sets the JSON schema options when creating from a method. + /// + /// + /// Defaults to if left unspecified. + /// + public AIJsonSchemaCreateOptions? SchemaCreateOptions { get; set; } + /// /// Creates a shallow clone of the current instance. /// @@ -65,5 +74,6 @@ internal McpServerPromptCreateOptions Clone() => Name = Name, Description = Description, SerializerOptions = SerializerOptions, + SchemaCreateOptions = SchemaCreateOptions, }; } diff --git a/tests/ModelContextProtocol.Tests/Server/McpServerPromptTests.cs b/tests/ModelContextProtocol.Tests/Server/McpServerPromptTests.cs index 2e251d033..3804cfbf8 100644 --- a/tests/ModelContextProtocol.Tests/Server/McpServerPromptTests.cs +++ b/tests/ModelContextProtocol.Tests/Server/McpServerPromptTests.cs @@ -3,7 +3,9 @@ using ModelContextProtocol.Protocol.Types; using ModelContextProtocol.Server; using Moq; +using System.ComponentModel; using System.Reflection; +using System.Text.Json; namespace ModelContextProtocol.Tests.Server; @@ -316,6 +318,30 @@ await Assert.ThrowsAsync(async () => await prompt.Get TestContext.Current.CancellationToken)); } + [Fact] + public async Task SupportsSchemaCreateOptions() + { + AIJsonSchemaCreateOptions schemaCreateOptions = new() + { + TransformSchemaNode = (context, node) => + { + node["description"] = "1234"; + return node; + } + }; + + McpServerPrompt prompt = McpServerPrompt.Create(([Description("argument1")] int num, [Description("argument2")] string str) => + { + return new ChatMessage(ChatRole.User, "Hello"); + }, new() { SchemaCreateOptions = schemaCreateOptions }); + + Assert.NotNull(prompt.ProtocolPrompt.Arguments); + Assert.All( + prompt.ProtocolPrompt.Arguments, + x => Assert.Equal("1234", x.Description) + ); + } + private sealed class MyService; private class DisposablePromptType : IDisposable