Skip to content

Commit 411cef6

Browse files
authored
Don't treat McpServerHandlers as an independent options type (#1313)
1 parent 80b1ad2 commit 411cef6

File tree

3 files changed

+89
-100
lines changed

3 files changed

+89
-100
lines changed

src/ModelContextProtocol/McpServerBuilderExtensions.cs

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,12 @@ public static IMcpServerBuilder WithListResourceTemplatesHandler(this IMcpServer
583583
{
584584
Throw.IfNull(builder);
585585

586-
builder.Services.Configure<McpServerHandlers>(s => s.ListResourceTemplatesHandler = handler);
586+
builder.Services.Configure<McpServerOptions>(options =>
587+
{
588+
options.Handlers.ListResourceTemplatesHandler = handler;
589+
options.Capabilities ??= new();
590+
options.Capabilities.Resources ??= new();
591+
});
587592
return builder;
588593
}
589594

@@ -616,7 +621,12 @@ public static IMcpServerBuilder WithListToolsHandler(this IMcpServerBuilder buil
616621
{
617622
Throw.IfNull(builder);
618623

619-
builder.Services.Configure<McpServerHandlers>(s => s.ListToolsHandler = handler);
624+
builder.Services.Configure<McpServerOptions>(options =>
625+
{
626+
options.Handlers.ListToolsHandler = handler;
627+
options.Capabilities ??= new();
628+
options.Capabilities.Tools ??= new();
629+
});
620630
return builder;
621631
}
622632

@@ -636,7 +646,12 @@ public static IMcpServerBuilder WithCallToolHandler(this IMcpServerBuilder build
636646
{
637647
Throw.IfNull(builder);
638648

639-
builder.Services.Configure<McpServerHandlers>(s => s.CallToolHandler = handler);
649+
builder.Services.Configure<McpServerOptions>(options =>
650+
{
651+
options.Handlers.CallToolHandler = handler;
652+
options.Capabilities ??= new();
653+
options.Capabilities.Tools ??= new();
654+
});
640655
return builder;
641656
}
642657

@@ -669,7 +684,12 @@ public static IMcpServerBuilder WithListPromptsHandler(this IMcpServerBuilder bu
669684
{
670685
Throw.IfNull(builder);
671686

672-
builder.Services.Configure<McpServerHandlers>(s => s.ListPromptsHandler = handler);
687+
builder.Services.Configure<McpServerOptions>(options =>
688+
{
689+
options.Handlers.ListPromptsHandler = handler;
690+
options.Capabilities ??= new();
691+
options.Capabilities.Prompts ??= new();
692+
});
673693
return builder;
674694
}
675695

@@ -684,7 +704,12 @@ public static IMcpServerBuilder WithGetPromptHandler(this IMcpServerBuilder buil
684704
{
685705
Throw.IfNull(builder);
686706

687-
builder.Services.Configure<McpServerHandlers>(s => s.GetPromptHandler = handler);
707+
builder.Services.Configure<McpServerOptions>(options =>
708+
{
709+
options.Handlers.GetPromptHandler = handler;
710+
options.Capabilities ??= new();
711+
options.Capabilities.Prompts ??= new();
712+
});
688713
return builder;
689714
}
690715

@@ -705,7 +730,12 @@ public static IMcpServerBuilder WithListResourcesHandler(this IMcpServerBuilder
705730
{
706731
Throw.IfNull(builder);
707732

708-
builder.Services.Configure<McpServerHandlers>(s => s.ListResourcesHandler = handler);
733+
builder.Services.Configure<McpServerOptions>(options =>
734+
{
735+
options.Handlers.ListResourcesHandler = handler;
736+
options.Capabilities ??= new();
737+
options.Capabilities.Resources ??= new();
738+
});
709739
return builder;
710740
}
711741

@@ -724,7 +754,12 @@ public static IMcpServerBuilder WithReadResourceHandler(this IMcpServerBuilder b
724754
{
725755
Throw.IfNull(builder);
726756

727-
builder.Services.Configure<McpServerHandlers>(s => s.ReadResourceHandler = handler);
757+
builder.Services.Configure<McpServerOptions>(options =>
758+
{
759+
options.Handlers.ReadResourceHandler = handler;
760+
options.Capabilities ??= new();
761+
options.Capabilities.Resources ??= new();
762+
});
728763
return builder;
729764
}
730765

@@ -743,7 +778,12 @@ public static IMcpServerBuilder WithCompleteHandler(this IMcpServerBuilder build
743778
{
744779
Throw.IfNull(builder);
745780

746-
builder.Services.Configure<McpServerHandlers>(s => s.CompleteHandler = handler);
781+
builder.Services.Configure<McpServerOptions>(options =>
782+
{
783+
options.Handlers.CompleteHandler = handler;
784+
options.Capabilities ??= new();
785+
options.Capabilities.Completions ??= new();
786+
});
747787
return builder;
748788
}
749789

@@ -773,7 +813,13 @@ public static IMcpServerBuilder WithSubscribeToResourcesHandler(this IMcpServerB
773813
{
774814
Throw.IfNull(builder);
775815

776-
builder.Services.Configure<McpServerHandlers>(s => s.SubscribeToResourcesHandler = handler);
816+
builder.Services.Configure<McpServerOptions>(options =>
817+
{
818+
options.Handlers.SubscribeToResourcesHandler = handler;
819+
options.Capabilities ??= new();
820+
options.Capabilities.Resources ??= new();
821+
options.Capabilities.Resources.Subscribe = true;
822+
});
777823
return builder;
778824
}
779825

@@ -803,7 +849,13 @@ public static IMcpServerBuilder WithUnsubscribeFromResourcesHandler(this IMcpSer
803849
{
804850
Throw.IfNull(builder);
805851

806-
builder.Services.Configure<McpServerHandlers>(s => s.UnsubscribeFromResourcesHandler = handler);
852+
builder.Services.Configure<McpServerOptions>(options =>
853+
{
854+
options.Handlers.UnsubscribeFromResourcesHandler = handler;
855+
options.Capabilities ??= new();
856+
options.Capabilities.Resources ??= new();
857+
options.Capabilities.Resources.Subscribe = true;
858+
});
807859
return builder;
808860
}
809861

@@ -830,7 +882,12 @@ public static IMcpServerBuilder WithSetLoggingLevelHandler(this IMcpServerBuilde
830882
{
831883
Throw.IfNull(builder);
832884

833-
builder.Services.Configure<McpServerHandlers>(s => s.SetLoggingLevelHandler = handler);
885+
builder.Services.Configure<McpServerOptions>(options =>
886+
{
887+
options.Handlers.SetLoggingLevelHandler = handler;
888+
options.Capabilities ??= new();
889+
options.Capabilities.Logging ??= new();
890+
});
834891
return builder;
835892
}
836893
#endregion
Lines changed: 1 addition & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
using Microsoft.Extensions.Options;
2-
using ModelContextProtocol.Protocol;
32
using ModelContextProtocol.Server;
43

54
namespace ModelContextProtocol;
65

76
/// <summary>
87
/// Configures the McpServerOptions using addition services from DI.
98
/// </summary>
10-
/// <param name="serverHandlers">The server handlers configuration options.</param>
119
/// <param name="serverTools">The individually registered tools.</param>
1210
/// <param name="serverPrompts">The individually registered prompts.</param>
1311
/// <param name="serverResources">The individually registered resources.</param>
1412
internal sealed class McpServerOptionsSetup(
15-
IOptions<McpServerHandlers> serverHandlers,
1613
IEnumerable<McpServerTool> serverTools,
1714
IEnumerable<McpServerPrompt> serverPrompts,
1815
IEnumerable<McpServerResource> serverResources) : IConfigureOptions<McpServerOptions>
1916
{
2017
/// <summary>
2118
/// Configures the given McpServerOptions instance by setting server information
22-
/// and applying custom server handlers and tools.
19+
/// and collecting registered server primitives.
2320
/// </summary>
2421
/// <param name="options">The options instance to be configured.</param>
2522
public void Configure(McpServerOptions options)
@@ -70,70 +67,5 @@ public void Configure(McpServerOptions options)
7067
{
7168
options.ResourceCollection = resourceCollection;
7269
}
73-
74-
// Apply custom server handlers.
75-
OverwriteWithSetHandlers(serverHandlers.Value, options);
76-
}
77-
78-
/// <summary>
79-
/// Overwrite any handlers in McpServerOptions with non-null handlers from this instance.
80-
/// </summary>
81-
private static void OverwriteWithSetHandlers(McpServerHandlers handlers, McpServerOptions options)
82-
{
83-
McpServerHandlers optionsHandlers = options.Handlers;
84-
85-
PromptsCapability? promptsCapability = options.Capabilities?.Prompts;
86-
if (handlers.ListPromptsHandler is not null || handlers.GetPromptHandler is not null)
87-
{
88-
promptsCapability ??= new();
89-
optionsHandlers.ListPromptsHandler = handlers.ListPromptsHandler ?? optionsHandlers.ListPromptsHandler;
90-
optionsHandlers.GetPromptHandler = handlers.GetPromptHandler ?? optionsHandlers.GetPromptHandler;
91-
}
92-
93-
ResourcesCapability? resourcesCapability = options.Capabilities?.Resources;
94-
if (handlers.ListResourceTemplatesHandler is not null || handlers.ListResourcesHandler is not null || handlers.ReadResourceHandler is not null)
95-
{
96-
resourcesCapability ??= new();
97-
optionsHandlers.ListResourceTemplatesHandler = handlers.ListResourceTemplatesHandler ?? optionsHandlers.ListResourceTemplatesHandler;
98-
optionsHandlers.ListResourcesHandler = handlers.ListResourcesHandler ?? optionsHandlers.ListResourcesHandler;
99-
optionsHandlers.ReadResourceHandler = handlers.ReadResourceHandler ?? optionsHandlers.ReadResourceHandler;
100-
}
101-
102-
if (handlers.SubscribeToResourcesHandler is not null || handlers.UnsubscribeFromResourcesHandler is not null)
103-
{
104-
resourcesCapability ??= new();
105-
optionsHandlers.SubscribeToResourcesHandler = handlers.SubscribeToResourcesHandler ?? optionsHandlers.SubscribeToResourcesHandler;
106-
optionsHandlers.UnsubscribeFromResourcesHandler = handlers.UnsubscribeFromResourcesHandler ?? optionsHandlers.UnsubscribeFromResourcesHandler;
107-
resourcesCapability.Subscribe = true;
108-
}
109-
110-
ToolsCapability? toolsCapability = options.Capabilities?.Tools;
111-
if (handlers.ListToolsHandler is not null || handlers.CallToolHandler is not null)
112-
{
113-
toolsCapability ??= new();
114-
optionsHandlers.ListToolsHandler = handlers.ListToolsHandler ?? optionsHandlers.ListToolsHandler;
115-
optionsHandlers.CallToolHandler = handlers.CallToolHandler ?? optionsHandlers.CallToolHandler;
116-
}
117-
118-
LoggingCapability? loggingCapability = options.Capabilities?.Logging;
119-
if (handlers.SetLoggingLevelHandler is not null)
120-
{
121-
loggingCapability ??= new();
122-
optionsHandlers.SetLoggingLevelHandler = handlers.SetLoggingLevelHandler;
123-
}
124-
125-
CompletionsCapability? completionsCapability = options.Capabilities?.Completions;
126-
if (handlers.CompleteHandler is not null)
127-
{
128-
completionsCapability ??= new();
129-
optionsHandlers.CompleteHandler = handlers.CompleteHandler;
130-
}
131-
132-
options.Capabilities ??= new();
133-
options.Capabilities.Prompts = promptsCapability;
134-
options.Capabilities.Resources = resourcesCapability;
135-
options.Capabilities.Tools = toolsCapability;
136-
options.Capabilities.Logging = loggingCapability;
137-
options.Capabilities.Completions = completionsCapability;
13870
}
13971
}

tests/ModelContextProtocol.Tests/Configuration/McpServerBuilderExtensionsHandlerTests.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ public void WithListToolsHandler_Sets_Handler()
2626
_builder.Object.WithListToolsHandler(handler);
2727

2828
var serviceProvider = _services.BuildServiceProvider();
29-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
29+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
3030

31-
Assert.Equal(handler, options.ListToolsHandler);
31+
Assert.Equal(handler, options.Handlers.ListToolsHandler);
3232
}
3333

3434
[Fact]
@@ -39,9 +39,9 @@ public void WithCallToolHandler_Sets_Handler()
3939
_builder.Object.WithCallToolHandler(handler);
4040

4141
var serviceProvider = _services.BuildServiceProvider();
42-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
42+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
4343

44-
Assert.Equal(handler, options.CallToolHandler);
44+
Assert.Equal(handler, options.Handlers.CallToolHandler);
4545
}
4646

4747
[Fact]
@@ -52,9 +52,9 @@ public void WithListPromptsHandler_Sets_Handler()
5252
_builder.Object.WithListPromptsHandler(handler);
5353

5454
var serviceProvider = _services.BuildServiceProvider();
55-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
55+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
5656

57-
Assert.Equal(handler, options.ListPromptsHandler);
57+
Assert.Equal(handler, options.Handlers.ListPromptsHandler);
5858
}
5959

6060
[Fact]
@@ -65,9 +65,9 @@ public void WithGetPromptHandler_Sets_Handler()
6565
_builder.Object.WithGetPromptHandler(handler);
6666

6767
var serviceProvider = _services.BuildServiceProvider();
68-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
68+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
6969

70-
Assert.Equal(handler, options.GetPromptHandler);
70+
Assert.Equal(handler, options.Handlers.GetPromptHandler);
7171
}
7272

7373
[Fact]
@@ -78,9 +78,9 @@ public void WithListResourceTemplatesHandler_Sets_Handler()
7878
_builder.Object.WithListResourceTemplatesHandler(handler);
7979

8080
var serviceProvider = _services.BuildServiceProvider();
81-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
81+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
8282

83-
Assert.Equal(handler, options.ListResourceTemplatesHandler);
83+
Assert.Equal(handler, options.Handlers.ListResourceTemplatesHandler);
8484
}
8585

8686
[Fact]
@@ -91,9 +91,9 @@ public void WithListResourcesHandler_Sets_Handler()
9191
_builder.Object.WithListResourcesHandler(handler);
9292

9393
var serviceProvider = _services.BuildServiceProvider();
94-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
94+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
9595

96-
Assert.Equal(handler, options.ListResourcesHandler);
96+
Assert.Equal(handler, options.Handlers.ListResourcesHandler);
9797
}
9898

9999
[Fact]
@@ -104,9 +104,9 @@ public void WithReadResourceHandler_Sets_Handler()
104104
_builder.Object.WithReadResourceHandler(handler);
105105

106106
var serviceProvider = _services.BuildServiceProvider();
107-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
107+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
108108

109-
Assert.Equal(handler, options.ReadResourceHandler);
109+
Assert.Equal(handler, options.Handlers.ReadResourceHandler);
110110
}
111111

112112
[Fact]
@@ -117,9 +117,9 @@ public void WithCompleteHandler_Sets_Handler()
117117
_builder.Object.WithCompleteHandler(handler);
118118

119119
var serviceProvider = _services.BuildServiceProvider();
120-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
120+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
121121

122-
Assert.Equal(handler, options.CompleteHandler);
122+
Assert.Equal(handler, options.Handlers.CompleteHandler);
123123
}
124124

125125
[Fact]
@@ -130,9 +130,9 @@ public void WithSubscribeToResourcesHandler_Sets_Handler()
130130
_builder.Object.WithSubscribeToResourcesHandler(handler);
131131

132132
var serviceProvider = _services.BuildServiceProvider();
133-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
133+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
134134

135-
Assert.Equal(handler, options.SubscribeToResourcesHandler);
135+
Assert.Equal(handler, options.Handlers.SubscribeToResourcesHandler);
136136
}
137137

138138
[Fact]
@@ -143,8 +143,8 @@ public void WithUnsubscribeFromResourcesHandler_Sets_Handler()
143143
_builder.Object.WithUnsubscribeFromResourcesHandler(handler);
144144

145145
var serviceProvider = _services.BuildServiceProvider();
146-
var options = serviceProvider.GetRequiredService<IOptions<McpServerHandlers>>().Value;
146+
var options = serviceProvider.GetRequiredService<IOptions<McpServerOptions>>().Value;
147147

148-
Assert.Equal(handler, options.UnsubscribeFromResourcesHandler);
148+
Assert.Equal(handler, options.Handlers.UnsubscribeFromResourcesHandler);
149149
}
150150
}

0 commit comments

Comments
 (0)