diff --git a/src/ModelContextProtocol/McpServerBuilderExtensions.cs b/src/ModelContextProtocol/McpServerBuilderExtensions.cs
index d925b24f..2d6314ba 100644
--- a/src/ModelContextProtocol/McpServerBuilderExtensions.cs
+++ b/src/ModelContextProtocol/McpServerBuilderExtensions.cs
@@ -53,6 +53,53 @@ public static partial class McpServerBuilderExtensions
return builder;
}
+ /// Adds instances to the service collection backing .
+ /// The tool type.
+ /// The builder instance.
+ /// The target instance from which the tools should be sourced.
+ /// The serializer options governing tool parameter marshalling.
+ /// The builder provided in .
+ /// is .
+ ///
+ ///
+ /// This method discovers all methods (public and non-public) on the specified
+ /// type, where the methods are attributed as , and adds an
+ /// instance for each, using as the associated instance for instance methods.
+ ///
+ ///
+ /// However, if is itself an of ,
+ /// this method will register those tools directly without scanning for methods on .
+ ///
+ ///
+ public static IMcpServerBuilder WithTools<[DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods)] TToolType>(
+ this IMcpServerBuilder builder,
+ TToolType target,
+ JsonSerializerOptions? serializerOptions = null)
+ {
+ Throw.IfNull(builder);
+ Throw.IfNull(target);
+
+ if (target is IEnumerable tools)
+ {
+ return builder.WithTools(tools);
+ }
+
+ foreach (var toolMethod in typeof(TToolType).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
+ {
+ if (toolMethod.GetCustomAttribute() is not null)
+ {
+ builder.Services.AddSingleton(services => McpServerTool.Create(
+ toolMethod,
+ toolMethod.IsStatic ? null : target,
+ new() { Services = services, SerializerOptions = serializerOptions }));
+ }
+ }
+
+ return builder;
+ }
+
/// Adds instances to the service collection backing .
/// The builder instance.
/// The instances to add to the server.
@@ -137,7 +184,7 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnume
///
///
/// Note that this method performs reflection at runtime and may not work in Native AOT scenarios. For
- /// Native AOT compatibility, consider using the generic method instead.
+ /// Native AOT compatibility, consider using the generic method instead.
///
///
[RequiresUnreferencedCode(WithToolsRequiresUnreferencedCodeMessage)]
@@ -193,6 +240,50 @@ where t.GetCustomAttribute() is not null
return builder;
}
+ /// Adds instances to the service collection backing .
+ /// The prompt type.
+ /// The builder instance.
+ /// The target instance from which the prompts should be sourced.
+ /// The serializer options governing prompt parameter marshalling.
+ /// The builder provided in .
+ /// is .
+ ///
+ ///
+ /// This method discovers all methods (public and non-public) on the specified
+ /// type, where the methods are attributed as , and adds an
+ /// instance for each, using as the associated instance for instance methods.
+ ///
+ ///
+ /// However, if is itself an of ,
+ /// this method will register those prompts directly without scanning for methods on .
+ ///
+ ///
+ public static IMcpServerBuilder WithPrompts<[DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods)] TPromptType>(
+ this IMcpServerBuilder builder,
+ TPromptType target,
+ JsonSerializerOptions? serializerOptions = null)
+ {
+ Throw.IfNull(builder);
+ Throw.IfNull(target);
+
+ if (target is IEnumerable prompts)
+ {
+ return builder.WithPrompts(prompts);
+ }
+
+ foreach (var promptMethod in typeof(TPromptType).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
+ {
+ if (promptMethod.GetCustomAttribute() is not null)
+ {
+ builder.Services.AddSingleton(services => McpServerPrompt.Create(promptMethod, target, new() { Services = services, SerializerOptions = serializerOptions }));
+ }
+ }
+
+ return builder;
+ }
+
/// Adds instances to the service collection backing .
/// The builder instance.
/// The instances to add to the server.
@@ -277,7 +368,7 @@ public static IMcpServerBuilder WithPrompts(this IMcpServerBuilder builder, IEnu
///
///
/// Note that this method performs reflection at runtime and may not work in Native AOT scenarios. For
- /// Native AOT compatibility, consider using the generic method instead.
+ /// Native AOT compatibility, consider using the generic method instead.
///
///
[RequiresUnreferencedCode(WithPromptsRequiresUnreferencedCodeMessage)]
@@ -311,7 +402,8 @@ where t.GetCustomAttribute() is not null
/// instance for each. For instance members, an instance will be constructed for each invocation of the resource.
///
public static IMcpServerBuilder WithResources<[DynamicallyAccessedMembers(
- DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
DynamicallyAccessedMemberTypes.PublicConstructors)] TResourceType>(
this IMcpServerBuilder builder)
{
@@ -330,6 +422,48 @@ where t.GetCustomAttribute() is not null
return builder;
}
+ /// Adds instances to the service collection backing .
+ /// The resource type.
+ /// The builder instance.
+ /// The target instance from which the prompts should be sourced.
+ /// The builder provided in .
+ /// is .
+ ///
+ ///
+ /// This method discovers all methods (public and non-public) on the specified
+ /// type, where the methods are attributed as , and adds an
+ /// instance for each, using as the associated instance for instance methods.
+ ///
+ ///
+ /// However, if is itself an of ,
+ /// this method will register those resources directly without scanning for methods on .
+ ///
+ ///
+ public static IMcpServerBuilder WithResources<[DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods)] TResourceType>(
+ this IMcpServerBuilder builder,
+ TResourceType target)
+ {
+ Throw.IfNull(builder);
+ Throw.IfNull(target);
+
+ if (target is IEnumerable resources)
+ {
+ return builder.WithResources(resources);
+ }
+
+ foreach (var resourceTemplateMethod in typeof(TResourceType).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance))
+ {
+ if (resourceTemplateMethod.GetCustomAttribute() is not null)
+ {
+ builder.Services.AddSingleton(services => McpServerResource.Create(resourceTemplateMethod, target, new() { Services = services }));
+ }
+ }
+
+ return builder;
+ }
+
/// Adds instances to the service collection backing .
/// The builder instance.
/// The instances to add to the server.
@@ -412,7 +546,7 @@ public static IMcpServerBuilder WithResources(this IMcpServerBuilder builder, IE
///
///
/// Note that this method performs reflection at runtime and may not work in Native AOT scenarios. For
- /// Native AOT compatibility, consider using the generic method instead.
+ /// Native AOT compatibility, consider using the generic method instead.
///
///
[RequiresUnreferencedCode(WithResourcesRequiresUnreferencedCodeMessage)]
diff --git a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsPromptsTests.cs b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsPromptsTests.cs
index 3fa2ec78..d697b979 100644
--- a/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsPromptsTests.cs
+++ b/tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsPromptsTests.cs
@@ -4,7 +4,10 @@
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
+using Moq;
+using System.Collections;
using System.ComponentModel;
+using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Channels;
@@ -217,13 +220,63 @@ public void WithPrompts_InvalidArgs_Throws()
Assert.Throws("prompts", () => builder.WithPrompts((IEnumerable)null!));
Assert.Throws("promptTypes", () => builder.WithPrompts((IEnumerable)null!));
+ Assert.Throws("target", () => builder.WithPrompts