Update Microsoft.Extensions.AI version & expose JSON configuration on McpServerResourceCreateOptions (#511)

* Update Microsoft.Extensions.AI version

* Update Microsoft.Extensions.AI.OpenAI

* Fix failing tests; add JSON configuration options to McpServerResourceCreateOptions.

* Replace temporary code with `AIFunction.ReturnJsonSchema`

---------

Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
This commit is contained in:
Sven Boemer 2025-06-13 05:50:14 -07:00 • committed by GitHub
commit 28d65470f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 45 additions and 35 deletions

View file

@ -85,30 +85,6 @@ public static partial class McpJsonUtilities
return false; // No type keyword found.
}
internal static JsonElement? GetReturnSchema(this AIFunction function, AIJsonSchemaCreateOptions? schemaCreateOptions)
{
// TODO replace with https://github.com/dotnet/extensions/pull/6447 once merged.
if (function.UnderlyingMethod?.ReturnType is not Type returnType)
{
return null;
}
if (returnType == typeof(void) || returnType == typeof(Task) || returnType == typeof(ValueTask))
{
// Do not report an output schema for void or Task methods.
return null;
}
if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() is Type genericTypeDef &&
(genericTypeDef == typeof(Task<>) || genericTypeDef == typeof(ValueTask<>)))
{
// Extract the real type from Task<T> or ValueTask<T> if applicable.
returnType = returnType.GetGenericArguments()[0];
}
return AIJsonUtilities.CreateJsonSchema(returnType, serializerOptions: function.JsonSerializerOptions, inferenceOptions: schemaCreateOptions);
}
// Keep in sync with CreateDefaultOptions above.
[JsonSourceGenerationOptions(JsonSerializerDefaults.Web,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
@ -157,6 +133,7 @@ public static partial class McpJsonUtilities
[JsonSerializable(typeof(SubscribeRequestParams))]
[JsonSerializable(typeof(UnsubscribeRequestParams))]
[JsonSerializable(typeof(IReadOnlyDictionary<string, object>))]
[JsonSerializable(typeof(PromptMessage[]))]
// Primitive types for use in consuming AIFunctions
[JsonSerializable(typeof(string))]

View file

@ -71,6 +71,7 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
Description = options?.Description,
MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result),
SerializerOptions = options?.SerializerOptions ?? McpJsonUtilities.DefaultOptions,
JsonSchemaCreateOptions = options?.SchemaCreateOptions,
ConfigureParameterBinding = pi =>
{
if (pi.ParameterType == typeof(RequestContext<GetPromptRequestParams>))
@ -151,7 +152,6 @@ internal sealed class AIFunctionMcpServerPrompt : McpServerPrompt
return null;
}
},
JsonSchemaCreateOptions = options?.SchemaCreateOptions,
};
/// <summary>Creates an <see cref="McpServerPrompt"/> that wraps the specified <see cref="AIFunction"/>.</summary>

View file

@ -77,7 +77,8 @@ internal sealed class AIFunctionMcpServerResource : McpServerResource
Name = options?.Name ?? method.GetCustomAttribute<McpServerResourceAttribute>()?.Name,
Description = options?.Description,
MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result),
SerializerOptions = McpJsonUtilities.DefaultOptions,
SerializerOptions = options?.SerializerOptions ?? McpJsonUtilities.DefaultOptions,
JsonSchemaCreateOptions = options?.SchemaCreateOptions,
ConfigureParameterBinding = pi =>
{
if (pi.ParameterType == typeof(RequestContext<ReadResourceRequestParams>))

View file

@ -86,6 +86,7 @@ internal sealed partial class AIFunctionMcpServerTool : McpServerTool
Description = options?.Description,
MarshalResult = static (result, _, cancellationToken) => new ValueTask<object?>(result),
SerializerOptions = options?.SerializerOptions ?? McpJsonUtilities.DefaultOptions,
JsonSchemaCreateOptions = options?.SchemaCreateOptions,
ConfigureParameterBinding = pi =>
{
if (pi.ParameterType == typeof(RequestContext<CallToolRequestParams>))
@ -166,7 +167,6 @@ internal sealed partial class AIFunctionMcpServerTool : McpServerTool
return null;
}
},
JsonSchemaCreateOptions = options?.SchemaCreateOptions,
};
/// <summary>Creates an <see cref="McpServerTool"/> that wraps the specified <see cref="AIFunction"/>.</summary>
@ -366,7 +366,7 @@ internal sealed partial class AIFunctionMcpServerTool : McpServerTool
return null;
}
if (function.GetReturnSchema(toolCreateOptions?.SchemaCreateOptions) is not JsonElement outputSchema)
if (function.ReturnJsonSchema is not JsonElement outputSchema)
{
return null;
}

View file

@ -1,4 +1,6 @@
using Microsoft.Extensions.AI;
using System.ComponentModel;
using System.Text.Json;
namespace ModelContextProtocol.Server;
@ -60,6 +62,22 @@ public sealed class McpServerResourceCreateOptions
/// </summary>
public string? MimeType { get; set; }
/// <summary>
/// Gets or sets the JSON serializer options to use when marshalling data to/from JSON.
/// </summary>
/// <remarks>
/// Defaults to <see cref="McpJsonUtilities.DefaultOptions"/> if left unspecified.
/// </remarks>
public JsonSerializerOptions? SerializerOptions { get; set; }
/// <summary>
/// Gets or sets the JSON schema options when creating <see cref="AIFunction"/> from a method.
/// </summary>
/// <remarks>
/// Defaults to <see cref="AIJsonSchemaCreateOptions.Default"/> if left unspecified.
/// </remarks>
public AIJsonSchemaCreateOptions? SchemaCreateOptions { get; set; }
/// <summary>
/// Creates a shallow clone of the current <see cref="McpServerResourceCreateOptions"/> instance.
/// </summary>
@ -71,5 +89,7 @@ public sealed class McpServerResourceCreateOptions
Name = Name,
Description = Description,
MimeType = MimeType,
SerializerOptions = SerializerOptions,
SchemaCreateOptions = SchemaCreateOptions,
};
}