rath.config#
Persistent local configuration for LLM providers, embedding/VLM provider selection, MCP servers, and memory stores.
Source#
Module |
Source |
|---|---|
|
|
|
|
|
|
|
|
Public contract#
OpenRath resolves config in this order:
Config resolution starts with explicit Provider fields, then environment
variables, and finally the resolved .openrath/config.json store.#
Location |
When used |
|---|---|
|
Explicit override. |
|
Project-local marker directory exists. |
|
Default user config. |
The file is JSON. Unknown fields round-trip through the Pydantic models so newer OpenRath or third-party tools can add sections without losing data.
{
"version": 1,
"llm": {
"default_provider": "openai-main",
"providers": {
"openai-main": {
"provider_kind": "openai",
"model": "gpt-5.5",
"api_key": "sk-...",
"base_url": "https://api.openai.com/v1"
},
"claude": {
"provider_kind": "anthropic",
"model": "claude-sonnet-4-5",
"api_key": "sk-ant-..."
}
}
},
"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": "embed-main",
"chat_provider": "openai-main"
}
}
}
}
Store helpers#
API |
Behavior |
|---|---|
|
Loads the resolved default path or seeds an empty config. |
|
Writes atomically, sets user-only permissions on POSIX, and writes |
|
Returns a named provider, or |
|
Finds the default matching provider, then the first matching provider. |
|
Returns a named local memory provider, or |
|
Returns one MCP server entry. |
|
Resolves every name in |
Consumers#
Consumer |
Config behavior |
|---|---|
|
Builds a |
|
Uses |
|
Uses |
|
Builds local memory store options from |
|
Falls back to the first |
|
Falls back to the first |
|
Builds MCP tool wrappers from one configured stdio server. |
Autodoc#
- rath.config.resolve_config_dir() Path[source]#
Return the directory that holds
config.json.Raises
FileNotFoundErroronly whenOPENRATH_HOMEis set but points at a non-directory path that already exists (e.g. a regular file). A missing target is fine — the caller will create it on first save.
- rath.config.resolve_config_path() Path[source]#
Return the full path to
config.jsonunder the resolved config dir.
- rath.config.is_project_local(config_dir: Path) bool[source]#
Return whether
config_diris the project-local./.openrath/.Used by
rath.config.secretsto decide whether to also append.openrath/to the surrounding project’s.gitignoreon save.
- class rath.config.RathConfig(*, version: int = 1, llm: LLMConfig = <factory>, mcp: MCPConfig = <factory>, memory: MemoryConfig = <factory>, **extra_data: Any)[source]#
Top-level on-disk schema.
Sections currently in use:
llm,mcp, andmemory. Future sections (e.g.backendfor OpenSandbox routing) can be added without touching callers becauseextra="allow"preserves them on round-trip.- model_config = {'extra': 'allow'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class rath.config.LLMConfig(*, default_provider: str | None = None, embedding_provider: str | None = None, vlm_provider: str | None = None, providers: dict[str, ~rath.config.schema.LLMProviderConfig]=<factory>, **extra_data: Any)[source]#
The
llmsection: named providers + which one is the default.default_provideris the chat fallback.embedding_providerandvlm_providerare independent overrides used byrath.llm.embedding.EmbeddingProviderandrath.llm.vlm.VLMProvider; when unset, those clients fall back todefault_provider’sapi_key/base_urlwith a sensible default model.- model_config = {'extra': 'allow'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class rath.config.LLMProviderConfig(*, provider_kind: Literal['openai', 'anthropic'] = 'openai', model: str | None = None, api_key: str | None = None, base_url: str | None = None, temperature: float | None = None, max_tokens: int | None = None, **extra_data: Any)[source]#
One named entry under
llm.providers.Mirrors the most common
Providerfields. Less-common knobs (frequency_penalty,logit_bias, …) stay on explicitProvider(...)kwargs — adding fields here later is non-breaking thanks toextra="allow".- model_config = {'extra': 'allow'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class rath.config.MCPConfig(*, default_enabled: list[str] = <factory>, servers: dict[str, ~rath.config.schema.MCPServerConfig]=<factory>, **extra_data: Any)[source]#
The
mcpsection: named server defs + which are enabled by default.- model_config = {'extra': 'allow'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class rath.config.MCPServerConfig(*, command: list[str], env: dict[str, str] = <factory>, **extra_data: ~typing.Any)[source]#
One named entry under
mcp.servers.commandis the full argv list passed to the stdio MCP server (the OpenRath adapter never shells out, so no string-form).envis merged into the subprocess environment by the adapter.- model_config = {'extra': 'allow'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class rath.config.MemoryConfig(*, default_provider: str | None = None, providers: dict[str, ~rath.config.schema.MemoryProviderConfig]=<factory>, **extra_data: Any)[source]#
The
memorysection: named local store presets.- model_config = {'extra': 'allow'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class rath.config.MemoryProviderConfig(*, backend_kind: Literal['local'] = 'local', path: str | None = None, embedding_provider: str | None = None, chat_provider: str | None = None, **extra_data: Any)[source]#
One named entry under
memory.providers(local backend only).embedding_providerandchat_providername entries underllm.providersused byLocalMemoryBackendfor vector search and commit-time memo extraction respectively. OpenViking connection settings stay onMemoryStoreSpec.optionsor environment variables — they are not modeled here.- model_config = {'extra': 'allow'}#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class rath.config.ConfigStore(path: Path | None = None)[source]#
Round-trip the config file at
path.The constructor immediately reads the file (or seeds defaults when it does not exist), so callers do not need to guard against
FileNotFoundErrorseparately. Subsequent reads should mutateconfigdirectly; callsave()to persist.
- exception rath.config.ConfigError[source]#
Raised on schema-validation failure or corrupt JSON.
The string carries a human-readable summary; the original
json.JSONDecodeErrororpydantic.ValidationErroris available via__cause__.