Implement two-stage installation with simplified MCP configuration

- Stage 1: MCP server selection (Context7, Sequential, Magic, Playwright, Serena, Morphllm)
- Stage 2: Framework components (Core, Modes, Commands, Agents, MCP Docs)

Major Changes:
- Created MCP config snippets in SuperClaude/MCP/configs/ for JSON-based configuration
- Simplified MCPComponent to modify .claude.json instead of npm/subprocess installation
- Added ModesComponent for behavioral modes (Brainstorming, Introspection, etc.)
- Added MCPDocsComponent for dynamic MCP documentation installation
- Completely removed Hooks component (deleted hooks.py, updated all references)
- Implemented two-stage interactive installation flow
- Updated profiles and configuration files

Benefits:
- Much simpler and more reliable MCP configuration
- Clear separation between server setup and documentation
- Auto-selection of MCP docs based on server choices
- User-friendly two-stage selection process

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
NomenAK
2025-08-14 20:35:19 +02:00
parent dc1c7f2e1b
commit 0e71f29598
15 changed files with 823 additions and 823 deletions

View File

@@ -138,7 +138,7 @@ def get_components_to_install(args: argparse.Namespace, registry: ComponentRegis
# Explicit components specified
if args.components:
if 'all' in args.components:
return ["core", "commands", "agents", "mcp"] # hooks removed - not yet implemented
return ["core", "commands", "agents", "modes", "mcp", "mcp_docs"]
return args.components
# Profile-based selection
@@ -169,38 +169,141 @@ def get_components_to_install(args: argparse.Namespace, registry: ComponentRegis
return interactive_component_selection(registry, config_manager)
def interactive_component_selection(registry: ComponentRegistry, config_manager: ConfigManager) -> Optional[List[str]]:
"""Interactive component selection"""
def select_mcp_servers(registry: ComponentRegistry) -> List[str]:
"""Stage 1: MCP Server Selection"""
logger = get_logger()
try:
# Get available components
available_components = registry.list_components()
# Get MCP component to access server list
mcp_instance = registry.get_component_instance("mcp", Path.home() / ".claude")
if not mcp_instance or not hasattr(mcp_instance, 'mcp_servers'):
logger.error("Could not access MCP server information")
return []
if not available_components:
logger.error("No components available for installation")
return None
# Create MCP server menu
mcp_servers = mcp_instance.mcp_servers
server_options = []
# Create component menu with descriptions
menu_options = []
for server_key, server_info in mcp_servers.items():
description = server_info["description"]
api_key_note = " (requires API key)" if server_info.get("requires_api_key", False) else ""
server_options.append(f"{server_key} - {description}{api_key_note}")
print(f"\n{Colors.CYAN}{Colors.BRIGHT}═══════════════════════════════════════════════════{Colors.RESET}")
print(f"{Colors.CYAN}{Colors.BRIGHT}Stage 1: MCP Server Selection (Optional){Colors.RESET}")
print(f"{Colors.CYAN}{Colors.BRIGHT}═══════════════════════════════════════════════════{Colors.RESET}")
print(f"\n{Colors.BLUE}MCP servers extend Claude Code with specialized capabilities.{Colors.RESET}")
print(f"{Colors.BLUE}Select servers to configure (you can always add more later):{Colors.RESET}")
# Add option to skip MCP
server_options.append("Skip MCP Server installation")
menu = Menu("Select MCP servers to configure:", server_options, multi_select=True)
selections = menu.display()
if not selections:
logger.info("No MCP servers selected")
return []
# Filter out the "skip" option and return server keys
server_keys = list(mcp_servers.keys())
selected_servers = []
for i in selections:
if i < len(server_keys): # Not the "skip" option
selected_servers.append(server_keys[i])
if selected_servers:
logger.info(f"Selected MCP servers: {', '.join(selected_servers)}")
else:
logger.info("No MCP servers selected")
return selected_servers
except Exception as e:
logger.error(f"Error in MCP server selection: {e}")
return []
def select_framework_components(registry: ComponentRegistry, config_manager: ConfigManager, selected_mcp_servers: List[str]) -> List[str]:
"""Stage 2: Framework Component Selection"""
logger = get_logger()
try:
# Framework components (excluding MCP-related ones)
framework_components = ["core", "modes", "commands", "agents"]
# Create component menu
component_options = []
component_info = {}
for component_name in available_components:
for component_name in framework_components:
metadata = registry.get_component_metadata(component_name)
if metadata:
description = metadata.get("description", "No description")
category = metadata.get("category", "unknown")
menu_options.append(f"{component_name} ({category}) - {description}")
component_options.append(f"{component_name} - {description}")
component_info[component_name] = metadata
else:
menu_options.append(f"{component_name} - Component description unavailable")
component_info[component_name] = {"description": "Unknown"}
# Add preset options
# Add MCP documentation option
if selected_mcp_servers:
mcp_docs_desc = f"MCP documentation for {', '.join(selected_mcp_servers)} (auto-selected)"
component_options.append(f"mcp_docs - {mcp_docs_desc}")
auto_selected_mcp_docs = True
else:
component_options.append("mcp_docs - MCP server documentation (none selected)")
auto_selected_mcp_docs = False
print(f"\n{Colors.CYAN}{Colors.BRIGHT}═══════════════════════════════════════════════════{Colors.RESET}")
print(f"{Colors.CYAN}{Colors.BRIGHT}Stage 2: Framework Component Selection{Colors.RESET}")
print(f"{Colors.CYAN}{Colors.BRIGHT}═══════════════════════════════════════════════════{Colors.RESET}")
print(f"\n{Colors.BLUE}Select SuperClaude framework components to install:{Colors.RESET}")
menu = Menu("Select components (Core is recommended):", component_options, multi_select=True)
selections = menu.display()
if not selections:
# Default to core if nothing selected
logger.info("No components selected, defaulting to core")
selected_components = ["core"]
else:
selected_components = []
all_components = framework_components + ["mcp_docs"]
for i in selections:
if i < len(all_components):
selected_components.append(all_components[i])
# Auto-select MCP docs if not explicitly deselected and we have MCP servers
if auto_selected_mcp_docs and "mcp_docs" not in selected_components:
# Check if user explicitly deselected it
mcp_docs_index = len(framework_components) # Index of mcp_docs in the menu
if mcp_docs_index not in selections:
# User didn't select it, but we auto-select it
selected_components.append("mcp_docs")
logger.info("Auto-selected MCP documentation for configured servers")
# Always include MCP component if servers were selected
if selected_mcp_servers and "mcp" not in selected_components:
selected_components.append("mcp")
logger.info(f"Selected framework components: {', '.join(selected_components)}")
return selected_components
except Exception as e:
logger.error(f"Error in framework component selection: {e}")
return ["core"] # Fallback to core
def interactive_component_selection(registry: ComponentRegistry, config_manager: ConfigManager) -> Optional[List[str]]:
"""Two-stage interactive component selection"""
logger = get_logger()
try:
# Add preset options first
preset_options = [
"Quick Installation (recommended components)",
"Minimal Installation (core only)",
"Custom Selection"
"Custom Two-Stage Selection"
]
print(f"\n{Colors.CYAN}SuperClaude Installation Options:{Colors.RESET}")
@@ -218,16 +321,19 @@ def interactive_component_selection(registry: ComponentRegistry, config_manager:
return ["core"]
elif choice == 1: # Minimal
return ["core"]
elif choice == 2: # Custom
print(f"\n{Colors.CYAN}Available Components:{Colors.RESET}")
component_menu = Menu("Select components to install:", menu_options, multi_select=True)
selections = component_menu.display()
elif choice == 2: # Custom Two-Stage
# Stage 1: MCP Server Selection
selected_mcp_servers = select_mcp_servers(registry)
if not selections:
logger.warning("No components selected")
return None
# Stage 2: Framework Component Selection
selected_components = select_framework_components(registry, config_manager, selected_mcp_servers)
return [available_components[i] for i in selections]
# Store selected MCP servers for components to use
if not hasattr(config_manager, '_installation_context'):
config_manager._installation_context = {}
config_manager._installation_context["selected_mcp_servers"] = selected_mcp_servers
return selected_components
return None
@@ -331,7 +437,7 @@ def run_system_diagnostics(validator: Validator) -> None:
print(" 3. Run 'SuperClaude install --diagnose' again to verify")
def perform_installation(components: List[str], args: argparse.Namespace) -> bool:
def perform_installation(components: List[str], args: argparse.Namespace, config_manager: ConfigManager = None) -> bool:
"""Perform the actual installation"""
logger = get_logger()
start_time = time.time()
@@ -370,7 +476,8 @@ def perform_installation(components: List[str], args: argparse.Namespace) -> boo
config = {
"force": args.force,
"backup": not args.no_backup,
"dry_run": args.dry_run
"dry_run": args.dry_run,
"selected_mcp_servers": getattr(config_manager, '_installation_context', {}).get("selected_mcp_servers", [])
}
success = installer.install_components(ordered_components, config)
@@ -518,7 +625,7 @@ def run(args: argparse.Namespace) -> int:
return 0
# Perform installation
success = perform_installation(components, args)
success = perform_installation(components, args, config_manager)
if success:
if not args.quiet: