Split configuration of request and message filters (#1308)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
27a3196c7f
commit
d21aa9e5a2
16 changed files with 1288 additions and 1078 deletions
|
|
@ -22,4 +22,9 @@ internal static class Obsoletions
|
|||
public const string LegacyTitledEnumSchema_DiagnosticId = "MCP9001";
|
||||
public const string LegacyTitledEnumSchema_Message = "The EnumSchema and LegacyTitledEnumSchema APIs are deprecated as of specification version 2025-11-25 and will be removed in a future major version. See SEP-1330 for more information.";
|
||||
public const string LegacyTitledEnumSchema_Url = "https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1330";
|
||||
|
||||
public const string MessageAndRequestFilter_DiagnosticId = "MCP9002";
|
||||
public const string MessageAndRequestFilter_Url = "https://github.com/modelcontextprotocol/csharp-sdk/pull/1308";
|
||||
public const string MessageFilter_Message = "Use WithMessageFilters() instead.";
|
||||
public const string RequestFilter_Message = "Use WithRequestFilters() instead.";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private void ConfigureListToolsFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListToolsFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListToolsFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
context.Items[AuthorizationFilterInvokedKey] = true;
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private static void CheckListToolsFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListToolsFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListToolsFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
var result = await next(context, cancellationToken);
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private void ConfigureCallToolFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.CallToolFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.CallToolFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
var authResult = await GetAuthorizationResultAsync(context.User, context.MatchedPrimitive, context.Services, context);
|
||||
if (!authResult.Succeeded)
|
||||
|
|
@ -89,7 +89,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private static void CheckCallToolFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.CallToolFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.CallToolFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
if (HasAuthorizationMetadata(context.MatchedPrimitive)
|
||||
&& !context.Items.ContainsKey(AuthorizationFilterInvokedKey))
|
||||
|
|
@ -103,7 +103,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private void ConfigureListResourcesFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListResourcesFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListResourcesFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
context.Items[AuthorizationFilterInvokedKey] = true;
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private static void CheckListResourcesFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListResourcesFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListResourcesFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
var result = await next(context, cancellationToken);
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private void ConfigureListResourceTemplatesFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListResourceTemplatesFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListResourceTemplatesFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
context.Items[AuthorizationFilterInvokedKey] = true;
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private static void CheckListResourceTemplatesFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListResourceTemplatesFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListResourceTemplatesFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
var result = await next(context, cancellationToken);
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private void ConfigureReadResourceFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ReadResourceFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ReadResourceFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
context.Items[AuthorizationFilterInvokedKey] = true;
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private static void CheckReadResourceFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ReadResourceFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ReadResourceFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
if (HasAuthorizationMetadata(context.MatchedPrimitive)
|
||||
&& !context.Items.ContainsKey(AuthorizationFilterInvokedKey))
|
||||
|
|
@ -193,7 +193,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private void ConfigureListPromptsFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListPromptsFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListPromptsFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
context.Items[AuthorizationFilterInvokedKey] = true;
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private static void CheckListPromptsFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.ListPromptsFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.ListPromptsFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
var result = await next(context, cancellationToken);
|
||||
|
||||
|
|
@ -223,7 +223,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private void ConfigureGetPromptFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.GetPromptFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.GetPromptFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
context.Items[AuthorizationFilterInvokedKey] = true;
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ internal sealed class AuthorizationFilterSetup(IAuthorizationPolicyProvider? pol
|
|||
|
||||
private static void CheckGetPromptFilter(McpServerOptions options)
|
||||
{
|
||||
options.Filters.GetPromptFilters.Add(next => async (context, cancellationToken) =>
|
||||
options.Filters.Request.GetPromptFilters.Add(next => async (context, cancellationToken) =>
|
||||
{
|
||||
if (HasAuthorizationMetadata(context.MatchedPrimitive)
|
||||
&& !context.Items.ContainsKey(AuthorizationFilterInvokedKey))
|
||||
|
|
|
|||
42
src/ModelContextProtocol.Core/Server/McpMessageFilters.cs
Normal file
42
src/ModelContextProtocol.Core/Server/McpMessageFilters.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using ModelContextProtocol.Protocol;
|
||||
|
||||
namespace ModelContextProtocol.Server;
|
||||
|
||||
/// <summary>
|
||||
/// Provides grouped message filter collections.
|
||||
/// </summary>
|
||||
public sealed class McpMessageFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the filters for all incoming JSON-RPC messages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters intercept all incoming JSON-RPC messages before they are processed by the server,
|
||||
/// including requests, notifications, responses, and errors. The filters can perform logging,
|
||||
/// authentication, rate limiting, or other cross-cutting concerns that apply to all message types.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Message filters are applied before request-specific filters. If a message filter does not call
|
||||
/// the next handler in the pipeline, the default handlers will not be executed.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IList<McpMessageFilter> IncomingFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for all outgoing JSON-RPC messages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters intercept all outgoing JSON-RPC messages before they are sent to the client,
|
||||
/// including responses, notifications, and errors. The filters can perform logging,
|
||||
/// redaction, auditing, or other cross-cutting concerns that apply to all message types.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If a message filter does not call the next handler in the pipeline, the message will not be sent.
|
||||
/// Filters may also call the next handler multiple times with different messages to emit additional
|
||||
/// server-to-client messages.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IList<McpMessageFilter> OutgoingFilters { get; } = [];
|
||||
}
|
||||
157
src/ModelContextProtocol.Core/Server/McpRequestFilters.cs
Normal file
157
src/ModelContextProtocol.Core/Server/McpRequestFilters.cs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
using ModelContextProtocol.Protocol;
|
||||
|
||||
namespace ModelContextProtocol.Server;
|
||||
|
||||
/// <summary>
|
||||
/// Provides grouped request-specific filter collections.
|
||||
/// </summary>
|
||||
public sealed class McpRequestFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-tools handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that return a list of available tools when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ToolsList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more tools.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// These filters work alongside any tools defined in the <see cref="McpServerTool"/> collection.
|
||||
/// Tools from both sources will be combined when returning results to clients.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<ListToolsRequestParams, ListToolsResult>> ListToolsFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the call-tool handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that are invoked when a client makes a call to a tool that isn't found in the <see cref="McpServerTool"/> collection.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ToolsCall"/> requests. The handler should implement logic to execute the requested tool and return appropriate results.
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<CallToolRequestParams, CallToolResult>> CallToolFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-prompts handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that return a list of available prompts when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.PromptsList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more prompts.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// These filters work alongside any prompts defined in the <see cref="McpServerPrompt"/> collection.
|
||||
/// Prompts from both sources will be combined when returning results to clients.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<ListPromptsRequestParams, ListPromptsResult>> ListPromptsFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the get-prompt handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that are invoked when a client requests details for a specific prompt that isn't found in the <see cref="McpServerPrompt"/> collection.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.PromptsGet"/> requests. The handler should implement logic to fetch or generate the requested prompt and return appropriate results.
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<GetPromptRequestParams, GetPromptResult>> GetPromptFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-resource-templates handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that return a list of available resource templates when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesTemplatesList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more resource templates.
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<ListResourceTemplatesRequestParams, ListResourceTemplatesResult>> ListResourceTemplatesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that return a list of available resources when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more resources.
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<ListResourcesRequestParams, ListResourcesResult>> ListResourcesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the read-resource handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that are invoked when a client requests the content of a specific resource identified by its URI.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesRead"/> requests. The handler should implement logic to locate and retrieve the requested resource.
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<ReadResourceRequestParams, ReadResourceResult>> ReadResourceFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the complete-handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that provide auto-completion suggestions for prompt arguments or resource references in the Model Context Protocol.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.CompletionComplete"/> requests. The handler processes auto-completion requests, returning a list of suggestions based on the
|
||||
/// reference type and current argument value.
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<CompleteRequestParams, CompleteResult>> CompleteFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the subscribe-to-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that are invoked when a client wants to receive notifications about changes to specific resources or resource patterns.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesSubscribe"/> requests. The handler should implement logic to register the client's interest in the specified resources
|
||||
/// and set up the necessary infrastructure to send notifications when those resources change.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After a successful subscription, the server should send resource change notifications to the client
|
||||
/// whenever a relevant resource is created, updated, or deleted.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<SubscribeRequestParams, EmptyResult>> SubscribeToResourcesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the unsubscribe-from-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that are invoked when a client wants to stop receiving notifications about previously subscribed resources.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesUnsubscribe"/> requests. The handler should implement logic to remove the client's subscriptions to the specified resources
|
||||
/// and clean up any associated resources.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After a successful unsubscription, the server should no longer send resource change notifications
|
||||
/// to the client for the specified resources.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<UnsubscribeRequestParams, EmptyResult>> UnsubscribeFromResourcesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the set-logging-level handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that process <see cref="RequestMethods.LoggingSetLevel"/> requests from clients. When set, it enables
|
||||
/// clients to control which log messages they receive by specifying a minimum severity threshold.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.LoggingSetLevel"/> requests.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After handling a level change request, the server typically begins sending log messages
|
||||
/// at or above the specified level to the client as notifications/message notifications.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public IList<McpRequestFilter<SetLevelRequestParams, EmptyResult>> SetLoggingLevelFilters { get; } = [];
|
||||
}
|
||||
|
|
@ -12,183 +12,12 @@ namespace ModelContextProtocol.Server;
|
|||
public sealed class McpServerFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the filters for all incoming JSON-RPC messages.
|
||||
/// Gets the filters for incoming and outgoing JSON-RPC messages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters intercept all incoming JSON-RPC messages before they are processed by the server,
|
||||
/// including requests, notifications, responses, and errors. The filters can perform logging,
|
||||
/// authentication, rate limiting, or other cross-cutting concerns that apply to all message types.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Message filters are applied before request-specific filters. If a message filter does not call
|
||||
/// the next handler in the pipeline, the default handlers will not be executed.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public List<McpMessageFilter> IncomingMessageFilters { get; } = [];
|
||||
public McpMessageFilters Message { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for all outgoing JSON-RPC messages.
|
||||
/// Gets the filters for request-specific MCP handler pipelines.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters intercept all outgoing JSON-RPC messages before they are sent to the client,
|
||||
/// including responses, notifications, and errors. The filters can perform logging,
|
||||
/// redaction, auditing, or other cross-cutting concerns that apply to all message types.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If a message filter does not call the next handler in the pipeline, the message will not be sent.
|
||||
/// Filters may also call the next handler multiple times with different messages to emit additional
|
||||
/// server-to-client messages.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public List<McpMessageFilter> OutgoingMessageFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-tools handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that return a list of available tools when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ToolsList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more tools.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// These filters work alongside any tools defined in the <see cref="McpServerTool"/> collection.
|
||||
/// Tools from both sources will be combined when returning results to clients.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<ListToolsRequestParams, ListToolsResult>> ListToolsFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the call-tool handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that are invoked when a client makes a call to a tool that isn't found in the <see cref="McpServerTool"/> collection.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ToolsCall"/> requests. The handler should implement logic to execute the requested tool and return appropriate results.
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<CallToolRequestParams, CallToolResult>> CallToolFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-prompts handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that return a list of available prompts when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.PromptsList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more prompts.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// These filters work alongside any prompts defined in the <see cref="McpServerPrompt"/> collection.
|
||||
/// Prompts from both sources will be combined when returning results to clients.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<ListPromptsRequestParams, ListPromptsResult>> ListPromptsFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the get-prompt handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that are invoked when a client requests details for a specific prompt that isn't found in the <see cref="McpServerPrompt"/> collection.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.PromptsGet"/> requests. The handler should implement logic to fetch or generate the requested prompt and return appropriate results.
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<GetPromptRequestParams, GetPromptResult>> GetPromptFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-resource-templates handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that return a list of available resource templates when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesTemplatesList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more resource templates.
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<ListResourceTemplatesRequestParams, ListResourceTemplatesResult>> ListResourceTemplatesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the list-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that return a list of available resources when requested by a client.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more resources.
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<ListResourcesRequestParams, ListResourcesResult>> ListResourcesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the read-resource handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that are invoked when a client requests the content of a specific resource identified by its URI.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesRead"/> requests. The handler should implement logic to locate and retrieve the requested resource.
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<ReadResourceRequestParams, ReadResourceResult>> ReadResourceFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the complete-handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These filters wrap handlers that provide auto-completion suggestions for prompt arguments or resource references in the Model Context Protocol.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.CompletionComplete"/> requests. The handler processes auto-completion requests, returning a list of suggestions based on the
|
||||
/// reference type and current argument value.
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<CompleteRequestParams, CompleteResult>> CompleteFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the subscribe-to-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that are invoked when a client wants to receive notifications about changes to specific resources or resource patterns.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesSubscribe"/> requests. The handler should implement logic to register the client's interest in the specified resources
|
||||
/// and set up the necessary infrastructure to send notifications when those resources change.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After a successful subscription, the server should send resource change notifications to the client
|
||||
/// whenever a relevant resource is created, updated, or deleted.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<SubscribeRequestParams, EmptyResult>> SubscribeToResourcesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the unsubscribe-from-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that are invoked when a client wants to stop receiving notifications about previously subscribed resources.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesUnsubscribe"/> requests. The handler should implement logic to remove the client's subscriptions to the specified resources
|
||||
/// and clean up any associated resources.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After a successful unsubscription, the server should no longer send resource change notifications
|
||||
/// to the client for the specified resources.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<UnsubscribeRequestParams, EmptyResult>> UnsubscribeFromResourcesFilters { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filters for the set-logging-level handler pipeline.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// These filters wrap handlers that process <see cref="RequestMethods.LoggingSetLevel"/> requests from clients. When set, it enables
|
||||
/// clients to control which log messages they receive by specifying a minimum severity threshold.
|
||||
/// The filters can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.LoggingSetLevel"/> requests.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After handling a level change request, the server typically begins sending log messages
|
||||
/// at or above the specified level to the client as notifications/message notifications.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public List<McpRequestFilter<SetLevelRequestParams, EmptyResult>> SetLoggingLevelFilters { get; } = [];
|
||||
public McpRequestFilters Request { get; } = new();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,8 +119,8 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
}
|
||||
|
||||
// And initialize the session.
|
||||
var incomingMessageFilter = BuildMessageFilterPipeline(options.Filters.IncomingMessageFilters);
|
||||
var outgoingMessageFilter = BuildMessageFilterPipeline(options.Filters.OutgoingMessageFilters);
|
||||
var incomingMessageFilter = BuildMessageFilterPipeline(options.Filters.Message.IncomingFilters);
|
||||
var outgoingMessageFilter = BuildMessageFilterPipeline(options.Filters.Message.OutgoingFilters);
|
||||
_sessionHandler = new McpSessionHandler(
|
||||
isServer: true,
|
||||
_sessionTransport,
|
||||
|
|
@ -260,7 +260,7 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
}
|
||||
|
||||
completeHandler ??= (static async (_, __) => new CompleteResult());
|
||||
completeHandler = BuildFilterPipeline(completeHandler, options.Filters.CompleteFilters);
|
||||
completeHandler = BuildFilterPipeline(completeHandler, options.Filters.Request.CompleteFilters);
|
||||
|
||||
ServerCapabilities.Completions = new();
|
||||
|
||||
|
|
@ -366,9 +366,9 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
// subscribe = true;
|
||||
}
|
||||
|
||||
listResourcesHandler = BuildFilterPipeline(listResourcesHandler, options.Filters.ListResourcesFilters);
|
||||
listResourceTemplatesHandler = BuildFilterPipeline(listResourceTemplatesHandler, options.Filters.ListResourceTemplatesFilters);
|
||||
readResourceHandler = BuildFilterPipeline(readResourceHandler, options.Filters.ReadResourceFilters, handler =>
|
||||
listResourcesHandler = BuildFilterPipeline(listResourcesHandler, options.Filters.Request.ListResourcesFilters);
|
||||
listResourceTemplatesHandler = BuildFilterPipeline(listResourceTemplatesHandler, options.Filters.Request.ListResourceTemplatesFilters);
|
||||
readResourceHandler = BuildFilterPipeline(readResourceHandler, options.Filters.Request.ReadResourceFilters, handler =>
|
||||
async (request, cancellationToken) =>
|
||||
{
|
||||
// Initial handler that sets MatchedPrimitive
|
||||
|
|
@ -405,8 +405,8 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
throw;
|
||||
}
|
||||
});
|
||||
subscribeHandler = BuildFilterPipeline(subscribeHandler, options.Filters.SubscribeToResourcesFilters);
|
||||
unsubscribeHandler = BuildFilterPipeline(unsubscribeHandler, options.Filters.UnsubscribeFromResourcesFilters);
|
||||
subscribeHandler = BuildFilterPipeline(subscribeHandler, options.Filters.Request.SubscribeToResourcesFilters);
|
||||
unsubscribeHandler = BuildFilterPipeline(unsubscribeHandler, options.Filters.Request.UnsubscribeFromResourcesFilters);
|
||||
|
||||
ServerCapabilities.Resources.ListChanged = listChanged;
|
||||
ServerCapabilities.Resources.Subscribe = subscribe;
|
||||
|
|
@ -496,8 +496,8 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
listChanged = true;
|
||||
}
|
||||
|
||||
listPromptsHandler = BuildFilterPipeline(listPromptsHandler, options.Filters.ListPromptsFilters);
|
||||
getPromptHandler = BuildFilterPipeline(getPromptHandler, options.Filters.GetPromptFilters, handler =>
|
||||
listPromptsHandler = BuildFilterPipeline(listPromptsHandler, options.Filters.Request.ListPromptsFilters);
|
||||
getPromptHandler = BuildFilterPipeline(getPromptHandler, options.Filters.Request.GetPromptFilters, handler =>
|
||||
async (request, cancellationToken) =>
|
||||
{
|
||||
// Initial handler that sets MatchedPrimitive
|
||||
|
|
@ -618,8 +618,8 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
listChanged = true;
|
||||
}
|
||||
|
||||
listToolsHandler = BuildFilterPipeline(listToolsHandler, options.Filters.ListToolsFilters);
|
||||
callToolHandler = BuildFilterPipeline(callToolHandler, options.Filters.CallToolFilters, handler =>
|
||||
listToolsHandler = BuildFilterPipeline(listToolsHandler, options.Filters.Request.ListToolsFilters);
|
||||
callToolHandler = BuildFilterPipeline(callToolHandler, options.Filters.Request.CallToolFilters, handler =>
|
||||
async (request, cancellationToken) =>
|
||||
{
|
||||
// Initial handler that sets MatchedPrimitive
|
||||
|
|
@ -819,7 +819,7 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
// Apply filters to the handler
|
||||
if (setLoggingLevelHandler is not null)
|
||||
{
|
||||
setLoggingLevelHandler = BuildFilterPipeline(setLoggingLevelHandler, options.Filters.SetLoggingLevelFilters);
|
||||
setLoggingLevelHandler = BuildFilterPipeline(setLoggingLevelHandler, options.Filters.Request.SetLoggingLevelFilters);
|
||||
}
|
||||
|
||||
ServerCapabilities.Logging = new();
|
||||
|
|
@ -903,7 +903,7 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
|
||||
private static McpRequestHandler<TParams, TResult> BuildFilterPipeline<TParams, TResult>(
|
||||
McpRequestHandler<TParams, TResult> baseHandler,
|
||||
List<McpRequestFilter<TParams, TResult>> filters,
|
||||
IList<McpRequestFilter<TParams, TResult>> filters,
|
||||
McpRequestFilter<TParams, TResult>? initialHandler = null)
|
||||
{
|
||||
var current = baseHandler;
|
||||
|
|
@ -921,7 +921,7 @@ internal sealed partial class McpServerImpl : McpServer
|
|||
return current;
|
||||
}
|
||||
|
||||
private JsonRpcMessageFilter BuildMessageFilterPipeline(List<McpMessageFilter> filters)
|
||||
private JsonRpcMessageFilter BuildMessageFilterPipeline(IList<McpMessageFilter> filters)
|
||||
{
|
||||
if (filters.Count == 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -94,29 +94,21 @@ public sealed class McpServerOptions
|
|||
/// </remarks>
|
||||
public ClientCapabilities? KnownClientCapabilities { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the container of handlers used by the server for processing protocol messages.
|
||||
/// </summary>
|
||||
public McpServerHandlers Handlers { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the filter collections for MCP server handlers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This property provides access to filter collections that can be used to modify the behavior
|
||||
/// of various MCP server handlers. Filters are applied in reverse order, so the last filter
|
||||
/// added will be the outermost (first to execute).
|
||||
/// of various MCP server handlers. The first filter added is the outermost (first to execute),
|
||||
/// and each subsequent filter wraps closer to the handler.
|
||||
/// </remarks>
|
||||
public McpServerFilters Filters { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the container of handlers used by the server for processing protocol messages.
|
||||
/// </summary>
|
||||
public McpServerHandlers Handlers
|
||||
{
|
||||
get => field ??= new();
|
||||
set
|
||||
{
|
||||
Throw.IfNull(value);
|
||||
field = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a collection of tools served by the server.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ namespace ModelContextProtocol.Server;
|
|||
/// </para>
|
||||
/// <para>
|
||||
/// This type is typically received as a parameter in message filter delegates registered via
|
||||
/// <see cref="McpServerFilters.IncomingMessageFilters"/> or <see cref="McpServerFilters.OutgoingMessageFilters"/>.
|
||||
/// <see cref="McpServerFilters.Message"/>'s <see cref="McpMessageFilters.IncomingFilters"/> or
|
||||
/// <see cref="McpMessageFilters.OutgoingFilters"/> collections.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MessageContext
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
internal sealed class DefaultMcpMessageFilterBuilder(IMcpServerBuilder serverBuilder) : IMcpMessageFilterBuilder
|
||||
{
|
||||
public IServiceCollection Services { get; } = serverBuilder.Services;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
internal sealed class DefaultMcpRequestFilterBuilder(IMcpServerBuilder serverBuilder) : IMcpRequestFilterBuilder
|
||||
{
|
||||
public IServiceCollection Services { get; } = serverBuilder.Services;
|
||||
}
|
||||
14
src/ModelContextProtocol/IMcpMessageFilterBuilder.cs
Normal file
14
src/ModelContextProtocol/IMcpMessageFilterBuilder.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using ModelContextProtocol.Server;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Provides a builder for configuring message-level MCP server filters.
|
||||
/// </summary>
|
||||
public interface IMcpMessageFilterBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the associated service collection.
|
||||
/// </summary>
|
||||
IServiceCollection Services { get; }
|
||||
}
|
||||
14
src/ModelContextProtocol/IMcpRequestFilterBuilder.cs
Normal file
14
src/ModelContextProtocol/IMcpRequestFilterBuilder.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using ModelContextProtocol.Server;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Provides a builder for configuring request-specific MCP server filters.
|
||||
/// </summary>
|
||||
public interface IMcpRequestFilterBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the associated service collection.
|
||||
/// </summary>
|
||||
IServiceCollection Services { get; }
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using ModelContextProtocol;
|
||||
using ModelContextProtocol.Server;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for configuring message-level MCP server filters.
|
||||
/// </summary>
|
||||
public static class McpMessageFilterBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a filter to intercept all incoming JSON-RPC messages.
|
||||
/// </summary>
|
||||
/// <param name="builder">The message filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the message handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpMessageFilterBuilder AddIncomingFilter(this IMcpMessageFilterBuilder builder, McpMessageFilter filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Message.IncomingFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to intercept all outgoing JSON-RPC messages.
|
||||
/// </summary>
|
||||
/// <param name="builder">The message filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the message handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpMessageFilterBuilder AddOutgoingFilter(this IMcpMessageFilterBuilder builder, McpMessageFilter filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Message.OutgoingFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
176
src/ModelContextProtocol/McpRequestFilterBuilderExtensions.cs
Normal file
176
src/ModelContextProtocol/McpRequestFilterBuilderExtensions.cs
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
using ModelContextProtocol;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using ModelContextProtocol.Server;
|
||||
|
||||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for configuring request-specific MCP server filters.
|
||||
/// </summary>
|
||||
public static class McpRequestFilterBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a filter to the list resource templates handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddListResourceTemplatesFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<ListResourceTemplatesRequestParams, ListResourceTemplatesResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.ListResourceTemplatesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the list tools handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddListToolsFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<ListToolsRequestParams, ListToolsResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.ListToolsFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the call tool handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddCallToolFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<CallToolRequestParams, CallToolResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.CallToolFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the list prompts handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddListPromptsFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<ListPromptsRequestParams, ListPromptsResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.ListPromptsFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the get prompt handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddGetPromptFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<GetPromptRequestParams, GetPromptResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.GetPromptFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the list resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddListResourcesFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<ListResourcesRequestParams, ListResourcesResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.ListResourcesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the read resource handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddReadResourceFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<ReadResourceRequestParams, ReadResourceResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.ReadResourceFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the complete handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddCompleteFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<CompleteRequestParams, CompleteResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.CompleteFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the subscribe-to-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddSubscribeToResourcesFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<SubscribeRequestParams, EmptyResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.SubscribeToResourcesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the unsubscribe-from-resources handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddUnsubscribeFromResourcesFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<UnsubscribeRequestParams, EmptyResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.UnsubscribeFromResourcesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the set logging level handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The request filter builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
public static IMcpRequestFilterBuilder AddSetLoggingLevelFilter(this IMcpRequestFilterBuilder builder, McpRequestFilter<SetLevelRequestParams, EmptyResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.Request.SetLoggingLevelFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
@ -893,28 +893,49 @@ public static partial class McpServerBuilderExtensions
|
|||
#endregion
|
||||
|
||||
#region Filters
|
||||
/// <summary>
|
||||
/// Configures message-level filters for the MCP server.
|
||||
/// </summary>
|
||||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="configure">A callback used to register message filters.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> or <paramref name="configure"/> is <see langword="null"/>.</exception>
|
||||
public static IMcpServerBuilder WithMessageFilters(this IMcpServerBuilder builder, Action<IMcpMessageFilterBuilder> configure)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(configure);
|
||||
|
||||
configure(new DefaultMcpMessageFilterBuilder(builder));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures request-specific filters for the MCP server.
|
||||
/// </summary>
|
||||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="configure">A callback used to register request-specific filters.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> or <paramref name="configure"/> is <see langword="null"/>.</exception>
|
||||
public static IMcpServerBuilder WithRequestFilters(this IMcpServerBuilder builder, Action<IMcpRequestFilterBuilder> configure)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(configure);
|
||||
|
||||
configure(new DefaultMcpRequestFilterBuilder(builder));
|
||||
return builder;
|
||||
}
|
||||
|
||||
#pragma warning disable CS0436 // ObsoleteAttribute polyfill conflicts with framework type on netstandard.
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the list resource templates handler pipeline.
|
||||
/// </summary>
|
||||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that return a list of available resource templates when requested by a client.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesTemplatesList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more resource templates.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddListResourceTemplatesFilter(this IMcpServerBuilder builder, McpRequestFilter<ListResourceTemplatesRequestParams, ListResourceTemplatesResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.ListResourceTemplatesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddListResourceTemplatesFilter(this IMcpServerBuilder builder, McpRequestFilter<ListResourceTemplatesRequestParams, ListResourceTemplatesResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddListResourceTemplatesFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the list tools handler pipeline.
|
||||
|
|
@ -922,26 +943,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that return a list of available tools when requested by a client.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ToolsList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more tools.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This filter works alongside any tools defined in the <see cref="McpServerTool"/> collection.
|
||||
/// Tools from both sources will be combined when returning results to clients.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddListToolsFilter(this IMcpServerBuilder builder, McpRequestFilter<ListToolsRequestParams, ListToolsResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.ListToolsFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddListToolsFilter(this IMcpServerBuilder builder, McpRequestFilter<ListToolsRequestParams, ListToolsResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddListToolsFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the call tool handler pipeline.
|
||||
|
|
@ -949,21 +953,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that are invoked when a client makes a call to a tool that isn't found in the <see cref="McpServerTool"/> collection.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ToolsCall"/> requests. The handler should implement logic to execute the requested tool and return appropriate results.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddCallToolFilter(this IMcpServerBuilder builder, McpRequestFilter<CallToolRequestParams, CallToolResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.CallToolFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddCallToolFilter(this IMcpServerBuilder builder, McpRequestFilter<CallToolRequestParams, CallToolResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddCallToolFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the list prompts handler pipeline.
|
||||
|
|
@ -971,26 +963,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that return a list of available prompts when requested by a client.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.PromptsList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more prompts.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This filter works alongside any prompts defined in the <see cref="McpServerPrompt"/> collection.
|
||||
/// Prompts from both sources will be combined when returning results to clients.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddListPromptsFilter(this IMcpServerBuilder builder, McpRequestFilter<ListPromptsRequestParams, ListPromptsResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.ListPromptsFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddListPromptsFilter(this IMcpServerBuilder builder, McpRequestFilter<ListPromptsRequestParams, ListPromptsResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddListPromptsFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the get prompt handler pipeline.
|
||||
|
|
@ -998,21 +973,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that are invoked when a client requests details for a specific prompt that isn't found in the <see cref="McpServerPrompt"/> collection.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.PromptsGet"/> requests. The handler should implement logic to fetch or generate the requested prompt and return appropriate results.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddGetPromptFilter(this IMcpServerBuilder builder, McpRequestFilter<GetPromptRequestParams, GetPromptResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.GetPromptFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddGetPromptFilter(this IMcpServerBuilder builder, McpRequestFilter<GetPromptRequestParams, GetPromptResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddGetPromptFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the list resources handler pipeline.
|
||||
|
|
@ -1020,22 +983,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that return a list of available resources when requested by a client.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesList"/> requests. It supports pagination through the cursor mechanism,
|
||||
/// where the client can make repeated calls with the cursor returned by the previous call to retrieve more resources.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddListResourcesFilter(this IMcpServerBuilder builder, McpRequestFilter<ListResourcesRequestParams, ListResourcesResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.ListResourcesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddListResourcesFilter(this IMcpServerBuilder builder, McpRequestFilter<ListResourcesRequestParams, ListResourcesResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddListResourcesFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the read resource handler pipeline.
|
||||
|
|
@ -1043,21 +993,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that are invoked when a client requests the content of a specific resource identified by its URI.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesRead"/> requests. The handler should implement logic to locate and retrieve the requested resource.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddReadResourceFilter(this IMcpServerBuilder builder, McpRequestFilter<ReadResourceRequestParams, ReadResourceResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.ReadResourceFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddReadResourceFilter(this IMcpServerBuilder builder, McpRequestFilter<ReadResourceRequestParams, ReadResourceResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddReadResourceFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the complete handler pipeline.
|
||||
|
|
@ -1065,22 +1003,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that provide auto-completion suggestions for prompt arguments or resource references in the Model Context Protocol.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.CompletionComplete"/> requests. The handler processes auto-completion requests, returning a list of suggestions based on the
|
||||
/// reference type and current argument value.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddCompleteFilter(this IMcpServerBuilder builder, McpRequestFilter<CompleteRequestParams, CompleteResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.CompleteFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddCompleteFilter(this IMcpServerBuilder builder, McpRequestFilter<CompleteRequestParams, CompleteResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddCompleteFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the subscribe-to-resources handler pipeline.
|
||||
|
|
@ -1088,26 +1013,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that are invoked when a client wants to receive notifications about changes to specific resources or resource patterns.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesSubscribe"/> requests. The handler should implement logic to register the client's interest in the specified resources
|
||||
/// and set up the necessary infrastructure to send notifications when those resources change.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After a successful subscription, the server should send resource change notifications to the client
|
||||
/// whenever a relevant resource is created, updated, or deleted.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddSubscribeToResourcesFilter(this IMcpServerBuilder builder, McpRequestFilter<SubscribeRequestParams, EmptyResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.SubscribeToResourcesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddSubscribeToResourcesFilter(this IMcpServerBuilder builder, McpRequestFilter<SubscribeRequestParams, EmptyResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddSubscribeToResourcesFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the unsubscribe-from-resources handler pipeline.
|
||||
|
|
@ -1115,26 +1023,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that are invoked when a client wants to stop receiving notifications about previously subscribed resources.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.ResourcesUnsubscribe"/> requests. The handler should implement logic to remove the client's subscriptions to the specified resources
|
||||
/// and clean up any associated resources.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After a successful unsubscription, the server should no longer send resource change notifications
|
||||
/// to the client for the specified resources.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddUnsubscribeFromResourcesFilter(this IMcpServerBuilder builder, McpRequestFilter<UnsubscribeRequestParams, EmptyResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.UnsubscribeFromResourcesFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddUnsubscribeFromResourcesFilter(this IMcpServerBuilder builder, McpRequestFilter<UnsubscribeRequestParams, EmptyResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddUnsubscribeFromResourcesFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to the set logging level handler pipeline.
|
||||
|
|
@ -1142,26 +1033,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter wraps handlers that process <see cref="RequestMethods.LoggingSetLevel"/> requests from clients. When set, it enables
|
||||
/// clients to control which log messages they receive by specifying a minimum severity threshold.
|
||||
/// The filter can modify, log, or perform additional operations on requests and responses for
|
||||
/// <see cref="RequestMethods.LoggingSetLevel"/> requests.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// After handling a level change request, the server typically begins sending log messages
|
||||
/// at or above the specified level to the client as notifications or message notifications.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddSetLoggingLevelFilter(this IMcpServerBuilder builder, McpRequestFilter<SetLevelRequestParams, EmptyResult> filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.SetLoggingLevelFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.RequestFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddSetLoggingLevelFilter(this IMcpServerBuilder builder, McpRequestFilter<SetLevelRequestParams, EmptyResult> filter) =>
|
||||
builder.WithRequestFilters(filters => filters.AddSetLoggingLevelFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to intercept all incoming JSON-RPC messages.
|
||||
|
|
@ -1169,36 +1043,9 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the message handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter intercepts all incoming JSON-RPC messages before they are processed by the server,
|
||||
/// including requests, notifications, responses, and errors. The filter can perform logging,
|
||||
/// authentication, rate limiting, or other cross-cutting concerns that apply to all message types.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Message filters are applied before request-specific filters. If a message filter does not call
|
||||
/// the next handler in the pipeline, the default handlers will not be executed.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Filters are applied in the order they are registered, with the first registered filter being the outermost.
|
||||
/// Each filter receives the next handler in the pipeline and can choose to:
|
||||
/// <list type="bullet">
|
||||
/// <item><description>Call the next handler to continue processing: <c>await next(context, cancellationToken)</c></description></item>
|
||||
/// <item><description>Skip the default handlers entirely by not calling next</description></item>
|
||||
/// <item><description>Perform operations before and/or after calling next</description></item>
|
||||
/// <item><description>Catch and handle exceptions from inner handlers</description></item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddIncomingMessageFilter(this IMcpServerBuilder builder, McpMessageFilter filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
Throw.IfNull(filter);
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.IncomingMessageFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
[Obsolete(Obsoletions.MessageFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddIncomingMessageFilter(this IMcpServerBuilder builder, McpMessageFilter filter) =>
|
||||
builder.WithMessageFilters(filters => filters.AddIncomingFilter(filter));
|
||||
|
||||
/// <summary>
|
||||
/// Adds a filter to intercept all outgoing JSON-RPC messages.
|
||||
|
|
@ -1206,26 +1053,11 @@ public static partial class McpServerBuilderExtensions
|
|||
/// <param name="builder">The builder instance.</param>
|
||||
/// <param name="filter">The filter function that wraps the message handler.</param>
|
||||
/// <returns>The builder provided in <paramref name="builder"/>.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This filter intercepts all outgoing JSON-RPC messages before they are sent to the client,
|
||||
/// including responses, notifications, and errors. The filter can perform logging, redaction,
|
||||
/// auditing, or other cross-cutting concerns that apply to all message types.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If a message filter does not call the next handler in the pipeline, the message will not be sent.
|
||||
/// Filters may also call the next handler multiple times with different messages to emit additional
|
||||
/// server-to-client messages.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IMcpServerBuilder AddOutgoingMessageFilter(this IMcpServerBuilder builder, McpMessageFilter filter)
|
||||
{
|
||||
Throw.IfNull(builder);
|
||||
[Obsolete(Obsoletions.MessageFilter_Message, DiagnosticId = Obsoletions.MessageAndRequestFilter_DiagnosticId, UrlFormat = Obsoletions.MessageAndRequestFilter_Url)]
|
||||
public static IMcpServerBuilder AddOutgoingMessageFilter(this IMcpServerBuilder builder, McpMessageFilter filter) =>
|
||||
builder.WithMessageFilters(filters => filters.AddOutgoingFilter(filter));
|
||||
|
||||
builder.Services.Configure<McpServerOptions>(options => options.Filters.OutgoingMessageFilters.Add(filter));
|
||||
return builder;
|
||||
}
|
||||
#pragma warning restore CS0436
|
||||
#endregion
|
||||
|
||||
#region Transports
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common\Throw.cs" Link="Throw.cs" />
|
||||
<Compile Include="..\Common\Obsoletions.cs" Link="Obsoletions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in a new issue