fast-agent-mcp 0.2.32__py3-none-any.whl → 0.2.33__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fast-agent-mcp might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fast-agent-mcp
3
- Version: 0.2.32
3
+ Version: 0.2.33
4
4
  Summary: Define, Prompt and Test MCP enabled Agents and Workflows
5
5
  Author-email: Shaun Smith <fastagent@llmindset.co.uk>
6
6
  License: Apache License
@@ -1,6 +1,6 @@
1
1
  mcp_agent/__init__.py,sha256=18T0AG0W9sJhTY38O9GFFOzliDhxx9p87CvRyti9zbw,1620
2
2
  mcp_agent/app.py,sha256=3mtHP1nRQcRaKhhxgTmCOv00alh70nT7UxNA8bN47QE,5560
3
- mcp_agent/config.py,sha256=c3KxDNXuOhLSBQ7InVw6sUaTc_5K5YbzVPnTMxgF_34,13924
3
+ mcp_agent/config.py,sha256=9GDvMugKIeT9SKRGGEv2gN3lsC78hQ_Oy-HSpItuqo0,15841
4
4
  mcp_agent/console.py,sha256=Gjf2QLFumwG1Lav__c07X_kZxxEUSkzV-1_-YbAwcwo,813
5
5
  mcp_agent/context.py,sha256=H7JbaZ_8SzzTagLmIgUPUPxX5370C5qjQAsasFPZG2Y,7510
6
6
  mcp_agent/context_dependent.py,sha256=QXfhw3RaQCKfscEEBRGuZ3sdMWqkgShz2jJ1ivGGX1I,1455
@@ -155,8 +155,8 @@ mcp_agent/resources/examples/workflows/router.py,sha256=E4x_-c3l4YW9w1i4ARcDtkde
155
155
  mcp_agent/resources/examples/workflows/short_story.txt,sha256=X3y_1AyhLFN2AKzCKvucJtDgAFIJfnlbsbGZO5bBWu0,1187
156
156
  mcp_agent/tools/tool_definition.py,sha256=L3Pxl-uLEXqlVoo-bYuFTFALeI-2pIU44YgFhsTKEtM,398
157
157
  mcp_agent/ui/console_display.py,sha256=UKqax5V2TC0hkZZORmmd6UqUk0DGX7A25E3h1k9f42k,10982
158
- fast_agent_mcp-0.2.32.dist-info/METADATA,sha256=qyRrXCLGN7z2izenh-0kXfUevePisaCmKLFqruzphD8,30799
159
- fast_agent_mcp-0.2.32.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
160
- fast_agent_mcp-0.2.32.dist-info/entry_points.txt,sha256=oKQeSUVn87pJv8_k1NQ7Ak8cXaaXHCnPAOJRCV_uUVg,230
161
- fast_agent_mcp-0.2.32.dist-info/licenses/LICENSE,sha256=cN3FxDURL9XuzE5mhK9L2paZo82LTfjwCYVT7e3j0e4,10939
162
- fast_agent_mcp-0.2.32.dist-info/RECORD,,
158
+ fast_agent_mcp-0.2.33.dist-info/METADATA,sha256=nWUeuUtV_vX9ugzUQqS5FY4RBGyZQxTDJg6i8PaHGV4,30799
159
+ fast_agent_mcp-0.2.33.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
160
+ fast_agent_mcp-0.2.33.dist-info/entry_points.txt,sha256=oKQeSUVn87pJv8_k1NQ7Ak8cXaaXHCnPAOJRCV_uUVg,230
161
+ fast_agent_mcp-0.2.33.dist-info/licenses/LICENSE,sha256=cN3FxDURL9XuzE5mhK9L2paZo82LTfjwCYVT7e3j0e4,10939
162
+ fast_agent_mcp-0.2.33.dist-info/RECORD,,
mcp_agent/config.py CHANGED
@@ -3,8 +3,10 @@ Reading settings from environment variables and providing a settings object
3
3
  for the application configuration.
4
4
  """
5
5
 
6
+ import os
7
+ import re
6
8
  from pathlib import Path
7
- from typing import Dict, List, Literal, Optional
9
+ from typing import Any, Dict, List, Literal, Optional
8
10
 
9
11
  from pydantic import BaseModel, ConfigDict, field_validator
10
12
  from pydantic_settings import BaseSettings, SettingsConfigDict
@@ -365,6 +367,36 @@ _settings: Settings | None = None
365
367
  def get_settings(config_path: str | None = None) -> Settings:
366
368
  """Get settings instance, automatically loading from config file if available."""
367
369
 
370
+ def resolve_env_vars(config_item: Any) -> Any:
371
+ """Recursively resolve environment variables in config data."""
372
+ if isinstance(config_item, dict):
373
+ return {k: resolve_env_vars(v) for k, v in config_item.items()}
374
+ elif isinstance(config_item, list):
375
+ return [resolve_env_vars(i) for i in config_item]
376
+ elif isinstance(config_item, str):
377
+ # Regex to find ${ENV_VAR} or ${ENV_VAR:default_value}
378
+ pattern = re.compile(r"\$\{([^}]+)\}")
379
+
380
+ def replace_match(match: re.Match) -> str:
381
+ var_name_with_default = match.group(1)
382
+ if ":" in var_name_with_default:
383
+ var_name, default_value = var_name_with_default.split(":", 1)
384
+ return os.getenv(var_name, default_value)
385
+ else:
386
+ var_name = var_name_with_default
387
+ env_value = os.getenv(var_name)
388
+ if env_value is None:
389
+ # Optionally, raise an error or return the placeholder if the env var is not set
390
+ # For now, returning the placeholder to avoid breaking if not set and no default
391
+ # print(f"Warning: Environment variable {var_name} not set and no default provided.")
392
+ return match.group(0)
393
+ return env_value
394
+
395
+ # Replace all occurrences
396
+ resolved_value = pattern.sub(replace_match, config_item)
397
+ return resolved_value
398
+ return config_item
399
+
368
400
  def deep_merge(base: dict, update: dict) -> dict:
369
401
  """Recursively merge two dictionaries, preserving nested structures."""
370
402
  merged = base.copy()
@@ -409,12 +441,14 @@ def get_settings(config_path: str | None = None) -> Settings:
409
441
  # Load main config
410
442
  with open(config_file, "r", encoding="utf-8") as f:
411
443
  yaml_settings = yaml.safe_load(f) or {}
412
- merged_settings = yaml_settings
444
+ # Resolve environment variables in the loaded YAML settings
445
+ resolved_yaml_settings = resolve_env_vars(yaml_settings)
446
+ merged_settings = resolved_yaml_settings
413
447
  # Look for secrets files recursively up the directory tree
414
448
  # but stop after finding the first one
415
449
  current_dir = config_file.parent
416
450
  found_secrets = False
417
- # Start with the absolute path of the config file's directory
451
+ # Start with the absolute path of the config file\'s directory
418
452
  current_dir = config_file.parent.resolve()
419
453
 
420
454
  while current_dir != current_dir.parent and not found_secrets:
@@ -425,7 +459,9 @@ def get_settings(config_path: str | None = None) -> Settings:
425
459
  if secrets_file.exists():
426
460
  with open(secrets_file, "r", encoding="utf-8") as f:
427
461
  yaml_secrets = yaml.safe_load(f) or {}
428
- merged_settings = deep_merge(merged_settings, yaml_secrets)
462
+ # Resolve environment variables in the loaded secrets YAML
463
+ resolved_secrets_yaml = resolve_env_vars(yaml_secrets)
464
+ merged_settings = deep_merge(merged_settings, resolved_secrets_yaml)
429
465
  found_secrets = True
430
466
  break
431
467
  if not found_secrets: