# `ConduitMcp.OptionalDeps`
[🔗](https://github.com/nyo16/conduit_mcp/blob/v0.11.0/lib/conduit_mcp/optional_deps.ex#L1)

Runtime availability checks for ConduitMCP's conditionally compiled modules.

`ConduitMcp.Plugs.OAuth`, `ConduitMcp.OAuth.KeyProvider.JWKS` and
`ConduitMcp.Client.SchemaValidator.JSV` only exist when their optional
dependency was present when `:conduit_mcp` was compiled. Every code path
that can reach one of them crosses an `init/1` (a plug's, or a client's
option validation), so availability is validated there — once, at boot or
compile time — rather than degrading into a per-request failure that is
indistinguishable from a configuration mistake.

The client's Streamable HTTP transport
(`ConduitMcp.Client.Transport.StreamableHTTP`) needs `:finch`; it calls
`finch!/0` when its options are validated and when it starts, so a build
without Finch fails when the client starts, never on a request.

See `ConduitMcp.OptionalDependencyError` for why adding the dependency to
`mix.exs` is not sufficient on its own.

# `client_assertion!`

```elixir
@spec client_assertion!() :: module()
```

Returns the `private_key_jwt` client-assertion signer (compiled only with
`:jose`), raising `ConduitMcp.OptionalDependencyError` naming
`{:jose, "~> 1.11"}` when it was not compiled in. Called when an OAuth
configuration with a `:private_key` is validated.

# `finch!`

```elixir
@spec finch!() :: module()
```

Returns the client's internal HTTP module (compiled only with `:finch`),
raising `ConduitMcp.OptionalDependencyError` naming `{:finch, "~> 0.21"}`
when it was not compiled in.

# `jsv!`

```elixir
@spec jsv!() :: module()
```

Returns the JSV schema validator module
(`ConduitMcp.Client.SchemaValidator.JSV`), raising
`ConduitMcp.OptionalDependencyError` when it was not compiled in.

`ConduitMcp.Client` calls it when its options are validated, if `:validate`
asks for argument or `structuredContent` validation with the default
validator; it is never called per request.

# `jsv_available?`

```elixir
@spec jsv_available?() :: boolean()
```

Returns `true` when the JSV schema validator is usable in this build.

# `oauth_available?`

```elixir
@spec oauth_available?() :: boolean()
```

Returns `true` when the `:oauth` auth strategy is usable in this build.

# `oauth_client!`

```elixir
@spec oauth_client!() :: module()
```

Returns the module that runs the client's OAuth flow for a connection
(an internal module compiled only with `:finch`), raising
`ConduitMcp.OptionalDependencyError` naming `{:finch, "~> 0.21"}` when it
was not compiled in. Called when a client configured with
`auth: {:oauth, ...}` starts.

# `oauth_plug!`

```elixir
@spec oauth_plug!() :: module()
```

Returns the OAuth plug module, raising `ConduitMcp.OptionalDependencyError`
when it was not compiled in.

# `validate_key_provider!`

```elixir
@spec validate_key_provider!(module()) :: :ok
```

Validates that a configured `:key_provider` module exists and implements
both `c:ConduitMcp.OAuth.KeyProvider.fetch_keys/1` and
`c:ConduitMcp.OAuth.KeyProvider.fetch_key/2`.

`ConduitMcp.Plugs.OAuth`'s `init/1` accepts any atom as a key provider and
dispatch is unguarded, so without this a missing provider or callback
surfaces as an `UndefinedFunctionError` on the first authenticated request.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
