diff --git a/src/mt_odoo_mcp/config.py b/src/mt_odoo_mcp/config.py index 9483e3d..b1cd059 100644 --- a/src/mt_odoo_mcp/config.py +++ b/src/mt_odoo_mcp/config.py @@ -1,4 +1,5 @@ from __future__ import annotations +from pydantic import field_validator from pydantic_settings import BaseSettings, SettingsConfigDict @@ -45,9 +46,20 @@ class Settings(BaseSettings): admin_password: str = "change-me" admin_session_ttl_hours: int = 12 + @field_validator("public_url", "frontend_base_url", mode="after") + @classmethod + def _strip_trailing_slash(cls, v: str) -> str: + # Every call site concatenates a leading-slash path directly onto + # these (e.g. f"{public_url}/mcp/sse") — a trailing slash in .env + # would silently produce a double-slash URL. + return v.rstrip("/") + @property def cors_origins_list(self) -> list[str]: - return [o.strip() for o in self.cors_origins.split(",") if o.strip()] + # A trailing slash here would never match a browser's Origin header + # (which never includes a path/slash), silently breaking CORS — + # strip it defensively so a .env typo can't cause that again. + return [o.strip().rstrip("/") for o in self.cors_origins.split(",") if o.strip()] settings = Settings()