ExMCP.ClientConfigEnhanced (ex_mcp v0.10.0)

View Source

Enhanced configuration builder for ExMCP clients with reduced code duplication.

This module provides the same comprehensive functionality as ClientConfig but with:

  • Macro-generated configuration setters to eliminate duplication
  • Environment-based configuration loading
  • Enhanced validation with custom rules
  • Configuration composition and templates
  • Performance optimizations

Usage

# Same API as original ClientConfig
config = ExMCP.ClientConfigEnhanced.new()
         |> ExMCP.ClientConfigEnhanced.put_transport(:http)
         |> ExMCP.ClientConfigEnhanced.put_url("https://api.example.com")

# New environment loading capability
config = ExMCP.ClientConfigEnhanced.from_env(:my_app, :mcp_config)

# Quick configuration helpers
config = ExMCP.ClientConfigEnhanced.quick_http("https://api.example.com")
config = ExMCP.ClientConfigEnhanced.quick_stdio(["python", "server.py"])

Environment Variables

The enhanced module supports loading configuration from environment variables:

EXMCP_TIMEOUT_CONNECT=5000
EXMCP_RETRY_MAX_ATTEMPTS=3
EXMCP_AUTH_TOKEN=secret-token
EXMCP_TRANSPORT_URL=https://api.example.com

Summary

Functions

Adds a custom validation rule for a specific field.

Shows differences between two configurations.

Creates a configuration from Application environment settings.

Creates a configuration from system environment variables.

Creates configuration from a template with customizations.

Pretty-prints configuration for debugging.

Merges two configurations with specified strategy.

Merges environment overrides into an existing configuration.

Configures client information with automatic user_agent generation.

Configures observability settings with enhanced deep merging.

Sets the pool configuration using enhanced macro-generated setter.

Configures retry policy with validation.

Quick HTTP configuration for common scenarios.

Quick stdio configuration for common scenarios.

Validates configuration with enhanced error reporting and custom rules.

Types

auth_config()

@type auth_config() :: ExMCP.ClientConfig.auth_config()

auth_type()

@type auth_type() :: ExMCP.ClientConfig.auth_type()

env_mapping()

@type env_mapping() :: %{required(String.t()) => atom() | {atom(), atom()}}

log_level()

@type log_level() :: ExMCP.ClientConfig.log_level()

merge_strategy()

@type merge_strategy() :: :shallow | :deep | :override | :preserve_existing

observability_config()

@type observability_config() :: ExMCP.ClientConfig.observability_config()

pool_config()

@type pool_config() :: ExMCP.ClientConfig.pool_config()

profile()

@type profile() :: ExMCP.ClientConfig.profile()

retry_policy()

@type retry_policy() :: ExMCP.ClientConfig.retry_policy()

t()

@type t() :: ExMCP.ClientConfig.t()

template_name()

@type template_name() :: :production_api | :development_local | :test_fast | :custom

timeout_config()

@type timeout_config() :: ExMCP.ClientConfig.timeout_config()

transport_config()

@type transport_config() :: ExMCP.ClientConfig.transport_config()

transport_type()

@type transport_type() :: ExMCP.ClientConfig.transport_type()

validation_rule()

@type validation_rule() :: (any() -> :ok | {:error, String.t()})

Functions

add_fallback(config, transport_type, opts \\ [])

See ExMCP.ClientConfig.add_fallback/3.

add_validation_rule(config, field, rule_fun, error_message)

@spec add_validation_rule(t(), atom(), validation_rule(), String.t()) :: t()

Adds a custom validation rule for a specific field.

Examples

config = ExMCP.ClientConfigEnhanced.new()
|> ExMCP.ClientConfigEnhanced.add_validation_rule(
  :timeout,
  &validate_timeout_range/1,
  "Timeout must be between 1000 and 300000 ms"
)

diff_configs(config1, config2)

@spec diff_configs(t(), t()) :: String.t()

Shows differences between two configurations.

Examples

diff = ExMCP.ClientConfigEnhanced.diff_configs(old_config, new_config)
IO.puts(diff)

from_env(app_name, config_key, opts \\ [])

@spec from_env(atom(), atom(), keyword()) :: t()

Creates a configuration from Application environment settings.

Examples

# Load from config/config.exs: config :my_app, mcp_config: [...]
config = ExMCP.ClientConfigEnhanced.from_env(:my_app, :mcp_config)

# With fallback to default profile
config = ExMCP.ClientConfigEnhanced.from_env(:my_app, :mcp_config, default: :production)

from_env_vars(mapping \\ nil)

@spec from_env_vars(env_mapping() | nil) :: t()

Creates a configuration from system environment variables.

Examples

# Use default variable mapping
config = ExMCP.ClientConfigEnhanced.from_env_vars()

# Use custom mapping
mapping = %{
  "API_URL" => :url,
  "API_TIMEOUT" => {:timeouts, :request},
  "RETRY_COUNT" => {:retry_policy, :max_attempts}
}
config = ExMCP.ClientConfigEnhanced.from_env_vars(mapping)

from_template(template_name, customizations \\ [])

@spec from_template(
  template_name(),
  keyword()
) :: t()

Creates configuration from a template with customizations.

Examples

# Production API template
config = ExMCP.ClientConfigEnhanced.from_template(:production_api, 
  url: "https://api.production.com",
  auth: [type: :bearer, token: "secret"]
)

# Development local template
config = ExMCP.ClientConfigEnhanced.from_template(:development_local,
  command: ["python", "dev_server.py"]
)

get_all_transports(config)

See ExMCP.ClientConfig.get_all_transports/1.

inspect_config(config, opts \\ [])

@spec inspect_config(
  t(),
  keyword()
) :: String.t()

Pretty-prints configuration for debugging.

Examples

ExMCP.ClientConfigEnhanced.inspect_config(config)
ExMCP.ClientConfigEnhanced.inspect_config(config, sections: [:transport, :auth])

merge_configs(base_config, override_config, strategy \\ :deep)

@spec merge_configs(t(), t(), merge_strategy()) :: t()

Merges two configurations with specified strategy.

Examples

# Deep merge (default)
merged = ExMCP.ClientConfigEnhanced.merge_configs(base, override)

# Override strategy
merged = ExMCP.ClientConfigEnhanced.merge_configs(base, override, :override)

merge_env_overrides(config, env_mapping)

@spec merge_env_overrides(t(), env_mapping()) :: t()

Merges environment overrides into an existing configuration.

Examples

base_config = ExMCP.ClientConfigEnhanced.new(:production)
config = ExMCP.ClientConfigEnhanced.merge_env_overrides(base_config, %{
  "OVERRIDE_URL" => :url,
  "OVERRIDE_TIMEOUT" => {:timeouts, :request}
})

new()

See ExMCP.ClientConfig.new/0.

new(profile_or_transport)

See ExMCP.ClientConfig.new/1.

new(transport_type, opts)

See ExMCP.ClientConfig.new/2.

put_auth(config, auth_type, opts \\ [])

See ExMCP.ClientConfig.put_auth/3.

put_client_info(config, opts)

@spec put_client_info(t(), keyword() | map()) :: t()

Configures client information with automatic user_agent generation.

put_custom(config, key, value)

See ExMCP.ClientConfig.put_custom/3.

put_observability(config, opts)

@spec put_observability(
  t(),
  keyword()
) :: t()

Configures observability settings with enhanced deep merging.

put_pool(config, opts)

@spec put_pool(t(), keyword() | map()) :: t()

Sets the pool configuration using enhanced macro-generated setter.

Automatically handles merging and validation based on field requirements.

put_retry_policy(config, opts)

@spec put_retry_policy(t(), keyword() | map()) :: t()
@spec put_retry_policy(
  t(),
  keyword()
) :: t()

Configures retry policy with validation.

put_timeout(config, opts)

See ExMCP.ClientConfig.put_timeout/2.

put_transport(config, transport_type, opts \\ [])

See ExMCP.ClientConfig.put_transport/3.

quick_http(url, opts \\ [])

@spec quick_http(
  String.t(),
  keyword()
) :: t()

Quick HTTP configuration for common scenarios.

Examples

config = ExMCP.ClientConfigEnhanced.quick_http("https://api.example.com")
config = ExMCP.ClientConfigEnhanced.quick_http("https://api.example.com", 
  auth: [type: :bearer, token: "secret"],
  timeout: 30_000
)

quick_stdio(command, opts \\ [])

@spec quick_stdio(
  String.t() | [String.t()],
  keyword()
) :: t()

Quick stdio configuration for common scenarios.

Examples

config = ExMCP.ClientConfigEnhanced.quick_stdio(["python", "server.py"])
config = ExMCP.ClientConfigEnhanced.quick_stdio("mcp-server", 
  env: [{"DEBUG", "1"}],
  timeout: 15_000
)

to_client_opts(config)

See ExMCP.ClientConfig.to_client_opts/1.

validate(config)

See ExMCP.ClientConfig.validate/1.

validate_with_rules(config, custom_rules \\ [])

@spec validate_with_rules(
  t(),
  keyword()
) :: :ok | {:error, [{atom(), String.t()}]}

Validates configuration with enhanced error reporting and custom rules.

Examples

case ExMCP.ClientConfigEnhanced.validate_with_rules(config) do
  :ok -> {:ok, client} = ExMCP.connect(config)
  {:error, detailed_errors} -> handle_validation_errors(detailed_errors)
end