Add McpClient/Session methods using .Protocol types (#1063)
This commit is contained in:
parent
d76bc16bd1
commit
4a84412331
53 changed files with 1116 additions and 639 deletions
|
|
@ -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
|
||||
|
|
@ -37,7 +37,7 @@ public sealed class InteractiveTools
|
|||
{
|
||||
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)
|
||||
|
|
@ -64,7 +64,7 @@ public sealed class InteractiveTools
|
|||
{
|
||||
Message = "What is your name?",
|
||||
RequestedSchema = nameSchema
|
||||
}, token);
|
||||
}, cancellationToken);
|
||||
|
||||
if (nameResponse.Action != "accept")
|
||||
{
|
||||
|
|
@ -100,7 +100,7 @@ public sealed class InteractiveTools
|
|||
{
|
||||
Message = message,
|
||||
RequestedSchema = guessSchema
|
||||
}, token);
|
||||
}, cancellationToken);
|
||||
|
||||
if (guessResponse.Action != "accept")
|
||||
{
|
||||
|
|
@ -128,7 +128,7 @@ public sealed class InteractiveTools
|
|||
[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
|
||||
|
|
@ -150,7 +150,7 @@ public sealed class InteractiveTools
|
|||
{
|
||||
Message = "Select a priority level:",
|
||||
RequestedSchema = prioritySchema
|
||||
}, token);
|
||||
}, cancellationToken);
|
||||
|
||||
if (priorityResponse.Action != "accept")
|
||||
{
|
||||
|
|
@ -184,7 +184,7 @@ public sealed class InteractiveTools
|
|||
{
|
||||
Message = "Select the issue severity:",
|
||||
RequestedSchema = severitySchema
|
||||
}, token);
|
||||
}, cancellationToken);
|
||||
|
||||
if (severityResponse.Action != "accept")
|
||||
{
|
||||
|
|
@ -218,7 +218,7 @@ public sealed class InteractiveTools
|
|||
{
|
||||
Message = "Select up to 3 tags:",
|
||||
RequestedSchema = tagsSchema
|
||||
}, token);
|
||||
}, cancellationToken);
|
||||
|
||||
if (tagsResponse.Action != "accept")
|
||||
{
|
||||
|
|
@ -257,7 +257,7 @@ public sealed class InteractiveTools
|
|||
{
|
||||
Message = "Select desired features:",
|
||||
RequestedSchema = featuresSchema
|
||||
}, token);
|
||||
}, cancellationToken);
|
||||
|
||||
if (featuresResponse.Action != "accept")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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—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.
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ if (firstArgument is not null)
|
|||
if (Enum.TryParse<LoggingLevel>(firstArgument, true, out var loggingLevel))
|
||||
{
|
||||
// <snippet_LoggingLevel>
|
||||
await mcpClient.SetLoggingLevel(loggingLevel);
|
||||
await mcpClient.SetLoggingLevelAsync(loggingLevel);
|
||||
// </snippet_LoggingLevel>
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ if (tools.Any(t => t.Name == "get_alerts"))
|
|||
/// </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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ public static class AIContentExtensions
|
|||
/// 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);
|
||||
|
|
@ -187,6 +188,7 @@ public static class AIContentExtensions
|
|||
/// <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);
|
||||
|
|
@ -207,6 +209,7 @@ public static class AIContentExtensions
|
|||
/// 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);
|
||||
|
|
@ -224,6 +227,7 @@ public static class AIContentExtensions
|
|||
/// 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);
|
||||
|
|
@ -251,6 +255,7 @@ public static class AIContentExtensions
|
|||
/// 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);
|
||||
|
|
@ -294,6 +299,8 @@ public static class AIContentExtensions
|
|||
/// 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);
|
||||
|
|
@ -325,6 +332,7 @@ public static class AIContentExtensions
|
|||
/// 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);
|
||||
|
|
@ -347,6 +355,7 @@ public static class AIContentExtensions
|
|||
/// 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);
|
||||
|
|
@ -357,8 +366,11 @@ public static class AIContentExtensions
|
|||
/// <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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ internal sealed partial class 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)
|
||||
{
|
||||
|
|
@ -135,7 +135,7 @@ internal sealed partial class 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)
|
||||
{
|
||||
|
|
@ -168,7 +168,7 @@ internal sealed partial class 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.
|
||||
|
|
@ -186,7 +186,7 @@ internal sealed partial class ClientOAuthProvider
|
|||
/// 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,
|
||||
|
|
@ -473,7 +473,7 @@ internal sealed partial class ClientOAuthProvider
|
|||
/// 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)
|
||||
{
|
||||
|
|
@ -488,7 +488,7 @@ internal sealed partial class ClientOAuthProvider
|
|||
/// 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,
|
||||
|
|
@ -609,7 +609,7 @@ internal sealed partial class ClientOAuthProvider
|
|||
/// </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>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public sealed class HttpClientTransport : IClientTransport, IAsyncDisposable
|
|||
/// <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);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using ModelContextProtocol.Server;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
|
|
@ -22,7 +20,7 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="loggerFactory">A logger factory for creating loggers for clients.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>An <see cref="McpClient"/> that's connected to the specified server.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="clientTransport"/> or <paramref name="clientOptions"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="clientTransport"/> is <see langword="null"/>.</exception>
|
||||
public static async Task<McpClient> CreateAsync(
|
||||
IClientTransport clientTransport,
|
||||
McpClientOptions? clientOptions = null,
|
||||
|
|
@ -41,7 +39,12 @@ public abstract partial class McpClient : McpSession
|
|||
}
|
||||
catch
|
||||
{
|
||||
await clientSession.DisposeAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await clientSession.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch { } // allow the original exception to propagate
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
|
|
@ -55,9 +58,9 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="resumeOptions">The metadata captured from the original session that should be applied when resuming.</param>
|
||||
/// <param name="clientOptions">Optional client settings that should mirror those used to create the original session.</param>
|
||||
/// <param name="loggerFactory">An optional logger factory for diagnostics.</param>
|
||||
/// <param name="cancellationToken">Token used when establishing the transport connection.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>An <see cref="McpClient"/> bound to the resumed session.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="clientTransport"/> or <paramref name="resumeOptions"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="clientTransport"/>, <paramref name="resumeOptions"/>, <see cref="ResumeClientSessionOptions.ServerCapabilities"/>, or <see cref="ResumeClientSessionOptions.ServerInfo"/> is <see langword="null"/>.</exception>
|
||||
public static async Task<McpClient> ResumeSessionAsync(
|
||||
IClientTransport clientTransport,
|
||||
ResumeClientSessionOptions resumeOptions,
|
||||
|
|
@ -71,10 +74,10 @@ public abstract partial class McpClient : McpSession
|
|||
Throw.IfNull(resumeOptions.ServerInfo);
|
||||
|
||||
var transport = await clientTransport.ConnectAsync(cancellationToken).ConfigureAwait(false);
|
||||
var endpointName = clientTransport.Name;
|
||||
|
||||
var clientSession = new McpClientImpl(transport, endpointName, clientOptions, loggerFactory);
|
||||
McpClientImpl clientSession = new(transport, clientTransport.Name, clientOptions, loggerFactory);
|
||||
clientSession.ResumeSession(resumeOptions);
|
||||
|
||||
return clientSession;
|
||||
}
|
||||
|
||||
|
|
@ -87,9 +90,31 @@ public abstract partial class McpClient : McpSession
|
|||
/// <exception cref="McpException">The server cannot be reached or returned an error response.</exception>
|
||||
public ValueTask<PingResult> PingAsync(RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return PingAsync(
|
||||
new PingRequestParams
|
||||
{
|
||||
Meta = options?.GetMetaForRequest()
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a ping request to verify server connectivity.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>A task containing the ping result.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="McpException">The server cannot be reached or returned an error response.</exception>
|
||||
public ValueTask<PingResult> PingAsync(
|
||||
PingRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.Ping,
|
||||
new PingRequestParams { Meta = options?.Meta },
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.PingRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.PingResult,
|
||||
cancellationToken: cancellationToken);
|
||||
|
|
@ -106,29 +131,49 @@ public abstract partial class McpClient : McpSession
|
|||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
List<McpClientTool>? tools = null;
|
||||
string? cursor = null;
|
||||
ListToolsRequestParams requestParams = new() { Meta = options?.GetMetaForRequest() };
|
||||
do
|
||||
{
|
||||
var toolResults = await SendRequestAsync(
|
||||
RequestMethods.ToolsList,
|
||||
new() { Cursor = cursor, Meta = options?.Meta },
|
||||
McpJsonUtilities.JsonContext.Default.ListToolsRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListToolsResult,
|
||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
tools ??= new List<McpClientTool>(toolResults.Tools.Count);
|
||||
var toolResults = await ListToolsAsync(requestParams, cancellationToken).ConfigureAwait(false);
|
||||
tools ??= new(toolResults.Tools.Count);
|
||||
foreach (var tool in toolResults.Tools)
|
||||
{
|
||||
tools.Add(new McpClientTool(this, tool, options?.JsonSerializerOptions));
|
||||
tools.Add(new(this, tool, options?.JsonSerializerOptions));
|
||||
}
|
||||
|
||||
cursor = toolResults.NextCursor;
|
||||
requestParams.Cursor = toolResults.NextCursor;
|
||||
}
|
||||
while (cursor is not null);
|
||||
while (requestParams.Cursor is not null);
|
||||
|
||||
return tools;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of available tools from the server.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request as provided by the server.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// The <see cref="ListToolsAsync(RequestOptions?, CancellationToken)"/> overload retrieves all tools by automatically handling pagination.
|
||||
/// This overload works with the lower-level <see cref="ListToolsRequestParams"/> and <see cref="ListToolsResult"/>, returning the raw result from the server.
|
||||
/// Any pagination needs to be managed by the caller.
|
||||
/// </remarks>
|
||||
public ValueTask<ListToolsResult> ListToolsAsync(
|
||||
ListToolsRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ToolsList,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListToolsRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListToolsResult,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of available prompts from the server.
|
||||
/// </summary>
|
||||
|
|
@ -140,29 +185,49 @@ public abstract partial class McpClient : McpSession
|
|||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
List<McpClientPrompt>? prompts = null;
|
||||
string? cursor = null;
|
||||
ListPromptsRequestParams requestParams = new() { Meta = options?.GetMetaForRequest() };
|
||||
do
|
||||
{
|
||||
var promptResults = await SendRequestAsync(
|
||||
RequestMethods.PromptsList,
|
||||
new() { Cursor = cursor, Meta = options?.Meta },
|
||||
McpJsonUtilities.JsonContext.Default.ListPromptsRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListPromptsResult,
|
||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
prompts ??= new List<McpClientPrompt>(promptResults.Prompts.Count);
|
||||
var promptResults = await ListPromptsAsync(requestParams, cancellationToken).ConfigureAwait(false);
|
||||
prompts ??= new(promptResults.Prompts.Count);
|
||||
foreach (var prompt in promptResults.Prompts)
|
||||
{
|
||||
prompts.Add(new McpClientPrompt(this, prompt));
|
||||
prompts.Add(new(this, prompt));
|
||||
}
|
||||
|
||||
cursor = promptResults.NextCursor;
|
||||
requestParams.Cursor = promptResults.NextCursor;
|
||||
}
|
||||
while (cursor is not null);
|
||||
while (requestParams.Cursor is not null);
|
||||
|
||||
return prompts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of available prompts from the server.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request as provided by the server.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// The <see cref="ListPromptsAsync(RequestOptions?, CancellationToken)"/> overload retrieves all prompts by automatically handling pagination.
|
||||
/// This overload works with the lower-level <see cref="ListPromptsRequestParams"/> and <see cref="ListPromptsResult"/>, returning the raw result from the server.
|
||||
/// Any pagination needs to be managed by the caller.
|
||||
/// </remarks>
|
||||
public ValueTask<ListPromptsResult> ListPromptsAsync(
|
||||
ListPromptsRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.PromptsList,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListPromptsRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListPromptsResult,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a specific prompt from the MCP server.
|
||||
/// </summary>
|
||||
|
|
@ -171,6 +236,8 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>A task containing the prompt's result with content and messages.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="name"/> is empty or composed entirely of whitespace.</exception>
|
||||
public ValueTask<GetPromptResult> GetPromptAsync(
|
||||
string name,
|
||||
IReadOnlyDictionary<string, object?>? arguments = null,
|
||||
|
|
@ -182,9 +249,32 @@ public abstract partial class McpClient : McpSession
|
|||
var serializerOptions = options?.JsonSerializerOptions ?? McpJsonUtilities.DefaultOptions;
|
||||
serializerOptions.MakeReadOnly();
|
||||
|
||||
return GetPromptAsync(
|
||||
new GetPromptRequestParams
|
||||
{
|
||||
Name = name,
|
||||
Arguments = ToArgumentsDictionary(arguments, serializerOptions),
|
||||
Meta = options?.GetMetaForRequest(),
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of available prompts from the server.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request as provided by the server.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
public ValueTask<GetPromptResult> GetPromptAsync(
|
||||
GetPromptRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.PromptsGet,
|
||||
new() { Name = name, Arguments = ToArgumentsDictionary(arguments, serializerOptions), Meta = options?.Meta },
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.GetPromptRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.GetPromptResult,
|
||||
cancellationToken: cancellationToken);
|
||||
|
|
@ -201,30 +291,49 @@ public abstract partial class McpClient : McpSession
|
|||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
List<McpClientResourceTemplate>? resourceTemplates = null;
|
||||
|
||||
string? cursor = null;
|
||||
ListResourceTemplatesRequestParams requestParams = new() { Meta = options?.GetMetaForRequest() };
|
||||
do
|
||||
{
|
||||
var templateResults = await SendRequestAsync(
|
||||
RequestMethods.ResourcesTemplatesList,
|
||||
new() { Cursor = cursor, Meta = options?.Meta },
|
||||
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesResult,
|
||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
resourceTemplates ??= new List<McpClientResourceTemplate>(templateResults.ResourceTemplates.Count);
|
||||
var templateResults = await ListResourceTemplatesAsync(requestParams, cancellationToken).ConfigureAwait(false);
|
||||
resourceTemplates ??= new(templateResults.ResourceTemplates.Count);
|
||||
foreach (var template in templateResults.ResourceTemplates)
|
||||
{
|
||||
resourceTemplates.Add(new McpClientResourceTemplate(this, template));
|
||||
resourceTemplates.Add(new(this, template));
|
||||
}
|
||||
|
||||
cursor = templateResults.NextCursor;
|
||||
requestParams.Cursor = templateResults.NextCursor;
|
||||
}
|
||||
while (cursor is not null);
|
||||
while (requestParams.Cursor is not null);
|
||||
|
||||
return resourceTemplates;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of available resource templates from the server.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request as provided by the server.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// The <see cref="ListResourceTemplatesAsync(RequestOptions?, CancellationToken)"/> overload retrieves all resource templates by automatically handling pagination.
|
||||
/// This overload works with the lower-level <see cref="ListResourceTemplatesRequestParams"/> and <see cref="ListResourceTemplatesResult"/>, returning the raw result from the server.
|
||||
/// Any pagination needs to be managed by the caller.
|
||||
/// </remarks>
|
||||
public ValueTask<ListResourceTemplatesResult> ListResourceTemplatesAsync(
|
||||
ListResourceTemplatesRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ResourcesTemplatesList,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListResourceTemplatesResult,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of available resources from the server.
|
||||
/// </summary>
|
||||
|
|
@ -236,47 +345,62 @@ public abstract partial class McpClient : McpSession
|
|||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
List<McpClientResource>? resources = null;
|
||||
|
||||
string? cursor = null;
|
||||
ListResourcesRequestParams requestParams = new() { Meta = options?.GetMetaForRequest() };
|
||||
do
|
||||
{
|
||||
var resourceResults = await SendRequestAsync(
|
||||
RequestMethods.ResourcesList,
|
||||
new() { Cursor = cursor, Meta = options?.Meta },
|
||||
McpJsonUtilities.JsonContext.Default.ListResourcesRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListResourcesResult,
|
||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
|
||||
resources ??= new List<McpClientResource>(resourceResults.Resources.Count);
|
||||
var resourceResults = await ListResourcesAsync(requestParams, cancellationToken).ConfigureAwait(false);
|
||||
resources ??= new(resourceResults.Resources.Count);
|
||||
foreach (var resource in resourceResults.Resources)
|
||||
{
|
||||
resources.Add(new McpClientResource(this, resource));
|
||||
resources.Add(new(this, resource));
|
||||
}
|
||||
|
||||
cursor = resourceResults.NextCursor;
|
||||
requestParams.Cursor = resourceResults.NextCursor;
|
||||
}
|
||||
while (cursor is not null);
|
||||
while (requestParams.Cursor is not null);
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of available resources from the server.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request as provided by the server.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// The <see cref="ListResourcesAsync(RequestOptions?, CancellationToken)"/> overload retrieves all resources by automatically handling pagination.
|
||||
/// This overload works with the lower-level <see cref="ListResourcesRequestParams"/> and <see cref="ListResourcesResult"/>, returning the raw result from the server.
|
||||
/// Any pagination needs to be managed by the caller.
|
||||
/// </remarks>
|
||||
public ValueTask<ListResourcesResult> ListResourcesAsync(
|
||||
ListResourcesRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ResourcesList,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListResourcesRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ListResourcesResult,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a resource from the server.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI of the resource.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <see langword="null"/>.</exception>
|
||||
public ValueTask<ReadResourceResult> ReadResourceAsync(
|
||||
string uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
Uri uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNullOrWhiteSpace(uri);
|
||||
Throw.IfNull(uri);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ResourcesRead,
|
||||
new() { Uri = uri, Meta = options?.Meta },
|
||||
McpJsonUtilities.JsonContext.Default.ReadResourceRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ReadResourceResult,
|
||||
cancellationToken: cancellationToken);
|
||||
return ReadResourceAsync(uri.AbsoluteUri, options, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -285,12 +409,18 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="uri">The URI of the resource.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="uri"/> is empty or composed entirely of whitespace.</exception>
|
||||
public ValueTask<ReadResourceResult> ReadResourceAsync(
|
||||
Uri uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
string uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(uri);
|
||||
Throw.IfNullOrWhiteSpace(uri);
|
||||
|
||||
return ReadResourceAsync(uri.ToString(), options, cancellationToken);
|
||||
return ReadResourceAsync(new ReadResourceRequestParams
|
||||
{
|
||||
Uri = uri,
|
||||
Meta = options?.GetMetaForRequest(),
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -300,15 +430,39 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="arguments">Arguments to use to format <paramref name="uriTemplate"/>.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="uriTemplate"/> or <paramref name="arguments"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="uriTemplate"/> is empty or composed entirely of whitespace.</exception>
|
||||
public ValueTask<ReadResourceResult> ReadResourceAsync(
|
||||
string uriTemplate, IReadOnlyDictionary<string, object?> arguments, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNullOrWhiteSpace(uriTemplate);
|
||||
Throw.IfNull(arguments);
|
||||
|
||||
return ReadResourceAsync(
|
||||
new ReadResourceRequestParams
|
||||
{
|
||||
Uri = UriTemplate.FormatUri(uriTemplate, arguments),
|
||||
Meta = options?.GetMetaForRequest(),
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a resource from the server.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
public ValueTask<ReadResourceResult> ReadResourceAsync(
|
||||
ReadResourceRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ResourcesRead,
|
||||
new() { Uri = UriTemplate.FormatUri(uriTemplate, arguments), Meta = options?.Meta },
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ReadResourceRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ReadResourceResult,
|
||||
cancellationToken: cancellationToken);
|
||||
|
|
@ -320,25 +474,64 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="reference">The reference object specifying the type and optional URI or name.</param>
|
||||
/// <param name="argumentName">The name of the argument for which completions are requested.</param>
|
||||
/// <param name="argumentValue">The current value of the argument, used to filter relevant completions.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>A <see cref="CompleteResult"/> containing completion suggestions.</returns>
|
||||
public ValueTask<CompleteResult> CompleteAsync(Reference reference, string argumentName, string argumentValue, CancellationToken cancellationToken = default)
|
||||
/// <exception cref="ArgumentNullException"><paramref name="reference"/> or <paramref name="argumentName"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="argumentName"/> is empty or composed entirely of whitespace.</exception>
|
||||
public ValueTask<CompleteResult> CompleteAsync(
|
||||
Reference reference, string argumentName, string argumentValue,
|
||||
RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(reference);
|
||||
Throw.IfNullOrWhiteSpace(argumentName);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.CompletionComplete,
|
||||
new()
|
||||
return CompleteAsync(
|
||||
new CompleteRequestParams
|
||||
{
|
||||
Ref = reference,
|
||||
Argument = new Argument { Name = argumentName, Value = argumentValue }
|
||||
Argument = new() { Name = argumentName, Value = argumentValue },
|
||||
Meta = options?.GetMetaForRequest(),
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests completion suggestions for a prompt argument or resource reference.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
public ValueTask<CompleteResult> CompleteAsync(
|
||||
CompleteRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.CompletionComplete,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.CompleteRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.CompleteResult,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from a resource on the server to stop receiving notifications about its changes.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI of the resource to which to subscribe.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <see langword="null"/>.</exception>
|
||||
public Task SubscribeToResourceAsync(Uri uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(uri);
|
||||
|
||||
return SubscribeToResourceAsync(uri.AbsoluteUri, options, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to a resource on the server to receive notifications when it changes.
|
||||
/// </summary>
|
||||
|
|
@ -346,51 +539,42 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="uri"/> is empty or composed entirely of whitespace.</exception>
|
||||
public Task SubscribeToResourceAsync(string uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNullOrWhiteSpace(uri);
|
||||
|
||||
return SubscribeToResourceAsync(
|
||||
new SubscribeRequestParams
|
||||
{
|
||||
Uri = uri,
|
||||
Meta = options?.GetMetaForRequest(),
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to a resource on the server to receive notifications when it changes.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
public Task SubscribeToResourceAsync(
|
||||
SubscribeRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ResourcesSubscribe,
|
||||
new() { Uri = uri, Meta = options?.Meta },
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.SubscribeRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||
cancellationToken: cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes to a resource on the server to receive notifications when it changes.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI of the resource to which to subscribe.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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.</returns>
|
||||
public Task SubscribeToResourceAsync(Uri uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(uri);
|
||||
|
||||
return SubscribeToResourceAsync(uri.ToString(), options, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from a resource on the server to stop receiving notifications about its changes.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI of the resource to unsubscribe from.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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.</returns>
|
||||
public Task UnsubscribeFromResourceAsync(string uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNullOrWhiteSpace(uri);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ResourcesUnsubscribe,
|
||||
new() { Uri = uri, Meta = options?.Meta },
|
||||
McpJsonUtilities.JsonContext.Default.UnsubscribeRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||
cancellationToken: cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from a resource on the server to stop receiving notifications about its changes.
|
||||
/// </summary>
|
||||
|
|
@ -398,11 +582,55 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <see langword="null"/>.</exception>
|
||||
public Task UnsubscribeFromResourceAsync(Uri uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(uri);
|
||||
|
||||
return UnsubscribeFromResourceAsync(uri.ToString(), options, cancellationToken);
|
||||
return UnsubscribeFromResourceAsync(uri.AbsoluteUri, options, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from a resource on the server to stop receiving notifications about its changes.
|
||||
/// </summary>
|
||||
/// <param name="uri">The URI of the resource to unsubscribe from.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="uri"/> is empty or composed entirely of whitespace.</exception>
|
||||
public Task UnsubscribeFromResourceAsync(string uri, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNullOrWhiteSpace(uri);
|
||||
|
||||
return UnsubscribeFromResourceAsync(
|
||||
new UnsubscribeRequestParams
|
||||
{
|
||||
Uri = uri,
|
||||
Meta = options?.GetMetaForRequest()
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unsubscribes from a resource on the server to stop receiving notifications about its changes.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
public Task UnsubscribeFromResourceAsync(
|
||||
UnsubscribeRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ResourcesUnsubscribe,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.UnsubscribeRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||
cancellationToken: cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -412,8 +640,9 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="arguments">An optional dictionary of arguments to pass to the tool.</param>
|
||||
/// <param name="progress">An optional progress reporter for server notifications.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</param>
|
||||
/// <param name="cancellationToken">A 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 <see cref="CallToolResult"/> from the tool execution.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="toolName"/> is <see langword="null"/>.</exception>
|
||||
public ValueTask<CallToolResult> CallToolAsync(
|
||||
string toolName,
|
||||
IReadOnlyDictionary<string, object?>? arguments = null,
|
||||
|
|
@ -422,25 +651,23 @@ public abstract partial class McpClient : McpSession
|
|||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(toolName);
|
||||
|
||||
var serializerOptions = options?.JsonSerializerOptions ?? McpJsonUtilities.DefaultOptions;
|
||||
serializerOptions.MakeReadOnly();
|
||||
|
||||
if (progress is not null)
|
||||
if (progress is null)
|
||||
{
|
||||
return SendRequestWithProgressAsync(toolName, arguments, progress, options?.Meta, serializerOptions, cancellationToken);
|
||||
return CallToolAsync(
|
||||
new CallToolRequestParams
|
||||
{
|
||||
Name = toolName,
|
||||
Arguments = ToArgumentsDictionary(arguments, serializerOptions),
|
||||
Meta = options?.GetMetaForRequest(),
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.ToolsCall,
|
||||
new()
|
||||
{
|
||||
Name = toolName,
|
||||
Arguments = ToArgumentsDictionary(arguments, serializerOptions),
|
||||
Meta = options?.Meta,
|
||||
},
|
||||
McpJsonUtilities.JsonContext.Default.CallToolRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.CallToolResult,
|
||||
cancellationToken: cancellationToken);
|
||||
return SendRequestWithProgressAsync(toolName, arguments, progress, options?.GetMetaForRequest(), serializerOptions, cancellationToken);
|
||||
|
||||
async ValueTask<CallToolResult> SendRequestWithProgressAsync(
|
||||
string toolName,
|
||||
|
|
@ -464,38 +691,39 @@ public abstract partial class McpClient : McpSession
|
|||
return default;
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var metaWithProgress = meta is not null ? new JsonObject(meta) : new JsonObject();
|
||||
JsonObject metaWithProgress = meta is not null ? new(meta) : [];
|
||||
metaWithProgress["progressToken"] = progressToken.ToString();
|
||||
|
||||
return await SendRequestAsync(
|
||||
RequestMethods.ToolsCall,
|
||||
return await CallToolAsync(
|
||||
new()
|
||||
{
|
||||
Name = toolName,
|
||||
Arguments = ToArgumentsDictionary(arguments, serializerOptions),
|
||||
Meta = metaWithProgress,
|
||||
},
|
||||
McpJsonUtilities.JsonContext.Default.CallToolRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.CallToolResult,
|
||||
cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the logging level for the server to control which log messages are sent to the client.
|
||||
/// Invokes a tool on the server.
|
||||
/// </summary>
|
||||
/// <param name="level">The minimum severity level of log messages to receive from the server.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</param>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</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>
|
||||
public Task SetLoggingLevel(LoggingLevel level, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
/// <returns>The result of the request.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
public ValueTask<CallToolResult> CallToolAsync(
|
||||
CallToolRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.LoggingSetLevel,
|
||||
new() { Level = level, Meta = options?.Meta },
|
||||
McpJsonUtilities.JsonContext.Default.SetLevelRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||
cancellationToken: cancellationToken).AsTask();
|
||||
RequestMethods.ToolsCall,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.CallToolRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.CallToolResult,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -505,8 +733,47 @@ public abstract partial class McpClient : McpSession
|
|||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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>
|
||||
public Task SetLoggingLevel(LogLevel level, RequestOptions? options = null, CancellationToken cancellationToken = default) =>
|
||||
SetLoggingLevel(McpServerImpl.ToLoggingLevel(level), options, cancellationToken);
|
||||
public Task SetLoggingLevelAsync(LogLevel level, RequestOptions? options = null, CancellationToken cancellationToken = default) =>
|
||||
SetLoggingLevelAsync(McpServerImpl.ToLoggingLevel(level), options, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the logging level for the server to control which log messages are sent to the client.
|
||||
/// </summary>
|
||||
/// <param name="level">The minimum severity level of log messages to receive from the server.</param>
|
||||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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>
|
||||
public Task SetLoggingLevelAsync(LoggingLevel level, RequestOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return SetLoggingLevelAsync(
|
||||
new SetLevelRequestParams
|
||||
{
|
||||
Level = level,
|
||||
Meta = options?.GetMetaForRequest()
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the logging level for the server to control which log messages are sent to the client.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
|
||||
/// <returns>The result of the request.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
public Task SetLoggingLevelAsync(
|
||||
SetLevelRequestParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendRequestAsync(
|
||||
RequestMethods.LoggingSetLevel,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.SetLevelRequestParams,
|
||||
McpJsonUtilities.JsonContext.Default.EmptyResult,
|
||||
cancellationToken: cancellationToken).AsTask();
|
||||
}
|
||||
|
||||
/// <summary>Converts a dictionary with <see cref="object"/> values to a dictionary with <see cref="JsonElement"/> values.</summary>
|
||||
private static Dictionary<string, JsonElement>? ToArgumentsDictionary(
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ internal sealed partial class McpClientImpl : McpClient
|
|||
{
|
||||
// Send initialize request
|
||||
string requestProtocol = _options.ProtocolVersion ?? McpSessionHandler.LatestProtocolVersion;
|
||||
var initializeResponse = await this.SendRequestAsync(
|
||||
var initializeResponse = await SendRequestAsync(
|
||||
RequestMethods.Initialize,
|
||||
new InitializeRequestParams
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace ModelContextProtocol.Client;
|
|||
/// <para>
|
||||
/// This class provides a client-side wrapper around a prompt defined on an MCP server. It allows
|
||||
/// retrieving the prompt's content by sending a request to the server with optional arguments.
|
||||
/// Instances of this class are typically obtained by calling <see cref="McpClient.ListPromptsAsync"/>.
|
||||
/// Instances of this class are typically obtained by calling <see cref="McpClient.ListPromptsAsync(RequestOptions?, CancellationToken)"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Each prompt has a name and optionally a description, and it can be invoked with arguments
|
||||
|
|
@ -29,7 +29,7 @@ public sealed class McpClientPrompt
|
|||
/// <remarks>
|
||||
/// <para>
|
||||
/// This constructor enables reusing cached prompt definitions across different <see cref="McpClient"/> instances
|
||||
/// without needing to call <see cref="McpClient.ListPromptsAsync"/> on every reconnect. This is particularly useful
|
||||
/// without needing to call <see cref="McpClient.ListPromptsAsync(RequestOptions?, CancellationToken)"/> on every reconnect. This is particularly useful
|
||||
/// in scenarios where prompt definitions are stable and network round-trips should be minimized.
|
||||
/// </para>
|
||||
/// <para>
|
||||
|
|
@ -83,7 +83,8 @@ public sealed class McpClientPrompt
|
|||
/// The server will process the request and return a result containing messages or other content.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This is a convenience method that internally calls <see cref="McpClient.GetPromptAsync"/>
|
||||
/// This is a convenience method that internally calls
|
||||
/// <see cref="McpClient.GetPromptAsync(string, IReadOnlyDictionary{string, object?}?, RequestOptions?, CancellationToken)"/>
|
||||
/// with this prompt's name and arguments.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace ModelContextProtocol.Client;
|
|||
/// <para>
|
||||
/// This class provides a client-side wrapper around a resource defined on an MCP server. It allows
|
||||
/// retrieving the resource's content by sending a request to the server with the resource's URI.
|
||||
/// Instances of this class are typically obtained by calling <see cref="McpClient.ListResourcesAsync"/>.
|
||||
/// Instances of this class are typically obtained by calling <see cref="McpClient.ListResourcesAsync(RequestOptions?, CancellationToken)"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class McpClientResource
|
||||
|
|
@ -24,7 +24,7 @@ public sealed class McpClientResource
|
|||
/// <remarks>
|
||||
/// <para>
|
||||
/// This constructor enables reusing cached resource definitions across different <see cref="McpClient"/> instances
|
||||
/// without needing to call <see cref="McpClient.ListResourcesAsync"/> on every reconnect. This is particularly useful
|
||||
/// without needing to call <see cref="McpClient.ListResourcesAsync(RequestOptions?, CancellationToken)"/> on every reconnect. This is particularly useful
|
||||
/// in scenarios where resource definitions are stable and network round-trips should be minimized.
|
||||
/// </para>
|
||||
/// <para>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace ModelContextProtocol.Client;
|
|||
/// <para>
|
||||
/// This class provides a client-side wrapper around a resource template defined on an MCP server. It allows
|
||||
/// retrieving the resource template's content by sending a request to the server with the resource's URI.
|
||||
/// Instances of this class are typically obtained by calling <see cref="McpClient.ListResourceTemplatesAsync"/>.
|
||||
/// Instances of this class are typically obtained by calling <see cref="McpClient.ListResourceTemplatesAsync(RequestOptions?, CancellationToken)"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public sealed class McpClientResourceTemplate
|
||||
|
|
@ -24,7 +24,7 @@ public sealed class McpClientResourceTemplate
|
|||
/// <remarks>
|
||||
/// <para>
|
||||
/// This constructor enables reusing cached resource template definitions across different <see cref="McpClient"/> instances
|
||||
/// without needing to call <see cref="McpClient.ListResourceTemplatesAsync"/> on every reconnect. This is particularly useful
|
||||
/// without needing to call <see cref="McpClient.ListResourceTemplatesAsync(RequestOptions?, CancellationToken)"/> on every reconnect. This is particularly useful
|
||||
/// in scenarios where resource template definitions are stable and network round-trips should be minimized.
|
||||
/// </para>
|
||||
/// <para>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace ModelContextProtocol.Client;
|
|||
/// <see cref="WithName"/> and <see cref="WithDescription"/> without changing the underlying tool functionality.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Typically, you would get instances of this class by calling the <see cref="McpClient.ListToolsAsync"/>
|
||||
/// Typically, you would get instances of this class by calling the <see cref="McpClient.ListToolsAsync(RequestOptions?, CancellationToken)"/>
|
||||
/// method on an <see cref="McpClient"/> instance.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
|
|
@ -49,8 +49,8 @@ public sealed class McpClientTool : AIFunction
|
|||
/// <remarks>
|
||||
/// <para>
|
||||
/// This constructor enables reusing cached tool definitions across different <see cref="McpClient"/> instances
|
||||
/// without needing to call <see cref="McpClient.ListToolsAsync"/> on every reconnect. This is particularly useful
|
||||
/// in scenarios where tool definitions are stable and network round-trips should be minimized.
|
||||
/// without needing to call <see cref="McpClient.ListToolsAsync(RequestOptions?, CancellationToken)"/> on every reconnect.
|
||||
/// This is particularly useful in scenarios where tool definitions are stable and network round-trips should be minimized.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The provided <paramref name="tool"/> must represent a tool that is actually available on the server
|
||||
|
|
@ -275,6 +275,7 @@ public sealed class McpClientTool : AIFunction
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
/// <returns>A new instance of <see cref="McpClientTool"/>, configured with the provided progress instance.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="progress"/> is <see langword="null"/>.</exception>
|
||||
public McpClientTool WithProgress(IProgress<ProgressNotificationValue> progress)
|
||||
{
|
||||
Throw.IfNull(progress);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public sealed partial class StdioClientTransport : IClientTransport
|
|||
/// </summary>
|
||||
/// <param name="options">Configuration options for the transport, including the command to execute, arguments, working directory, and environment variables.</param>
|
||||
/// <param name="loggerFactory">A logger factory for creating loggers used for diagnostic output during transport operations.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="options"/> is <see langword="null"/>.</exception>
|
||||
public StdioClientTransport(StdioClientTransportOptions options, ILoggerFactory? loggerFactory = null)
|
||||
{
|
||||
Throw.IfNull(options);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public sealed class StreamClientTransport : IClientTransport
|
|||
/// Reads from this stream will receive messages from the server.
|
||||
/// </param>
|
||||
/// <param name="loggerFactory">A logger factory for creating loggers.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="serverInput"/> or <paramref name="serverOutput"/> is <see langword="null"/>.</exception>
|
||||
public StreamClientTransport(
|
||||
Stream serverInput, Stream serverOutput, ILoggerFactory? loggerFactory = null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,9 +29,13 @@ public abstract partial class McpSession : IAsyncDisposable
|
|||
serializerOptions ??= McpJsonUtilities.DefaultOptions;
|
||||
serializerOptions.MakeReadOnly();
|
||||
|
||||
JsonTypeInfo<TParameters> paramsTypeInfo = serializerOptions.GetTypeInfo<TParameters>();
|
||||
JsonTypeInfo<TResult> resultTypeInfo = serializerOptions.GetTypeInfo<TResult>();
|
||||
return SendRequestAsync(method, parameters, paramsTypeInfo, resultTypeInfo, requestId, cancellationToken);
|
||||
return SendRequestAsync(
|
||||
method,
|
||||
parameters,
|
||||
serializerOptions.GetTypeInfo<TParameters>(),
|
||||
serializerOptions.GetTypeInfo<TResult>(),
|
||||
requestId,
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -76,6 +80,8 @@ public abstract partial class McpSession : IAsyncDisposable
|
|||
/// <param name="method">The notification method name.</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 send operation.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="method"/> is empty or composed entirely of whitespace.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method sends a notification without any parameters. Notifications are one-way messages
|
||||
|
|
@ -86,6 +92,7 @@ public abstract partial class McpSession : IAsyncDisposable
|
|||
public Task SendNotificationAsync(string method, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNullOrWhiteSpace(method);
|
||||
|
||||
return SendMessageAsync(new JsonRpcNotification { Method = method }, cancellationToken);
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +105,8 @@ public abstract partial class McpSession : IAsyncDisposable
|
|||
/// <param name="serializerOptions">The options governing parameter serialization. If null, default options are used.</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 send operation.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="method"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException"><paramref name="method"/> is empty or composed entirely of whitespace.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method sends a notification with parameters to the connected session. Notifications are one-way
|
||||
|
|
@ -153,7 +162,7 @@ public abstract partial class McpSession : IAsyncDisposable
|
|||
/// <param name="options">Optional request options including metadata, serialization settings, and progress tracking.</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 completion of the notification operation (not the operation being tracked).</returns>
|
||||
/// <exception cref="ArgumentNullException">The current session instance is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="progress"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method sends a progress notification to the connected session using the Model Context Protocol's
|
||||
|
|
@ -170,14 +179,44 @@ public abstract partial class McpSession : IAsyncDisposable
|
|||
RequestOptions? options = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return SendNotificationAsync(
|
||||
NotificationMethods.ProgressNotification,
|
||||
Throw.IfNull(progress);
|
||||
|
||||
return NotifyProgressAsync(
|
||||
new ProgressNotificationParams
|
||||
{
|
||||
ProgressToken = progressToken,
|
||||
Progress = progress,
|
||||
Meta = options?.Meta,
|
||||
Meta = options?.GetMetaForRequest(),
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the connected session of progress for a long-running operation.
|
||||
/// </summary>
|
||||
/// <param name="requestParams">The request parameters to send in the request.</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 completion of the notification operation (not the operation being tracked).</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="requestParams"/> is <see langword="null"/>.</exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method sends a progress notification to the connected session using the Model Context Protocol's
|
||||
/// standardized progress notification format. Progress updates are identified by a <see cref="ProgressToken"/>
|
||||
/// that allows the recipient to correlate multiple updates with a specific long-running operation.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Progress notifications are sent asynchronously and don't block the operation from continuing.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public Task NotifyProgressAsync(
|
||||
ProgressNotificationParams requestParams,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
Throw.IfNull(requestParams);
|
||||
|
||||
return SendNotificationAsync(
|
||||
NotificationMethods.ProgressNotification,
|
||||
requestParams,
|
||||
McpJsonUtilities.JsonContext.Default.ProgressNotificationParams,
|
||||
cancellationToken);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ internal sealed class NotificationHandlers
|
|||
/// </summary>
|
||||
/// <param name="method">The notification method name to invoke handlers for.</param>
|
||||
/// <param name="notification">The notification object to pass to each handler.</param>
|
||||
/// <param name="cancellationToken">A token that can be used 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>
|
||||
/// <remarks>
|
||||
/// Handlers are invoked in reverse order of registration (newest first).
|
||||
/// If any handler throws an exception, all handlers will still be invoked, and an <see cref="AggregateException"/>
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ public sealed class ElicitRequestParams : RequestParams
|
|||
return psd;
|
||||
}
|
||||
|
||||
private static IList<EnumSchemaOption> DeserializeEnumOptions(ref Utf8JsonReader reader)
|
||||
private static List<EnumSchemaOption> DeserializeEnumOptions(ref Utf8JsonReader reader)
|
||||
{
|
||||
if (reader.TokenType != JsonTokenType.StartArray)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public readonly struct ProgressToken : IEquatable<ProgressToken>
|
|||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="ProgressToken"/> with a specified value.</summary>
|
||||
/// <param name="value">The required ID value.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
|
||||
public ProgressToken(string value)
|
||||
{
|
||||
Throw.IfNull(value);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue