refactor: consolidate MCP integration to unified gateway

**Changes**:
- Remove individual MCP server docs (superclaude/mcp/*.md)
- Remove MCP server configs (superclaude/mcp/configs/*.json)
- Delete MCP docs component (setup/components/mcp_docs.py)
- Simplify installer (setup/core/installer.py)
- Update components for unified gateway approach

**Rationale**:
- Unified gateway (airis-mcp-gateway) provides all MCP servers
- Individual docs/configs no longer needed (managed centrally)
- Reduces maintenance burden and file count
- Simplifies installation process

**Files Removed**: 17 MCP files (docs + configs)
**Installer Changes**: Removed legacy MCP installation logic

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kazuki
2025-10-17 07:24:01 +09:00
parent 4a5d7499a4
commit 01ddc14354
30 changed files with 253 additions and 1242 deletions

View File

@@ -138,12 +138,12 @@ def get_components_to_install(
# Explicit components specified
if args.components:
if "all" in args.components:
components = ["framework_docs", "commands", "agents", "modes", "mcp", "mcp_docs"]
components = ["framework_docs", "commands", "agents", "modes", "mcp"]
else:
components = args.components
# If mcp or mcp_docs is specified, handle MCP server selection
if ("mcp" in components or "mcp_docs" in components) and not args.yes:
# If mcp is specified, handle MCP server selection
if "mcp" in components and not args.yes:
selected_servers = select_mcp_servers(registry)
if not hasattr(config_manager, "_installation_context"):
config_manager._installation_context = {}
@@ -151,26 +151,16 @@ def get_components_to_install(
selected_servers
)
# If the user selected some servers, ensure both mcp and mcp_docs are included
# If the user selected some servers, ensure mcp is included
if selected_servers:
if "mcp" not in components:
components.append("mcp")
logger.debug(
f"Auto-added 'mcp' component for selected servers: {selected_servers}"
)
if "mcp_docs" not in components:
components.append("mcp_docs")
logger.debug(
f"Auto-added 'mcp_docs' component for selected servers: {selected_servers}"
)
logger.info(f"Final components to install: {components}")
# If mcp_docs was explicitly requested but no servers selected, allow auto-detection
elif not selected_servers and "mcp_docs" in components:
logger.info("mcp_docs component will auto-detect existing MCP servers")
logger.info("Documentation will be installed for any detected servers")
return components
# Interactive two-stage selection
@@ -227,7 +217,7 @@ def select_mcp_servers(registry: ComponentRegistry) -> List[str]:
try:
# Get MCP component to access server list
mcp_instance = registry.get_component_instance(
"mcp", get_home_directory() / ".claude"
"mcp", DEFAULT_INSTALL_DIR
)
if not mcp_instance or not hasattr(mcp_instance, "mcp_servers"):
logger.error("Could not access MCP server information")
@@ -325,16 +315,7 @@ def select_framework_components(
component_options.append(f"{component_name} - {description}")
component_info[component_name] = metadata
# 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
# MCP documentation is integrated into airis-mcp-gateway, no separate component needed
print(f"\n{Colors.CYAN}{Colors.BRIGHT}{'='*51}{Colors.RESET}")
print(
@@ -358,21 +339,12 @@ def select_framework_components(
selected_components = ["framework_docs"]
else:
selected_components = []
all_components = framework_components + ["mcp_docs"]
all_components = framework_components
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")
@@ -601,9 +573,6 @@ def perform_installation(
if summary["installed"]:
logger.info(f"Installed components: {', '.join(summary['installed'])}")
if summary["backup_path"]:
logger.info(f"Backup created: {summary['backup_path']}")
else:
logger.error(
f"Installation completed with errors in {duration:.1f} seconds"

View File

@@ -79,14 +79,6 @@ def verify_superclaude_file(file_path: Path, component: str) -> bool:
"MODE_Task_Management.md",
"MODE_Token_Efficiency.md",
],
"mcp_docs": [
"MCP_Context7.md",
"MCP_Sequential.md",
"MCP_Magic.md",
"MCP_Playwright.md",
"MCP_Morphllm.md",
"MCP_Serena.md",
],
}
# For commands component, verify it's in the sc/ subdirectory
@@ -427,8 +419,7 @@ def _custom_component_selection(
"core": "Core Framework Files (CLAUDE.md, FLAGS.md, PRINCIPLES.md, etc.)",
"commands": "superclaude Commands (commands/sc/*.md)",
"agents": "Specialized Agents (agents/*.md)",
"mcp": "MCP Server Configurations",
"mcp_docs": "MCP Documentation",
"mcp": "MCP Server Configurations (airis-mcp-gateway)",
"modes": "superclaude Modes",
}
@@ -568,9 +559,8 @@ def display_component_details(component: str, info: Dict[str, Any]) -> Dict[str,
},
"mcp": {
"files": "MCP server configurations in .claude.json",
"description": "MCP server configurations",
"description": "MCP server configurations (airis-mcp-gateway)",
},
"mcp_docs": {"files": "MCP/*.md", "description": "MCP documentation files"},
"modes": {"files": "MODE_*.md", "description": "superclaude operational modes"},
}

View File

@@ -389,9 +389,6 @@ def perform_update(
if summary.get("updated"):
logger.info(f"Updated components: {', '.join(summary['updated'])}")
if summary.get("backup_path"):
logger.info(f"Backup created: {summary['backup_path']}")
else:
logger.error(f"Update completed with errors in {duration:.1f} seconds")

View File

@@ -5,7 +5,6 @@ from .commands import CommandsComponent
from .mcp import MCPComponent
from .agents import AgentsComponent
from .modes import ModesComponent
from .mcp_docs import MCPDocsComponent
__all__ = [
"FrameworkDocsComponent",
@@ -13,5 +12,4 @@ __all__ = [
"MCPComponent",
"AgentsComponent",
"ModesComponent",
"MCPDocsComponent",
]

View File

@@ -25,6 +25,13 @@ class AgentsComponent(Component):
"category": "agents",
}
def is_reinstallable(self) -> bool:
"""
Agents should always be synced to latest version.
SuperClaude agent files always overwrite existing files.
"""
return True
def get_metadata_modifications(self) -> Dict[str, Any]:
"""Get metadata modifications for agents"""
return {
@@ -64,14 +71,14 @@ class AgentsComponent(Component):
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with agents configuration")
# Add component registration
# Add component registration (with file list for sync)
self.settings_manager.add_component_registration(
"agents",
{
"version": __version__,
"category": "agents",
"agents_count": len(self.component_files),
"agents_list": self.component_files,
"files": list(self.component_files), # Track for sync/deletion
},
)
@@ -129,57 +136,51 @@ class AgentsComponent(Component):
return ["framework_docs"]
def update(self, config: Dict[str, Any]) -> bool:
"""Update agents component"""
"""
Sync agents component (overwrite + delete obsolete files).
No backup needed - SuperClaude source files are always authoritative.
"""
try:
self.logger.info("Updating SuperClaude agents component...")
self.logger.info("Syncing SuperClaude agents component...")
# Check current version
current_version = self.settings_manager.get_component_version("agents")
target_version = self.get_metadata()["version"]
if current_version == target_version:
self.logger.info(
f"Agents component already at version {target_version}"
)
return True
self.logger.info(
f"Updating agents component from {current_version} to {target_version}"
# Get previously installed files from metadata
metadata = self.settings_manager.load_metadata()
previous_files = set(
metadata.get("components", {}).get("agents", {}).get("files", [])
)
# Create backup of existing agents
backup_files = []
for filename in self.component_files:
# Get current files from source
current_files = set(self.component_files)
# Files to delete (were installed before, but no longer in source)
files_to_delete = previous_files - current_files
# Delete obsolete files
deleted_count = 0
for filename in files_to_delete:
file_path = self.install_component_subdir / filename
if file_path.exists():
backup_path = self.file_manager.backup_file(file_path)
if backup_path:
backup_files.append(backup_path)
self.logger.debug(f"Backed up agent: {filename}")
# Perform installation (will overwrite existing files)
if self._install(config):
self.logger.success(
f"Agents component updated to version {target_version}"
)
return True
else:
# Restore backups on failure
self.logger.error("Agents update failed, restoring backups...")
for backup_path in backup_files:
try:
original_path = (
self.install_component_subdir
/ backup_path.name.replace(".backup", "")
)
self.file_manager.copy_file(backup_path, original_path)
self.logger.debug(f"Restored {original_path.name}")
file_path.unlink()
deleted_count += 1
self.logger.info(f"Deleted obsolete agent: {filename}")
except Exception as e:
self.logger.warning(f"Could not restore {backup_path}: {e}")
return False
self.logger.warning(f"Could not delete {filename}: {e}")
# Install/overwrite current files (no backup)
success = self._install(config)
if success:
self.logger.success(
f"Agents synced: {len(current_files)} files, {deleted_count} obsolete files removed"
)
else:
self.logger.error("Agents sync failed")
return success
except Exception as e:
self.logger.exception(f"Unexpected error during agents update: {e}")
self.logger.exception(f"Unexpected error during agents sync: {e}")
return False
def _get_source_dir(self) -> Path:

View File

@@ -14,6 +14,15 @@ class CommandsComponent(Component):
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize commands component"""
if install_dir is None:
install_dir = Path.home() / ".claude"
# Commands are installed directly to ~/.claude/commands/sc/
# not under superclaude/ subdirectory (Claude Code official location)
if "superclaude" in str(install_dir):
# ~/.claude/superclaude -> ~/.claude
install_dir = install_dir.parent
super().__init__(install_dir, Path("commands/sc"))
def get_metadata(self) -> Dict[str, str]:
@@ -25,6 +34,13 @@ class CommandsComponent(Component):
"category": "commands",
}
def is_reinstallable(self) -> bool:
"""
Commands should always be synced to latest version.
SuperClaude command files always overwrite existing files.
"""
return True
def get_metadata_modifications(self) -> Dict[str, Any]:
"""Get metadata modifications for commands component"""
return {
@@ -54,13 +70,14 @@ class CommandsComponent(Component):
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with commands configuration")
# Add component registration to metadata
# Add component registration to metadata (with file list for sync)
self.settings_manager.add_component_registration(
"commands",
{
"version": __version__,
"category": "commands",
"files_count": len(self.component_files),
"files": list(self.component_files), # Track for sync/deletion
},
)
self.logger.info("Updated metadata with commands component registration")
@@ -68,6 +85,16 @@ class CommandsComponent(Component):
self.logger.error(f"Failed to update metadata: {e}")
return False
# Clean up old commands directory in superclaude/ (from previous versions)
try:
old_superclaude_commands = Path.home() / ".claude" / "superclaude" / "commands"
if old_superclaude_commands.exists():
import shutil
shutil.rmtree(old_superclaude_commands)
self.logger.info("Removed old commands directory from superclaude/")
except Exception as e:
self.logger.debug(f"Could not remove old commands directory: {e}")
return True
def uninstall(self) -> bool:
@@ -156,66 +183,63 @@ class CommandsComponent(Component):
return ["framework_docs"]
def update(self, config: Dict[str, Any]) -> bool:
"""Update commands component"""
"""
Sync commands component (overwrite + delete obsolete files).
No backup needed - SuperClaude source files are always authoritative.
"""
try:
self.logger.info("Updating SuperClaude commands component...")
self.logger.info("Syncing SuperClaude commands component...")
# Check current version
current_version = self.settings_manager.get_component_version("commands")
target_version = self.get_metadata()["version"]
if current_version == target_version:
self.logger.info(
f"Commands component already at version {target_version}"
)
return True
self.logger.info(
f"Updating commands component from {current_version} to {target_version}"
# Get previously installed files from metadata
metadata = self.settings_manager.load_metadata()
previous_files = set(
metadata.get("components", {}).get("commands", {}).get("files", [])
)
# Create backup of existing command files
# Get current files from source
current_files = set(self.component_files)
# Files to delete (were installed before, but no longer in source)
files_to_delete = previous_files - current_files
# Delete obsolete files
deleted_count = 0
commands_dir = self.install_dir / "commands" / "sc"
backup_files = []
for filename in files_to_delete:
file_path = commands_dir / filename
if file_path.exists():
try:
file_path.unlink()
deleted_count += 1
self.logger.info(f"Deleted obsolete command: {filename}")
except Exception as e:
self.logger.warning(f"Could not delete {filename}: {e}")
if commands_dir.exists():
for filename in self.component_files:
file_path = commands_dir / filename
if file_path.exists():
backup_path = self.file_manager.backup_file(file_path)
if backup_path:
backup_files.append(backup_path)
self.logger.debug(f"Backed up {filename}")
# Perform installation (overwrites existing files)
# Install/overwrite current files (no backup)
success = self.install(config)
if success:
# Remove backup files on successful update
for backup_path in backup_files:
try:
backup_path.unlink()
except Exception:
pass # Ignore cleanup errors
# Update metadata with current file list
self.settings_manager.add_component_registration(
"commands",
{
"version": __version__,
"category": "commands",
"files_count": len(current_files),
"files": list(current_files), # Track installed files
},
)
self.logger.success(
f"Commands component updated to version {target_version}"
f"Commands synced: {len(current_files)} files, {deleted_count} obsolete files removed"
)
else:
# Restore from backup on failure
self.logger.warning("Update failed, restoring from backup...")
for backup_path in backup_files:
try:
original_path = backup_path.with_suffix("")
backup_path.rename(original_path)
self.logger.debug(f"Restored {original_path.name}")
except Exception as e:
self.logger.error(f"Could not restore {backup_path}: {e}")
self.logger.error("Commands sync failed")
return success
except Exception as e:
self.logger.exception(f"Unexpected error during commands update: {e}")
self.logger.exception(f"Unexpected error during commands sync: {e}")
return False
def validate_installation(self) -> Tuple[bool, List[str]]:

View File

@@ -28,6 +28,13 @@ class FrameworkDocsComponent(Component):
"category": "documentation",
}
def is_reinstallable(self) -> bool:
"""
Framework docs should always be updated to latest version.
SuperClaude-related documentation should always overwrite existing files.
"""
return True
def get_metadata_modifications(self) -> Dict[str, Any]:
"""Get metadata modifications for SuperClaude"""
return {
@@ -59,13 +66,14 @@ class FrameworkDocsComponent(Component):
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with framework configuration")
# Add component registration to metadata
# Add component registration to metadata (with file list for sync)
self.settings_manager.add_component_registration(
"framework_docs",
{
"version": __version__,
"category": "documentation",
"files_count": len(self.component_files),
"files": list(self.component_files), # Track for sync/deletion
},
)
@@ -144,61 +152,64 @@ class FrameworkDocsComponent(Component):
return []
def update(self, config: Dict[str, Any]) -> bool:
"""Update framework docs component"""
"""
Sync framework docs component (overwrite + delete obsolete files).
No backup needed - SuperClaude source files are always authoritative.
"""
try:
self.logger.info("Updating SuperClaude framework docs component...")
self.logger.info("Syncing SuperClaude framework docs component...")
# Check current version
current_version = self.settings_manager.get_component_version("framework_docs")
target_version = self.get_metadata()["version"]
if current_version == target_version:
self.logger.info(f"Framework docs component already at version {target_version}")
return True
self.logger.info(
f"Updating framework docs component from {current_version} to {target_version}"
# Get previously installed files from metadata
metadata = self.settings_manager.load_metadata()
previous_files = set(
metadata.get("components", {})
.get("framework_docs", {})
.get("files", [])
)
# Create backup of existing files
backup_files = []
for filename in self.component_files:
# Get current files from source
current_files = set(self.component_files)
# Files to delete (were installed before, but no longer in source)
files_to_delete = previous_files - current_files
# Delete obsolete files
deleted_count = 0
for filename in files_to_delete:
file_path = self.install_dir / filename
if file_path.exists():
backup_path = self.file_manager.backup_file(file_path)
if backup_path:
backup_files.append(backup_path)
self.logger.debug(f"Backed up {filename}")
try:
file_path.unlink()
deleted_count += 1
self.logger.info(f"Deleted obsolete file: {filename}")
except Exception as e:
self.logger.warning(f"Could not delete {filename}: {e}")
# Perform installation (overwrites existing files)
# Install/overwrite current files (no backup)
success = self.install(config)
if success:
# Remove backup files on successful update
for backup_path in backup_files:
try:
backup_path.unlink()
except Exception:
pass # Ignore cleanup errors
# Update metadata with current file list
self.settings_manager.add_component_registration(
"framework_docs",
{
"version": __version__,
"category": "documentation",
"files_count": len(current_files),
"files": list(current_files), # Track installed files
},
)
self.logger.success(
f"Framework docs component updated to version {target_version}"
f"Framework docs synced: {len(current_files)} files, {deleted_count} obsolete files removed"
)
else:
# Restore from backup on failure
self.logger.warning("Update failed, restoring from backup...")
for backup_path in backup_files:
try:
original_path = backup_path.with_suffix("")
shutil.move(str(backup_path), str(original_path))
self.logger.debug(f"Restored {original_path.name}")
except Exception as e:
self.logger.error(f"Could not restore {backup_path}: {e}")
self.logger.error("Framework docs sync failed")
return success
except Exception as e:
self.logger.exception(f"Unexpected error during framework docs update: {e}")
self.logger.exception(f"Unexpected error during framework docs sync: {e}")
return False
def validate_installation(self) -> Tuple[bool, List[str]]:

View File

@@ -1,374 +0,0 @@
"""
MCP Documentation component for SuperClaude MCP server documentation
"""
from typing import Dict, List, Tuple, Optional, Any
from pathlib import Path
from ..core.base import Component
from setup import __version__
from ..services.claude_md import CLAUDEMdService
class MCPDocsComponent(Component):
"""MCP documentation component - installs docs for selected MCP servers"""
def __init__(self, install_dir: Optional[Path] = None):
"""Initialize MCP docs component"""
# Initialize attributes before calling parent constructor
# because parent calls _discover_component_files() which needs these
self.selected_servers: List[str] = []
# Map server names to documentation files
self.server_docs_map = {
"context7": "MCP_Context7.md",
"sequential": "MCP_Sequential.md",
"sequential-thinking": "MCP_Sequential.md", # Handle both naming conventions
"magic": "MCP_Magic.md",
"playwright": "MCP_Playwright.md",
"serena": "MCP_Serena.md",
"morphllm": "MCP_Morphllm.md",
"morphllm-fast-apply": "MCP_Morphllm.md", # Handle both naming conventions
"tavily": "MCP_Tavily.md",
}
super().__init__(install_dir, Path(""))
def get_metadata(self) -> Dict[str, str]:
"""Get component metadata"""
return {
"name": "mcp_docs",
"version": __version__,
"description": "MCP server documentation and usage guides",
"category": "documentation",
}
def is_reinstallable(self) -> bool:
"""
Allow mcp_docs to be reinstalled to handle different server selections.
This enables users to add or change MCP server documentation.
"""
return True
def set_selected_servers(self, selected_servers: List[str]) -> None:
"""Set which MCP servers were selected for documentation installation"""
self.selected_servers = selected_servers
self.logger.debug(f"MCP docs will be installed for: {selected_servers}")
def get_files_to_install(self) -> List[Tuple[Path, Path]]:
"""
Return list of files to install based on selected MCP servers
Returns:
List of tuples (source_path, target_path)
"""
source_dir = self._get_source_dir()
files = []
if source_dir and self.selected_servers:
for server_name in self.selected_servers:
if server_name in self.server_docs_map:
doc_file = self.server_docs_map[server_name]
source = source_dir / doc_file
target = self.install_dir / doc_file
if source.exists():
files.append((source, target))
self.logger.debug(
f"Will install documentation for {server_name}: {doc_file}"
)
else:
self.logger.warning(
f"Documentation file not found for {server_name}: {doc_file}"
)
return files
def _discover_component_files(self) -> List[str]:
"""
Override parent method to dynamically discover files based on selected servers
"""
files = []
# Check if selected_servers is not empty
if self.selected_servers:
for server_name in self.selected_servers:
if server_name in self.server_docs_map:
files.append(self.server_docs_map[server_name])
return files
def _detect_existing_mcp_servers_from_config(self) -> List[str]:
"""Detect existing MCP servers from Claude Desktop config"""
detected_servers = []
try:
# Try to find Claude Desktop config file
config_paths = [
self.install_dir / "claude_desktop_config.json",
Path.home() / ".claude" / "claude_desktop_config.json",
Path.home() / ".claude.json", # Claude CLI config
Path.home()
/ "AppData"
/ "Roaming"
/ "Claude"
/ "claude_desktop_config.json", # Windows
Path.home()
/ "Library"
/ "Application Support"
/ "Claude"
/ "claude_desktop_config.json", # macOS
]
config_file = None
for path in config_paths:
if path.exists():
config_file = path
break
if not config_file:
self.logger.debug("No Claude Desktop config file found")
return detected_servers
import json
with open(config_file, "r") as f:
config = json.load(f)
# Extract MCP server names from mcpServers section
mcp_servers = config.get("mcpServers", {})
for server_name in mcp_servers.keys():
# Map common name variations to our doc file names
normalized_name = self._normalize_server_name(server_name)
if normalized_name and normalized_name in self.server_docs_map:
detected_servers.append(normalized_name)
if detected_servers:
self.logger.info(
f"Detected existing MCP servers from config: {detected_servers}"
)
except Exception as e:
self.logger.warning(f"Could not read Claude Desktop config: {e}")
return detected_servers
def _normalize_server_name(self, server_name: str) -> Optional[str]:
"""Normalize server name to match our documentation mapping"""
if not server_name:
return None
server_name = server_name.lower().strip()
# Map common variations to our server_docs_map keys
name_mappings = {
"context7": "context7",
"sequential-thinking": "sequential-thinking",
"sequential": "sequential-thinking",
"magic": "magic",
"playwright": "playwright",
"serena": "serena",
"morphllm": "morphllm",
"morphllm-fast-apply": "morphllm",
"morph": "morphllm",
}
return name_mappings.get(server_name)
def _install(self, config: Dict[str, Any]) -> bool:
"""Install MCP documentation component with auto-detection"""
self.logger.info("Installing MCP server documentation...")
# Auto-detect existing servers
self.logger.info("Auto-detecting existing MCP servers for documentation...")
detected_servers = self._detect_existing_mcp_servers_from_config()
# Get selected servers from config
selected_servers = config.get("selected_mcp_servers", [])
# Get previously documented servers from metadata
previous_servers = self.settings_manager.get_metadata_setting(
"components.mcp_docs.servers_documented", []
)
# Merge all server lists
all_servers = list(set(detected_servers + selected_servers + previous_servers))
# Filter to only servers we have documentation for
valid_servers = [s for s in all_servers if s in self.server_docs_map]
if not valid_servers:
self.logger.info(
"No MCP servers detected or selected for documentation installation"
)
# Still proceed to update metadata
self.set_selected_servers([])
self.component_files = []
return self._post_install()
self.logger.info(
f"Installing documentation for MCP servers: {', '.join(valid_servers)}"
)
if detected_servers:
self.logger.info(f" - Detected from config: {detected_servers}")
if selected_servers:
self.logger.info(f" - Newly selected: {selected_servers}")
if previous_servers:
self.logger.info(f" - Previously documented: {previous_servers}")
# Set the servers for which we'll install documentation
self.set_selected_servers(valid_servers)
self.component_files = self._discover_component_files()
# Validate installation
success, errors = self.validate_prerequisites()
if not success:
for error in errors:
self.logger.error(error)
return False
# Get files to install
files_to_install = self.get_files_to_install()
if not files_to_install:
self.logger.warning("No MCP documentation files found to install")
return False
# Copy documentation files
success_count = 0
successfully_copied_files = []
for source, target in files_to_install:
self.logger.debug(f"Copying {source.name} to {target}")
if self.file_manager.copy_file(source, target):
success_count += 1
successfully_copied_files.append(source.name)
self.logger.debug(f"Successfully copied {source.name}")
else:
self.logger.error(f"Failed to copy {source.name}")
if success_count != len(files_to_install):
self.logger.error(
f"Only {success_count}/{len(files_to_install)} documentation files copied successfully"
)
return False
# Update component_files to only include successfully copied files
self.component_files = successfully_copied_files
self.logger.success(
f"MCP documentation installed successfully ({success_count} files for {len(valid_servers)} servers)"
)
return self._post_install()
def _post_install(self) -> bool:
"""Post-installation tasks"""
try:
# Update metadata
metadata_mods = {
"components": {
"mcp_docs": {
"version": __version__,
"installed": True,
"files_count": len(self.component_files),
"servers_documented": self.selected_servers,
}
}
}
self.settings_manager.update_metadata(metadata_mods)
self.logger.info("Updated metadata with MCP docs component registration")
# Update CLAUDE.md with MCP documentation imports
try:
manager = CLAUDEMdService(self.install_dir)
manager.add_imports(self.component_files, category="MCP Documentation")
self.logger.info("Updated CLAUDE.md with MCP documentation imports")
except Exception as e:
self.logger.warning(
f"Failed to update CLAUDE.md with MCP documentation imports: {e}"
)
# Don't fail the whole installation for this
return True
except Exception as e:
self.logger.error(f"Failed to update metadata: {e}")
return False
def uninstall(self) -> bool:
"""Uninstall MCP documentation component"""
try:
self.logger.info("Uninstalling MCP documentation component...")
# Remove all MCP documentation files
removed_count = 0
source_dir = self._get_source_dir()
if source_dir and source_dir.exists():
# Remove all possible MCP doc files
for doc_file in self.server_docs_map.values():
file_path = self.install_component_subdir / doc_file
if self.file_manager.remove_file(file_path):
removed_count += 1
self.logger.debug(f"Removed {doc_file}")
# Remove mcp directory if empty
try:
if self.install_component_subdir.exists():
remaining_files = list(self.install_component_subdir.iterdir())
if not remaining_files:
self.install_component_subdir.rmdir()
self.logger.debug("Removed empty mcp directory")
except Exception as e:
self.logger.warning(f"Could not remove mcp directory: {e}")
# Update settings.json
try:
if self.settings_manager.is_component_installed("mcp_docs"):
self.settings_manager.remove_component_registration("mcp_docs")
self.logger.info("Removed MCP docs component from settings.json")
except Exception as e:
self.logger.warning(f"Could not update settings.json: {e}")
self.logger.success(
f"MCP documentation uninstalled ({removed_count} files removed)"
)
return True
except Exception as e:
self.logger.exception(
f"Unexpected error during MCP docs uninstallation: {e}"
)
return False
def get_dependencies(self) -> List[str]:
"""Get dependencies"""
return ["framework_docs"]
def _get_source_dir(self) -> Optional[Path]:
"""Get source directory for MCP documentation files"""
# Assume we're in superclaude/setup/components/mcp_docs.py
# and MCP docs are in superclaude/superclaude/MCP/
project_root = Path(__file__).parent.parent.parent
mcp_dir = project_root / "superclaude" / "mcp"
# Return None if directory doesn't exist to prevent warning
if not mcp_dir.exists():
return None
return mcp_dir
def get_size_estimate(self) -> int:
"""Get estimated installation size"""
source_dir = self._get_source_dir()
total_size = 0
if source_dir and source_dir.exists() and self.selected_servers:
for server_name in self.selected_servers:
if server_name in self.server_docs_map:
doc_file = self.server_docs_map[server_name]
file_path = source_dir / doc_file
if file_path.exists():
total_size += file_path.stat().st_size
# Minimum size estimate
total_size = max(total_size, 10240) # At least 10KB
return total_size

View File

@@ -26,6 +26,13 @@ class ModesComponent(Component):
"category": "modes",
}
def is_reinstallable(self) -> bool:
"""
Modes should always be synced to latest version.
SuperClaude mode files always overwrite existing files.
"""
return True
def _install(self, config: Dict[str, Any]) -> bool:
"""Install modes component"""
self.logger.info("Installing SuperClaude behavioral modes...")
@@ -77,6 +84,7 @@ class ModesComponent(Component):
"version": __version__,
"installed": True,
"files_count": len(self.component_files),
"files": list(self.component_files), # Track for sync/deletion
}
}
}
@@ -142,6 +150,67 @@ class ModesComponent(Component):
"""Get dependencies"""
return ["framework_docs"]
def update(self, config: Dict[str, Any]) -> bool:
"""
Sync modes component (overwrite + delete obsolete files).
No backup needed - SuperClaude source files are always authoritative.
"""
try:
self.logger.info("Syncing SuperClaude modes component...")
# Get previously installed files from metadata
metadata = self.settings_manager.load_metadata()
previous_files = set(
metadata.get("components", {}).get("modes", {}).get("files", [])
)
# Get current files from source
current_files = set(self.component_files)
# Files to delete (were installed before, but no longer in source)
files_to_delete = previous_files - current_files
# Delete obsolete files
deleted_count = 0
for filename in files_to_delete:
file_path = self.install_dir / filename
if file_path.exists():
try:
file_path.unlink()
deleted_count += 1
self.logger.info(f"Deleted obsolete mode: {filename}")
except Exception as e:
self.logger.warning(f"Could not delete {filename}: {e}")
# Install/overwrite current files (no backup)
success = self.install(config)
if success:
# Update metadata with current file list
metadata_mods = {
"components": {
"modes": {
"version": __version__,
"installed": True,
"files_count": len(current_files),
"files": list(current_files), # Track installed files
}
}
}
self.settings_manager.update_metadata(metadata_mods)
self.logger.success(
f"Modes synced: {len(current_files)} files, {deleted_count} obsolete files removed"
)
else:
self.logger.error("Modes sync failed")
return success
except Exception as e:
self.logger.exception(f"Unexpected error during modes sync: {e}")
return False
def _get_source_dir(self) -> Optional[Path]:
"""Get source directory for mode files"""
# Assume we're in superclaude/setup/components/modes.py

View File

@@ -37,7 +37,6 @@ class Installer:
self.failed_components: Set[str] = set()
self.skipped_components: Set[str] = set()
self.backup_path: Optional[Path] = None
self.logger = get_logger()
def register_component(self, component: Component) -> None:
@@ -132,59 +131,6 @@ class Installer:
return len(errors) == 0, errors
def create_backup(self) -> Optional[Path]:
"""
Create backup of existing installation
Returns:
Path to backup archive or None if no existing installation
"""
if not self.install_dir.exists():
return None
if self.dry_run:
return self.install_dir / "backup_dryrun.tar.gz"
# Create backup directory
backup_dir = self.install_dir / "backups"
backup_dir.mkdir(exist_ok=True)
# Create timestamped backup
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_name = f"superclaude_backup_{timestamp}"
backup_path = backup_dir / f"{backup_name}.tar.gz"
# Create temporary directory for backup
with tempfile.TemporaryDirectory() as temp_dir:
temp_backup = Path(temp_dir) / backup_name
# Ensure temp backup directory exists
temp_backup.mkdir(parents=True, exist_ok=True)
# Copy all files except backups and local directories
for item in self.install_dir.iterdir():
if item.name not in ["backups", "local"]:
try:
if item.is_file():
shutil.copy2(item, temp_backup / item.name)
elif item.is_dir():
shutil.copytree(item, temp_backup / item.name)
except Exception as e:
# Log warning but continue backup process
self.logger.warning(f"Could not backup {item.name}: {e}")
# Always create an archive, even if empty, to ensure it's a valid tarball
base_path = backup_dir / backup_name
shutil.make_archive(str(base_path), "gztar", temp_backup)
if not any(temp_backup.iterdir()):
self.logger.warning(
f"No files to backup, created empty backup archive: {backup_path.name}"
)
self.backup_path = backup_path
return backup_path
def install_component(self, component_name: str, config: Dict[str, Any]) -> bool:
"""
Install a single component
@@ -201,9 +147,9 @@ class Installer:
component = self.components[component_name]
# Framework components (agents, commands, modes, core, mcp_docs) are ALWAYS updated to latest version
# Framework components are ALWAYS updated to latest version
# These are SuperClaude implementation files, not user configurations
framework_components = {'agents', 'commands', 'modes', 'core', 'mcp_docs', 'mcp'}
framework_components = {'framework_docs', 'agents', 'commands', 'modes', 'core', 'mcp'}
if component_name in framework_components:
# Always update framework components to latest version
@@ -233,13 +179,17 @@ class Installer:
self.failed_components.add(component_name)
return False
# Perform installation
# Perform installation or update
try:
if self.dry_run:
self.logger.info(f"[DRY RUN] Would install {component_name}")
success = True
else:
success = component.install(config)
# If component is already installed and this is a framework component, call update() instead of install()
if component_name in self.installed_components and component_name in framework_components:
success = component.update(config)
else:
success = component.install(config)
if success:
self.installed_components.add(component_name)
@@ -284,15 +234,6 @@ class Installer:
self.logger.error(f" - {error}")
return False
# Create backup if updating
if self.install_dir.exists() and not self.dry_run:
self.logger.info("Creating backup of existing installation...")
try:
self.create_backup()
except Exception as e:
self.logger.error(f"Failed to create backup: {e}")
return False
# Install each component
all_success = True
for name in ordered_names:
@@ -352,7 +293,6 @@ class Installer:
"installed": list(self.installed_components),
"failed": list(self.failed_components),
"skipped": list(self.skipped_components),
"backup_path": str(self.backup_path) if self.backup_path else None,
"install_dir": str(self.install_dir),
"dry_run": self.dry_run,
}
@@ -361,5 +301,4 @@ class Installer:
return {
"updated": list(self.updated_components),
"failed": list(self.failed_components),
"backup_path": str(self.backup_path) if self.backup_path else None,
}

View File

@@ -36,15 +36,6 @@
"enabled": true,
"required_tools": []
},
"mcp_docs": {
"name": "mcp_docs",
"version": "4.1.5",
"description": "MCP server documentation and usage guides",
"category": "documentation",
"dependencies": ["core"],
"enabled": true,
"required_tools": []
},
"agents": {
"name": "agents",
"version": "4.1.5",

View File

@@ -90,7 +90,6 @@ def run_diagnostics() -> dict:
if install_dir.exists():
components = {
"CLAUDE.md": "Core framework entry point",
"MCP_*.md": "MCP documentation files",
"MODE_*.md": "Behavioral mode files",
}
@@ -100,13 +99,6 @@ def run_diagnostics() -> dict:
"message": "Installed" if claude_md.exists() else "Not installed",
}
# Count MCP docs
mcp_docs = list(install_dir.glob("MCP_*.md"))
results["MCP Documentation"] = {
"status": len(mcp_docs) > 0,
"message": f"{len(mcp_docs)} servers documented" if mcp_docs else "None installed",
}
# Count modes
mode_files = list(install_dir.glob("MODE_*.md"))
results["Behavioral Modes"] = {

View File

@@ -9,6 +9,7 @@ from rich.panel import Panel
from rich.prompt import Confirm
from rich.progress import Progress, SpinnerColumn, TextColumn
from superclaude.cli._console import console
from setup import DEFAULT_INSTALL_DIR
# Create install command group
app = typer.Typer(
@@ -33,7 +34,7 @@ def install_callback(
help="Installation profile: api (with API keys), noapi (without), or custom",
),
install_dir: Path = typer.Option(
Path.home() / ".claude",
DEFAULT_INSTALL_DIR,
"--install-dir",
help="Installation directory",
),
@@ -82,7 +83,7 @@ def install_all(
help="Installation profile: api (with API keys), noapi (without), or custom",
),
install_dir: Path = typer.Option(
Path.home() / ".claude",
DEFAULT_INSTALL_DIR,
"--install-dir",
help="Installation directory",
),
@@ -148,7 +149,7 @@ def _run_installation(
verbose=verbose,
quiet=False,
yes=True, # Always non-interactive
components=["framework_docs", "modes", "commands", "agents", "mcp_docs"], # Full install
components=["framework_docs", "modes", "commands", "agents"], # Full install (mcp integrated into airis-mcp-gateway)
no_backup=False,
list_components=False,
diagnose=False,
@@ -197,7 +198,7 @@ def install_components(
help="Component names to install (e.g., core modes commands agents)",
),
install_dir: Path = typer.Option(
Path.home() / ".claude",
DEFAULT_INSTALL_DIR,
"--install-dir",
help="Installation directory",
),
@@ -221,7 +222,7 @@ def install_components(
- commands: Slash commands (26 commands)
- agents: Specialized agents (17 agents)
- mcp: MCP server integrations
- mcp_docs: MCP documentation
- mcp: MCP server configurations (airis-mcp-gateway)
"""
console.print(
Panel.fit(

View File

@@ -1,32 +0,0 @@
# Chrome DevTools MCP Server
**Purpose**: Performance analysis, debugging, and real-time browser inspection
## Triggers
- Performance auditing and analysis requests
- Debugging of layout issues (e.g., CLS)
- Investigation of slow loading times (e.g., LCP)
- Analysis of console errors and network requests
- Real-time inspection of the DOM and CSS
## Choose When
- **For deep performance analysis**: When you need to understand performance bottlenecks.
- **For live debugging**: To inspect the runtime state of a web page and debug live issues.
- **For network analysis**: To inspect network requests and identify issues like CORS errors.
- **Not for E2E testing**: Use Playwright for end-to-end testing scenarios.
- **Not for static analysis**: Use native Claude for code review and logic validation.
## Works Best With
- **Sequential**: Sequential plans a performance improvement strategy → Chrome DevTools analyzes and verifies the improvements.
- **Playwright**: Playwright automates a user flow → Chrome DevTools analyzes the performance of that flow.
## Examples
```
"analyze the performance of this page" → Chrome DevTools (performance analysis)
"why is this page loading slowly?" → Chrome DevTools (performance analysis)
"debug the layout shift on this element" → Chrome DevTools (live debugging)
"check for console errors on the homepage" → Chrome DevTools (live debugging)
"what network requests are failing?" → Chrome DevTools (network analysis)
"test the login flow" → Playwright (browser automation)
"review this function's logic" → Native Claude (static analysis)
```

View File

@@ -1,30 +0,0 @@
# Context7 MCP Server
**Purpose**: Official library documentation lookup and framework pattern guidance
## Triggers
- Import statements: `import`, `require`, `from`, `use`
- Framework keywords: React, Vue, Angular, Next.js, Express, etc.
- Library-specific questions about APIs or best practices
- Need for official documentation patterns vs generic solutions
- Version-specific implementation requirements
## Choose When
- **Over WebSearch**: When you need curated, version-specific documentation
- **Over native knowledge**: When implementation must follow official patterns
- **For frameworks**: React hooks, Vue composition API, Angular services
- **For libraries**: Correct API usage, authentication flows, configuration
- **For compliance**: When adherence to official standards is mandatory
## Works Best With
- **Sequential**: Context7 provides docs → Sequential analyzes implementation strategy
- **Magic**: Context7 supplies patterns → Magic generates framework-compliant components
## Examples
```
"implement React useEffect" → Context7 (official React patterns)
"add authentication with Auth0" → Context7 (official Auth0 docs)
"migrate to Vue 3" → Context7 (official migration guide)
"optimize Next.js performance" → Context7 (official optimization patterns)
"just explain this function" → Native Claude (no external docs needed)
```

View File

@@ -1,31 +0,0 @@
# Magic MCP Server
**Purpose**: Modern UI component generation from 21st.dev patterns with design system integration
## Triggers
- UI component requests: button, form, modal, card, table, nav
- Design system implementation needs
- `/ui` or `/21` commands
- Frontend-specific keywords: responsive, accessible, interactive
- Component enhancement or refinement requests
## Choose When
- **For UI components**: Use Magic, not native HTML/CSS generation
- **Over manual coding**: When you need production-ready, accessible components
- **For design systems**: When consistency with existing patterns matters
- **For modern frameworks**: React, Vue, Angular with current best practices
- **Not for backend**: API logic, database queries, server configuration
## Works Best With
- **Context7**: Magic uses 21st.dev patterns → Context7 provides framework integration
- **Sequential**: Sequential analyzes UI requirements → Magic implements structured components
## Examples
```
"create a login form" → Magic (UI component generation)
"build a responsive navbar" → Magic (UI pattern with accessibility)
"add a data table with sorting" → Magic (complex UI component)
"make this component accessible" → Magic (UI enhancement)
"write a REST API" → Native Claude (backend logic)
"fix database query" → Native Claude (non-UI task)
```

View File

@@ -1,31 +0,0 @@
# Morphllm MCP Server
**Purpose**: Pattern-based code editing engine with token optimization for bulk transformations
## Triggers
- Multi-file edit operations requiring consistent patterns
- Framework updates, style guide enforcement, code cleanup
- Bulk text replacements across multiple files
- Natural language edit instructions with specific scope
- Token optimization needed (efficiency gains 30-50%)
## Choose When
- **Over Serena**: For pattern-based edits, not symbol operations
- **For bulk operations**: Style enforcement, framework updates, text replacements
- **When token efficiency matters**: Fast Apply scenarios with compression needs
- **For simple to moderate complexity**: <10 files, straightforward transformations
- **Not for semantic operations**: Symbol renames, dependency tracking, LSP integration
## Works Best With
- **Serena**: Serena analyzes semantic context → Morphllm executes precise edits
- **Sequential**: Sequential plans edit strategy → Morphllm applies systematic changes
## Examples
```
"update all React class components to hooks" → Morphllm (pattern transformation)
"enforce ESLint rules across project" → Morphllm (style guide application)
"replace all console.log with logger calls" → Morphllm (bulk text replacement)
"rename getUserData function everywhere" → Serena (symbol operation)
"analyze code architecture" → Sequential (complex analysis)
"explain this algorithm" → Native Claude (simple explanation)
```

View File

@@ -1,32 +0,0 @@
# Playwright MCP Server
**Purpose**: Browser automation and E2E testing with real browser interaction
## Triggers
- Browser testing and E2E test scenarios
- Visual testing, screenshot, or UI validation requests
- Form submission and user interaction testing
- Cross-browser compatibility validation
- Performance testing requiring real browser rendering
- Accessibility testing with automated WCAG compliance
## Choose When
- **For real browser interaction**: When you need actual rendering, not just code
- **Over unit tests**: For integration testing, user journeys, visual validation
- **For E2E scenarios**: Login flows, form submissions, multi-page workflows
- **For visual testing**: Screenshot comparisons, responsive design validation
- **Not for code analysis**: Static code review, syntax checking, logic validation
## Works Best With
- **Sequential**: Sequential plans test strategy → Playwright executes browser automation
- **Magic**: Magic creates UI components → Playwright validates accessibility and behavior
## Examples
```
"test the login flow" → Playwright (browser automation)
"check if form validation works" → Playwright (real user interaction)
"take screenshots of responsive design" → Playwright (visual testing)
"validate accessibility compliance" → Playwright (automated WCAG testing)
"review this function's logic" → Native Claude (static analysis)
"explain the authentication code" → Native Claude (code review)
```

View File

@@ -1,33 +0,0 @@
# Sequential MCP Server
**Purpose**: Multi-step reasoning engine for complex analysis and systematic problem solving
## Triggers
- Complex debugging scenarios with multiple layers
- Architectural analysis and system design questions
- `--think`, `--think-hard`, `--ultrathink` flags
- Problems requiring hypothesis testing and validation
- Multi-component failure investigation
- Performance bottleneck identification requiring methodical approach
## Choose When
- **Over native reasoning**: When problems have 3+ interconnected components
- **For systematic analysis**: Root cause analysis, architecture review, security assessment
- **When structure matters**: Problems benefit from decomposition and evidence gathering
- **For cross-domain issues**: Problems spanning frontend, backend, database, infrastructure
- **Not for simple tasks**: Basic explanations, single-file changes, straightforward fixes
## Works Best With
- **Context7**: Sequential coordinates analysis → Context7 provides official patterns
- **Magic**: Sequential analyzes UI logic → Magic implements structured components
- **Playwright**: Sequential identifies testing strategy → Playwright executes validation
## Examples
```
"why is this API slow?" → Sequential (systematic performance analysis)
"design a microservices architecture" → Sequential (structured system design)
"debug this authentication flow" → Sequential (multi-component investigation)
"analyze security vulnerabilities" → Sequential (comprehensive threat modeling)
"explain this function" → Native Claude (simple explanation)
"fix this typo" → Native Claude (straightforward change)
```

View File

@@ -1,32 +0,0 @@
# Serena MCP Server
**Purpose**: Semantic code understanding with project memory and session persistence
## Triggers
- Symbol operations: rename, extract, move functions/classes
- Project-wide code navigation and exploration
- Multi-language projects requiring LSP integration
- Session lifecycle: `/sc:load`, `/sc:save`, project activation
- Memory-driven development workflows
- Large codebase analysis (>50 files, complex architecture)
## Choose When
- **Over Morphllm**: For symbol operations, not pattern-based edits
- **For semantic understanding**: Symbol references, dependency tracking, LSP integration
- **For session persistence**: Project context, memory management, cross-session learning
- **For large projects**: Multi-language codebases requiring architectural understanding
- **Not for simple edits**: Basic text replacements, style enforcement, bulk operations
## Works Best With
- **Morphllm**: Serena analyzes semantic context → Morphllm executes precise edits
- **Sequential**: Serena provides project context → Sequential performs architectural analysis
## Examples
```
"rename getUserData function everywhere" → Serena (symbol operation with dependency tracking)
"find all references to this class" → Serena (semantic search and navigation)
"load my project context" → Serena (/sc:load with project activation)
"save my current work session" → Serena (/sc:save with memory persistence)
"update all console.log to logger" → Morphllm (pattern-based replacement)
"create a login form" → Magic (UI component generation)
```

View File

@@ -1,285 +0,0 @@
# Tavily MCP Server
**Purpose**: Web search and real-time information retrieval for research and current events
## Triggers
- Web search requirements beyond Claude's knowledge cutoff
- Current events, news, and real-time information needs
- Market research and competitive analysis tasks
- Technical documentation not in training data
- Academic research requiring recent publications
- Fact-checking and verification needs
- Deep research investigations requiring multi-source analysis
- `/sc:research` command activation
## Choose When
- **Over WebSearch**: When you need structured search with advanced filtering
- **Over WebFetch**: When you need multi-source search, not single page extraction
- **For research**: Comprehensive investigations requiring multiple sources
- **For current info**: Events, updates, or changes after knowledge cutoff
- **Not for**: Simple questions answerable from training, code generation, local file operations
## Works Best With
- **Sequential**: Tavily provides raw information → Sequential analyzes and synthesizes
- **Playwright**: Tavily discovers URLs → Playwright extracts complex content
- **Context7**: Tavily searches for updates → Context7 provides stable documentation
- **Serena**: Tavily performs searches → Serena stores research sessions
## Configuration
Requires TAVILY_API_KEY environment variable from https://app.tavily.com
## Search Capabilities
- **Web Search**: General web searches with ranking algorithms
- **News Search**: Time-filtered news and current events
- **Academic Search**: Scholarly articles and research papers
- **Domain Filtering**: Include/exclude specific domains
- **Content Extraction**: Full-text extraction from search results
- **Freshness Control**: Prioritize recent content
- **Multi-Round Searching**: Iterative refinement based on gaps
## Examples
```
"latest TypeScript features 2024" → Tavily (current technical information)
"OpenAI GPT updates this week" → Tavily (recent news and updates)
"quantum computing breakthroughs 2024" → Tavily (recent research)
"best practices React Server Components" → Tavily (current best practices)
"explain recursion" → Native Claude (general concept explanation)
"write a Python function" → Native Claude (code generation)
```
## Search Patterns
### Basic Search
```
Query: "search term"
→ Returns: Ranked results with snippets
```
### Domain-Specific Search
```
Query: "search term"
Domains: ["arxiv.org", "github.com"]
→ Returns: Results from specified domains only
```
### Time-Filtered Search
```
Query: "search term"
Recency: "week" | "month" | "year"
→ Returns: Recent results within timeframe
```
### Deep Content Search
```
Query: "search term"
Extract: true
→ Returns: Full content extraction from top results
```
## Quality Optimization
- **Query Refinement**: Iterate searches based on initial results
- **Source Diversity**: Ensure multiple perspectives in results
- **Credibility Filtering**: Prioritize authoritative sources
- **Deduplication**: Remove redundant information across sources
- **Relevance Scoring**: Focus on most pertinent results
## Integration Flows
### Research Flow
```
1. Tavily: Initial broad search
2. Sequential: Analyze and identify gaps
3. Tavily: Targeted follow-up searches
4. Sequential: Synthesize findings
5. Serena: Store research session
```
### Fact-Checking Flow
```
1. Tavily: Search for claim verification
2. Tavily: Find contradicting sources
3. Sequential: Analyze evidence
4. Report: Present balanced findings
```
### Competitive Analysis Flow
```
1. Tavily: Search competitor information
2. Tavily: Search market trends
3. Sequential: Comparative analysis
4. Context7: Technical comparisons
5. Report: Strategic insights
```
### Deep Research Flow (DR Agent)
```
1. Planning: Decompose research question
2. Tavily: Execute planned searches
3. Analysis: Assess URL complexity
4. Routing: Simple → Tavily extract | Complex → Playwright
5. Synthesis: Combine all sources
6. Iteration: Refine based on gaps
```
## Advanced Search Strategies
### Multi-Hop Research
```yaml
Initial_Search:
query: "core topic"
depth: broad
Follow_Up_1:
query: "entities from initial"
depth: targeted
Follow_Up_2:
query: "relationships discovered"
depth: deep
Synthesis:
combine: all_findings
resolve: contradictions
```
### Adaptive Query Generation
```yaml
Simple_Query:
- Direct search terms
- Single concept focus
Complex_Query:
- Multiple search variations
- Boolean operators
- Domain restrictions
- Time filters
Iterative_Query:
- Start broad
- Refine based on results
- Target specific gaps
```
### Source Credibility Assessment
```yaml
High_Credibility:
- Academic institutions
- Government sources
- Established media
- Official documentation
Medium_Credibility:
- Industry publications
- Expert blogs
- Community resources
Low_Credibility:
- User forums
- Social media
- Unverified sources
```
## Performance Considerations
### Search Optimization
- Batch similar searches together
- Cache search results for reuse
- Prioritize high-value sources
- Limit depth based on confidence
### Rate Limiting
- Maximum searches per minute
- Token usage per search
- Result caching duration
- Parallel search limits
### Cost Management
- Monitor API usage
- Set budget limits
- Optimize query efficiency
- Use caching effectively
## Integration with DR Agent Architecture
### Planning Strategy Support
```yaml
Planning_Only:
- Direct query execution
- No refinement needed
Intent_Planning:
- Clarify search intent
- Generate focused queries
Unified:
- Present search plan
- Adjust based on feedback
```
### Multi-Hop Execution
```yaml
Hop_Management:
- Track search genealogy
- Build on previous results
- Detect circular references
- Maintain hop context
```
### Self-Reflection Integration
```yaml
Quality_Check:
- Assess result relevance
- Identify coverage gaps
- Trigger additional searches
- Calculate confidence scores
```
### Case-Based Learning
```yaml
Pattern_Storage:
- Successful query formulations
- Effective search strategies
- Domain preferences
- Time filter patterns
```
## Error Handling
### Common Issues
- API key not configured
- Rate limit exceeded
- Network timeout
- No results found
- Invalid query format
### Fallback Strategies
- Use native WebSearch
- Try alternative queries
- Expand search scope
- Use cached results
- Simplify search terms
## Best Practices
### Query Formulation
1. Start with clear, specific terms
2. Use quotes for exact phrases
3. Include relevant keywords
4. Specify time ranges when needed
5. Use domain filters strategically
### Result Processing
1. Verify source credibility
2. Cross-reference multiple sources
3. Check publication dates
4. Identify potential biases
5. Extract key information
### Integration Workflow
1. Plan search strategy
2. Execute initial searches
3. Analyze results
4. Identify gaps
5. Refine and iterate
6. Synthesize findings
7. Store valuable patterns

View File

@@ -1,9 +0,0 @@
{
"context7": {
"command": "npx",
"args": [
"-y",
"@upstash/context7-mcp@latest"
]
}
}

View File

@@ -1,12 +0,0 @@
{
"magic": {
"type": "stdio",
"command": "npx",
"args": [
"@21st-dev/magic"
],
"env": {
"TWENTYFIRST_API_KEY": ""
}
}
}

View File

@@ -1,13 +0,0 @@
{
"morphllm-fast-apply": {
"command": "npx",
"args": [
"@morph-llm/morph-fast-apply",
"/home/"
],
"env": {
"MORPH_API_KEY": "",
"ALL_TOOLS": "true"
}
}
}

View File

@@ -1,8 +0,0 @@
{
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}

View File

@@ -1,9 +0,0 @@
{
"sequential-thinking": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sequential-thinking"
]
}
}

View File

@@ -1,14 +0,0 @@
{
"serena": {
"command": "docker",
"args": [
"run",
"--rm",
"-v", "${PWD}:/workspace",
"--workdir", "/workspace",
"python:3.11-slim",
"bash", "-c",
"pip install uv && uv tool install serena-ai && uv tool run serena-ai start-mcp-server --context ide-assistant --project /workspace"
]
}
}

View File

@@ -1,13 +0,0 @@
{
"serena": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/oraios/serena",
"serena",
"start-mcp-server",
"--context",
"ide-assistant"
]
}
}

View File

@@ -1,13 +0,0 @@
{
"tavily": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.tavily.com/mcp/?tavilyApiKey=${TAVILY_API_KEY}"
],
"env": {
"TAVILY_API_KEY": "${TAVILY_API_KEY}"
}
}
}