""" Configuration settings for MCP Python Project Manager Server. """ import os from pathlib import Path from typing import Optional, List from pydantic import BaseModel, Field, field_validator class ServerConfig(BaseModel): """Main server configuration.""" # Server settings server_name: str = Field(default="mcp-python-manager", description="Name of the MCP server") version: str = Field(default="1.0.0", description="Server version") # Paths workspace_root: Path = Field( default=Path("C:/Users/dimir/projects"), description="Root directory for Python projects" ) venv_name: str = Field(default=".venv", description="Default virtual environment name") # Python settings python_executable: Optional[str] = Field( default=None, description="Path to Python executable (auto-detected if None)" ) default_python_version: str = Field(default="3.11", description="Default Python version") # Debug settings debug_mode: bool = Field(default=False, description="Enable debug logging") log_level: str = Field(default="INFO", description="Logging level") log_file: Optional[Path] = Field(default=None, description="Path to log file") # Tool settings max_execution_time: int = Field(default=300, description="Max execution time for commands (seconds)") max_output_length: int = Field(default=50000, description="Max characters in command output") allowed_commands: List[str] = Field( default_factory=lambda: ["python", "pip", "pytest", "black", "flake8", "pylint"], description="List of allowed shell commands" ) # File watching enable_file_watching: bool = Field(default=True, description="Enable file change notifications") watch_patterns: List[str] = Field( default_factory=lambda: ["*.py", "*.txt", "*.md", "requirements*.txt"], description="File patterns to watch" ) ignore_patterns: List[str] = Field( default_factory=lambda: ["__pycache__", "*.pyc", ".git", ".venv", "node_modules"], description="Patterns to ignore when watching" ) @field_validator('workspace_root', 'log_file', mode='before') @classmethod def convert_to_path(cls, v): if isinstance(v, str): return Path(v) return v @field_validator('log_level') @classmethod def validate_log_level(cls, v): valid_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] if v.upper() not in valid_levels: raise ValueError(f"log_level must be one of {valid_levels}") return v.upper() class ProjectConfig(BaseModel): """Per-project configuration.""" name: str path: Path python_version: Optional[str] = None venv_path: Optional[Path] = None entry_point: Optional[str] = None test_command: str = Field(default="pytest", description="Command to run tests") run_args: List[str] = Field(default_factory=list, description="Default arguments for running") @field_validator('path', 'venv_path', mode='before') @classmethod def convert_to_path(cls, v): if isinstance(v, str): return Path(v) return v # Global config instance config = ServerConfig() def load_config_from_env(): """Load configuration from environment variables.""" import os if os.getenv("MCP_PYTHON_WORKSPACE"): config.workspace_root = Path(os.getenv("MCP_PYTHON_WORKSPACE")) if os.getenv("MCP_PYTHON_DEBUG") == "true": config.debug_mode = True if os.getenv("MCP_PYTHON_LOG_LEVEL"): config.log_level = os.getenv("MCP_PYTHON_LOG_LEVEL") if os.getenv("MCP_PYTHON_MAX_EXEC_TIME"): config.max_execution_time = int(os.getenv("MCP_PYTHON_MAX_EXEC_TIME")) return config