Skip to content

Commit 4a84412

Browse files
authored
Add McpClient/Session methods using .Protocol types (#1063)
1 parent d76bc16 commit 4a84412

File tree

53 files changed

+1116
-639
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1116
-639
lines changed

docs/concepts/elicitation/samples/server/Tools/InteractiveTools.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public sealed class InteractiveTools
1414
[McpServerTool, Description("A simple game where the user has to guess a number between 1 and 10.")]
1515
public async Task<string> GuessTheNumber(
1616
McpServer server, // Get the McpServer from DI container
17-
CancellationToken token
17+
CancellationToken cancellationToken
1818
)
1919
{
2020
// Check if the client supports elicitation
@@ -37,7 +37,7 @@ CancellationToken token
3737
{
3838
Message = "Do you want to play a game?",
3939
RequestedSchema = playSchema
40-
}, token);
40+
}, cancellationToken);
4141

4242
// Check if user wants to play
4343
if (playResponse.Action != "accept" || playResponse.Content?["Answer"].ValueKind != JsonValueKind.True)
@@ -64,7 +64,7 @@ CancellationToken token
6464
{
6565
Message = "What is your name?",
6666
RequestedSchema = nameSchema
67-
}, token);
67+
}, cancellationToken);
6868

6969
if (nameResponse.Action != "accept")
7070
{
@@ -100,7 +100,7 @@ CancellationToken token
100100
{
101101
Message = message,
102102
RequestedSchema = guessSchema
103-
}, token);
103+
}, cancellationToken);
104104

105105
if (guessResponse.Action != "accept")
106106
{
@@ -128,7 +128,7 @@ CancellationToken token
128128
[McpServerTool, Description("Example tool demonstrating various enum schema types")]
129129
public async Task<string> EnumExamples(
130130
McpServer server,
131-
CancellationToken token
131+
CancellationToken cancellationToken
132132
)
133133
{
134134
// Example 1: UntitledSingleSelectEnumSchema - Simple enum without display titles
@@ -150,7 +150,7 @@ CancellationToken token
150150
{
151151
Message = "Select a priority level:",
152152
RequestedSchema = prioritySchema
153-
}, token);
153+
}, cancellationToken);
154154

155155
if (priorityResponse.Action != "accept")
156156
{
@@ -184,7 +184,7 @@ CancellationToken token
184184
{
185185
Message = "Select the issue severity:",
186186
RequestedSchema = severitySchema
187-
}, token);
187+
}, cancellationToken);
188188

189189
if (severityResponse.Action != "accept")
190190
{
@@ -218,7 +218,7 @@ CancellationToken token
218218
{
219219
Message = "Select up to 3 tags:",
220220
RequestedSchema = tagsSchema
221-
}, token);
221+
}, cancellationToken);
222222

223223
if (tagsResponse.Action != "accept")
224224
{
@@ -257,7 +257,7 @@ CancellationToken token
257257
{
258258
Message = "Select desired features:",
259259
RequestedSchema = featuresSchema
260-
}, token);
260+
}, cancellationToken);
261261

262262
if (featuresResponse.Action != "accept")
263263
{

docs/concepts/logging/logging.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Clients should check if the server supports logging by checking the <xref:ModelC
6969
[!code-csharp[](samples/client/Program.cs?name=snippet_LoggingCapabilities)]
7070

7171
If the server supports logging, the client should set the level of log messages it wishes to receive with
72-
the <xref:ModelContextProtocol.Client.McpClient.SetLoggingLevel*> method on <xref:ModelContextProtocol.Client.McpClient>. If the client does not set a logging level, the server might choose
72+
the <xref:ModelContextProtocol.Client.McpClient.SetLoggingLevelAsync*> method on <xref:ModelContextProtocol.Client.McpClient>. If the client does not set a logging level, the server might choose
7373
to send all log messages or none&mdash;this is not specified in the protocol. So it's important that the client
7474
sets a logging level to ensure it receives the desired log messages and only those messages.
7575

docs/concepts/logging/samples/client/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
if (Enum.TryParse<LoggingLevel>(firstArgument, true, out var loggingLevel))
3131
{
3232
// <snippet_LoggingLevel>
33-
await mcpClient.SetLoggingLevel(loggingLevel);
33+
await mcpClient.SetLoggingLevelAsync(loggingLevel);
3434
// </snippet_LoggingLevel>
3535
}
3636
else

samples/ProtectedMcpClient/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
/// </summary>
7171
/// <param name="authorizationUrl">The authorization URL to open in the browser.</param>
7272
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
73-
/// <param name="cancellationToken">The cancellation token.</param>
73+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
7474
/// <returns>The authorization code extracted from the callback, or null if the operation failed.</returns>
7575
static async Task<string?> HandleAuthorizationUrlAsync(Uri authorizationUrl, Uri redirectUri, CancellationToken cancellationToken)
7676
{

src/ModelContextProtocol.Core/AIContentExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ internal static AdditionalPropertiesDictionary ToAdditionalProperties(this JsonO
161161
/// This method transforms a protocol-specific <see cref="PromptMessage"/> from the Model Context Protocol
162162
/// into a standard <see cref="ChatMessage"/> object that can be used with AI client libraries.
163163
/// </remarks>
164+
/// <exception cref="ArgumentNullException"><paramref name="promptMessage"/> is <see langword="null"/>.</exception>
164165
public static ChatMessage ToChatMessage(this PromptMessage promptMessage)
165166
{
166167
Throw.IfNull(promptMessage);
@@ -187,6 +188,7 @@ public static ChatMessage ToChatMessage(this PromptMessage promptMessage)
187188
/// <see cref="ChatRole.Tool"/> message containing a <see cref="FunctionResultContent"/> with result as a
188189
/// serialized <see cref="JsonElement"/>.
189190
/// </remarks>
191+
/// <exception cref="ArgumentNullException"><paramref name="result"/> or <paramref name="callId"/> is <see langword="null"/>.</exception>
190192
public static ChatMessage ToChatMessage(this CallToolResult result, string callId)
191193
{
192194
Throw.IfNull(result);
@@ -207,6 +209,7 @@ public static ChatMessage ToChatMessage(this CallToolResult result, string callI
207209
/// This method transforms protocol-specific <see cref="PromptMessage"/> objects from a Model Context Protocol
208210
/// prompt result into standard <see cref="ChatMessage"/> objects that can be used with AI client libraries.
209211
/// </remarks>
212+
/// <exception cref="ArgumentNullException"><paramref name="promptResult"/> is <see langword="null"/>.</exception>
210213
public static IList<ChatMessage> ToChatMessages(this GetPromptResult promptResult)
211214
{
212215
Throw.IfNull(promptResult);
@@ -224,6 +227,7 @@ public static IList<ChatMessage> ToChatMessages(this GetPromptResult promptResul
224227
/// protocol-specific <see cref="PromptMessage"/> objects for the Model Context Protocol system.
225228
/// Only representable content items are processed.
226229
/// </remarks>
230+
/// <exception cref="ArgumentNullException"><paramref name="chatMessage"/> is <see langword="null"/>.</exception>
227231
public static IList<PromptMessage> ToPromptMessages(this ChatMessage chatMessage)
228232
{
229233
Throw.IfNull(chatMessage);
@@ -251,6 +255,7 @@ public static IList<PromptMessage> ToPromptMessages(this ChatMessage chatMessage
251255
/// This method converts Model Context Protocol content types to the equivalent Microsoft.Extensions.AI
252256
/// content types, enabling seamless integration between the protocol and AI client libraries.
253257
/// </remarks>
258+
/// <exception cref="ArgumentNullException"><paramref name="content"/> is <see langword="null"/>.</exception>
254259
public static AIContent? ToAIContent(this ContentBlock content)
255260
{
256261
Throw.IfNull(content);
@@ -294,6 +299,8 @@ public static IList<PromptMessage> ToPromptMessages(this ChatMessage chatMessage
294299
/// This method converts Model Context Protocol resource types to the equivalent Microsoft.Extensions.AI
295300
/// content types, enabling seamless integration between the protocol and AI client libraries.
296301
/// </remarks>
302+
/// <exception cref="ArgumentNullException"><paramref name="content"/> is <see langword="null"/>.</exception>
303+
/// <exception cref="NotSupportedException">The resource type is not supported.</exception>
297304
public static AIContent ToAIContent(this ResourceContents content)
298305
{
299306
Throw.IfNull(content);
@@ -325,6 +332,7 @@ public static AIContent ToAIContent(this ResourceContents content)
325332
/// preserving the type-specific conversion logic for text, images, audio, and resources.
326333
/// </para>
327334
/// </remarks>
335+
/// <exception cref="ArgumentNullException"><paramref name="contents"/> is <see langword="null"/>.</exception>
328336
public static IList<AIContent> ToAIContents(this IEnumerable<ContentBlock> contents)
329337
{
330338
Throw.IfNull(contents);
@@ -347,6 +355,7 @@ public static IList<AIContent> ToAIContents(this IEnumerable<ContentBlock> conte
347355
/// binary resources become <see cref="DataContent"/> objects.
348356
/// </para>
349357
/// </remarks>
358+
/// <exception cref="ArgumentNullException"><paramref name="contents"/> is <see langword="null"/>.</exception>
350359
public static IList<AIContent> ToAIContents(this IEnumerable<ResourceContents> contents)
351360
{
352361
Throw.IfNull(contents);
@@ -357,8 +366,11 @@ public static IList<AIContent> ToAIContents(this IEnumerable<ResourceContents> c
357366
/// <summary>Creates a new <see cref="ContentBlock"/> from the content of an <see cref="AIContent"/>.</summary>
358367
/// <param name="content">The <see cref="AIContent"/> to convert.</param>
359368
/// <returns>The created <see cref="ContentBlock"/>.</returns>
369+
/// <exception cref="ArgumentNullException"><paramref name="content"/> is <see langword="null"/>.</exception>
360370
public static ContentBlock ToContentBlock(this AIContent content)
361371
{
372+
Throw.IfNull(content);
373+
362374
ContentBlock contentBlock = content switch
363375
{
364376
TextContent textContent => new TextContentBlock

src/ModelContextProtocol.Core/Authentication/AuthorizationRedirectDelegate.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace ModelContextProtocol.Authentication;
66
/// </summary>
77
/// <param name="authorizationUri">The authorization URL that the user needs to visit.</param>
88
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
9-
/// <param name="cancellationToken">The cancellation token.</param>
9+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
1010
/// <returns>A task that represents the asynchronous operation. The task result contains the authorization code if successful, or null if the operation failed or was cancelled.</returns>
1111
/// <remarks>
1212
/// <para>

src/ModelContextProtocol.Core/Authentication/ClientOAuthProvider.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public ClientOAuthProvider(
102102
/// </summary>
103103
/// <param name="authorizationUrl">The authorization URL to handle.</param>
104104
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
105-
/// <param name="cancellationToken">The cancellation token.</param>
105+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
106106
/// <returns>The authorization code entered by the user, or null if none was provided.</returns>
107107
private static Task<string?> DefaultAuthorizationUrlHandler(Uri authorizationUrl, Uri redirectUri, CancellationToken cancellationToken)
108108
{
@@ -135,7 +135,7 @@ public ClientOAuthProvider(
135135
/// </summary>
136136
/// <param name="scheme">The authentication scheme to use.</param>
137137
/// <param name="resourceUri">The URI of the resource requiring authentication.</param>
138-
/// <param name="cancellationToken">A token to cancel the operation.</param>
138+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
139139
/// <returns>An authentication token string, or null if no token could be obtained for the specified scheme.</returns>
140140
public async Task<string?> GetCredentialAsync(string scheme, Uri resourceUri, CancellationToken cancellationToken = default)
141141
{
@@ -168,7 +168,7 @@ public ClientOAuthProvider(
168168
/// </summary>
169169
/// <param name="scheme">The authentication scheme that was used when the unauthorized response was received.</param>
170170
/// <param name="response">The HTTP response that contained the 401 status code.</param>
171-
/// <param name="cancellationToken">A token to cancel the operation.</param>
171+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
172172
/// <returns>
173173
/// A result object indicating if the provider was able to handle the unauthorized response,
174174
/// and the authentication scheme that should be used for the next attempt, if any.
@@ -186,7 +186,7 @@ public async Task HandleUnauthorizedResponseAsync(
186186
/// Performs OAuth authorization by selecting an appropriate authorization server and completing the OAuth flow.
187187
/// </summary>
188188
/// <param name="response">The 401 Unauthorized response containing authentication challenge.</param>
189-
/// <param name="cancellationToken">The cancellation token.</param>
189+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
190190
/// <returns>A result object indicating whether authorization was successful.</returns>
191191
private async Task PerformOAuthAuthorizationAsync(
192192
HttpResponseMessage response,
@@ -473,7 +473,7 @@ private async Task<TokenContainer> HandleSuccessfulTokenResponseAsync(HttpRespon
473473
/// Fetches the protected resource metadata from the provided URL.
474474
/// </summary>
475475
/// <param name="metadataUrl">The URL to fetch the metadata from.</param>
476-
/// <param name="cancellationToken">A token to cancel the operation.</param>
476+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
477477
/// <returns>The fetched ProtectedResourceMetadata, or null if it couldn't be fetched.</returns>
478478
private async Task<ProtectedResourceMetadata?> FetchProtectedResourceMetadataAsync(Uri metadataUrl, CancellationToken cancellationToken = default)
479479
{
@@ -488,7 +488,7 @@ private async Task<TokenContainer> HandleSuccessfulTokenResponseAsync(HttpRespon
488488
/// Performs dynamic client registration with the authorization server.
489489
/// </summary>
490490
/// <param name="authServerMetadata">The authorization server metadata.</param>
491-
/// <param name="cancellationToken">Cancellation token.</param>
491+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
492492
/// <returns>A task representing the asynchronous operation.</returns>
493493
private async Task PerformDynamicClientRegistrationAsync(
494494
AuthorizationServerMetadata authServerMetadata,
@@ -609,7 +609,7 @@ private static string NormalizeUri(Uri uri)
609609
/// </summary>
610610
/// <param name="response">The HTTP response containing the WWW-Authenticate header.</param>
611611
/// <param name="serverUrl">The server URL to verify against the resource metadata.</param>
612-
/// <param name="cancellationToken">A token to cancel the operation.</param>
612+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
613613
/// <returns>The resource metadata if the resource matches the server, otherwise throws an exception.</returns>
614614
/// <exception cref="InvalidOperationException">Thrown when the response is not a 401, lacks a WWW-Authenticate header,
615615
/// lacks a resource_metadata parameter, the metadata can't be fetched, or the resource URI doesn't match the server URL.</exception>

src/ModelContextProtocol.Core/Client/HttpClientTransport.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public HttpClientTransport(HttpClientTransportOptions transportOptions, ILoggerF
4141
/// <see langword="true"/> to dispose of <paramref name="httpClient"/> when the transport is disposed;
4242
/// <see langword="false"/> if the caller is retaining ownership of the <paramref name="httpClient"/>'s lifetime.
4343
/// </param>
44+
/// <exception cref="ArgumentNullException"><paramref name="transportOptions"/> or <paramref name="httpClient"/> is <see langword="null"/>.</exception>
4445
public HttpClientTransport(HttpClientTransportOptions transportOptions, HttpClient httpClient, ILoggerFactory? loggerFactory = null, bool ownsHttpClient = false)
4546
{
4647
Throw.IfNull(transportOptions);

0 commit comments

Comments
 (0)