Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public sealed class InteractiveTools
[McpServerTool, Description("A simple game where the user has to guess a number between 1 and 10.")]
public async Task<string> GuessTheNumber(
McpServer server, // Get the McpServer from DI container
CancellationToken token
CancellationToken cancellationToken
)
{
// Check if the client supports elicitation
Expand All @@ -37,7 +37,7 @@ CancellationToken token
{
Message = "Do you want to play a game?",
RequestedSchema = playSchema
}, token);
}, cancellationToken);

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

if (nameResponse.Action != "accept")
{
Expand Down Expand Up @@ -100,7 +100,7 @@ CancellationToken token
{
Message = message,
RequestedSchema = guessSchema
}, token);
}, cancellationToken);

if (guessResponse.Action != "accept")
{
Expand Down Expand Up @@ -128,7 +128,7 @@ CancellationToken token
[McpServerTool, Description("Example tool demonstrating various enum schema types")]
public async Task<string> EnumExamples(
McpServer server,
CancellationToken token
CancellationToken cancellationToken
)
{
// Example 1: UntitledSingleSelectEnumSchema - Simple enum without display titles
Expand All @@ -150,7 +150,7 @@ CancellationToken token
{
Message = "Select a priority level:",
RequestedSchema = prioritySchema
}, token);
}, cancellationToken);

if (priorityResponse.Action != "accept")
{
Expand Down Expand Up @@ -184,7 +184,7 @@ CancellationToken token
{
Message = "Select the issue severity:",
RequestedSchema = severitySchema
}, token);
}, cancellationToken);

if (severityResponse.Action != "accept")
{
Expand Down Expand Up @@ -218,7 +218,7 @@ CancellationToken token
{
Message = "Select up to 3 tags:",
RequestedSchema = tagsSchema
}, token);
}, cancellationToken);

if (tagsResponse.Action != "accept")
{
Expand Down Expand Up @@ -257,7 +257,7 @@ CancellationToken token
{
Message = "Select desired features:",
RequestedSchema = featuresSchema
}, token);
}, cancellationToken);

if (featuresResponse.Action != "accept")
{
Expand Down
2 changes: 1 addition & 1 deletion docs/concepts/logging/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Clients should check if the server supports logging by checking the <xref:ModelC
[!code-csharp[](samples/client/Program.cs?name=snippet_LoggingCapabilities)]

If the server supports logging, the client should set the level of log messages it wishes to receive with
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
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
to send all log messages or none&mdash;this is not specified in the protocol. So it's important that the client
sets a logging level to ensure it receives the desired log messages and only those messages.

Expand Down
2 changes: 1 addition & 1 deletion docs/concepts/logging/samples/client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
if (Enum.TryParse<LoggingLevel>(firstArgument, true, out var loggingLevel))
{
// <snippet_LoggingLevel>
await mcpClient.SetLoggingLevel(loggingLevel);
await mcpClient.SetLoggingLevelAsync(loggingLevel);
// </snippet_LoggingLevel>
}
else
Expand Down
2 changes: 1 addition & 1 deletion samples/ProtectedMcpClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
/// </summary>
/// <param name="authorizationUrl">The authorization URL to open in the browser.</param>
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>The authorization code extracted from the callback, or null if the operation failed.</returns>
static async Task<string?> HandleAuthorizationUrlAsync(Uri authorizationUrl, Uri redirectUri, CancellationToken cancellationToken)
{
Expand Down
12 changes: 12 additions & 0 deletions src/ModelContextProtocol.Core/AIContentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ internal static AdditionalPropertiesDictionary ToAdditionalProperties(this JsonO
/// This method transforms a protocol-specific <see cref="PromptMessage"/> from the Model Context Protocol
/// into a standard <see cref="ChatMessage"/> object that can be used with AI client libraries.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="promptMessage"/> is <see langword="null"/>.</exception>
public static ChatMessage ToChatMessage(this PromptMessage promptMessage)
{
Throw.IfNull(promptMessage);
Expand All @@ -187,6 +188,7 @@ public static ChatMessage ToChatMessage(this PromptMessage promptMessage)
/// <see cref="ChatRole.Tool"/> message containing a <see cref="FunctionResultContent"/> with result as a
/// serialized <see cref="JsonElement"/>.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="result"/> or <paramref name="callId"/> is <see langword="null"/>.</exception>
public static ChatMessage ToChatMessage(this CallToolResult result, string callId)
{
Throw.IfNull(result);
Expand All @@ -207,6 +209,7 @@ public static ChatMessage ToChatMessage(this CallToolResult result, string callI
/// This method transforms protocol-specific <see cref="PromptMessage"/> objects from a Model Context Protocol
/// prompt result into standard <see cref="ChatMessage"/> objects that can be used with AI client libraries.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="promptResult"/> is <see langword="null"/>.</exception>
public static IList<ChatMessage> ToChatMessages(this GetPromptResult promptResult)
{
Throw.IfNull(promptResult);
Expand All @@ -224,6 +227,7 @@ public static IList<ChatMessage> ToChatMessages(this GetPromptResult promptResul
/// protocol-specific <see cref="PromptMessage"/> objects for the Model Context Protocol system.
/// Only representable content items are processed.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="chatMessage"/> is <see langword="null"/>.</exception>
public static IList<PromptMessage> ToPromptMessages(this ChatMessage chatMessage)
{
Throw.IfNull(chatMessage);
Expand Down Expand Up @@ -251,6 +255,7 @@ public static IList<PromptMessage> ToPromptMessages(this ChatMessage chatMessage
/// This method converts Model Context Protocol content types to the equivalent Microsoft.Extensions.AI
/// content types, enabling seamless integration between the protocol and AI client libraries.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="content"/> is <see langword="null"/>.</exception>
public static AIContent? ToAIContent(this ContentBlock content)
{
Throw.IfNull(content);
Expand Down Expand Up @@ -294,6 +299,8 @@ public static IList<PromptMessage> ToPromptMessages(this ChatMessage chatMessage
/// This method converts Model Context Protocol resource types to the equivalent Microsoft.Extensions.AI
/// content types, enabling seamless integration between the protocol and AI client libraries.
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="content"/> is <see langword="null"/>.</exception>
/// <exception cref="NotSupportedException">The resource type is not supported.</exception>
public static AIContent ToAIContent(this ResourceContents content)
{
Throw.IfNull(content);
Expand Down Expand Up @@ -325,6 +332,7 @@ public static AIContent ToAIContent(this ResourceContents content)
/// preserving the type-specific conversion logic for text, images, audio, and resources.
/// </para>
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="contents"/> is <see langword="null"/>.</exception>
public static IList<AIContent> ToAIContents(this IEnumerable<ContentBlock> contents)
{
Throw.IfNull(contents);
Expand All @@ -347,6 +355,7 @@ public static IList<AIContent> ToAIContents(this IEnumerable<ContentBlock> conte
/// binary resources become <see cref="DataContent"/> objects.
/// </para>
/// </remarks>
/// <exception cref="ArgumentNullException"><paramref name="contents"/> is <see langword="null"/>.</exception>
public static IList<AIContent> ToAIContents(this IEnumerable<ResourceContents> contents)
{
Throw.IfNull(contents);
Expand All @@ -357,8 +366,11 @@ public static IList<AIContent> ToAIContents(this IEnumerable<ResourceContents> c
/// <summary>Creates a new <see cref="ContentBlock"/> from the content of an <see cref="AIContent"/>.</summary>
/// <param name="content">The <see cref="AIContent"/> to convert.</param>
/// <returns>The created <see cref="ContentBlock"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="content"/> is <see langword="null"/>.</exception>
public static ContentBlock ToContentBlock(this AIContent content)
{
Throw.IfNull(content);

ContentBlock contentBlock = content switch
{
TextContent textContent => new TextContentBlock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace ModelContextProtocol.Authentication;
/// </summary>
/// <param name="authorizationUri">The authorization URL that the user needs to visit.</param>
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <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>
/// <remarks>
/// <para>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public ClientOAuthProvider(
/// </summary>
/// <param name="authorizationUrl">The authorization URL to handle.</param>
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>The authorization code entered by the user, or null if none was provided.</returns>
private static Task<string?> DefaultAuthorizationUrlHandler(Uri authorizationUrl, Uri redirectUri, CancellationToken cancellationToken)
{
Expand Down Expand Up @@ -135,7 +135,7 @@ public ClientOAuthProvider(
/// </summary>
/// <param name="scheme">The authentication scheme to use.</param>
/// <param name="resourceUri">The URI of the resource requiring authentication.</param>
/// <param name="cancellationToken">A token to cancel the operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>An authentication token string, or null if no token could be obtained for the specified scheme.</returns>
public async Task<string?> GetCredentialAsync(string scheme, Uri resourceUri, CancellationToken cancellationToken = default)
{
Expand Down Expand Up @@ -168,7 +168,7 @@ public ClientOAuthProvider(
/// </summary>
/// <param name="scheme">The authentication scheme that was used when the unauthorized response was received.</param>
/// <param name="response">The HTTP response that contained the 401 status code.</param>
/// <param name="cancellationToken">A token to cancel the operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>
/// A result object indicating if the provider was able to handle the unauthorized response,
/// and the authentication scheme that should be used for the next attempt, if any.
Expand All @@ -186,7 +186,7 @@ public async Task HandleUnauthorizedResponseAsync(
/// Performs OAuth authorization by selecting an appropriate authorization server and completing the OAuth flow.
/// </summary>
/// <param name="response">The 401 Unauthorized response containing authentication challenge.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>A result object indicating whether authorization was successful.</returns>
private async Task PerformOAuthAuthorizationAsync(
HttpResponseMessage response,
Expand Down Expand Up @@ -473,7 +473,7 @@ private async Task<TokenContainer> HandleSuccessfulTokenResponseAsync(HttpRespon
/// Fetches the protected resource metadata from the provided URL.
/// </summary>
/// <param name="metadataUrl">The URL to fetch the metadata from.</param>
/// <param name="cancellationToken">A token to cancel the operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>The fetched ProtectedResourceMetadata, or null if it couldn't be fetched.</returns>
private async Task<ProtectedResourceMetadata?> FetchProtectedResourceMetadataAsync(Uri metadataUrl, CancellationToken cancellationToken = default)
{
Expand All @@ -488,7 +488,7 @@ private async Task<TokenContainer> HandleSuccessfulTokenResponseAsync(HttpRespon
/// Performs dynamic client registration with the authorization server.
/// </summary>
/// <param name="authServerMetadata">The authorization server metadata.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>A task representing the asynchronous operation.</returns>
private async Task PerformDynamicClientRegistrationAsync(
AuthorizationServerMetadata authServerMetadata,
Expand Down Expand Up @@ -609,7 +609,7 @@ private static string NormalizeUri(Uri uri)
/// </summary>
/// <param name="response">The HTTP response containing the WWW-Authenticate header.</param>
/// <param name="serverUrl">The server URL to verify against the resource metadata.</param>
/// <param name="cancellationToken">A token to cancel the operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>The resource metadata if the resource matches the server, otherwise throws an exception.</returns>
/// <exception cref="InvalidOperationException">Thrown when the response is not a 401, lacks a WWW-Authenticate header,
/// lacks a resource_metadata parameter, the metadata can't be fetched, or the resource URI doesn't match the server URL.</exception>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public HttpClientTransport(HttpClientTransportOptions transportOptions, ILoggerF
/// <see langword="true"/> to dispose of <paramref name="httpClient"/> when the transport is disposed;
/// <see langword="false"/> if the caller is retaining ownership of the <paramref name="httpClient"/>'s lifetime.
/// </param>
/// <exception cref="ArgumentNullException"><paramref name="transportOptions"/> or <paramref name="httpClient"/> is <see langword="null"/>.</exception>
public HttpClientTransport(HttpClientTransportOptions transportOptions, HttpClient httpClient, ILoggerFactory? loggerFactory = null, bool ownsHttpClient = false)
{
Throw.IfNull(transportOptions);
Expand Down
Loading
Loading