1
- using ModelContextProtocol . Client ;
1
+ using Microsoft . Extensions . AI ;
2
+ using Microsoft . Extensions . Logging ;
3
+ using ModelContextProtocol . Client ;
2
4
using ModelContextProtocol . Protocol . Messages ;
3
5
using ModelContextProtocol . Protocol . Transport ;
4
6
using ModelContextProtocol . Protocol . Types ;
5
7
using ModelContextProtocol . Server ;
6
8
using ModelContextProtocol . Tests . Utils ;
7
- using Microsoft . Extensions . AI ;
8
- using Microsoft . Extensions . Logging ;
9
9
using Moq ;
10
+ using System . Reflection ;
10
11
11
12
namespace ModelContextProtocol . Tests . Server ;
12
13
@@ -43,7 +44,7 @@ private static McpServerOptions CreateOptions(ServerCapabilities? capabilities =
43
44
public async Task Constructor_Should_Initialize_With_Valid_Parameters ( )
44
45
{
45
46
// Arrange & Act
46
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
47
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
47
48
48
49
// Assert
49
50
Assert . NotNull ( server ) ;
@@ -53,21 +54,21 @@ public async Task Constructor_Should_Initialize_With_Valid_Parameters()
53
54
public void Constructor_Throws_For_Null_Transport ( )
54
55
{
55
56
// Arrange, Act & Assert
56
- Assert . Throws < ArgumentNullException > ( ( ) => new McpServer ( null ! , _options , _loggerFactory . Object , _serviceProvider ) ) ;
57
+ Assert . Throws < ArgumentNullException > ( ( ) => McpServerFactory . Create ( null ! , _options , _loggerFactory . Object , _serviceProvider ) ) ;
57
58
}
58
59
59
60
[ Fact ]
60
61
public void Constructor_Throws_For_Null_Options ( )
61
62
{
62
63
// Arrange, Act & Assert
63
- Assert . Throws < ArgumentNullException > ( ( ) => new McpServer ( _serverTransport . Object , null ! , _loggerFactory . Object , _serviceProvider ) ) ;
64
+ Assert . Throws < ArgumentNullException > ( ( ) => McpServerFactory . Create ( _serverTransport . Object , null ! , _loggerFactory . Object , _serviceProvider ) ) ;
64
65
}
65
66
66
67
[ Fact ]
67
68
public async Task Constructor_Does_Not_Throw_For_Null_Logger ( )
68
69
{
69
70
// Arrange & Act
70
- await using var server = new McpServer ( _serverTransport . Object , _options , null , _serviceProvider ) ;
71
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , null , _serviceProvider ) ;
71
72
72
73
// Assert
73
74
Assert . NotNull ( server ) ;
@@ -77,25 +78,17 @@ public async Task Constructor_Does_Not_Throw_For_Null_Logger()
77
78
public async Task Constructor_Does_Not_Throw_For_Null_ServiceProvider ( )
78
79
{
79
80
// Arrange & Act
80
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , null ) ;
81
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , null ) ;
81
82
82
83
// Assert
83
84
Assert . NotNull ( server ) ;
84
85
}
85
86
86
- [ Fact ]
87
- public async Task Property_EndpointName_Return_Infos ( )
88
- {
89
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
90
- server . ClientInfo = new Implementation { Name = "TestClient" , Version = "1.1" } ;
91
- Assert . Equal ( "Server (TestServer 1.0), Client (TestClient 1.1)" , server . EndpointName ) ;
92
- }
93
-
94
87
[ Fact ]
95
88
public async Task StartAsync_Should_Throw_InvalidOperationException_If_Already_Initializing ( )
96
89
{
97
90
// Arrange
98
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
91
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
99
92
server . GetType ( ) . GetField ( "_isInitializing" , System . Reflection . BindingFlags . NonPublic | System . Reflection . BindingFlags . Instance ) ? . SetValue ( server , true ) ;
100
93
101
94
// Act & Assert
@@ -106,8 +99,8 @@ public async Task StartAsync_Should_Throw_InvalidOperationException_If_Already_I
106
99
public async Task StartAsync_Should_Do_Nothing_If_Already_Initialized ( )
107
100
{
108
101
// Arrange
109
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
110
- server . IsInitialized = true ;
102
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
103
+ SetInitialized ( server , true ) ;
111
104
112
105
await server . StartAsync ( TestContext . Current . CancellationToken ) ;
113
106
@@ -119,7 +112,7 @@ public async Task StartAsync_Should_Do_Nothing_If_Already_Initialized()
119
112
public async Task StartAsync_ShouldStartListening ( )
120
113
{
121
114
// Arrange
122
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
115
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
123
116
124
117
// Act
125
118
await server . StartAsync ( TestContext . Current . CancellationToken ) ;
@@ -132,7 +125,7 @@ public async Task StartAsync_ShouldStartListening()
132
125
public async Task StartAsync_Sets_Initialized_After_Transport_Responses_Initialized_Notification ( )
133
126
{
134
127
await using var transport = new TestServerTransport ( ) ;
135
- await using var server = new McpServer ( transport , _options , _loggerFactory . Object , _serviceProvider ) ;
128
+ await using var server = McpServerFactory . Create ( transport , _options , _loggerFactory . Object , _serviceProvider ) ;
136
129
137
130
await server . StartAsync ( TestContext . Current . CancellationToken ) ;
138
131
@@ -152,8 +145,8 @@ await transport.SendMessageAsync(new JsonRpcNotification
152
145
public async Task RequestSamplingAsync_Should_Throw_McpServerException_If_Client_Does_Not_Support_Sampling ( )
153
146
{
154
147
// Arrange
155
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
156
- server . ClientCapabilities = new ClientCapabilities ( ) ;
148
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
149
+ SetClientCapabilities ( server , new ClientCapabilities ( ) ) ;
157
150
158
151
var action = ( ) => server . RequestSamplingAsync ( new CreateMessageRequestParams { Messages = [ ] } , CancellationToken . None ) ;
159
152
@@ -166,8 +159,8 @@ public async Task RequestSamplingAsync_Should_SendRequest()
166
159
{
167
160
// Arrange
168
161
await using var transport = new TestServerTransport ( ) ;
169
- await using var server = new McpServer ( transport , _options , _loggerFactory . Object , _serviceProvider ) ;
170
- server . ClientCapabilities = new ClientCapabilities { Sampling = new SamplingCapability ( ) } ;
162
+ await using var server = McpServerFactory . Create ( transport , _options , _loggerFactory . Object , _serviceProvider ) ;
163
+ SetClientCapabilities ( server , new ClientCapabilities { Sampling = new SamplingCapability ( ) } ) ;
171
164
172
165
await server . StartAsync ( TestContext . Current . CancellationToken ) ;
173
166
@@ -184,8 +177,8 @@ public async Task RequestSamplingAsync_Should_SendRequest()
184
177
public async Task RequestRootsAsync_Should_Throw_McpServerException_If_Client_Does_Not_Support_Roots ( )
185
178
{
186
179
// Arrange
187
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
188
- server . ClientCapabilities = new ClientCapabilities ( ) ;
180
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
181
+ SetClientCapabilities ( server , new ClientCapabilities ( ) ) ;
189
182
190
183
// Act & Assert
191
184
await Assert . ThrowsAsync < ArgumentException > ( "server" , ( ) => server . RequestRootsAsync ( new ListRootsRequestParams ( ) , CancellationToken . None ) ) ;
@@ -196,8 +189,8 @@ public async Task RequestRootsAsync_Should_SendRequest()
196
189
{
197
190
// Arrange
198
191
await using var transport = new TestServerTransport ( ) ;
199
- await using var server = new McpServer ( transport , _options , _loggerFactory . Object , _serviceProvider ) ;
200
- server . ClientCapabilities = new ClientCapabilities { Roots = new RootsCapability ( ) } ;
192
+ await using var server = McpServerFactory . Create ( transport , _options , _loggerFactory . Object , _serviceProvider ) ;
193
+ SetClientCapabilities ( server , new ClientCapabilities { Roots = new RootsCapability ( ) } ) ;
201
194
await server . StartAsync ( TestContext . Current . CancellationToken ) ;
202
195
203
196
// Act
@@ -213,8 +206,8 @@ public async Task RequestRootsAsync_Should_SendRequest()
213
206
[ Fact ]
214
207
public async Task Throws_Exception_If_Not_Connected ( )
215
208
{
216
- await using var server = new McpServer ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
217
- server . ClientCapabilities = new ClientCapabilities { Roots = new RootsCapability ( ) } ;
209
+ await using var server = McpServerFactory . Create ( _serverTransport . Object , _options , _loggerFactory . Object , _serviceProvider ) ;
210
+ SetClientCapabilities ( server , new ClientCapabilities { Roots = new RootsCapability ( ) } ) ;
218
211
_serverTransport . SetupGet ( t => t . IsConnected ) . Returns ( false ) ;
219
212
220
213
var action = async ( ) => await server . RequestRootsAsync ( new ListRootsRequestParams ( ) , CancellationToken . None ) ;
@@ -522,7 +515,7 @@ private async Task Can_Handle_Requests(ServerCapabilities? serverCapabilities, s
522
515
var options = CreateOptions ( serverCapabilities ) ;
523
516
configureOptions ? . Invoke ( options ) ;
524
517
525
- await using var server = new McpServer ( transport , options , _loggerFactory . Object , _serviceProvider ) ;
518
+ await using var server = McpServerFactory . Create ( transport , options , _loggerFactory . Object , _serviceProvider ) ;
526
519
527
520
await server . StartAsync ( ) ;
528
521
@@ -595,6 +588,20 @@ public async Task AsSamplingChatClient_HandlesRequestResponse()
595
588
Assert . Equal ( ChatRole . Assistant , response . Messages [ 0 ] . Role ) ;
596
589
}
597
590
591
+ private static void SetClientCapabilities ( IMcpServer server , ClientCapabilities capabilities )
592
+ {
593
+ PropertyInfo ? property = server . GetType ( ) . GetProperty ( "ClientCapabilities" , BindingFlags . Public | BindingFlags . Instance ) ;
594
+ Assert . NotNull ( property ) ;
595
+ property . SetValue ( server , capabilities ) ;
596
+ }
597
+
598
+ private static void SetInitialized ( IMcpServer server , bool isInitialized )
599
+ {
600
+ PropertyInfo ? property = server . GetType ( ) . GetProperty ( "IsInitialized" , BindingFlags . Public | BindingFlags . Instance ) ;
601
+ Assert . NotNull ( property ) ;
602
+ property . SetValue ( server , isInitialized ) ;
603
+ }
604
+
598
605
private sealed class TestServerForIChatClient ( bool supportsSampling ) : IMcpServer
599
606
{
600
607
public ClientCapabilities ? ClientCapabilities =>
0 commit comments