The validated options of a ConduitMcp.Client.
ConduitMcp.Client.child_spec/1 and ConduitMcp.Client.start_link/1 run
new!/1, so a misspelled or invalid option raises an ArgumentError
naming the key when the client starts, never at the first request.
Options
:name(term/0) - Required. Identifies the client. Any term: it is a key inConduitMcp.Client.Registry, never an atom-registered name, so{MyApp.GitHub, tenant_id}or{__MODULE__, make_ref()}work. EveryConduitMcp.Clientfunction takes it.:server_id- The operator-assigned id of the server, stamped on everyConduitMcp.Client.Tool,ResourceandPromptthis client returns. Defaults to:namewhen it is a string, elseinspect(name). The default value isnil.:transport- Required.{module, opts}: a module implementingConduitMcp.Client.Transportand its options, for example{ConduitMcp.Client.Transport.InProcess, server: MyServer}.:protocol- Which protocol era to speak.:autoprobesserver/discoverand falls back toinitializeonly on legacy evidence (seeConduitMcp.Client.Negotiation.classify_probe/3).:modernand:legacyskip the probe; a version string ("2026-07-28","2025-11-25","2025-06-18") pins that exact version. The default value is:auto.:probe_timeout(pos_integer/0) - How longprotocol: :autowaits for theserver/discoverprobe, in milliseconds. Defaults by transport kind: 5 000 for:http, 3 000 otherwise.:prior- A previously observed era (for example a cachedera/1).:legacyskips the probe and starts withinitialize; if that is refused, the next attempt probes again.:modernchanges nothing, sinceserver/discoveris the modern handshake. The default value isnil.:handler- A module implementingConduitMcp.Client.Handler. Its callbacks decide the advertised client capabilities (ConduitMcp.Client.Negotiation.client_capabilities/2); without one the client advertises{}. The default value isnil.:client_info- TheImplementationsent asclientInfo: a string-keyed map with at least"name"and"version". Defaults to%{"name" => "conduit_mcp", "version" => <library version>}.:request_timeout(pos_integer/0) - Default deadline of each request, in milliseconds, and of the connect and handshake steps. A request's:timeoutoverrides it. The default value is60000.:max_total_timeout(pos_integer/0) - Withreset_timeout_on_progress: true, progress notifications push a request's deadline forward, but never past this many milliseconds after it was sent. The default value is300000.:max_in_flight(pos_integer/0) - Requests sent and not yet answered. One more is refused at once with%ConduitMcp.Client.Error{kind: :overloaded}. The default value is64.:max_queued(pos_integer/0) - Requests waiting for the connection to become ready. One more is refused withkind: :overloaded. The default value is128.:backoff(function of arity 1) -fn attempt -> milliseconds end: the delay before reconnect attemptattempt(1, 2, …). Defaults toConduitMcp.Client.Backoff.full_jitter/1. It runs in the connection process, so it must be pure and fast; one that raises or returns anything but a non-negative integer is replaced byfull_jitter/1for that attempt, with a warning. The default value is&ConduitMcp.Client.Backoff.full_jitter/1.:max_reconnects- Consecutive failed reconnect attempts before giving up. The count resets once the connection has stayed ready for:stable_after. The default value is:infinity.:on_give_up- After:max_reconnects::staykeeps the connection alive in the:closedstate (sostatus/1explains why, andreconnect/1can retry);:stopexits so a supervisor restarts it. The default value is:stay.:stable_after(pos_integer/0) - Milliseconds the connection must stay ready before the reconnect attempt count resets. The default value is30000.:health_check_interval- When set, a ready connection checks the server every this many milliseconds (legacyping, modernserver/discover); two unanswered checks in a row restart the transport. The default value isnil.:assigns(map/0) - Host data passed toConduitMcp.Client.Handlercallbacks asctx.assignswhen a server request is not tied to a call (a call's own:assignsoption wins for requests tied to it). The default value is%{}.:handler_timeout(keyword/0) - Milliseconds a legacy server-to-client request may run in its handler task before it is killed and answered-32603, per method. Modern input requests run in the caller and are bounded by the call. The default value is[].:sampling(pos_integer/0) - The default value is60000.:elicitation(pos_integer/0) - The default value is300000.:roots(pos_integer/0) - The default value is60000.
:max_server_requests(pos_integer/0) - Legacy server-to-client requests handled at once; one more is answered-32000(busy) without running the handler. The default value is8.:input_rate_limit(keyword/0) - The per-server budget of input requests (sampling, elicitation, roots) in both eras. Over it, sampling is refused with the sampling:rejection_codeand the others with-32000. The default value is[].:per_second(pos_integer/0) - The default value is10.:burst(pos_integer/0) - The default value is20.
:log_rate_limit(keyword/0) - The per-connection budget ofnotifications/messagelog entries from the server. Over it, entries are dropped before they reach subscribers orhandle_log/3, and each drop emits[:conduit_mcp, :client, :log, :dropped]. The default value is[].:per_second(pos_integer/0) - The default value is50.:burst(pos_integer/0) - The default value is100.
:sampling(keyword/0) - Safety settings forsampling/createMessage(used only when the handler implementshandle_sampling/2).:max_tokensclamps the server'smaxTokens.:contextdeclaressampling.contextand letsincludeContextthrough; otherwise it is coerced to"none".:toolsdeclaressampling.tools.:allow_idleaccepts legacy sampling requests that arrive while no call is in flight (refused by default).:max_tool_iterationsbounds a sampling tool loop: a request whosemessagesalready hold more assistanttool_useturns than this is refused. Refusals use:rejection_code. The default value is[].:max_tokens(pos_integer/0) - The default value is4096.:context(boolean/0) - The default value isfalse.:tools(boolean/0) - The default value isfalse.:allow_idle(boolean/0) - The default value isfalse.:max_tool_iterations(pos_integer/0) - The default value is5.:rejection_code(integer/0) - The default value is-1.
:elicitation(keyword/0) -:origin- the server's origin ("https://host[:port]") that a URL-mode elicitation URL is compared with, for transports that do not report one. The handler getsorigin_mismatch?: truefor any other origin, and when no origin is known. The default value is[].:origin- The default value isnil.
:roots(keyword/0) -:list_changed- declareroots.listChangedto legacy servers (the host announces changes withConduitMcp.Client.notify_roots_changed/1). Used only when the handler implementslist_roots/1. The default value is[].:list_changed(boolean/0) - The default value istrue.
:max_cache_ttl(pos_integer/0) - The longest a cached list (ConduitMcp.Client.Cache) is served without asking the server again, whatever itsttlMshint says. The default value is3600000.:policy- Authorizes tool calls (ConduitMcp.Client.Policy): theConduitMcp.Client.Policy.compile/1options, a compiled policy, or{:named, name}to read the policy stored withConduitMcp.Client.Policy.update/2at each call (a missing one denies).nil(the default) means no authorization: the client sends what it is asked to (R6). Setting it routescall_tool/4throughConduitMcp.Client.Pipeline. The default value isnil.:on_ask- The approver for calls the policy decides:ask:fun.(%ConduitMcp.Client.ToolCall{}, ctx)or{Module, :function}, returning{:allow, :once | :always},{:deny, reason}or{:deny, reason, :halt}(seeConduitMcp.Client.Pipeline). Without one,:askdenies. The default value isnil.:ask_timeout(pos_integer/0) - Milliseconds:on_askmay take; after that the call is denied. The default value is60000.:grant_ttl(pos_integer/0) - How long an{:allow, :always}answer is remembered, in milliseconds (ConduitMcp.Client.Grants). The default value is86400000.:approved_fingerprints- The tool definitions the policy'spin_toolsandallow_new_toolstreat as approved::first_listingrecords the fingerprints of the first full tool list the client reads; a map of tool name toConduitMcp.Client.Fingerprintpins exactly those. The default value is:first_listing.:hooks- Pre-call, post-call, failure, listing, resource and prompt hooks; seeConduitMcp.Client.Hooks. The default value is[].:hook_timeout(pos_integer/0) - Default milliseconds a hook may run before it fails (closed). The default value is5000.:tools- Which tools are visible at all:[include: [...], exclude: [...]](ConduitMcp.Client.ToolFilter). Hidden tools are left out of every tool list and calling one fails withkind: :not_found. The default value isnil.:validate(keyword/0) - JSON Schema validation of call arguments (inputSchema) and ofstructuredContent(outputSchema); seeConduitMcp.Client.SchemaValidator. The default validator needs the optional:jsvdependency: asking for validation without it raisesConduitMcp.OptionalDependencyErrorhere. The default value is[].:arguments(boolean/0) - The default value isfalse.:structured_content(boolean/0) - The default value isfalse.:validator(atom/0) - The default value isConduitMcp.Client.SchemaValidator.JSV.
:trusted(boolean/0) - Trust this server's tool annotations in policy annotation rules (PO-8) and itsinstructionsinConduitMcp.Client.instructions_for_llm/1. The default value isfalse.:max_result_bytes_for_llm(pos_integer/0) - The cap on a tool result shaped for a model (shape: :llm, seeConduitMcp.Client.Pipeline). The default value is102400.:include_instructions(boolean/0) - WhetherConduitMcp.Client.instructions_for_llm/1returns the server'sinstructions(PI-1). Off by default. The default value isfalse.:clock-fn -> unix_milliseconds endused for grant expiry (default the system clock); for tests. The default value isnil.:telemetry(keyword/0) - Telemetry settings. Client events carry allowlisted metadata only (seeConduitMcp.Telemetry); payload capture is the one opt-in exception. The default value is[].:capture_payloads- Opt-in capture of tool-call payloads in the[:conduit_mcp, :client, :tool_call, ...]span (TL-2).false(the default): the span's metadata has no:argumentsor:resultkey at all. To enable it, pass[redact: fun, max_bytes: n]::redact(required;truealone is rejected) is a one-arity function run in the calling process on the arguments and on the result before they reach any handler, and:max_bytes(default 4 096) caps the JSON size of what it returns. See "Payload capture" inConduitMcp.Telemetry. The default value isfalse.
Summary
Functions
Validates opts and returns the config; raises ArgumentError naming the
offending key. A %Config{} is returned unchanged.
Types
@type protocol() :: :auto | :modern | :legacy | String.t()
@type t() :: %ConduitMcp.Client.Config{ assigns: map(), backoff: (pos_integer() -> non_neg_integer()), capabilities: %{modern: map(), legacy: map()}, capture_payloads: false | %{redact: (term() -> term()), max_bytes: pos_integer()}, client_info: %{required(String.t()) => term()}, elicitation: keyword(), governance: struct(), handler: module() | nil, handler_timeout: keyword(), health_check_interval: pos_integer() | nil, input_rate_limit: keyword(), log_rate_limit: keyword(), max_cache_ttl: pos_integer(), max_in_flight: pos_integer(), max_queued: pos_integer(), max_reconnects: non_neg_integer() | :infinity, max_server_requests: pos_integer(), max_total_timeout: pos_integer(), name: term(), on_give_up: :stay | :stop, prior: :modern | :legacy | nil, probe_timeout: pos_integer(), protocol: protocol(), request_timeout: pos_integer(), roots: keyword(), sampling: keyword(), server_id: String.t(), stable_after: pos_integer(), transport: {module(), keyword()} }
Functions
Validates opts and returns the config; raises ArgumentError naming the
offending key. A %Config{} is returned unchanged.
The governance options (:policy through :clock above) are compiled
into the governance field.
Example
iex> config =
...> ConduitMcp.Client.Config.new!(
...> name: :docs,
...> transport: {ConduitMcp.Client.Transport.InProcess, server: ConduitMcp.TestServer}
...> )
iex> {config.protocol, config.probe_timeout, config.max_in_flight}
{:auto, 3000, 64}