Skip to main content
Glama
config.py5.03 kB
#!/usr/bin/env python3 # src/chuk_mcp_math_server/config.py """ Server configuration management using Pydantic. """ import json import logging import os from pathlib import Path from typing import Literal, Optional import yaml from pydantic import BaseModel, Field logger = logging.getLogger(__name__) class ServerConfig(BaseModel): """Comprehensive server configuration with all customization options.""" # Transport settings transport: Literal["stdio", "http"] = "stdio" port: int = Field(default=8000, ge=1, le=65535) host: str = "0.0.0.0" # nosec B104 # Global feature toggles enable_tools: bool = True enable_prompts: bool = True enable_resources: bool = True # Function filtering function_allowlist: list[str] = Field(default_factory=list) function_denylist: list[str] = Field(default_factory=list) domain_allowlist: list[str] = Field(default_factory=list) domain_denylist: list[str] = Field(default_factory=list) category_allowlist: list[str] = Field(default_factory=list) category_denylist: list[str] = Field(default_factory=list) # Performance settings cache_strategy: Literal["none", "memory", "smart"] = "smart" cache_size: int = Field(default=1000, ge=0) max_concurrent_calls: int = Field(default=10, ge=1) computation_timeout: float = Field(default=30.0, ge=0) # Logging and debugging log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO" verbose: bool = False quiet: bool = False # Security settings enable_cors: bool = True rate_limit_enabled: bool = False rate_limit_per_minute: int = Field(default=60, ge=1) # Server metadata server_name: str = "chuk-mcp-math-server" server_description: str = "Configurable mathematical computation server" model_config = { "validate_assignment": True, "arbitrary_types_allowed": True, } @classmethod def from_file(cls, config_path: str | Path) -> "ServerConfig": """Load configuration from file (YAML or JSON).""" path = Path(config_path) if not path.exists(): raise FileNotFoundError(f"Configuration file not found: {path}") with open(path, "r") as f: if path.suffix.lower() in [".yml", ".yaml"]: data = yaml.safe_load(f) elif path.suffix.lower() == ".json": data = json.load(f) else: raise ValueError(f"Unsupported config file format: {path.suffix}") return cls(**data) @classmethod def from_env(cls) -> "ServerConfig": """Load configuration from environment variables.""" env_mapping = { "MCP_SERVER_TRANSPORT": "transport", "MCP_SERVER_PORT": ("port", int), "MCP_SERVER_HOST": "host", "MCP_SERVER_LOG_LEVEL": "log_level", "MCP_SERVER_CACHE_STRATEGY": "cache_strategy", "MCP_SERVER_CACHE_SIZE": ("cache_size", int), "MCP_SERVER_NAME": "server_name", } config_dict = {} for env_var, field_info in env_mapping.items(): value = os.getenv(env_var) if value is not None: if isinstance(field_info, tuple): field_name, converter = field_info config_dict[field_name] = converter(value) else: config_dict[field_info] = value return cls(**config_dict) def save_to_file(self, config_path: str | Path) -> None: """Save configuration to file (YAML or JSON).""" path = Path(config_path) with open(path, "w") as f: if path.suffix.lower() in [".yml", ".yaml"]: yaml.dump( self.model_dump(), f, default_flow_style=False, sort_keys=False ) elif path.suffix.lower() == ".json": json.dump(self.model_dump(), f, indent=2) else: raise ValueError(f"Unsupported config file format: {path.suffix}") def load_configuration_from_sources( config_file: Optional[str | Path] = None, env_overrides: bool = True, cli_overrides: Optional[dict] = None, ) -> ServerConfig: """Load configuration from multiple sources with priority ordering. Priority (highest to lowest): 1. CLI overrides 2. Environment variables 3. Configuration file 4. Defaults """ # Start with file-based config or defaults if config_file: config = ServerConfig.from_file(config_file) base_dict = config.model_dump() else: base_dict = {} # Apply environment overrides if env_overrides: env_config = ServerConfig.from_env() env_dict = {k: v for k, v in env_config.model_dump().items() if k in os.environ} base_dict.update(env_dict) # Apply CLI overrides (highest priority) if cli_overrides: base_dict.update(cli_overrides) return ServerConfig(**base_dict)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chrishayuk/chuk-mcp-math-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server