diff --git a/src/ModelContextProtocol/McpServerBuilderExtensions.cs b/src/ModelContextProtocol/McpServerBuilderExtensions.cs
index da63dc31d..41bc4d60d 100644
--- a/src/ModelContextProtocol/McpServerBuilderExtensions.cs
+++ b/src/ModelContextProtocol/McpServerBuilderExtensions.cs
@@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.Json;
+using Microsoft.Extensions.AI;
namespace Microsoft.Extensions.DependencyInjection;
@@ -120,11 +121,27 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnume
return builder;
}
-
+
+ /// Adds instances to the service collection backing .
+ /// The builder instance.
+ /// Types with -attributed methods to add as tools to the server.
+ /// The serializer options governing tool parameter marshalling.
+ /// The builder provided in .
+ /// or is .
+ ///
+ /// This method discovers all instance and static methods (public and non-public) on the specified
+ /// types, where the methods are attributed as , and adds an
+ /// instance for each. For instance methods, an instance is constructed for each invocation of the tool.
+ ///
+ [RequiresUnreferencedCode(WithToolsRequiresUnreferencedCodeMessage)]
+ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnumerable toolTypes, JsonSerializerOptions? serializerOptions = null) =>
+ builder.WithTools(toolTypes, schemaCreateOptions: null, serializerOptions);
+
/// Adds instances to the service collection backing .
/// The builder instance.
/// Types with -attributed methods to add as tools to the server.
/// The serializer options governing tool parameter marshalling.
+ /// The schema creation options governing tool parameter/output schema generation.
/// The builder provided in .
/// or is .
///
@@ -133,7 +150,7 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnume
/// instance for each. For instance methods, an instance is constructed for each invocation of the tool.
///
[RequiresUnreferencedCode(WithToolsRequiresUnreferencedCodeMessage)]
- public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnumerable toolTypes, JsonSerializerOptions? serializerOptions = null)
+ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnumerable toolTypes, AIJsonSchemaCreateOptions? schemaCreateOptions, JsonSerializerOptions? serializerOptions = null)
{
Throw.IfNull(builder);
Throw.IfNull(toolTypes);
@@ -147,8 +164,8 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnume
if (toolMethod.GetCustomAttribute() is not null)
{
builder.Services.AddSingleton((Func)(toolMethod.IsStatic ?
- services => McpServerTool.Create(toolMethod, options: new() { Services = services, SerializerOptions = serializerOptions }) :
- services => McpServerTool.Create(toolMethod, r => CreateTarget(r.Services, toolType), new() { Services = services, SerializerOptions = serializerOptions })));
+ services => McpServerTool.Create(toolMethod, options: new() { Services = services, SerializerOptions = serializerOptions, SchemaCreateOptions = schemaCreateOptions }) :
+ services => McpServerTool.Create(toolMethod, r => CreateTarget(r.Services, toolType), new() { Services = services, SerializerOptions = serializerOptions, SchemaCreateOptions = schemaCreateOptions })));
}
}
}
@@ -157,6 +174,50 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnume
return builder;
}
+ ///
+ /// Adds types marked with the attribute from the given assembly as tools to the server.
+ ///
+ /// The builder instance.
+ /// The serializer options governing tool parameter marshalling.
+ /// The assembly to load the types from. If , the calling assembly is used.
+ /// The schema creation options governing tool parameter/output schema generation.
+ /// The builder provided in .
+ /// is .
+ ///
+ ///
+ /// This method scans the specified assembly (or the calling assembly if none is provided) for classes
+ /// marked with the . It then discovers all methods within those
+ /// classes that are marked with the and registers them as s
+ /// in the 's .
+ ///
+ ///
+ /// The method automatically handles both static and instance methods. For instance methods, a new instance
+ /// of the containing class is constructed for each invocation of the tool.
+ ///
+ ///
+ /// Tools registered through this method can be discovered by clients using the list_tools request
+ /// and invoked using the call_tool request.
+ ///
+ ///
+ /// Note that this method performs reflection at runtime and might not work in Native AOT scenarios. For
+ /// Native AOT compatibility, consider using the generic method instead.
+ ///
+ ///
+ [RequiresUnreferencedCode(WithToolsRequiresUnreferencedCodeMessage)]
+ public static IMcpServerBuilder WithToolsFromAssembly(this IMcpServerBuilder builder, AIJsonSchemaCreateOptions? schemaCreateOptions, Assembly? toolAssembly = null, JsonSerializerOptions? serializerOptions = null)
+ {
+ Throw.IfNull(builder);
+
+ toolAssembly ??= Assembly.GetCallingAssembly();
+
+ return builder.WithTools(
+ from t in toolAssembly.GetTypes()
+ where t.GetCustomAttribute() is not null
+ select t,
+ schemaCreateOptions,
+ serializerOptions);
+ }
+
///
/// Adds types marked with the attribute from the given assembly as tools to the server.
///
@@ -196,6 +257,7 @@ public static IMcpServerBuilder WithToolsFromAssembly(this IMcpServerBuilder bui
from t in toolAssembly.GetTypes()
where t.GetCustomAttribute() is not null
select t,
+ schemaCreateOptions: null,
serializerOptions);
}
#endregion
diff --git a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs
index 518b70f00..e3896f788 100644
--- a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs
+++ b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsToolsTests.cs
@@ -482,7 +482,7 @@ public void WithTools_InvalidArgs_Throws()
IMcpServerBuilder builder = new ServiceCollection().AddMcpServer();
Assert.Throws("tools", () => builder.WithTools((IEnumerable)null!));
- Assert.Throws("toolTypes", () => builder.WithTools((IEnumerable)null!));
+ Assert.Throws("toolTypes", () => builder.WithTools(toolTypes: (IEnumerable)null!));
Assert.Throws("target", () => builder.WithTools