NoteDiscovery/mcp_server/config.py

80 lines
2.3 KiB
Python

"""
Configuration management for the MCP server.
Handles environment variables and provides validated configuration.
"""
import os
from dataclasses import dataclass
from typing import Optional
from urllib.parse import urlparse
@dataclass(frozen=True)
class MCPConfig:
"""Immutable configuration for the MCP server."""
base_url: str
api_key: Optional[str]
timeout: float
max_retries: int
def __post_init__(self) -> None:
"""Validate configuration after initialization."""
# Validate URL format
parsed = urlparse(self.base_url)
if not parsed.scheme or not parsed.netloc:
raise ValueError(f"Invalid NOTEDISCOVERY_URL: {self.base_url}")
if parsed.scheme not in ("http", "https"):
raise ValueError(f"URL must use http or https: {self.base_url}")
@property
def headers(self) -> dict[str, str]:
"""Get HTTP headers for API requests."""
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "NoteDiscovery-MCP/1.0",
}
if self.api_key:
headers["X-API-Key"] = self.api_key
return headers
def load_config() -> MCPConfig:
"""
Load configuration from environment variables.
Environment Variables:
NOTEDISCOVERY_URL: Server URL (default: http://localhost:8000)
NOTEDISCOVERY_API_KEY: API key for authentication (optional)
NOTEDISCOVERY_TIMEOUT: Request timeout in seconds (default: 30)
NOTEDISCOVERY_MAX_RETRIES: Max retry attempts (default: 3)
Returns:
MCPConfig: Validated configuration object
Raises:
ValueError: If configuration is invalid
"""
base_url = os.getenv("NOTEDISCOVERY_URL", "http://localhost:8000").rstrip("/")
api_key = os.getenv("NOTEDISCOVERY_API_KEY", "").strip() or None
try:
timeout = float(os.getenv("NOTEDISCOVERY_TIMEOUT", "30"))
except ValueError:
timeout = 30.0
try:
max_retries = int(os.getenv("NOTEDISCOVERY_MAX_RETRIES", "3"))
except ValueError:
max_retries = 3
return MCPConfig(
base_url=base_url,
api_key=api_key,
timeout=timeout,
max_retries=max_retries,
)