fix: config file values no longer override env vars and CLI flags - #403
Merged
AutomateIP merged 1 commit intoAug 10, 2026
Merged
Conversation
load_config() always passed config-file values as explicit constructor kwargs, so a file value won whenever the key was present -- silently overriding env vars and CLI flags and contradicting the documented precedence (env/CLI > file > defaults). Filter file-derived kwargs via _filter_file_data() so any field whose backing env var is already set in os.environ is omitted, letting its env-backed default_factory fire instead. _env_key_for_field() resolves the backing env var from each field's default_factory (needed because the env key isn't always mechanically derivable from the section name, e.g. auth fields map to ITENTIAL_MCP_SERVER_AUTH_*). Scope limited to config/loaders.py and its tests; config/models.py and the section-dispatch logic are untouched.
3 tasks
AutomateIP
added a commit
that referenced
this pull request
Aug 10, 2026
… mangling (#404) Fixes two coupled bugs in the config-file loader that broke the documented file-based auth configuration path. docs/mcp.conf.example documents all auth fields under [server] with an auth_* prefix, but those keys were being silently dropped, and oauth_* field names were being mangled. - Reorder the section-dispatch loop in config/loaders.py so server_auth_/ auth_ keys are matched before the broad server_ prefix. Previously the server_ branch absorbed every [server] auth_* key into server_data, where pydantic silently dropped them (dead server_auth_ branch). - Add _strip_auth_prefix(), a prefix-only strip (removeprefix), replacing the global key.replace("auth_", "") that mangled all 8 oauth_* field names (e.g. oauth_client_id -> oclient_id). - Add coverage in tests/test_config.py for the documented [server] auth_* path, the [auth] section, oauth field-name integrity, and confirmation that #403's env/CLI-over-file precedence still holds. Addresses roadmap 0.14.0 Tier B #26 and #27. Both surfaced during #403 and are fixed together as they share the same dispatch/parsing path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restores the documented configuration precedence (environment variables and
CLI flags over the config file).
load_config()was always passingconfig-file values as explicit constructor kwargs, so a file value won
whenever its key was present in the file -- silently overriding env vars and
CLI flags and contradicting this project's own documented precedence
(env/CLI > file > defaults). Long-standing, traced to the config-module
refactor in PR #292.
Changes
config/loaders.py: add_filter_file_data()to drop file-derived keyswhose backing env var is already present in
os.environ, letting thatfield's env-backed
default_factoryrun instead.config/loaders.py: add_env_key_for_field()to resolve a field'sbacking env var from its
default_factory(env keys aren't always derivablefrom the section name -- e.g. auth fields map to
ITENTIAL_MCP_SERVER_AUTH_*).ServerConfig/AuthConfig/PlatformConfigconstruction sites; correct the stale inline precedence comment.
(env-beats-file, file-beats-default, CLI-flag-beats-file).
Scope is limited to
config/loaders.pyand its tests.config/models.pyand the section-dispatch/prefix-stripping logic are intentionally untouched.
Two unrelated pre-existing bugs were found during this work and are
deliberately NOT fixed here (documented in test comments, will be tracked
separately): (a)
[server] auth_typein a config file is silently absorbeddue to section-dispatch ordering, (b) a global (non-prefix) string replace
mangles
oauth_*field names read from a config file.Testing
make ci, 2793 tests, ruff/bandit/headers clean)still connects; env vars override file across server/platform/auth
fields incl.
ITENTIAL_MCP_SERVER_AUTH_TYPE; a live SSE server startedvia
--transport sseagainst a file sayingtransport=stdio; liveOAuth unaffected when nothing overrides; live
get_healthsucceeded)Related Issues
Fixes the config-precedence bug tracked as Tier B #25 in the 0.14.0 roadmap.