From 96267c2caf040bc4b4f4ac92604a29b6dbbe3397 Mon Sep 17 00:00:00 2001 From: goutamadwant Date: Sat, 27 Jun 2026 23:42:43 -0700 Subject: [PATCH] Apply default tool annotations from attributes --- .../Server/AIFunctionMcpServerTool.cs | 25 ++++--------------- .../Client/McpClientTests.cs | 6 ++--- .../McpServerBuilderExtensionsToolsTests.cs | 8 +++--- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs index 82b6ceb9d..54d6f740a 100644 --- a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs +++ b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs @@ -167,25 +167,10 @@ private static McpServerToolCreateOptions DeriveOptions(MethodInfo method, McpSe newOptions.Name ??= toolAttr.Name; newOptions.Title ??= toolAttr.Title; - if (toolAttr._destructive is bool destructive) - { - newOptions.Destructive ??= destructive; - } - - if (toolAttr._idempotent is bool idempotent) - { - newOptions.Idempotent ??= idempotent; - } - - if (toolAttr._openWorld is bool openWorld) - { - newOptions.OpenWorld ??= openWorld; - } - - if (toolAttr._readOnly is bool readOnly) - { - newOptions.ReadOnly ??= readOnly; - } + newOptions.Destructive ??= toolAttr.Destructive; + newOptions.Idempotent ??= toolAttr.Idempotent; + newOptions.OpenWorld ??= toolAttr.OpenWorld; + newOptions.ReadOnly ??= toolAttr.ReadOnly; if (newOptions.Icons is null && toolAttr.IconSource is { Length: > 0 } iconSource) { @@ -805,4 +790,4 @@ private static bool IsPrimitiveHeaderType(Type type) type == typeof(uint) || type == typeof(long); } -} \ No newline at end of file +} diff --git a/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs b/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs index 4dda7bc38..9e9b9a5e7 100644 --- a/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs +++ b/tests/ModelContextProtocol.Tests/Client/McpClientTests.cs @@ -367,15 +367,15 @@ public async Task ListToolsAsync_AllToolsReturned() var valuesSetViaAttr = tools.Single(t => t.Name == "ValuesSetViaAttr"); Assert.Null(valuesSetViaAttr.ProtocolTool.Annotations?.Title); - Assert.Null(valuesSetViaAttr.ProtocolTool.Annotations?.ReadOnlyHint); - Assert.Null(valuesSetViaAttr.ProtocolTool.Annotations?.IdempotentHint); + Assert.False(valuesSetViaAttr.ProtocolTool.Annotations?.ReadOnlyHint); + Assert.False(valuesSetViaAttr.ProtocolTool.Annotations?.IdempotentHint); Assert.False(valuesSetViaAttr.ProtocolTool.Annotations?.DestructiveHint); Assert.True(valuesSetViaAttr.ProtocolTool.Annotations?.OpenWorldHint); var valuesSetViaOptions = tools.Single(t => t.Name == "ValuesSetViaOptions"); Assert.Null(valuesSetViaOptions.ProtocolTool.Annotations?.Title); Assert.True(valuesSetViaOptions.ProtocolTool.Annotations?.ReadOnlyHint); - Assert.Null(valuesSetViaOptions.ProtocolTool.Annotations?.IdempotentHint); + Assert.False(valuesSetViaOptions.ProtocolTool.Annotations?.IdempotentHint); Assert.True(valuesSetViaOptions.ProtocolTool.Annotations?.DestructiveHint); Assert.False(valuesSetViaOptions.ProtocolTool.Annotations?.OpenWorldHint); } diff --git a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs index 5359ec73c..dadc23c9f 100644 --- a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs +++ b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs @@ -698,10 +698,10 @@ public void Create_ExtractsToolAnnotations_SomeSet() var annotations = tool.ProtocolTool.Annotations; Assert.NotNull(annotations); Assert.Null(annotations.Title); - Assert.Null(annotations.DestructiveHint); + Assert.True(annotations.DestructiveHint); Assert.False(annotations.IdempotentHint); - Assert.Null(annotations.OpenWorldHint); - Assert.Null(annotations.ReadOnlyHint); + Assert.True(annotations.OpenWorldHint); + Assert.False(annotations.ReadOnlyHint); } [Fact] @@ -970,4 +970,4 @@ public class ComplexObject [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(CallToolResult))] partial class BuilderToolsJsonContext : JsonSerializerContext; -} \ No newline at end of file +}