from pathlib import Path from tempfile import NamedTemporaryFile from pydantic import Field, PrivateAttr from pydantic_settings import BaseSettings BASE_PATH = Path(__file__).resolve().parents[4] # goes up to project root class GMailSettings(BaseSettings): """Settings for Gmail MCP server.""" creds_json: str = Field(..., env="GMAIL_CREDS_JSON") token_json: str = Field(..., env="GMAIL_TOKEN_JSON") gmail_mcp_dir: Path = Field(default=BASE_PATH / "src/mcp_servers/gmail-mcp") _creds_file: Path | None = PrivateAttr(default=None) _token_file: Path | None = PrivateAttr(default=None) model_config = { "env_file": ".env", "env_file_encoding": "utf-8", } @staticmethod def _write_temp(prefix: str, content: str) -> Path: with NamedTemporaryFile(delete=False, prefix=f"{prefix}_", suffix=".json") as tmp: tmp.write(content.encode("utf-8")) return Path(tmp.name) def materialize_files(self) -> tuple[Path, Path]: """ Writes the credential and token JSON from env to temp files and returns their paths for downstream tooling that expects paths. """ if self._creds_file is None: self._creds_file = self._write_temp("gmail_creds", self.creds_json) if self._token_file is None: self._token_file = self._write_temp("gmail_token", self.token_json) return self._creds_file, self._token_file if __name__ == "__main__": settings = GMailSettings() creds_path, token_path = settings.materialize_files() print(settings) print(creds_path) print(token_path)