Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mcp_bridge/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from mcp_bridge.config.env_subst import substitute_env_vars
from mcp_bridge.config.initial import initial_settings
from mcp_bridge.config.final import Settings
from typing import Any, Callable
Expand Down Expand Up @@ -38,6 +39,8 @@
for cfg in configs:
always_merger.merge(result, cfg)

result = substitute_env_vars(result)

# build the config
try:
config = Settings(**result)
Expand Down
31 changes: 31 additions & 0 deletions mcp_bridge/config/env_subst.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from string import Template
from typing import Any
import os

from loguru import logger


def substitute_env_vars(config: Any, env: dict[str, str] | None = None) -> Any:
"""Substitute environment variables in a configuration object."""

# copy the environment if it is not provided
if env is None:
env = os.environ.copy()

assert env is not None, "env is None" # the guard should have caught this

# handle strings
if isinstance(config, str):
return Template(config).safe_substitute(env)

# handle other types
elif isinstance(config, dict):
return {
k: substitute_env_vars(v, env) for k, v in config.items() if v is not None
}

# handle lists
elif isinstance(config, list):
return [substitute_env_vars(v, env) for v in config]

return config