using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using ModelContextProtocol.AspNetCore;
using ModelContextProtocol.Server;
namespace Microsoft.Extensions.DependencyInjection;
///
/// Provides methods for configuring HTTP MCP servers via dependency injection.
///
public static class HttpMcpServerBuilderExtensions
{
///
/// Adds the services necessary for
/// to handle MCP requests and sessions using the MCP Streamable HTTP transport.
///
/// The builder instance.
/// Configures options for the Streamable HTTP transport. This allows configuring per-session
/// and running logic before and after a session.
/// The builder provided in .
/// For more information on configuring the underlying HTTP server
/// to control things like port binding custom TLS certificates, see the Minimal APIs quick reference.
///
/// is .
public static IMcpServerBuilder WithHttpTransport(this IMcpServerBuilder builder, Action? configureOptions = null)
{
ArgumentNullException.ThrowIfNull(builder);
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.TryAddSingleton();
builder.Services.AddHostedService();
builder.Services.TryAddEnumerable(ServiceDescriptor.Transient, AuthorizationFilterSetup>());
if (configureOptions is not null)
{
builder.Services.Configure(configureOptions);
}
return builder;
}
///
/// Adds authorization filters to support
/// on MCP server tools, prompts, and resources. This method should always be called when using
/// ASP.NET Core integration to ensure proper authorization support.
///
/// The builder instance.
/// The builder provided in .
/// is .
///
/// This method automatically configures authorization filters for all MCP server handlers. These filters respect
/// authorization attributes such as
/// and .
///
public static IMcpServerBuilder AddAuthorizationFilters(this IMcpServerBuilder builder)
{
ArgumentNullException.ThrowIfNull(builder);
// Allow the authorization filters to get added multiple times in case other middleware changes the matched primitive.
builder.Services.AddTransient, AuthorizationFilterSetup>();
return builder;
}
}