using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using ModelContextProtocol.Protocol;
namespace ModelContextProtocol.Client;
///
/// Represents an instance of a Model Context Protocol (MCP) client session that connects to and communicates with an MCP server.
///
public abstract partial class McpClient : McpSession
{
///
/// Initializes a new instance of the class.
///
[Experimental(Experimentals.Subclassing_DiagnosticId, UrlFormat = Experimentals.Subclassing_Url)]
protected McpClient()
{
}
///
/// Gets the capabilities supported by the connected server.
///
/// The client is not connected.
public abstract ServerCapabilities ServerCapabilities { get; }
///
/// Gets the implementation information of the connected server.
///
///
///
/// This property provides identification details about the connected server, including its name and version.
/// It is populated during the initialization handshake and is available after a successful connection.
///
///
/// This information can be useful for logging, debugging, compatibility checks, and displaying server
/// information to users.
///
///
/// The client is not connected.
public abstract Implementation ServerInfo { get; }
///
/// Gets any instructions describing how to use the connected server and its features.
///
///
///
/// This property contains instructions provided by the server during initialization that explain
/// how to effectively use its capabilities. They should focus on guidance that helps a model
/// use the server effectively and should avoid duplicating tool, prompt, or resource descriptions.
///
///
/// This can be used by clients to improve an LLM's understanding of how to use the server.
/// It can be thought of like a "hint" to the model and can be added to a system prompt.
///
///
public abstract string? ServerInstructions { get; }
///
/// Gets a that completes when the client session has completed.
///
///
///
/// The task always completes successfully. The result provides details about why the session
/// completed. Transport implementations may return derived types with additional strongly-typed
/// information, such as .
///
///
/// For graceful closure (e.g., explicit disposal),
/// will be . For unexpected closure (e.g., process crash, network failure),
/// it may contain an exception that caused or that represents the failure.
///
///
public abstract Task Completion { get; }
///
/// Resolves input requests embedded in an by dispatching
/// each request to the appropriate registered handler.
///
///
/// The input requests from the task, keyed by request identifier. Each value is an
/// wrapping the server-to-client request payload.
///
/// The to monitor for cancellation requests.
/// A dictionary of responses keyed by the same identifiers as the input requests.
private protected abstract ValueTask> ResolveInputRequestsAsync(
IDictionary inputRequests, CancellationToken cancellationToken);
///
/// Gets the maximum number of consecutive stuck-in- polls
/// allowed by before the client cancels and throws.
/// Sourced from .
///
private protected abstract int MaxConsecutiveStuckPolls { get; }
///
/// Inspects a received cacheable result (tools/list, prompts/list, resources/list,
/// resources/templates/list, or resources/read) so derived clients can emit diagnostics.
///
/// The request method that produced the result.
/// The cacheable result returned by the server.
///
/// This is used to warn (never throw) when a server that negotiated a protocol version requiring the
/// SEP-2549 ttlMs/cacheScope fields omits them. The default implementation does nothing.
///
private protected virtual void ValidateCacheableResult(string method, ICacheableResult result)
{
}
///
/// Registers one or more tool definitions in the client's tool cache, enabling the transport
/// to send Mcp-Param-* headers for those tools without requiring a prior call.
///
/// The tool definitions to register.
///
///
/// This method allows callers who already have tool schema information (e.g., from a previous session,
/// hardcoded configuration, or an out-of-band source) to provide it directly to the client. Once registered,
/// any
/// call for a registered tool will automatically include Mcp-Param-* HTTP headers based on
/// the tool's x-mcp-header schema annotations, exactly as if the tool had been discovered
/// via .
///
///
/// Cache interaction behavior:
///
/// - Registered tools are added to the same internal tool cache used by .
/// - Calling after preserves
/// manually registered tools — only server-discovered tools are cleared and repopulated.
/// - If the server returns a tool with the same name as a manually registered tool, the server's
/// definition overwrites the registered one in the cache, but the tool retains its known status
/// and will survive subsequent cache clears. This registration is sticky for the lifetime of the
/// ; use or to
/// explicitly drop known tools that are no longer needed.
/// - Tools can be registered at any time — before or after ,
/// and across multiple calls.
/// - Re-registering a tool with the same name overwrites the previous definition in the cache (last write wins).
///
///
///
/// Tools with invalid x-mcp-header annotations cause an to be thrown.
/// No tools are added to the cache if any tool in the batch fails validation (all-or-nothing).
///
///
/// is .
/// One or more tools have invalid x-mcp-header annotations.
public virtual void AddKnownTools(IEnumerable tools)
{
Throw.IfNull(tools);
throw new NotSupportedException($"{GetType().Name} does not support adding known tools.");
}
///
/// Removes one or more previously registered tool definitions from the client's tool cache by name.
///
/// The names of the tools to remove.
///
///
/// This removes the specified tools from both the known-tools set and the internal tool cache.
/// After removal, those tools will no longer survive
/// cache clears, and Mcp-Param-* headers will no longer be sent for them unless the server
/// re-discovers them via .
///
///
/// Removing a tool name that was not previously added via is a no-op.
///
///
/// is .
public virtual void RemoveKnownTools(IEnumerable toolNames)
{
Throw.IfNull(toolNames);
throw new NotSupportedException($"{GetType().Name} does not support removing known tools.");
}
///
/// Removes all previously registered tool definitions from the client's tool cache.
///
///
///
/// This clears all tools that were added via from both the known-tools
/// set and the internal tool cache. Server-discovered tools that are not also known tools are not affected
/// and will remain in the cache until the next call.
///
///
public virtual void ClearKnownTools()
{
throw new NotSupportedException($"{GetType().Name} does not support clearing known tools.");
}
}