Skip to main content
Glama
config.py6.85 kB
from __future__ import annotations import os import json from dataclasses import dataclass from typing import Optional @dataclass class ServerConfig: # Transport: stdio (default), http, sse transport: str = os.getenv("MCP_TRANSPORT", "stdio") host: str = os.getenv("MCP_HOST", "127.0.0.1") port: int = int(os.getenv("MCP_PORT", "3030")) # Base URL and Tenant (for Cloudera AI Agent Studio) base_url: Optional[str] = os.getenv("SSB_BASE_URL") or None tenant: Optional[str] = os.getenv("SSB_TENANT") or None # Knox + SSB knox_gateway_url: str = os.getenv("KNOX_GATEWAY_URL", "") ssb_api_base: Optional[str] = os.getenv("SSB_API_BASE") # Auth options knox_token: Optional[str] = os.getenv("KNOX_TOKEN") or None knox_cookie: Optional[str] = os.getenv("KNOX_COOKIE") or None knox_user: Optional[str] = os.getenv("KNOX_USER") or None knox_password: Optional[str] = os.getenv("KNOX_PASSWORD") or None knox_token_endpoint: Optional[str] = os.getenv("KNOX_TOKEN_ENDPOINT") or None # Optional passcode token (e.g., Livy/Knox) for alternate auth patterns knox_passcode_token: Optional[str] = os.getenv("KNOX_PASSCODE_TOKEN") or None # Direct SSB authentication (when not using Knox) ssb_user: Optional[str] = os.getenv("SSB_USER") or None ssb_password: Optional[str] = os.getenv("SSB_PASSWORD") or None # TLS/HTTP verify_ssl_env: str = os.getenv("KNOX_VERIFY_SSL", "true").lower() ca_bundle: Optional[str] = os.getenv("KNOX_CA_BUNDLE") timeout_seconds: int = int(os.getenv("HTTP_TIMEOUT_SECONDS", "30")) max_retries: int = int(os.getenv("HTTP_MAX_RETRIES", "3")) rate_limit_rps: float = float(os.getenv("HTTP_RATE_LIMIT_RPS", "5")) # Behavior readonly: bool = os.getenv("SSB_READONLY", "true").lower() == "true" allowed_actions_csv: str = os.getenv("SSB_ALLOWED_ACTIONS", "") # CDP-specific proxy headers proxy_context_path: Optional[str] = os.getenv("SSB_PROXY_CONTEXT_PATH") # MVE API credentials (for Materialized View Engine) mve_api_base: Optional[str] = os.getenv("MVE_API_BASE") mve_username: Optional[str] = os.getenv("MVE_USERNAME") mve_password: Optional[str] = os.getenv("MVE_PASSWORD") @classmethod def from_json_file(cls, config_path: str = "config/cloud_ssb_config.json") -> "ServerConfig": """Load configuration from JSON file with environment variable override.""" config = cls() # Start with environment variables try: with open(config_path, 'r') as f: json_config = json.load(f) # Load cloud_ssb section if it exists cloud_config = json_config.get("cloud_ssb", {}) # Override with JSON values if environment variables are not set if not os.getenv("SSB_BASE_URL") and cloud_config.get("base_url"): config.base_url = cloud_config["base_url"] if not os.getenv("SSB_TENANT") and cloud_config.get("tenant"): config.tenant = cloud_config["tenant"] if not os.getenv("KNOX_GATEWAY_URL") and cloud_config.get("knox_gateway_url"): config.knox_gateway_url = cloud_config["knox_gateway_url"] if not os.getenv("SSB_API_BASE") and cloud_config.get("ssb_api_base"): config.ssb_api_base = cloud_config["ssb_api_base"] # If base_url and tenant are set, clear ssb_api_base to use the new logic if config.base_url and config.tenant and not os.getenv("SSB_API_BASE"): config.ssb_api_base = None if not os.getenv("KNOX_TOKEN") and cloud_config.get("jwt_token"): config.knox_token = cloud_config["jwt_token"] if not os.getenv("KNOX_VERIFY_SSL") and cloud_config.get("knox_verify_ssl") is not None: config.verify_ssl_env = str(cloud_config["knox_verify_ssl"]).lower() if not os.getenv("SSB_READONLY") and cloud_config.get("ssb_readonly") is not None: config.readonly = cloud_config["ssb_readonly"] if not os.getenv("HTTP_TIMEOUT_SECONDS") and cloud_config.get("http_timeout_seconds"): config.timeout_seconds = cloud_config["http_timeout_seconds"] if not os.getenv("HTTP_MAX_RETRIES") and cloud_config.get("http_max_retries"): config.max_retries = cloud_config["http_max_retries"] if not os.getenv("HTTP_RATE_LIMIT_RPS") and cloud_config.get("http_rate_limit_rps"): config.rate_limit_rps = cloud_config["http_rate_limit_rps"] # MVE API credentials if not os.getenv("MVE_API_BASE") and cloud_config.get("mve_api_base"): config.mve_api_base = cloud_config["mve_api_base"] if not os.getenv("MVE_USERNAME") and cloud_config.get("mve_username"): config.mve_username = cloud_config["mve_username"] if not os.getenv("MVE_PASSWORD") and cloud_config.get("mve_password"): config.mve_password = cloud_config["mve_password"] # If base_url and tenant are set, clear mve_api_base to use the new logic if config.base_url and config.tenant and not os.getenv("MVE_API_BASE"): config.mve_api_base = None except FileNotFoundError: # If config file doesn't exist, use environment variables only pass except Exception as e: # Log error but continue with environment variables print(f"Warning: Could not load config file {config_path}: {e}") return config def build_verify(self) -> bool | str: if self.ca_bundle: return self.ca_bundle return self.verify_ssl_env not in {"0", "false", "no"} def build_ssb_base(self) -> str: if self.ssb_api_base: return self.ssb_api_base.rstrip("/") # Try to build from base_url and tenant if self.base_url and self.tenant: base_url = self.base_url.rstrip("/") return f"{base_url}/{self.tenant}/cdp-proxy-token/ssb-sse-api/api/v1" # Fallback to knox_gateway_url if self.knox_gateway_url: return f"{self.knox_gateway_url.rstrip('/')}/irb-ssb-test/cdp-proxy-token/ssb-sse-api/api/v1" # Provide more helpful error message import os env_vars = [] if os.getenv("SSB_API_BASE"): env_vars.append("SSB_API_BASE") if os.getenv("SSB_BASE_URL"): env_vars.append("SSB_BASE_URL") if os.getenv("KNOX_GATEWAY_URL"): env_vars.append("KNOX_GATEWAY_URL") if env_vars: raise ValueError(f"Environment variables {', '.join(env_vars)} are set but not being read properly. Please check your MCP server configuration.") else: raise ValueError("SSB_BASE_URL+SSB_TENANT, SSB_API_BASE, or KNOX_GATEWAY_URL must be set. Please configure your MCP server with the appropriate environment variables.") def get_mve_credentials(self) -> tuple[str, str] | None: """Get MVE API credentials as (username, password) tuple.""" if self.mve_username and self.mve_password: return (self.mve_username, self.mve_password) return None def get_mve_api_base(self) -> str | None: """Get MVE API base URL.""" if self.mve_api_base: return self.mve_api_base # Try to build from base_url and tenant if self.base_url and self.tenant: base_url = self.base_url.rstrip("/") return f"{base_url}/{self.tenant}/cdp-proxy-api/ssb-mve-api/api/v1" return None

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/BrooksIan/SSB-MCP-Server'

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