"""Configuration management with environment variable and file support."""
import json
import os
from dataclasses import dataclass
from pathlib import Path
import platformdirs
@dataclass
class Config:
"""SharePoint MCP configuration.
Attributes:
client_id: Azure AD application (client) ID
tenant_id: Azure AD tenant (directory) ID
redirect_uri: OAuth redirect URI for local callback server
log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
"""
client_id: str
tenant_id: str
redirect_uri: str = "http://localhost:8765/callback"
log_level: str = "INFO"
def load_config() -> Config:
"""Load configuration from environment or config file.
Priority order:
1. Environment variables (AZURE_CLIENT_ID, AZURE_TENANT_ID or
SHAREPOINT_CLIENT_ID, SHAREPOINT_TENANT_ID)
2. Config file at ~/.config/sharepoint-mcp/config.json
Returns:
Config object with loaded settings
Raises:
ConfigurationError: If configuration is missing or invalid
"""
# Try environment variables first
client_id = os.environ.get("AZURE_CLIENT_ID") or os.environ.get("SHAREPOINT_CLIENT_ID")
tenant_id = os.environ.get("AZURE_TENANT_ID") or os.environ.get("SHAREPOINT_TENANT_ID")
if client_id and tenant_id:
return Config(
client_id=client_id,
tenant_id=tenant_id,
redirect_uri=os.environ.get("REDIRECT_URI", "http://localhost:8765/callback"),
log_level=os.environ.get("LOG_LEVEL", "INFO"),
)
# Try config file
config_dir = Path(platformdirs.user_config_dir("sharepoint-mcp"))
config_file = config_dir / "config.json"
if config_file.exists():
with open(config_file) as f:
data = json.load(f)
return Config(
client_id=data["client_id"],
tenant_id=data["tenant_id"],
redirect_uri=data.get("redirect_uri", "http://localhost:8765/callback"),
log_level=data.get("log_level", "INFO"),
)
raise ConfigurationError(
"Missing configuration. Set AZURE_CLIENT_ID and AZURE_TENANT_ID environment variables, "
f"or create {config_file} with the following structure:\n"
'{\n "client_id": "your-azure-app-client-id",\n "tenant_id": "your-azure-tenant-id"\n}'
)
def save_config(config: Config) -> None:
"""Save configuration to config file.
Args:
config: Configuration to save
"""
config_dir = Path(platformdirs.user_config_dir("sharepoint-mcp"))
config_dir.mkdir(parents=True, exist_ok=True)
config_file = config_dir / "config.json"
data = {
"client_id": config.client_id,
"tenant_id": config.tenant_id,
"redirect_uri": config.redirect_uri,
"log_level": config.log_level,
}
with open(config_file, "w") as f:
json.dump(data, f, indent=2)
class ConfigurationError(Exception):
"""Configuration-related errors."""
pass