From fc571e2763f7a2b8e8a7884206e3e3965c5b80a0 Mon Sep 17 00:00:00 2001 From: PederHP Date: Mon, 1 Sep 2025 17:36:04 +0200 Subject: [PATCH 1/3] Fix structured output backwards compatibility for string literals --- .../Server/AIFunctionMcpServerTool.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs index 664ede5ab..0d6cae3fe 100644 --- a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs +++ b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs @@ -257,10 +257,13 @@ public override async ValueTask InvokeAsync( Content = [], StructuredContent = structuredContent, }, - + string text => new() { - Content = [new TextContentBlock { Text = text }], + // If there is structuredOutput we must stringify it, as the MCP specification requires Content to be for backwards compatibility + // but otherwise not differ + Content = [new TextContentBlock { Text = structuredContent == null ? text : + JsonSerializer.Serialize(result, AIFunction.JsonSerializerOptions.GetTypeInfo(typeof(object)))}], StructuredContent = structuredContent, }, From b9468e2ddd9e3a685ca258e76e562a6544aa70f8 Mon Sep 17 00:00:00 2001 From: PederHP Date: Mon, 1 Sep 2025 21:18:30 +0200 Subject: [PATCH 2/3] Serialize structured content not result --- src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs index 0d6cae3fe..cb88e6377 100644 --- a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs +++ b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs @@ -263,7 +263,7 @@ public override async ValueTask InvokeAsync( // If there is structuredOutput we must stringify it, as the MCP specification requires Content to be for backwards compatibility // but otherwise not differ Content = [new TextContentBlock { Text = structuredContent == null ? text : - JsonSerializer.Serialize(result, AIFunction.JsonSerializerOptions.GetTypeInfo(typeof(object)))}], + JsonSerializer.Serialize(structuredContent, AIFunction.JsonSerializerOptions.GetTypeInfo(typeof(object)))}], StructuredContent = structuredContent, }, From b015e38795452b0e17ca4ea07cf48c64cc2617c3 Mon Sep 17 00:00:00 2001 From: Peder Holdgaard Pedersen <127606677+PederHP@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:55:58 +0200 Subject: [PATCH 3/3] Update src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs Co-authored-by: Eirik Tsarpalis --- .../Server/AIFunctionMcpServerTool.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs index cb88e6377..2f9286af0 100644 --- a/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs +++ b/src/ModelContextProtocol.Core/Server/AIFunctionMcpServerTool.cs @@ -260,8 +260,8 @@ public override async ValueTask InvokeAsync( string text => new() { - // If there is structuredOutput we must stringify it, as the MCP specification requires Content to be for backwards compatibility - // but otherwise not differ + // If there is structuredOutput we must return that in stringified form, + // as required for backward compatibility by the MCP specification. Content = [new TextContentBlock { Text = structuredContent == null ? text : JsonSerializer.Serialize(structuredContent, AIFunction.JsonSerializerOptions.GetTypeInfo(typeof(object)))}], StructuredContent = structuredContent,