5
5
using ModelContextProtocol . Shared ;
6
6
using ModelContextProtocol . Utils ;
7
7
using ModelContextProtocol . Utils . Json ;
8
+ using System . Diagnostics ;
8
9
9
10
namespace ModelContextProtocol . Server ;
10
11
@@ -44,49 +45,43 @@ public McpServer(ITransport transport, McpServerOptions options, ILoggerFactory?
44
45
Services = serviceProvider ;
45
46
_endpointName = $ "Server ({ options . ServerInfo ? . Name ?? DefaultImplementation . Name } { options . ServerInfo ? . Version ?? DefaultImplementation . Version } )";
46
47
47
- _toolsChangedDelegate = delegate
48
- {
49
- _ = SendMessageAsync ( new JsonRpcNotification ( )
50
- {
51
- Method = NotificationMethods . ToolListChangedNotification ,
52
- } ) ;
53
- } ;
54
- _promptsChangedDelegate = delegate
55
- {
56
- _ = SendMessageAsync ( new JsonRpcNotification ( )
57
- {
58
- Method = NotificationMethods . PromptListChangedNotification ,
59
- } ) ;
60
- } ;
48
+ // Configure all request handlers based on the supplied options.
49
+ SetInitializeHandler ( options ) ;
50
+ SetToolsHandler ( options ) ;
51
+ SetPromptsHandler ( options ) ;
52
+ SetResourcesHandler ( options ) ;
53
+ SetSetLoggingLevelHandler ( options ) ;
54
+ SetCompletionHandler ( options ) ;
55
+ SetPingHandler ( ) ;
61
56
62
- NotificationHandlers . Add ( NotificationMethods . InitializedNotification , _ =>
57
+ // Register any notification handlers that were provided.
58
+ if ( options . Capabilities ? . NotificationHandlers is { } notificationHandlers )
63
59
{
64
- if ( ServerOptions . Capabilities ? . Tools ? . ToolCollection is { } tools )
65
- {
66
- tools . Changed += _toolsChangedDelegate ;
67
- }
60
+ NotificationHandlers . RegisterRange ( notificationHandlers ) ;
61
+ }
68
62
69
- if ( ServerOptions . Capabilities ? . Prompts ? . PromptCollection is { } prompts )
63
+ // Now that everything has been configured, subscribe to any necessary notifications.
64
+ if ( ServerOptions . Capabilities ? . Tools ? . ToolCollection is { } tools )
65
+ {
66
+ _toolsChangedDelegate = delegate
70
67
{
71
- prompts . Changed += _promptsChangedDelegate ;
72
- }
68
+ _ = SendMessageAsync ( new JsonRpcNotification ( ) { Method = NotificationMethods . ToolListChangedNotification } ) ;
69
+ } ;
73
70
74
- return Task . CompletedTask ;
75
- } ) ;
71
+ tools . Changed += _toolsChangedDelegate ;
72
+ }
76
73
77
- if ( options . Capabilities ? . NotificationHandlers is { } notificationHandlers )
74
+ if ( ServerOptions . Capabilities ? . Prompts ? . PromptCollection is { } prompts )
78
75
{
79
- NotificationHandlers . AddRange ( notificationHandlers ) ;
80
- }
76
+ _promptsChangedDelegate = delegate
77
+ {
78
+ _ = SendMessageAsync ( new JsonRpcNotification ( ) { Method = NotificationMethods . PromptListChangedNotification } ) ;
79
+ } ;
81
80
82
- SetToolsHandler ( options ) ;
83
- SetInitializeHandler ( options ) ;
84
- SetCompletionHandler ( options ) ;
85
- SetPingHandler ( ) ;
86
- SetPromptsHandler ( options ) ;
87
- SetResourcesHandler ( options ) ;
88
- SetSetLoggingLevelHandler ( options ) ;
81
+ prompts . Changed += _promptsChangedDelegate ;
82
+ }
89
83
84
+ // And start the session.
90
85
StartSession ( transport ) ;
91
86
}
92
87
@@ -129,12 +124,14 @@ public async Task RunAsync(CancellationToken cancellationToken = default)
129
124
130
125
public override async ValueTask DisposeUnsynchronizedAsync ( )
131
126
{
132
- if ( ServerOptions . Capabilities ? . Tools ? . ToolCollection is { } tools )
127
+ if ( _toolsChangedDelegate is not null &&
128
+ ServerOptions . Capabilities ? . Tools ? . ToolCollection is { } tools )
133
129
{
134
130
tools . Changed -= _toolsChangedDelegate ;
135
131
}
136
132
137
- if ( ServerOptions . Capabilities ? . Prompts ? . PromptCollection is { } prompts )
133
+ if ( _promptsChangedDelegate is not null &&
134
+ ServerOptions . Capabilities ? . Prompts ? . PromptCollection is { } prompts )
138
135
{
139
136
prompts . Changed -= _promptsChangedDelegate ;
140
137
}
@@ -179,8 +176,8 @@ private void SetCompletionHandler(McpServerOptions options)
179
176
// This capability is not optional, so return an empty result if there is no handler.
180
177
RequestHandlers . Set ( RequestMethods . CompletionComplete ,
181
178
options . GetCompletionHandler is { } handler ?
182
- ( request , ct ) => handler ( new ( this , request ) , ct ) :
183
- ( request , ct ) => Task . FromResult ( new CompleteResult ( ) { Completion = new ( ) { Values = [ ] , Total = 0 , HasMore = false } } ) ,
179
+ ( request , cancellationToken ) => handler ( new ( this , request ) , cancellationToken ) :
180
+ ( request , cancellationToken ) => Task . FromResult ( new CompleteResult ( ) { Completion = new ( ) { Values = [ ] , Total = 0 , HasMore = false } } ) ,
184
181
McpJsonUtilities . JsonContext . Default . CompleteRequestParams ,
185
182
McpJsonUtilities . JsonContext . Default . CompleteResult ) ;
186
183
}
@@ -205,20 +202,20 @@ private void SetResourcesHandler(McpServerOptions options)
205
202
206
203
RequestHandlers . Set (
207
204
RequestMethods . ResourcesList ,
208
- ( request , ct ) => listResourcesHandler ( new ( this , request ) , ct ) ,
205
+ ( request , cancellationToken ) => listResourcesHandler ( new ( this , request ) , cancellationToken ) ,
209
206
McpJsonUtilities . JsonContext . Default . ListResourcesRequestParams ,
210
207
McpJsonUtilities . JsonContext . Default . ListResourcesResult ) ;
211
208
212
209
RequestHandlers . Set (
213
210
RequestMethods . ResourcesRead ,
214
- ( request , ct ) => readResourceHandler ( new ( this , request ) , ct ) ,
211
+ ( request , cancellationToken ) => readResourceHandler ( new ( this , request ) , cancellationToken ) ,
215
212
McpJsonUtilities . JsonContext . Default . ReadResourceRequestParams ,
216
213
McpJsonUtilities . JsonContext . Default . ReadResourceResult ) ;
217
214
218
215
listResourceTemplatesHandler ??= ( static ( _ , _ ) => Task . FromResult ( new ListResourceTemplatesResult ( ) ) ) ;
219
216
RequestHandlers . Set (
220
217
RequestMethods . ResourcesTemplatesList ,
221
- ( request , ct ) => listResourceTemplatesHandler ( new ( this , request ) , ct ) ,
218
+ ( request , cancellationToken ) => listResourceTemplatesHandler ( new ( this , request ) , cancellationToken ) ,
222
219
McpJsonUtilities . JsonContext . Default . ListResourceTemplatesRequestParams ,
223
220
McpJsonUtilities . JsonContext . Default . ListResourceTemplatesResult ) ;
224
221
@@ -236,13 +233,13 @@ private void SetResourcesHandler(McpServerOptions options)
236
233
237
234
RequestHandlers . Set (
238
235
RequestMethods . ResourcesSubscribe ,
239
- ( request , ct ) => subscribeHandler ( new ( this , request ) , ct ) ,
236
+ ( request , cancellationToken ) => subscribeHandler ( new ( this , request ) , cancellationToken ) ,
240
237
McpJsonUtilities . JsonContext . Default . SubscribeRequestParams ,
241
238
McpJsonUtilities . JsonContext . Default . EmptyResult ) ;
242
239
243
240
RequestHandlers . Set (
244
241
RequestMethods . ResourcesUnsubscribe ,
245
- ( request , ct ) => unsubscribeHandler ( new ( this , request ) , ct ) ,
242
+ ( request , cancellationToken ) => unsubscribeHandler ( new ( this , request ) , cancellationToken ) ,
246
243
McpJsonUtilities . JsonContext . Default . UnsubscribeRequestParams ,
247
244
McpJsonUtilities . JsonContext . Default . EmptyResult ) ;
248
245
}
@@ -329,13 +326,13 @@ await originalListPromptsHandler(request, cancellationToken).ConfigureAwait(fals
329
326
330
327
RequestHandlers . Set (
331
328
RequestMethods . PromptsList ,
332
- ( request , ct ) => listPromptsHandler ( new ( this , request ) , ct ) ,
329
+ ( request , cancellationToken ) => listPromptsHandler ( new ( this , request ) , cancellationToken ) ,
333
330
McpJsonUtilities . JsonContext . Default . ListPromptsRequestParams ,
334
331
McpJsonUtilities . JsonContext . Default . ListPromptsResult ) ;
335
332
336
333
RequestHandlers . Set (
337
334
RequestMethods . PromptsGet ,
338
- ( request , ct ) => getPromptHandler ( new ( this , request ) , ct ) ,
335
+ ( request , cancellationToken ) => getPromptHandler ( new ( this , request ) , cancellationToken ) ,
339
336
McpJsonUtilities . JsonContext . Default . GetPromptRequestParams ,
340
337
McpJsonUtilities . JsonContext . Default . GetPromptResult ) ;
341
338
}
@@ -422,13 +419,13 @@ await originalListToolsHandler(request, cancellationToken).ConfigureAwait(false)
422
419
423
420
RequestHandlers . Set (
424
421
RequestMethods . ToolsList ,
425
- ( request , ct ) => listToolsHandler ( new ( this , request ) , ct ) ,
422
+ ( request , cancellationToken ) => listToolsHandler ( new ( this , request ) , cancellationToken ) ,
426
423
McpJsonUtilities . JsonContext . Default . ListToolsRequestParams ,
427
424
McpJsonUtilities . JsonContext . Default . ListToolsResult ) ;
428
425
429
426
RequestHandlers . Set (
430
427
RequestMethods . ToolsCall ,
431
- ( request , ct ) => callToolHandler ( new ( this , request ) , ct ) ,
428
+ ( request , cancellationToken ) => callToolHandler ( new ( this , request ) , cancellationToken ) ,
432
429
McpJsonUtilities . JsonContext . Default . CallToolRequestParams ,
433
430
McpJsonUtilities . JsonContext . Default . CallToolResponse ) ;
434
431
}
@@ -447,7 +444,7 @@ private void SetSetLoggingLevelHandler(McpServerOptions options)
447
444
448
445
RequestHandlers . Set (
449
446
RequestMethods . LoggingSetLevel ,
450
- ( request , ct ) => setLoggingLevelHandler ( new ( this , request ) , ct ) ,
447
+ ( request , cancellationToken ) => setLoggingLevelHandler ( new ( this , request ) , cancellationToken ) ,
451
448
McpJsonUtilities . JsonContext . Default . SetLevelRequestParams ,
452
449
McpJsonUtilities . JsonContext . Default . EmptyResult ) ;
453
450
}
0 commit comments