""" Centralized path resolution for Basecamp MCP Server. All paths can be overridden via environment variables. """ import os from pathlib import Path def get_log_directory() -> Path: """ Get the directory for log files. Priority order: 1. BASECAMP_LOG_DIR env variable 2. XDG_STATE_HOME (typically ~/.local/state) 3. ~/.local/state/basecamp-mcp (fallback) """ if log_dir := os.getenv("BASECAMP_LOG_DIR"): return Path(log_dir) if xdg_state := os.getenv("XDG_STATE_HOME"): return Path(xdg_state) / "basecamp-mcp" return Path.home() / ".local/state/basecamp-mcp" def get_config_directory() -> Path: """ Get the directory for configuration files (.env). Priority order: 1. BASECAMP_CONFIG_DIR env variable 2. XDG_CONFIG_HOME (typically ~/.config) 3. ~/.config/basecamp-mcp (fallback) NOTE: This is only used if BASECAMP_ENV_FILE is not set and a .env file exists in the config directory. The server works entirely with environment variables and doesn't require .env files. """ if config_dir := os.getenv("BASECAMP_CONFIG_DIR"): return Path(config_dir) if xdg_config := os.getenv("XDG_CONFIG_HOME"): return Path(xdg_config) / "basecamp-mcp" return Path.home() / ".config/basecamp-mcp" def get_env_file_path() -> Path: """ Get the path for .env file (optional). Priority order: 1. BASECAMP_ENV_FILE env variable (explicitly specified) 2. Config directory + / .env The server does NOT require this file - it's optional. If not found, environment will be used as-is. """ if env_file := os.getenv("BASECAMP_ENV_FILE"): return Path(env_file) return get_config_directory() / ".env" def get_token_file_path() -> Path: """ Get the path for OAuth token storage. Priority order: 1. BASECAMP_TOKEN_FILE env variable 2. XDG_DATA_HOME (typically ~/.local/share) 3. ~/.local/share/basecamp-mcp/oauth_tokens.json (fallback) """ if token_file := os.getenv("BASECAMP_TOKEN_FILE"): return Path(token_file) if xdg_data := os.getenv("XDG_DATA_HOME"): return Path(xdg_data) / "basecamp-mcp" / "oauth_tokens.json" return Path.home() / ".local/share/basecamp-mcp" / "oauth_tokens.json" def ensure_directories_exist() -> None: """ Create all necessary directories if they don't exist. """ get_log_directory().mkdir(parents=True, exist_ok=True) get_config_directory().mkdir(parents=True, exist_ok=True) get_token_file_path().parent.mkdir(parents=True, exist_ok=True)