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
2 changes: 1 addition & 1 deletion src/ModelContextProtocol/Client/McpClientExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ public static Task UnsubscribeFromResourceAsync(this IMcpClient client, Uri uri,
}

/// <summary>
/// Invokes a tool on the server
/// Invokes a tool on the server.
/// </summary>
/// <param name="client">The client instance used to communicate with the MCP server.</param>
/// <param name="toolName">The name of the tool to call on the server..</param>
Expand Down
57 changes: 48 additions & 9 deletions src/ModelContextProtocol/Client/McpClientTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,53 @@ internal McpClientTool(
protected async override ValueTask<object?> InvokeCoreAsync(
AIFunctionArguments arguments, CancellationToken cancellationToken)
{
CallToolResponse result = await _client.CallToolAsync(ProtocolTool.Name, arguments, _progress, JsonSerializerOptions, cancellationToken: cancellationToken).ConfigureAwait(false);
CallToolResponse result = await CallAsync(arguments, _progress, JsonSerializerOptions, cancellationToken).ConfigureAwait(false);
return JsonSerializer.SerializeToElement(result, McpJsonUtilities.JsonContext.Default.CallToolResponse);
}

/// <summary>
/// Invokes the tool on the server.
/// </summary>
/// <param name="arguments">An optional dictionary of arguments to pass to the tool. Each key represents a parameter name,
/// and its associated value represents the argument value.
/// </param>
/// <param name="progress">
/// An optional <see cref="IProgress{T}"/> to have progress notifications reported to it. Setting this to a non-<see langword="null"/>
/// value will result in a progress token being included in the call, and any resulting progress notifications during the operation
/// routed to this instance.
/// </param>
/// <param name="serializerOptions">
/// The JSON serialization options governing argument serialization. If <see langword="null"/>, the default serialization options will be 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 containing the <see cref="CallToolResponse"/> from the tool execution. The response includes
/// the tool's output content, which may be structured data, text, or an error message.
/// </returns>
/// <remarks>
/// The base <see cref="AIFunction.InvokeAsync"/> method is overridden to invoke this <see cref="CallAsync"/> method.
/// The only difference in behavior is <see cref="AIFunction.InvokeAsync"/> will serialize the resulting <see cref="CallToolResponse"/>"/>
/// such that the <see cref="object"/> returned is a <see cref="JsonElement"/> containing the serialized <see cref="CallToolResponse"/>.
/// This <see cref="CallToolResponse"/> method is intended to be called directly by user code, whereas the base <see cref="AIFunction.InvokeAsync"/>
/// is intended to be used polymorphically via the base class, typically as part of an <see cref="IChatClient"/> operation.
/// </remarks>
/// <exception cref="McpException">The server could not find the requested tool, or the server encountered an error while processing the request.</exception>
/// <example>
/// <code>
/// var result = await tool.CallAsync(
/// new Dictionary&lt;string, object?&gt;
/// {
/// ["message"] = "Hello MCP!"
/// });
/// </code>
/// </example>
public Task<CallToolResponse> CallAsync(
IReadOnlyDictionary<string, object?>? arguments = null,
IProgress<ProgressNotificationValue>? progress = null,
JsonSerializerOptions? serializerOptions = null,
CancellationToken cancellationToken = default) =>
_client.CallToolAsync(ProtocolTool.Name, arguments, progress, serializerOptions, cancellationToken);

/// <summary>
/// Creates a new instance of the tool but modified to return the specified name from its <see cref="Name"/> property.
/// </summary>
Expand All @@ -114,10 +157,8 @@ internal McpClientTool(
/// the value returned from this instance's <see cref="AITool.Name"/>.
/// </para>
/// </remarks>
public McpClientTool WithName(string name)
{
return new McpClientTool(_client, ProtocolTool, JsonSerializerOptions, name, _description, _progress);
}
public McpClientTool WithName(string name) =>
new McpClientTool(_client, ProtocolTool, JsonSerializerOptions, name, _description, _progress);

/// <summary>
/// Creates a new instance of the tool but modified to return the specified description from its <see cref="Description"/> property.
Expand All @@ -140,10 +181,8 @@ public McpClientTool WithName(string name)
/// </para>
/// </remarks>
/// <returns>A new instance of <see cref="McpClientTool"/> with the provided description.</returns>
public McpClientTool WithDescription(string description)
{
return new McpClientTool(_client, ProtocolTool, JsonSerializerOptions, _name, description, _progress);
}
public McpClientTool WithDescription(string description) =>
new McpClientTool(_client, ProtocolTool, JsonSerializerOptions, _name, description, _progress);

/// <summary>
/// Creates a new instance of the tool but modified to report progress via the specified <see cref="IProgress{T}"/>.
Expand Down