Skip to content

Commit 68fe047

Browse files
committed
Add ClientSupportsRoots and ClientSupportsSampling methods
rename SupportsElicitation to ClientSupportsElicitation
1 parent 4f99673 commit 68fe047

File tree

2 files changed

+135
-6
lines changed

2 files changed

+135
-6
lines changed

src/ModelContextProtocol.Core/Server/McpServerExtensions.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,46 @@ public static ValueTask<ElicitResult> ElicitAsync(
245245
/// <remarks>
246246
/// When <see langword="true"/>, the server can call <see cref="McpServerExtensions.ElicitAsync"/> to request additional information from the user via the client.
247247
/// </remarks>
248-
public static bool SupportsElicitation(this IMcpServer server)
248+
public static bool ClientSupportsElicitation(this IMcpServer server)
249249
{
250250
Throw.IfNull(server);
251251
return server.ClientCapabilities?.Elicitation is not null;
252252
}
253253

254+
/// <summary>
255+
/// Determines whether client supports roots capability.
256+
/// </summary>
257+
/// <param name="server">McpServer instance to check.</param>
258+
/// <returns>
259+
/// <see langword="true"/> if client supports roots requests; otherwise, <see langword="false"/>.
260+
/// </returns>
261+
/// <exception cref="ArgumentNullException"><paramref name="server"/> is <see langword="null"/>.</exception>
262+
/// <remarks>
263+
/// When <see langword="true"/>, the server can call <see cref="McpServerExtensions.RequestRootsAsync"/> to request the list of roots exposed by the client.
264+
/// </remarks>
265+
public static bool ClientSupportsRoots(this IMcpServer server)
266+
{
267+
Throw.IfNull(server);
268+
return server.ClientCapabilities?.Roots is not null;
269+
}
270+
271+
/// <summary>
272+
/// Determines whether client supports sampling capability.
273+
/// </summary>
274+
/// <param name="server">McpServer instance to check.</param>
275+
/// <returns>
276+
/// <see langword="true"/> if client supports sampling requests; otherwise, <see langword="false"/>.
277+
/// </returns>
278+
/// <exception cref="ArgumentNullException"><paramref name="server"/> is <see langword="null"/>.</exception>
279+
/// <remarks>
280+
/// When <see langword="true"/>, the server can call sampling methods to request LLM sampling via the client.
281+
/// </remarks>
282+
public static bool ClientSupportsSampling(this IMcpServer server)
283+
{
284+
Throw.IfNull(server);
285+
return server.ClientCapabilities?.Sampling is not null;
286+
}
287+
254288
private static void ThrowIfSamplingUnsupported(IMcpServer server)
255289
{
256290
if (server.ClientCapabilities?.Sampling is null)

tests/ModelContextProtocol.Tests/Server/McpServerTests.cs

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,28 +178,123 @@ public async Task ElicitAsync_Should_Throw_Exception_If_Client_Does_Not_Support_
178178
}
179179

180180
[Fact]
181-
public void SupportsElicitation_Should_Throw_ArgumentNullException_If_Server_Is_Null()
181+
public void ClientSupportsElicitation_Should_Throw_ArgumentNullException_If_Server_Is_Null()
182182
{
183183
// Arrange
184184
IMcpServer? server = null;
185185

186186
// Act & Assert
187-
Assert.Throws<ArgumentNullException>(() => server!.SupportsElicitation());
187+
Assert.Throws<ArgumentNullException>(() => server!.ClientSupportsElicitation());
188188
}
189189

190190
[Fact]
191-
public async Task SupportsElicitation_Should_Return_False_If_ElicitationCapability_Is_Not_Set()
191+
public async Task ClientSupportsElicitation_Should_Return_False_If_ElicitationCapability_Is_Not_Set()
192192
{
193193
// Arrange
194194
await using var transport = new TestServerTransport();
195195
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
196196
SetClientCapabilities(server, new ClientCapabilities { Elicitation = null });
197197

198198
// Act
199-
var supportsElicitation = server.SupportsElicitation();
199+
var clientSupportsElicitation = server.ClientSupportsElicitation();
200200

201201
// Assert
202-
Assert.False(supportsElicitation);
202+
Assert.False(clientSupportsElicitation);
203+
}
204+
205+
[Fact]
206+
public async Task ClientSupportsElicitation_Should_Return_True_If_ElicitationCapability_Is_Set()
207+
{
208+
// Arrange
209+
await using var transport = new TestServerTransport();
210+
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
211+
SetClientCapabilities(server, new ClientCapabilities { Elicitation = new ElicitationCapability() });
212+
213+
// Act
214+
var clientSupportsElicitation = server.ClientSupportsElicitation();
215+
216+
// Assert
217+
Assert.True(clientSupportsElicitation);
218+
}
219+
220+
[Fact]
221+
public void ClientSupportsRoots_Should_Throw_ArgumentNullException_If_Server_Is_Null()
222+
{
223+
// Arrange
224+
IMcpServer? server = null;
225+
226+
// Act & Assert
227+
Assert.Throws<ArgumentNullException>(() => server!.ClientSupportsRoots());
228+
}
229+
230+
[Fact]
231+
public async Task ClientSupportsRoots_Should_Return_False_If_RootsCapability_Is_Not_Set()
232+
{
233+
// Arrange
234+
await using var transport = new TestServerTransport();
235+
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
236+
SetClientCapabilities(server, new ClientCapabilities { Roots = null });
237+
238+
// Act
239+
var clientSupportsRoots = server.ClientSupportsRoots();
240+
241+
// Assert
242+
Assert.False(clientSupportsRoots);
243+
}
244+
245+
[Fact]
246+
public async Task ClientSupportsRoots_Should_Return_True_If_RootsCapability_Is_Set()
247+
{
248+
// Arrange
249+
await using var transport = new TestServerTransport();
250+
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
251+
SetClientCapabilities(server, new ClientCapabilities { Roots = new RootsCapability() });
252+
253+
// Act
254+
var clientSupportsRoots = server.ClientSupportsRoots();
255+
256+
// Assert
257+
Assert.True(clientSupportsRoots);
258+
}
259+
260+
[Fact]
261+
public void ClientSupportsSampling_Should_Throw_ArgumentNullException_If_Server_Is_Null()
262+
{
263+
// Arrange
264+
IMcpServer? server = null;
265+
266+
// Act & Assert
267+
Assert.Throws<ArgumentNullException>(() => server!.ClientSupportsSampling());
268+
}
269+
270+
[Fact]
271+
public async Task ClientSupportsSampling_Should_Return_False_If_SamplingCapability_Is_Not_Set()
272+
{
273+
// Arrange
274+
await using var transport = new TestServerTransport();
275+
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
276+
SetClientCapabilities(server, new ClientCapabilities { Sampling = null });
277+
278+
// Act
279+
var clientSupportsSampling = server.ClientSupportsSampling();
280+
281+
// Assert
282+
Assert.False(clientSupportsSampling);
283+
}
284+
285+
[Fact]
286+
public async Task ClientSupportsSampling_Should_Return_True_If_SamplingCapability_Is_Set()
287+
{
288+
// Arrange
289+
await using var transport = new TestServerTransport();
290+
await using var server = McpServerFactory.Create(transport, _options, LoggerFactory);
291+
SetClientCapabilities(server, new ClientCapabilities { Sampling = new SamplingCapability() });
292+
293+
// Act
294+
var clientSupportsSampling = server.ClientSupportsSampling();
295+
296+
// Assert
297+
Assert.True(clientSupportsSampling);
203298
}
204299

205300
[Fact]

0 commit comments

Comments
 (0)