Module: Woods::MCP::ConfigResolver

Defined in:
lib/woods/mcp/config_resolver.rb

Overview

Resolves the embedding configuration that the MCP server should use.

Reads woods.json (the resolved config snapshot written at embed time), applies environment-variable overrides, validates, and returns either a populated Configuration or raises a typed BootstrapError subclass that the caller can present to an operator.

This class is extracted from Bootstrapper to isolate the config-resolution concern from network probing and store construction. Bootstrapper delegates to ConfigResolver.resolve as its first step.

Resolution order (highest priority first):

  1. Host Rails initializer (Woods.configuration already has embedding_provider). When woods.json is also present the stored config is loaded and asserted compatible via ResolvedConfig#assert_compatible!.

  2. woods.json snapshot alone (MCP server running without a host initializer). The stored config is used to populate config in place.

  3. Environment-variable auto-detect (deprecated, opt-in via WOODS_ALLOW_AUTODETECT=1). Mutates config to set provider and stores.

  4. If none of the above applies, raises MissingArtifact.

Examples:

Typical Bootstrapper usage

config, source = ConfigResolver.resolve(Woods.configuration, artifact: artifact)
# config.embedding_provider is now guaranteed to be non-nil (or :none was returned)

Class Method Summary collapse

Class Method Details

.resolve(config, artifact:, env: ENV, ollama_probe: nil) ⇒ Array(Woods::Configuration, Symbol)

Resolve and validate the embedding configuration.

When woods.json is present in the artifact directory it is parsed into a ResolvedConfig and, if the host already has a provider configured, validated for compatibility (dimension + provider class/model must agree). If the host has no provider configured the stored config is applied to config so Builder can construct the correct provider.

When woods.json is absent and the host already has a provider configured, the host config is trusted and used as-is.

When woods.json is absent and the host has no provider configured:

  • If WOODS_ALLOW_AUTODETECT is 1, falls through to env-var auto-detect (deprecated, emits a structured warning).

  • Otherwise raises MissingArtifact.

Parameters:

  • config (Woods::Configuration)

    the live host configuration object. May be mutated in the auto-detect path.

  • artifact (Woods::IndexArtifact, nil)

    the on-disk artifact wrapper.

  • env (Hash) (defaults to: ENV)

    environment variable source (default ENV, overridable in specs without stubbing the global ENV).

  • ollama_probe (#call, nil) (defaults to: nil)

    callable used to check Ollama reachability in the deprecated auto-detect path. Defaults to ollama_reachable? on this module. Callers may pass a different probe to facilitate testing without touching global state.

Returns:

  • (Array(Woods::Configuration, Symbol))

    tuple of [config, source] where source is one of :snapshot, :host_config, :autodetect, or :none. The config is the same object passed in, possibly mutated.

Raises:



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/woods/mcp/config_resolver.rb', line 71

def self.resolve(config, artifact:, env: ENV, ollama_probe: nil)
  stored = read_stored_config(artifact)

  if stored
    [apply_stored_config(config, stored, artifact: artifact, env: env), :snapshot]
  elsif config.embedding_provider
    # Host initializer configured a provider; no woods.json to validate
    # against. Trust the host config and proceed.
    [config, :host_config]
  else
    resolve_without_artifact(config, artifact: artifact, env: env, ollama_probe: ollama_probe)
  end
end