initial mcp server setup
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
Centralized Configuration Manager
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
from typing import Dict, Any, Optional
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from dotenv import load_dotenv
|
||||
DOTENV_AVAILABLE = True
|
||||
except ImportError:
|
||||
DOTENV_AVAILABLE = False
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
"""Centralized configuration manager for MCP components"""
|
||||
|
||||
def __init__(self, config_file: Optional[str] = None, env_file: Optional[str] = None):
|
||||
self._config_file = config_file or "config.json"
|
||||
self._env_file = env_file or ".env"
|
||||
self._config: Dict[str, Any] = {}
|
||||
self._loaded = False
|
||||
|
||||
async def load_config(self) -> Dict[str, Any]:
|
||||
"""Load configuration from all sources"""
|
||||
if self._loaded:
|
||||
return self._config
|
||||
|
||||
# Load environment variables
|
||||
await self._load_env_vars()
|
||||
|
||||
# Load JSON configuration file
|
||||
await self._load_json_config()
|
||||
|
||||
# Merge configurations
|
||||
self._config = await self._merge_configs()
|
||||
|
||||
self._loaded = True
|
||||
return self._config
|
||||
|
||||
async def _load_env_vars(self) -> None:
|
||||
"""Load environment variables"""
|
||||
if DOTENV_AVAILABLE and Path(self._env_file).exists():
|
||||
load_dotenv(self._env_file)
|
||||
|
||||
async def _load_json_config(self) -> Dict[str, Any]:
|
||||
"""Load JSON configuration file"""
|
||||
config_path = Path(self._config_file)
|
||||
|
||||
if config_path.exists():
|
||||
with open(config_path, 'r') as f:
|
||||
return json.load(f)
|
||||
|
||||
return {}
|
||||
|
||||
async def _merge_configs(self) -> Dict[str, Any]:
|
||||
"""Merge all configuration sources"""
|
||||
merged = {}
|
||||
|
||||
# Start with JSON config as base
|
||||
json_config = await self._load_json_config()
|
||||
merged.update(json_config)
|
||||
|
||||
# Override with environment variables
|
||||
env_config = await self._get_env_config()
|
||||
self._deep_update(merged, env_config)
|
||||
|
||||
return merged
|
||||
|
||||
async def _get_env_config(self) -> Dict[str, Any]:
|
||||
"""Get configuration from environment variables"""
|
||||
env_config = {}
|
||||
|
||||
# Server configuration
|
||||
if os.getenv("MCP_SERVER_NAME"):
|
||||
env_config.setdefault("server", {})["name"] = os.getenv("MCP_SERVER_NAME")
|
||||
if os.getenv("MCP_SERVER_HOST"):
|
||||
env_config.setdefault("server", {})["host"] = os.getenv("MCP_SERVER_HOST")
|
||||
if os.getenv("MCP_SERVER_PORT"):
|
||||
env_config.setdefault("server", {})["port"] = int(os.getenv("MCP_SERVER_PORT"))
|
||||
if os.getenv("MCP_TRANSPORT"):
|
||||
env_config.setdefault("server", {})["transport"] = os.getenv("MCP_TRANSPORT")
|
||||
|
||||
# Client configuration
|
||||
if os.getenv("MCP_AI_PROVIDER"):
|
||||
env_config.setdefault("client", {})["provider"] = os.getenv("MCP_AI_PROVIDER")
|
||||
if os.getenv("MCP_AI_MODEL"):
|
||||
env_config.setdefault("client", {})["model"] = os.getenv("MCP_AI_MODEL")
|
||||
|
||||
# API keys
|
||||
for provider in ["OPENAI", "CLAUDE", "GROK"]:
|
||||
api_key = os.getenv(f"{provider}_API_KEY")
|
||||
if api_key:
|
||||
env_config.setdefault("api_keys", {})[provider.lower()] = api_key
|
||||
|
||||
return env_config
|
||||
|
||||
def _deep_update(self, base_dict: Dict[str, Any], update_dict: Dict[str, Any]) -> None:
|
||||
"""Deep update dictionary"""
|
||||
for key, value in update_dict.items():
|
||||
if isinstance(value, dict) and key in base_dict and isinstance(base_dict[key], dict):
|
||||
self._deep_update(base_dict[key], value)
|
||||
else:
|
||||
base_dict[key] = value
|
||||
|
||||
async def get_server_config(self) -> Dict[str, Any]:
|
||||
"""Get server-specific configuration"""
|
||||
config = await self.load_config()
|
||||
return config.get("server", {})
|
||||
|
||||
async def get_client_config(self) -> Dict[str, Any]:
|
||||
"""Get client-specific configuration"""
|
||||
config = await self.load_config()
|
||||
return config.get("client", {})
|
||||
|
||||
async def get_api_key(self, provider: str) -> Optional[str]:
|
||||
"""Get API key for a specific provider"""
|
||||
config = await self.load_config()
|
||||
api_keys = config.get("api_keys", {})
|
||||
return api_keys.get(provider.lower())
|
||||
|
||||
async def save_config(self, config: Dict[str, Any]) -> None:
|
||||
"""Save configuration to file"""
|
||||
with open(self._config_file, 'w') as f:
|
||||
json.dump(config, f, indent=2)
|
||||
|
||||
async def update_config(self, updates: Dict[str, Any]) -> None:
|
||||
"""Update configuration and save"""
|
||||
config = await self.load_config()
|
||||
self._deep_update(config, updates)
|
||||
await self.save_config(config)
|
||||
self._loaded = False # Force reload on next access
|
||||
Reference in New Issue
Block a user