using ModelContextProtocol.Protocol;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Nodes;
namespace ModelContextProtocol.Client;
///
/// Provides configuration options for creating instances.
///
///
/// These options are typically passed to when creating a client.
/// They define client capabilities, protocol version, and other client-specific settings.
///
public sealed class McpClientOptions
{
///
/// Gets or sets information about this client implementation, including its name and version.
///
///
///
/// This information is sent to the server during initialization to identify the client.
/// It's often displayed in server logs and can be used for debugging and compatibility checks.
///
///
/// When not specified, information sourced from the current process is used.
///
///
public Implementation? ClientInfo { get; set; }
///
/// Gets or sets the client capabilities to advertise to the server.
///
public ClientCapabilities? Capabilities { get; set; }
///
/// Gets or sets the metadata to include in the _meta field of the request.
///
///
///
/// When set, this value is sent as on the during the initialization handshake.
/// This allows passing implementation-specific data to the server alongside the standard initialize parameters,
/// such as authentication context a server validates before completing the handshake.
///
///
/// When , no _meta field is sent.
///
///
public JsonObject? InitializeMeta { get; set; }
///
/// Gets or sets the protocol version to request from the server, using a date-based versioning scheme.
///
///
///
/// Supported values are 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25,
/// and 2026-07-28.
///
///
/// When (the default), the client prefers the latest revision (2026-07-28),
/// which removed the initialize handshake and Streamable HTTP sessions. It probes with
/// server/discover and automatically falls back to the initialize handshake,
/// downgrading to an initialize-capable version the server advertises, when the server does not support that revision.
///
///
/// When non-, this value is both the requested version and the minimum the client
/// will accept: the client requests exactly this version and refuses to downgrade below it, throwing an
/// instead of falling back. Setting it to 2026-07-28 therefore disables
/// the automatic initialize-handshake server fallback, and setting it to a version that still supports Streamable HTTP
/// sessions, such as 2025-11-25, forces the initialize handshake and fails if the server
/// negotiates a different version. To try more than one version, leave this unset for automatic fallback
/// or retry the connection with a different value.
///
///
public string? ProtocolVersion { get; set; }
///
/// Gets or sets a timeout for the client-server initialization handshake sequence.
///
///
/// The timeout for the client-server initialization handshake sequence. The default value is 60 seconds.
///
///
///
/// This timeout determines how long the client will wait for the server to respond during
/// the initialization protocol handshake. If the server doesn't respond within this timeframe,
/// an exception is thrown.
///
///
/// Setting an appropriate timeout prevents the client from hanging indefinitely when
/// connecting to unresponsive servers.
///
///
public TimeSpan InitializationTimeout { get; set; } = TimeSpan.FromSeconds(60);
///
/// Gets or sets the timeout applied to the server/discover probe that the client issues
/// before falling back to the initialize handshake.
///
///
/// The probe timeout. The default value is 5 seconds. Use
/// to disable the separate probe timeout
/// and rely solely on .
///
///
///
/// This timeout only has an effect when the client prefers the 2026-07-28 protocol revision, that is,
/// when is (the default) or 2026-07-28.
/// In that mode the client first probes the server with a
/// server/discover request. A server that predates the 2026-07-28 revision may
/// silently drop the unknown method, so the probe is bounded by this timeout; when it elapses the
/// client concludes the server requires initialize and falls back to that handshake on the
/// same connection. When the caller pins an initialize-capable , no probe is issued
/// and this value has no effect.
///
///
/// The default is intentionally short so that dual-path clients fall back quickly against initialize-handshake
/// servers. Increase it for high-latency environments (for example, cold-start serverless peers or
/// satellite links) where a short probe could trigger the initialize fallback before a server on the
/// per-request metadata revision has had a chance to respond. The probe is always also bounded by
/// , which governs the overall connect budget: if this value is
/// greater than or equal to , the probe is effectively bounded by
/// alone.
///
///
///
/// The value is not positive and is not .
///
public TimeSpan DiscoverProbeTimeout
{
get;
set
{
if (value <= TimeSpan.Zero && value != Timeout.InfiniteTimeSpan)
{
throw new ArgumentOutOfRangeException(nameof(value), value, "must be positive or Timeout.InfiniteTimeSpan.");
}
field = value;
}
} = TimeSpan.FromSeconds(5);
///
/// Gets or sets the container of handlers used by the client for processing protocol messages.
///
public McpClientHandlers Handlers
{
get => field ??= new();
set
{
Throw.IfNull(value);
field = value;
}
}
}