Skip to main content
Glama

Documentation Search MCP Server

config_manager.py8.4 kB
""" Environment-aware configuration manager for documentation-search-enhanced MCP server. Supports development, staging, and production environments with different settings. """ import json import os from typing import Dict, Any, Optional from importlib import resources from dataclasses import dataclass @dataclass class EnvironmentConfig: """Configuration for a specific environment""" logging_level: str = "INFO" cache_ttl_hours: float = 24 cache_max_entries: int = 1000 rate_limit_enabled: bool = True requests_per_minute: int = 60 max_concurrent_requests: int = 10 request_timeout_seconds: int = 30 features: Optional[Dict[str, bool]] = None def __post_init__(self): if self.features is None: self.features = { "caching_enabled": True, "real_time_search": True, "github_integration": True, "rate_limiting": self.rate_limit_enabled, "analytics": True, } class ConfigManager: """Manages environment-specific configurations""" def __init__(self): self.environment = self._detect_environment() self.base_config = self._load_base_config() self.env_config = self._get_environment_config() def _detect_environment(self) -> str: """Detect current environment from environment variables""" env = os.getenv("ENVIRONMENT", os.getenv("ENV", "development")).lower() # Common environment name mappings env_mappings = { "dev": "development", "develop": "development", "development": "development", "stage": "staging", "staging": "staging", "prod": "production", "production": "production", "test": "testing", "testing": "testing", } return env_mappings.get(env, "development") def _load_base_config(self) -> Dict[str, Any]: """Load base configuration from config.json""" try: # Try to load from package resources first (for installed package) try: config_text = resources.read_text( "documentation_search_enhanced", "config.json" ) config = json.loads(config_text) except (FileNotFoundError, ModuleNotFoundError): # Fallback to relative path (for development) config_path = os.path.join(os.path.dirname(__file__), "config.json") with open(config_path, "r") as f: config = json.load(f) except Exception: # Final fallback - return minimal config config = {"docs_urls": {}, "cache": {"enabled": True}} return config def _get_environment_config(self) -> EnvironmentConfig: """Get configuration for current environment""" environments = { "development": EnvironmentConfig( logging_level="DEBUG", cache_ttl_hours=1, cache_max_entries=100, rate_limit_enabled=False, requests_per_minute=120, max_concurrent_requests=20, request_timeout_seconds=60, features={ "caching_enabled": True, "real_time_search": True, "github_integration": True, "rate_limiting": False, "analytics": True, }, ), "testing": EnvironmentConfig( logging_level="WARN", cache_ttl_hours=0.5, cache_max_entries=50, rate_limit_enabled=True, requests_per_minute=30, max_concurrent_requests=5, request_timeout_seconds=15, features={ "caching_enabled": False, "real_time_search": True, "github_integration": False, "rate_limiting": True, "analytics": False, }, ), "staging": EnvironmentConfig( logging_level="INFO", cache_ttl_hours=12, cache_max_entries=500, rate_limit_enabled=True, requests_per_minute=60, max_concurrent_requests=10, request_timeout_seconds=30, features={ "caching_enabled": True, "real_time_search": True, "github_integration": True, "rate_limiting": True, "analytics": True, }, ), "production": EnvironmentConfig( logging_level="ERROR", cache_ttl_hours=24, cache_max_entries=1000, rate_limit_enabled=True, requests_per_minute=60, max_concurrent_requests=10, request_timeout_seconds=30, features={ "caching_enabled": True, "real_time_search": True, "github_integration": True, "rate_limiting": True, "analytics": True, }, ), } return environments.get(self.environment, environments["development"]) def get_config(self) -> Dict[str, Any]: """Get merged configuration for current environment""" # Start with base config merged_config = self.base_config.copy() # Override with environment-specific settings if "server_config" not in merged_config: merged_config["server_config"] = {} merged_config["server_config"].update( { "environment": self.environment, "logging_level": self.env_config.logging_level, "max_concurrent_requests": self.env_config.max_concurrent_requests, "request_timeout_seconds": self.env_config.request_timeout_seconds, "features": self.env_config.features, } ) if "cache" not in merged_config: merged_config["cache"] = {} features = self.env_config.features or {} merged_config["cache"].update( { "ttl_hours": self.env_config.cache_ttl_hours, "max_entries": self.env_config.cache_max_entries, "enabled": features.get("caching_enabled", True), } ) if "rate_limiting" not in merged_config: merged_config["rate_limiting"] = {} merged_config["rate_limiting"].update( { "enabled": self.env_config.rate_limit_enabled, "requests_per_minute": self.env_config.requests_per_minute, } ) return merged_config def get_docs_urls(self) -> Dict[str, str]: """Get documentation URLs with environment filtering""" docs_urls = {} config = self.get_config() for lib_name, lib_data in config.get("docs_urls", {}).items(): if isinstance(lib_data, dict): # Check if library is enabled for this environment environments = lib_data.get( "environments", ["development", "staging", "production"] ) if self.environment in environments: docs_urls[lib_name] = lib_data.get("url", "") else: # Legacy format - always include docs_urls[lib_name] = lib_data return docs_urls def is_feature_enabled(self, feature_name: str) -> bool: """Check if a feature is enabled in current environment""" features = self.env_config.features or {} return features.get(feature_name, False) def get_cache_config(self) -> Dict[str, Any]: """Get cache configuration for current environment""" features = self.env_config.features or {} return { "ttl_hours": self.env_config.cache_ttl_hours, "max_entries": self.env_config.cache_max_entries, "enabled": features.get("caching_enabled", True), } # Global configuration manager config_manager = ConfigManager()

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/anton-prosterity/documentation-search-mcp'

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