Files
dss/dss/mcp/config.py
Bruno Sarlo 41fba59bf7 Major refactor: Consolidate DSS into unified package structure
- Create new dss/ Python package at project root
- Move MCP core from tools/dss_mcp/ to dss/mcp/
- Move storage layer from tools/storage/ to dss/storage/
- Move domain logic from dss-mvp1/dss/ to dss/
- Move services from tools/api/services/ to dss/services/
- Move API server to apps/api/
- Move CLI to apps/cli/
- Move Storybook assets to storybook/
- Create unified dss/__init__.py with comprehensive exports
- Merge configuration into dss/settings.py (Pydantic-based)
- Create pyproject.toml for proper package management
- Update startup scripts for new paths
- Remove old tools/ and dss-mvp1/ directories

Architecture changes:
- DSS is now MCP-first with 40+ tools for Claude Code
- Clean imports: from dss import Projects, Components, FigmaToolSuite
- No more sys.path.insert() hacking
- apps/ contains thin application wrappers (API, CLI)
- Single unified Python package for all DSS logic

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 12:46:43 -03:00

146 lines
4.8 KiB
Python

"""
MCP Server Configuration
Loads configuration from environment variables and provides settings
for the MCP server, integrations, and security.
"""
import os
from pathlib import Path
from typing import Optional
from dotenv import load_dotenv
from cryptography.fernet import Fernet
# Load environment variables
load_dotenv()
# Base paths
PROJECT_ROOT = Path(__file__).parent.parent.parent
TOOLS_DIR = PROJECT_ROOT / "tools"
STORAGE_DIR = PROJECT_ROOT / "tools" / "storage"
CACHE_DIR = PROJECT_ROOT / os.getenv("DSS_CACHE_DIR", ".dss/cache")
class MCPConfig:
"""MCP Server Configuration"""
# Server Settings
HOST: str = os.getenv("DSS_MCP_HOST", "127.0.0.1")
PORT: int = int(os.getenv("DSS_MCP_PORT", "3457"))
# Database
DATABASE_PATH: str = os.getenv(
"DATABASE_PATH",
str(STORAGE_DIR / "dss.db")
)
# Context Caching
CONTEXT_CACHE_TTL: int = int(os.getenv("DSS_CONTEXT_CACHE_TTL", "300")) # 5 minutes
# Encryption
ENCRYPTION_KEY: Optional[str] = os.getenv("DSS_ENCRYPTION_KEY")
@classmethod
def get_cipher(cls) -> Optional[Fernet]:
"""Get Fernet cipher for encryption/decryption"""
if not cls.ENCRYPTION_KEY:
return None
return Fernet(cls.ENCRYPTION_KEY.encode())
@classmethod
def generate_encryption_key(cls) -> str:
"""Generate a new encryption key"""
return Fernet.generate_key().decode()
# Redis/Celery for worker pool
REDIS_URL: str = os.getenv("REDIS_URL", "redis://localhost:6379/0")
CELERY_BROKER_URL: str = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0")
CELERY_RESULT_BACKEND: str = os.getenv("CELERY_RESULT_BACKEND", "redis://localhost:6379/0")
# Circuit Breaker
CIRCUIT_BREAKER_FAILURE_THRESHOLD: int = int(
os.getenv("CIRCUIT_BREAKER_FAILURE_THRESHOLD", "5")
)
CIRCUIT_BREAKER_TIMEOUT_SECONDS: int = int(
os.getenv("CIRCUIT_BREAKER_TIMEOUT_SECONDS", "60")
)
# Logging
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO").upper()
class IntegrationConfig:
"""External Integration Configuration"""
# Figma
FIGMA_TOKEN: Optional[str] = os.getenv("FIGMA_TOKEN")
FIGMA_CACHE_TTL: int = int(os.getenv("FIGMA_CACHE_TTL", "300"))
# Anthropic (for Sequential Thinking)
ANTHROPIC_API_KEY: Optional[str] = os.getenv("ANTHROPIC_API_KEY")
# Jira (defaults, can be overridden per-user)
JIRA_URL: Optional[str] = os.getenv("JIRA_URL")
JIRA_USERNAME: Optional[str] = os.getenv("JIRA_USERNAME")
JIRA_API_TOKEN: Optional[str] = os.getenv("JIRA_API_TOKEN")
# Confluence (defaults, can be overridden per-user)
CONFLUENCE_URL: Optional[str] = os.getenv("CONFLUENCE_URL")
CONFLUENCE_USERNAME: Optional[str] = os.getenv("CONFLUENCE_USERNAME")
CONFLUENCE_API_TOKEN: Optional[str] = os.getenv("CONFLUENCE_API_TOKEN")
# Singleton instances
mcp_config = MCPConfig()
integration_config = IntegrationConfig()
def validate_config() -> list[str]:
"""
Validate configuration and return list of warnings.
Returns:
List of warning messages for missing optional config
"""
warnings = []
if not mcp_config.ENCRYPTION_KEY:
warnings.append(
"DSS_ENCRYPTION_KEY not set. Integration credentials will not be encrypted. "
f"Generate one with: python -c \"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())\""
)
if not integration_config.ANTHROPIC_API_KEY:
warnings.append("ANTHROPIC_API_KEY not set. Sequential Thinking tools will not be available.")
if not integration_config.FIGMA_TOKEN:
warnings.append("FIGMA_TOKEN not set. Figma tools will not be available.")
return warnings
if __name__ == "__main__":
print("=== DSS MCP Configuration ===\n")
print(f"MCP Server: {mcp_config.HOST}:{mcp_config.PORT}")
print(f"Database: {mcp_config.DATABASE_PATH}")
print(f"Context Cache TTL: {mcp_config.CONTEXT_CACHE_TTL}s")
print(f"Encryption Key: {'✓ Set' if mcp_config.ENCRYPTION_KEY else '✗ Not Set'}")
print(f"Redis URL: {mcp_config.REDIS_URL}")
print(f"\nCircuit Breaker:")
print(f" Failure Threshold: {mcp_config.CIRCUIT_BREAKER_FAILURE_THRESHOLD}")
print(f" Timeout: {mcp_config.CIRCUIT_BREAKER_TIMEOUT_SECONDS}s")
print(f"\n=== Integration Configuration ===\n")
print(f"Figma Token: {'✓ Set' if integration_config.FIGMA_TOKEN else '✗ Not Set'}")
print(f"Anthropic API Key: {'✓ Set' if integration_config.ANTHROPIC_API_KEY else '✗ Not Set'}")
print(f"Jira URL: {integration_config.JIRA_URL or '✗ Not Set'}")
print(f"Confluence URL: {integration_config.CONFLUENCE_URL or '✗ Not Set'}")
warnings = validate_config()
if warnings:
print(f"\n⚠️ Warnings:")
for warning in warnings:
print(f" - {warning}")
else:
print(f"\n✓ Configuration is valid")