(pkg-config)= # `rath.config` Persistent local configuration for LLM providers, embedding/VLM provider selection, MCP servers, memory stores, and backend presets. v1.3.0 separates routing config from credentials and centralizes environment-variable declarations. ## Source | Module | Source | | --- | --- | | `rath.config.paths` | `src/rath/config/paths.py` | | `rath.config.schema` | `src/rath/config/schema.py` | | `rath.config.secrets` | `src/rath/config/secrets.py` | | `rath.config.credentials` | `src/rath/config/credentials.py` | | `rath.config.env` | `src/rath/config/env.py` | | `rath.config.store` | `src/rath/config/store.py` | ## Public contract OpenRath resolves config in this order: ```{figure} ../_static/config-resolution-stack.png :alt: OpenRath configuration resolution stack Config resolution starts with explicit `Provider` fields, then environment variables, and finally the resolved `.openrath/config.json` store. ``` | Location | When used | | --- | --- | | `$OPENRATH_HOME/config.json` | Explicit override. | | `./.openrath/config.json` | Project-local marker directory exists. | | `~/.openrath/config.json` | Default user config. | The routing file is JSON. Unknown fields round-trip through the Pydantic models so newer OpenRath or third-party tools can add sections without losing data. API keys live in a sibling `credentials.json` after save. `config.json`: ```json { "version": 1, "llm": { "default_provider": "openai-main", "providers": { "openai-main": { "provider_kind": "openai", "model": "gpt-5.5", "base_url": "https://api.openai.com/v1" }, "claude": { "provider_kind": "anthropic", "model": "claude-sonnet-4-5" }, "gemini": { "provider_kind": "litellm", "model": "gemini/gemini-2.0-flash" } } }, "mcp": { "default_enabled": ["filesystem"], "servers": { "filesystem": { "command": ["python", "-m", "mcp_server_filesystem"], "env": {} } } }, "memory": { "default_provider": "local-main", "providers": { "local-main": { "backend_kind": "local", "path": ".openrath/memory", "embedding_provider": "openai-main", "chat_provider": "openai-main" } } }, "backend": { "default_provider": "sandbox-main", "providers": { "sandbox-main": { "backend_kind": "opensandbox", "domain": "127.0.0.1:8080", "options": {} } } } } ``` `credentials.json` (mode `0600` on POSIX): ```json { "version": 1, "llm": { "providers": { "openai-main": "sk-...", "claude": "sk-ant-..." } }, "backend": { "providers": { "sandbox-main": "sandbox-key" } } } ``` Legacy inline `api_key` values still load and take precedence over the sidecar. The next `save()` migrates them. When another non-empty credential causes the sidecar to be rewritten, keys set to `None` are omitted. If the resulting credentials payload is empty, v1.3.0 does not remove or rewrite an existing sidecar; remove that file or entry explicitly when revoking the last key. ```{admonition} OpenSandbox config boundary :class: warning In v1.3.0, backend `domain` participates in availability/config resolution but is not injected into the SDK connection created by the backend, and backend `api_key` has no runtime consumer. Configure actual connections with `OPEN_SANDBOX_DOMAIN` and `OPEN_SANDBOX_API_KEY` (or the SDK's `~/.sandbox.toml`). ``` ### Store helpers | API | Behavior | | --- | --- | | `ConfigStore.load()` | Loads the resolved default path or seeds an empty config. | | `store.save()` | Splits secrets, atomically replaces each written file independently, sets user-only permissions on POSIX, writes `.gitignore` guards, and refreshes the root manifest. This is not a two-file transaction. | | `store.get_llm_provider(name)` | Returns a named provider, or `llm.default_provider` when `name=None`. | | `store.find_provider_by_kind(kind)` | Finds the default matching provider, then the first matching provider. | | `store.get_memory_provider(name)` | Returns a named local memory provider, or `memory.default_provider` when `name=None`. | | `store.get_backend_provider(name)` | Returns a named backend provider, or `backend.default_provider` when `name=None`. | | `store.get_mcp_server(name)` | Returns one MCP server entry. | | `store.enabled_mcp_servers()` | Resolves every name in `mcp.default_enabled`. | ### Consumers | Consumer | Config behavior | | --- | --- | | `Provider.from_config(name=None, **overrides)` | Builds a `Provider` from `llm.providers`; explicit overrides win. | | `EmbeddingProvider.from_config(name=None, **overrides)` | Uses `llm.embedding_provider` first, then chat default credentials with a safe embedding model. | | `VLMProvider.from_config(name=None, **overrides)` | Uses `llm.vlm_provider` or an explicit name; no chat fallback is assumed. | | `MemoryStoreSpec.from_config(name=None, **overrides)` | Builds local memory store options from `memory.providers`. | | `RathOpenAIChatClient` | Falls back to the first `provider_kind="openai"` config entry after Provider kwargs and environment variables. | | `RathAnthropicChatClient` | Falls back to the first `provider_kind="anthropic"` config entry after Provider kwargs and environment variables. | | `RathLiteLLMChatClient` | Does not scan OpenRath config directly; use `Provider.from_config(...)` before client dispatch. Requires `openrath[litellm]`. | | `mcp_tools_from_config(name=None)` | Builds MCP tool wrappers from one configured stdio server. | ### Environment registry `rath.config.env` is the central registry for provider and OpenSandbox environment variables. (`OPENRATH_HOME` remains path configuration.) It preserves the existing precedence: **explicit field → environment → config**. | API | Behavior | | --- | --- | | `get_env_spec(name)` | Returns one declared `EnvSpec` or raises on a typo. | | `env_value(name)` | Returns a stripped value/default or `None`. | | `env_flag(name)` | Interprets `1`, `true`, `yes`, or `on`. | | `resolve_env(name, *explicit)` | Returns the first explicit non-empty value, then the environment tier. | | `all_env_specs()` | Returns sorted declarations. | | `env_reference_rows()` / `env_reference_markdown()` | Produces stable documentation data without secret values. | ## Autodoc ```{eval-rst} .. autofunction:: rath.config.resolve_config_dir .. autofunction:: rath.config.resolve_config_path .. autofunction:: rath.config.is_project_local .. autoclass:: rath.config.RathConfig :members: .. autoclass:: rath.config.LLMConfig :members: .. autoclass:: rath.config.LLMProviderConfig :members: .. autoclass:: rath.config.MCPConfig :members: .. autoclass:: rath.config.MCPServerConfig :members: .. autoclass:: rath.config.MemoryConfig :members: .. autoclass:: rath.config.MemoryProviderConfig :members: .. raw:: html .. autoclass:: rath.config.schema.BackendConfig :members: .. raw:: html .. autoclass:: rath.config.schema.BackendProviderConfig :members: .. autoclass:: rath.config.env.EnvSpec :members: .. autofunction:: rath.config.env.get_env_spec .. autofunction:: rath.config.env.env_value .. autofunction:: rath.config.env.env_flag .. autofunction:: rath.config.env.resolve_env .. autofunction:: rath.config.env.env_reference_markdown .. autoclass:: rath.config.ConfigStore .. autoexception:: rath.config.ConfigError ``` [← API Reference](index.md)