1
1
using Microsoft . Extensions . DependencyInjection . Extensions ;
2
2
using Microsoft . Extensions . Logging ;
3
3
using Microsoft . Extensions . Options ;
4
- using ModelContextProtocol ;
4
+ using ModelContextProtocol . AspNetCore ;
5
+ using ModelContextProtocol . AspNetCore . Configuration ;
5
6
using ModelContextProtocol . Protocol ;
6
7
using ModelContextProtocol . Server ;
7
8
using System . Diagnostics . CodeAnalysis ;
@@ -38,7 +39,7 @@ public static partial class McpServerBuilderExtensions
38
39
this IMcpServerBuilder builder ,
39
40
JsonSerializerOptions ? serializerOptions = null )
40
41
{
41
- Throw . IfNull ( builder ) ;
42
+ ArgumentNullException . ThrowIfNull ( builder ) ;
42
43
43
44
foreach ( var toolMethod in typeof ( TToolType ) . GetMethods ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Static | BindingFlags . Instance ) )
44
45
{
@@ -61,8 +62,8 @@ public static partial class McpServerBuilderExtensions
61
62
/// <exception cref="ArgumentNullException"><paramref name="tools"/> is <see langword="null"/>.</exception>
62
63
public static IMcpServerBuilder WithTools ( this IMcpServerBuilder builder , IEnumerable < McpServerTool > tools )
63
64
{
64
- Throw . IfNull ( builder ) ;
65
- Throw . IfNull ( tools ) ;
65
+ ArgumentNullException . ThrowIfNull ( builder ) ;
66
+ ArgumentNullException . ThrowIfNull ( tools ) ;
66
67
67
68
foreach ( var tool in tools )
68
69
{
@@ -90,8 +91,8 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnume
90
91
[ RequiresUnreferencedCode ( WithToolsRequiresUnreferencedCodeMessage ) ]
91
92
public static IMcpServerBuilder WithTools ( this IMcpServerBuilder builder , IEnumerable < Type > toolTypes , JsonSerializerOptions ? serializerOptions = null )
92
93
{
93
- Throw . IfNull ( builder ) ;
94
- Throw . IfNull ( toolTypes ) ;
94
+ ArgumentNullException . ThrowIfNull ( builder ) ;
95
+ ArgumentNullException . ThrowIfNull ( toolTypes ) ;
95
96
96
97
foreach ( var toolType in toolTypes )
97
98
{
@@ -143,7 +144,7 @@ public static IMcpServerBuilder WithTools(this IMcpServerBuilder builder, IEnume
143
144
[ RequiresUnreferencedCode ( WithToolsRequiresUnreferencedCodeMessage ) ]
144
145
public static IMcpServerBuilder WithToolsFromAssembly ( this IMcpServerBuilder builder , Assembly ? toolAssembly = null , JsonSerializerOptions ? serializerOptions = null )
145
146
{
146
- Throw . IfNull ( builder ) ;
147
+ ArgumentNullException . ThrowIfNull ( builder ) ;
147
148
148
149
toolAssembly ??= Assembly . GetCallingAssembly ( ) ;
149
150
@@ -178,7 +179,7 @@ where t.GetCustomAttribute<McpServerToolTypeAttribute>() is not null
178
179
this IMcpServerBuilder builder ,
179
180
JsonSerializerOptions ? serializerOptions = null )
180
181
{
181
- Throw . IfNull ( builder ) ;
182
+ ArgumentNullException . ThrowIfNull ( builder ) ;
182
183
183
184
foreach ( var promptMethod in typeof ( TPromptType ) . GetMethods ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Static | BindingFlags . Instance ) )
184
185
{
@@ -201,8 +202,8 @@ where t.GetCustomAttribute<McpServerToolTypeAttribute>() is not null
201
202
/// <exception cref="ArgumentNullException"><paramref name="prompts"/> is <see langword="null"/>.</exception>
202
203
public static IMcpServerBuilder WithPrompts ( this IMcpServerBuilder builder , IEnumerable < McpServerPrompt > prompts )
203
204
{
204
- Throw . IfNull ( builder ) ;
205
- Throw . IfNull ( prompts ) ;
205
+ ArgumentNullException . ThrowIfNull ( builder ) ;
206
+ ArgumentNullException . ThrowIfNull ( prompts ) ;
206
207
207
208
foreach ( var prompt in prompts )
208
209
{
@@ -230,8 +231,8 @@ public static IMcpServerBuilder WithPrompts(this IMcpServerBuilder builder, IEnu
230
231
[ RequiresUnreferencedCode ( WithPromptsRequiresUnreferencedCodeMessage ) ]
231
232
public static IMcpServerBuilder WithPrompts ( this IMcpServerBuilder builder , IEnumerable < Type > promptTypes , JsonSerializerOptions ? serializerOptions = null )
232
233
{
233
- Throw . IfNull ( builder ) ;
234
- Throw . IfNull ( promptTypes ) ;
234
+ ArgumentNullException . ThrowIfNull ( builder ) ;
235
+ ArgumentNullException . ThrowIfNull ( promptTypes ) ;
235
236
236
237
foreach ( var promptType in promptTypes )
237
238
{
@@ -283,7 +284,7 @@ public static IMcpServerBuilder WithPrompts(this IMcpServerBuilder builder, IEnu
283
284
[ RequiresUnreferencedCode ( WithPromptsRequiresUnreferencedCodeMessage ) ]
284
285
public static IMcpServerBuilder WithPromptsFromAssembly ( this IMcpServerBuilder builder , Assembly ? promptAssembly = null , JsonSerializerOptions ? serializerOptions = null )
285
286
{
286
- Throw . IfNull ( builder ) ;
287
+ ArgumentNullException . ThrowIfNull ( builder ) ;
287
288
288
289
promptAssembly ??= Assembly . GetCallingAssembly ( ) ;
289
290
@@ -315,7 +316,7 @@ where t.GetCustomAttribute<McpServerPromptTypeAttribute>() is not null
315
316
DynamicallyAccessedMemberTypes . PublicConstructors ) ] TResourceType > (
316
317
this IMcpServerBuilder builder )
317
318
{
318
- Throw . IfNull ( builder ) ;
319
+ ArgumentNullException . ThrowIfNull ( builder ) ;
319
320
320
321
foreach ( var resourceTemplateMethod in typeof ( TResourceType ) . GetMethods ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Static | BindingFlags . Instance ) )
321
322
{
@@ -338,8 +339,8 @@ where t.GetCustomAttribute<McpServerPromptTypeAttribute>() is not null
338
339
/// <exception cref="ArgumentNullException"><paramref name="resourceTemplates"/> is <see langword="null"/>.</exception>
339
340
public static IMcpServerBuilder WithResources ( this IMcpServerBuilder builder , IEnumerable < McpServerResource > resourceTemplates )
340
341
{
341
- Throw . IfNull ( builder ) ;
342
- Throw . IfNull ( resourceTemplates ) ;
342
+ ArgumentNullException . ThrowIfNull ( builder ) ;
343
+ ArgumentNullException . ThrowIfNull ( resourceTemplates ) ;
343
344
344
345
foreach ( var resourceTemplate in resourceTemplates )
345
346
{
@@ -366,8 +367,8 @@ public static IMcpServerBuilder WithResources(this IMcpServerBuilder builder, IE
366
367
[ RequiresUnreferencedCode ( WithResourcesRequiresUnreferencedCodeMessage ) ]
367
368
public static IMcpServerBuilder WithResources ( this IMcpServerBuilder builder , IEnumerable < Type > resourceTemplateTypes )
368
369
{
369
- Throw . IfNull ( builder ) ;
370
- Throw . IfNull ( resourceTemplateTypes ) ;
370
+ ArgumentNullException . ThrowIfNull ( builder ) ;
371
+ ArgumentNullException . ThrowIfNull ( resourceTemplateTypes ) ;
371
372
372
373
foreach ( var resourceTemplateType in resourceTemplateTypes )
373
374
{
@@ -418,7 +419,7 @@ public static IMcpServerBuilder WithResources(this IMcpServerBuilder builder, IE
418
419
[ RequiresUnreferencedCode ( WithResourcesRequiresUnreferencedCodeMessage ) ]
419
420
public static IMcpServerBuilder WithResourcesFromAssembly ( this IMcpServerBuilder builder , Assembly ? resourceAssembly = null )
420
421
{
421
- Throw . IfNull ( builder ) ;
422
+ ArgumentNullException . ThrowIfNull ( builder ) ;
422
423
423
424
resourceAssembly ??= Assembly . GetCallingAssembly ( ) ;
424
425
@@ -453,7 +454,7 @@ where t.GetCustomAttribute<McpServerResourceTypeAttribute>() is not null
453
454
/// </remarks>
454
455
public static IMcpServerBuilder WithListResourceTemplatesHandler ( this IMcpServerBuilder builder , Func < RequestContext < ListResourceTemplatesRequestParams > , CancellationToken , ValueTask < ListResourceTemplatesResult > > handler )
455
456
{
456
- Throw . IfNull ( builder ) ;
457
+ ArgumentNullException . ThrowIfNull ( builder ) ;
457
458
458
459
builder . Services . Configure < McpServerHandlers > ( s => s . ListResourceTemplatesHandler = handler ) ;
459
460
return builder ;
@@ -486,7 +487,7 @@ public static IMcpServerBuilder WithListResourceTemplatesHandler(this IMcpServer
486
487
/// </remarks>
487
488
public static IMcpServerBuilder WithListToolsHandler ( this IMcpServerBuilder builder , Func < RequestContext < ListToolsRequestParams > , CancellationToken , ValueTask < ListToolsResult > > handler )
488
489
{
489
- Throw . IfNull ( builder ) ;
490
+ ArgumentNullException . ThrowIfNull ( builder ) ;
490
491
491
492
builder . Services . Configure < McpServerHandlers > ( s => s . ListToolsHandler = handler ) ;
492
493
return builder ;
@@ -506,7 +507,7 @@ public static IMcpServerBuilder WithListToolsHandler(this IMcpServerBuilder buil
506
507
/// </remarks>
507
508
public static IMcpServerBuilder WithCallToolHandler ( this IMcpServerBuilder builder , Func < RequestContext < CallToolRequestParams > , CancellationToken , ValueTask < CallToolResponse > > handler )
508
509
{
509
- Throw . IfNull ( builder ) ;
510
+ ArgumentNullException . ThrowIfNull ( builder ) ;
510
511
511
512
builder . Services . Configure < McpServerHandlers > ( s => s . CallToolHandler = handler ) ;
512
513
return builder ;
@@ -539,7 +540,7 @@ public static IMcpServerBuilder WithCallToolHandler(this IMcpServerBuilder build
539
540
/// </remarks>
540
541
public static IMcpServerBuilder WithListPromptsHandler ( this IMcpServerBuilder builder , Func < RequestContext < ListPromptsRequestParams > , CancellationToken , ValueTask < ListPromptsResult > > handler )
541
542
{
542
- Throw . IfNull ( builder ) ;
543
+ ArgumentNullException . ThrowIfNull ( builder ) ;
543
544
544
545
builder . Services . Configure < McpServerHandlers > ( s => s . ListPromptsHandler = handler ) ;
545
546
return builder ;
@@ -554,7 +555,7 @@ public static IMcpServerBuilder WithListPromptsHandler(this IMcpServerBuilder bu
554
555
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
555
556
public static IMcpServerBuilder WithGetPromptHandler ( this IMcpServerBuilder builder , Func < RequestContext < GetPromptRequestParams > , CancellationToken , ValueTask < GetPromptResult > > handler )
556
557
{
557
- Throw . IfNull ( builder ) ;
558
+ ArgumentNullException . ThrowIfNull ( builder ) ;
558
559
559
560
builder . Services . Configure < McpServerHandlers > ( s => s . GetPromptHandler = handler ) ;
560
561
return builder ;
@@ -575,7 +576,7 @@ public static IMcpServerBuilder WithGetPromptHandler(this IMcpServerBuilder buil
575
576
/// </remarks>
576
577
public static IMcpServerBuilder WithListResourcesHandler ( this IMcpServerBuilder builder , Func < RequestContext < ListResourcesRequestParams > , CancellationToken , ValueTask < ListResourcesResult > > handler )
577
578
{
578
- Throw . IfNull ( builder ) ;
579
+ ArgumentNullException . ThrowIfNull ( builder ) ;
579
580
580
581
builder . Services . Configure < McpServerHandlers > ( s => s . ListResourcesHandler = handler ) ;
581
582
return builder ;
@@ -594,7 +595,7 @@ public static IMcpServerBuilder WithListResourcesHandler(this IMcpServerBuilder
594
595
/// </remarks>
595
596
public static IMcpServerBuilder WithReadResourceHandler ( this IMcpServerBuilder builder , Func < RequestContext < ReadResourceRequestParams > , CancellationToken , ValueTask < ReadResourceResult > > handler )
596
597
{
597
- Throw . IfNull ( builder ) ;
598
+ ArgumentNullException . ThrowIfNull ( builder ) ;
598
599
599
600
builder . Services . Configure < McpServerHandlers > ( s => s . ReadResourceHandler = handler ) ;
600
601
return builder ;
@@ -613,7 +614,7 @@ public static IMcpServerBuilder WithReadResourceHandler(this IMcpServerBuilder b
613
614
/// </remarks>
614
615
public static IMcpServerBuilder WithCompleteHandler ( this IMcpServerBuilder builder , Func < RequestContext < CompleteRequestParams > , CancellationToken , ValueTask < CompleteResult > > handler )
615
616
{
616
- Throw . IfNull ( builder ) ;
617
+ ArgumentNullException . ThrowIfNull ( builder ) ;
617
618
618
619
builder . Services . Configure < McpServerHandlers > ( s => s . CompleteHandler = handler ) ;
619
620
return builder ;
@@ -643,7 +644,7 @@ public static IMcpServerBuilder WithCompleteHandler(this IMcpServerBuilder build
643
644
/// </remarks>
644
645
public static IMcpServerBuilder WithSubscribeToResourcesHandler ( this IMcpServerBuilder builder , Func < RequestContext < SubscribeRequestParams > , CancellationToken , ValueTask < EmptyResult > > handler )
645
646
{
646
- Throw . IfNull ( builder ) ;
647
+ ArgumentNullException . ThrowIfNull ( builder ) ;
647
648
648
649
builder . Services . Configure < McpServerHandlers > ( s => s . SubscribeToResourcesHandler = handler ) ;
649
650
return builder ;
@@ -673,7 +674,7 @@ public static IMcpServerBuilder WithSubscribeToResourcesHandler(this IMcpServerB
673
674
/// </remarks>
674
675
public static IMcpServerBuilder WithUnsubscribeFromResourcesHandler ( this IMcpServerBuilder builder , Func < RequestContext < UnsubscribeRequestParams > , CancellationToken , ValueTask < EmptyResult > > handler )
675
676
{
676
- Throw . IfNull ( builder ) ;
677
+ ArgumentNullException . ThrowIfNull ( builder ) ;
677
678
678
679
builder . Services . Configure < McpServerHandlers > ( s => s . UnsubscribeFromResourcesHandler = handler ) ;
679
680
return builder ;
@@ -700,7 +701,7 @@ public static IMcpServerBuilder WithUnsubscribeFromResourcesHandler(this IMcpSer
700
701
/// </remarks>
701
702
public static IMcpServerBuilder WithSetLoggingLevelHandler ( this IMcpServerBuilder builder , Func < RequestContext < SetLevelRequestParams > , CancellationToken , ValueTask < EmptyResult > > handler )
702
703
{
703
- Throw . IfNull ( builder ) ;
704
+ ArgumentNullException . ThrowIfNull ( builder ) ;
704
705
705
706
builder . Services . Configure < McpServerHandlers > ( s => s . SetLoggingLevelHandler = handler ) ;
706
707
return builder ;
@@ -728,10 +729,15 @@ public static IMcpServerBuilder WithSetLoggingLevelHandler(this IMcpServerBuilde
728
729
/// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
729
730
public static IMcpServerBuilder WithStdioServerTransport ( this IMcpServerBuilder builder )
730
731
{
731
- Throw . IfNull ( builder ) ;
732
+ ArgumentNullException . ThrowIfNull ( builder ) ;
732
733
733
734
AddSingleSessionServerDependencies ( builder . Services ) ;
734
- builder . Services . AddSingleton < ITransport , StdioServerTransport > ( ) ;
735
+ builder . Services . AddSingleton < ITransport > ( sp =>
736
+ {
737
+ var serverOptions = sp . GetRequiredService < IOptions < McpServerOptions > > ( ) ;
738
+ var loggerFactory = sp . GetService < ILoggerFactory > ( ) ;
739
+ return new StdioServerTransport ( serverOptions . Value , loggerFactory ) ;
740
+ } ) ;
735
741
736
742
return builder ;
737
743
}
@@ -751,16 +757,43 @@ public static IMcpServerBuilder WithStreamServerTransport(
751
757
Stream inputStream ,
752
758
Stream outputStream )
753
759
{
754
- Throw . IfNull ( builder ) ;
755
- Throw . IfNull ( inputStream ) ;
756
- Throw . IfNull ( outputStream ) ;
760
+ ArgumentNullException . ThrowIfNull ( builder ) ;
761
+ ArgumentNullException . ThrowIfNull ( inputStream ) ;
762
+ ArgumentNullException . ThrowIfNull ( outputStream ) ;
757
763
758
764
AddSingleSessionServerDependencies ( builder . Services ) ;
759
765
builder . Services . AddSingleton < ITransport > ( new StreamServerTransport ( inputStream , outputStream ) ) ;
760
766
761
767
return builder ;
762
768
}
763
769
770
+ /// <summary>
771
+ /// Adds the services necessary for <see cref="M:McpEndpointRouteBuilderExtensions.MapMcp"/>
772
+ /// to handle MCP requests and sessions using the MCP Streamable HTTP transport. For more information on configuring the underlying HTTP server
773
+ /// to control things like port binding custom TLS certificates, see the <see href="https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis">Minimal APIs quick reference</see>.
774
+ /// </summary>
775
+ /// <param name="builder">The builder instance.</param>
776
+ /// <param name="configureOptions">Configures options for the Streamable HTTP transport. This allows configuring per-session
777
+ /// <see cref="McpServerOptions"/> and running logic before and after a session.</param>
778
+ /// <returns>The builder provided in <paramref name="builder"/>.</returns>
779
+ /// <exception cref="ArgumentNullException"><paramref name="builder"/> is <see langword="null"/>.</exception>
780
+ public static IMcpServerBuilder WithHttpTransport ( this IMcpServerBuilder builder , Action < HttpServerTransportOptions > ? configureOptions = null )
781
+ {
782
+ ArgumentNullException . ThrowIfNull ( builder ) ;
783
+
784
+ builder . Services . TryAddSingleton < StreamableHttpHandler > ( ) ;
785
+ builder . Services . TryAddSingleton < SseHandler > ( ) ;
786
+ builder . Services . AddHostedService < IdleTrackingBackgroundService > ( ) ;
787
+ builder . Services . AddDataProtection ( ) ;
788
+
789
+ if ( configureOptions is not null )
790
+ {
791
+ builder . Services . Configure ( configureOptions ) ;
792
+ }
793
+
794
+ return builder ;
795
+ }
796
+
764
797
private static void AddSingleSessionServerDependencies ( IServiceCollection services )
765
798
{
766
799
services . AddHostedService < SingleSessionMcpServerHostedService > ( ) ;
0 commit comments