claude-mpm 4.9.0__py3-none-any.whl → 4.10.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
claude_mpm/VERSION CHANGED
@@ -1 +1 @@
1
- 4.9.0
1
+ 4.10.0
@@ -87,28 +87,35 @@
87
87
  ],
88
88
  "best_practices": [
89
89
  "CRITICAL: Claude Code permanently retains ALL file contents - no memory release possible",
90
- "TOP PRIORITY: Use mcp__mcp-vector-search__search_code for semantic pattern discovery",
91
- "FIRST PRIORITY: Use mcp__claude-mpm-gateway__document_summarizer for ALL files >20KB",
92
- "SECOND PRIORITY: Use mcp__mcp-vector-search__search_similar to find related code patterns",
93
- "THIRD PRIORITY: Use mcp__mcp-vector-search__search_context for understanding functionality",
94
- "LAST RESORT: Read tool ONLY for files <20KB when other tools unavailable",
95
- "Always index project first with mcp__mcp-vector-search__index_project if not indexed",
96
- "Use mcp__mcp-vector-search__get_project_status to check indexing status",
97
- "Extract key patterns from 3-5 representative files ABSOLUTE MAXIMUM",
98
- "NEVER exceed 5 files even if task requests 'thorough' or 'complete' analysis",
99
- "Leverage vector search for finding similar implementations and patterns",
100
- "Use grep with line numbers (-n) only when vector search unavailable",
101
- "MANDATORY: Leverage MCP summarizer tool for files exceeding 20KB thresholds",
102
- "Trigger summarization at 20KB or 200 lines for single files",
103
- "Apply batch summarization after 3 files or 50KB cumulative content",
104
- "Use file type-specific thresholds for optimal processing",
105
- "Process files sequentially to prevent memory accumulation",
106
- "Check file sizes BEFORE reading - NEVER read files >1MB, use vector search instead",
107
- "Reset cumulative counters after batch summarization",
108
- "Extract and summarize patterns immediately (behavioral guidance only - memory persists)",
109
- "Review file commit history before modifications: git log --oneline -5 <file_path>",
110
- "Write succinct commit messages explaining WHAT changed and WHY",
111
- "Follow conventional commits format: feat/fix/docs/refactor/perf/test/chore"
90
+ "TOOL AVAILABILITY: Check if mcp-vector-search tools are available before use",
91
+ "IF VECTOR SEARCH AVAILABLE:",
92
+ " - TOP PRIORITY: Use mcp__mcp-vector-search__search_code for semantic pattern discovery",
93
+ " - SECOND PRIORITY: Use mcp__mcp-vector-search__search_similar to find related code patterns",
94
+ " - THIRD PRIORITY: Use mcp__mcp-vector-search__search_context for understanding functionality",
95
+ " - Always index project first with mcp__mcp-vector-search__index_project if not indexed",
96
+ " - Use mcp__mcp-vector-search__get_project_status to check indexing status",
97
+ " - Leverage vector search for finding similar implementations and patterns",
98
+ "IF VECTOR SEARCH UNAVAILABLE:",
99
+ " - PRIMARY: Use Grep tool with pattern matching for code search",
100
+ " - SECONDARY: Use Glob tool for file discovery by pattern",
101
+ " - CONTEXT: Use grep with -A/-B flags for contextual code understanding",
102
+ " - ADAPTIVE: Adjust grep context based on matches (>50: -A 2 -B 2, <20: -A 10 -B 10)",
103
+ "UNIVERSAL BEST PRACTICES (always apply):",
104
+ " - FIRST PRIORITY: Use mcp__claude-mpm-gateway__document_summarizer for ALL files >20KB",
105
+ " - LAST RESORT: Read tool ONLY for files <20KB when other tools unavailable",
106
+ " - Extract key patterns from 3-5 representative files ABSOLUTE MAXIMUM",
107
+ " - NEVER exceed 5 files even if task requests 'thorough' or 'complete' analysis",
108
+ " - MANDATORY: Leverage MCP summarizer tool for files exceeding 20KB thresholds",
109
+ " - Trigger summarization at 20KB or 200 lines for single files",
110
+ " - Apply batch summarization after 3 files or 50KB cumulative content",
111
+ " - Use file type-specific thresholds for optimal processing",
112
+ " - Process files sequentially to prevent memory accumulation",
113
+ " - Check file sizes BEFORE reading - NEVER read files >1MB",
114
+ " - Reset cumulative counters after batch summarization",
115
+ " - Extract and summarize patterns immediately (behavioral guidance only - memory persists)",
116
+ " - Review file commit history before modifications: git log --oneline -5 <file_path>",
117
+ " - Write succinct commit messages explaining WHAT changed and WHY",
118
+ " - Follow conventional commits format: feat/fix/docs/refactor/perf/test/chore"
112
119
  ],
113
120
  "constraints": [
114
121
  "PERMANENT MEMORY: Claude Code retains ALL file contents permanently - no release mechanism exists",
@@ -128,7 +135,7 @@
128
135
  "PREFER mcp__claude-mpm-gateway__document_summarizer over Read tool in ALL cases >20KB"
129
136
  ]
130
137
  },
131
- "instructions": "You are an expert research analyst with deep expertise in codebase investigation, architectural analysis, and system understanding. Your approach combines systematic methodology with efficient resource management to deliver comprehensive insights while maintaining strict memory discipline.\n\n**Core Responsibilities:**\n\nYou will investigate and analyze systems with focus on:\n- Comprehensive codebase exploration and pattern identification\n- Architectural analysis and system boundary mapping\n- Technology stack assessment and dependency analysis\n- Security posture evaluation and vulnerability identification\n- Performance characteristics and bottleneck analysis\n- Code quality metrics and technical debt assessment\n\n**Research Methodology:**\n\nWhen conducting analysis, you will:\n\n1. **Plan Investigation Strategy**: Systematically approach research by:\n - Checking project indexing status with mcp__mcp-vector-search__get_project_status\n - Running mcp__mcp-vector-search__index_project if needed for initial indexing\n - Defining clear research objectives and scope boundaries\n - Prioritizing critical components and high-impact areas\n - Selecting appropriate tools and techniques for discovery\n - Establishing memory-efficient sampling strategies\n\n2. **Execute Strategic Discovery**: Conduct analysis using:\n - Semantic search with mcp__mcp-vector-search__search_code for pattern discovery\n - Similarity analysis with mcp__mcp-vector-search__search_similar for related code\n - Context search with mcp__mcp-vector-search__search_context for functionality understanding\n - Pattern-based search techniques to identify key components\n - Architectural mapping through dependency analysis\n - Representative sampling of critical system components\n - Progressive refinement of understanding through iterations\n\n3. **Analyze Findings**: Process discovered information by:\n - Extracting meaningful patterns from code structures\n - Identifying architectural decisions and design principles\n - Documenting system boundaries and interaction patterns\n - Assessing technical debt and improvement opportunities\n\n4. **Synthesize Insights**: Create comprehensive understanding through:\n - Connecting disparate findings into coherent system view\n - Identifying risks, opportunities, and recommendations\n - Documenting key insights and architectural decisions\n - Providing actionable recommendations for improvement\n\n**Memory Management Excellence:**\n\nYou will maintain strict memory discipline through:\n- Prioritizing mcp-vector-search tools to avoid loading files into memory\n- Strategic sampling of representative components (maximum 3-5 files per session)\n- Preference for semantic search over traditional file reading\n- Mandatory use of document summarization for files exceeding 20KB\n- Sequential processing to prevent memory accumulation\n- Immediate extraction and summarization of key insights\n\n**Research Focus Areas:**\n\n**Architectural Analysis:**\n- System design patterns and architectural decisions\n- Service boundaries and interaction mechanisms\n- Data flow patterns and processing pipelines\n- Integration points and external dependencies\n\n**Code Quality Assessment:**\n- Design pattern usage and code organization\n- Technical debt identification and quantification\n- Security vulnerability assessment\n- Performance bottleneck identification\n\n**Technology Evaluation:**\n- Framework and library usage patterns\n- Configuration management approaches\n- Development and deployment practices\n- Tooling and automation strategies\n\n**Communication Style:**\n\nWhen presenting research findings, you will:\n- Provide clear, structured analysis with supporting evidence\n- Highlight key insights and their implications\n- Recommend specific actions based on discovered patterns\n- Document assumptions and limitations of the analysis\n- Present findings in actionable, prioritized format\n\n**Research Standards:**\n\nYou will maintain high standards through:\n- Systematic approach to investigation and analysis\n- Evidence-based conclusions with clear supporting data\n- Comprehensive documentation of methodology and findings\n- Regular validation of assumptions against discovered evidence\n- Clear separation of facts, inferences, and recommendations\n\nYour goal is to provide comprehensive, accurate, and actionable insights that enable informed decision-making about system architecture, code quality, and technical strategy while maintaining exceptional memory efficiency throughout the research process.",
138
+ "instructions": "You are an expert research analyst with deep expertise in codebase investigation, architectural analysis, and system understanding. Your approach combines systematic methodology with efficient resource management to deliver comprehensive insights while maintaining strict memory discipline.\n\n**Core Responsibilities:**\n\nYou will investigate and analyze systems with focus on:\n- Comprehensive codebase exploration and pattern identification\n- Architectural analysis and system boundary mapping\n- Technology stack assessment and dependency analysis\n- Security posture evaluation and vulnerability identification\n- Performance characteristics and bottleneck analysis\n- Code quality metrics and technical debt assessment\n\n**Research Methodology:**\n\nWhen conducting analysis, you will:\n\n1. **Plan Investigation Strategy**: Systematically approach research by:\n - Checking tool availability (vector search vs grep/glob fallback)\n - IF vector search available: Check indexing status with mcp__mcp-vector-search__get_project_status\n - IF vector search available AND not indexed: Run mcp__mcp-vector-search__index_project\n - IF vector search unavailable: Plan grep/glob pattern-based search strategy\n - Defining clear research objectives and scope boundaries\n - Prioritizing critical components and high-impact areas\n - Selecting appropriate tools based on availability\n - Establishing memory-efficient sampling strategies\n\n2. **Execute Strategic Discovery**: Conduct analysis using available tools:\n\n **WITH VECTOR SEARCH (preferred when available):**\n - Semantic search with mcp__mcp-vector-search__search_code for pattern discovery\n - Similarity analysis with mcp__mcp-vector-search__search_similar for related code\n - Context search with mcp__mcp-vector-search__search_context for functionality understanding\n\n **WITHOUT VECTOR SEARCH (graceful fallback):**\n - Pattern-based search with Grep tool for code discovery\n - File discovery with Glob tool using patterns like \"**/*.py\" or \"src/**/*.ts\"\n - Contextual understanding with grep -A/-B flags for surrounding code\n - Adaptive context: >50 matches use -A 2 -B 2, <20 matches use -A 10 -B 10\n\n **UNIVERSAL TECHNIQUES (always available):**\n - Pattern-based search techniques to identify key components\n - Architectural mapping through dependency analysis\n - Representative sampling of critical system components (3-5 files maximum)\n - Progressive refinement of understanding through iterations\n - MCP document summarizer for files >20KB\n\n3. **Analyze Findings**: Process discovered information by:\n - Extracting meaningful patterns from code structures\n - Identifying architectural decisions and design principles\n - Documenting system boundaries and interaction patterns\n - Assessing technical debt and improvement opportunities\n\n4. **Synthesize Insights**: Create comprehensive understanding through:\n - Connecting disparate findings into coherent system view\n - Identifying risks, opportunities, and recommendations\n - Documenting key insights and architectural decisions\n - Providing actionable recommendations for improvement\n\n**Memory Management Excellence:**\n\nYou will maintain strict memory discipline through:\n- Prioritizing search tools (vector search OR grep/glob) to avoid loading files into memory\n- Using vector search when available for semantic understanding without file loading\n- Using grep/glob as fallback when vector search is unavailable\n- Strategic sampling of representative components (maximum 3-5 files per session)\n- Preference for search tools over direct file reading\n- Mandatory use of document summarization for files exceeding 20KB\n- Sequential processing to prevent memory accumulation\n- Immediate extraction and summarization of key insights\n\n**Tool Availability and Graceful Degradation:**\n\nYou will adapt your approach based on available tools:\n- Check if mcp-vector-search tools are available in your tool set\n- If available: Use semantic search capabilities for efficient pattern discovery\n- If unavailable: Gracefully fall back to grep/glob for pattern-based search\n- Never fail a task due to missing optional tools - adapt your strategy\n- Inform the user if falling back to alternative search methods\n- Maintain same quality of analysis regardless of tool availability\n\n**Research Focus Areas:**\n\n**Architectural Analysis:**\n- System design patterns and architectural decisions\n- Service boundaries and interaction mechanisms\n- Data flow patterns and processing pipelines\n- Integration points and external dependencies\n\n**Code Quality Assessment:**\n- Design pattern usage and code organization\n- Technical debt identification and quantification\n- Security vulnerability assessment\n- Performance bottleneck identification\n\n**Technology Evaluation:**\n- Framework and library usage patterns\n- Configuration management approaches\n- Development and deployment practices\n- Tooling and automation strategies\n\n**Communication Style:**\n\nWhen presenting research findings, you will:\n- Provide clear, structured analysis with supporting evidence\n- Highlight key insights and their implications\n- Recommend specific actions based on discovered patterns\n- Document assumptions and limitations of the analysis\n- Present findings in actionable, prioritized format\n\n**Research Standards:**\n\nYou will maintain high standards through:\n- Systematic approach to investigation and analysis\n- Evidence-based conclusions with clear supporting data\n- Comprehensive documentation of methodology and findings\n- Regular validation of assumptions against discovered evidence\n- Clear separation of facts, inferences, and recommendations\n\nYour goal is to provide comprehensive, accurate, and actionable insights that enable informed decision-making about system architecture, code quality, and technical strategy while maintaining exceptional memory efficiency throughout the research process.",
132
139
  "memory_routing": {
133
140
  "description": "Stores analysis findings, domain knowledge, and architectural decisions",
134
141
  "categories": [
@@ -16,8 +16,7 @@ from rich.panel import Panel
16
16
  from rich.syntax import Syntax
17
17
  from rich.table import Table
18
18
 
19
- from claude_mpm.cli.utils import handle_async_errors
20
- from claude_mpm.services.service_container import get_service_container
19
+ from claude_mpm.services.core.service_container import get_global_container
21
20
 
22
21
  console = Console()
23
22
 
@@ -27,8 +26,9 @@ class MCPSearchInterface:
27
26
 
28
27
  def __init__(self):
29
28
  """Initialize the search interface."""
30
- self.container = get_service_container()
29
+ self.container = get_global_container()
31
30
  self.mcp_gateway = None
31
+ self.vector_search_available = False
32
32
 
33
33
  async def initialize(self):
34
34
  """Initialize the MCP gateway connection."""
@@ -39,10 +39,127 @@ class MCPSearchInterface:
39
39
  if not self.mcp_gateway:
40
40
  self.mcp_gateway = MCPGatewayService()
41
41
  await self.mcp_gateway.initialize()
42
+
43
+ # Check if vector search is available
44
+ self.vector_search_available = await self._check_vector_search_available()
45
+
42
46
  except Exception as e:
43
47
  console.print(f"[red]Failed to initialize MCP gateway: {e}[/red]")
44
48
  raise
45
49
 
50
+ async def _check_vector_search_available(self) -> bool:
51
+ """Check if mcp-vector-search is available and offer installation if not."""
52
+ import importlib.util
53
+
54
+ # Check if package is installed
55
+ spec = importlib.util.find_spec("mcp_vector_search")
56
+ if spec is not None:
57
+ return True
58
+
59
+ # Package not found - offer installation
60
+ console.print("\n[yellow]⚠️ mcp-vector-search not found[/yellow]")
61
+ console.print("This package enables semantic code search (optional feature).")
62
+ console.print("\nInstallation options:")
63
+ console.print(" 1. Install via pip (recommended for this project)")
64
+ console.print(" 2. Install via pipx (isolated, system-wide)")
65
+ console.print(" 3. Skip (use traditional grep/glob instead)")
66
+
67
+ try:
68
+ choice = input("\nChoose option (1/2/3) [3]: ").strip() or "3"
69
+
70
+ if choice == "1":
71
+ return await self._install_via_pip()
72
+ if choice == "2":
73
+ return await self._install_via_pipx()
74
+ console.print(
75
+ "[dim]Continuing with fallback search methods (grep/glob)[/dim]"
76
+ )
77
+ return False
78
+
79
+ except (EOFError, KeyboardInterrupt):
80
+ console.print("\n[dim]Installation cancelled, using fallback methods[/dim]")
81
+ return False
82
+
83
+ async def _install_via_pip(self) -> bool:
84
+ """Install mcp-vector-search via pip."""
85
+ import subprocess
86
+
87
+ try:
88
+ console.print("\n[cyan]📦 Installing mcp-vector-search via pip...[/cyan]")
89
+ result = subprocess.run(
90
+ [sys.executable, "-m", "pip", "install", "mcp-vector-search"],
91
+ capture_output=True,
92
+ text=True,
93
+ timeout=120,
94
+ check=False,
95
+ )
96
+
97
+ if result.returncode == 0:
98
+ console.print(
99
+ "[green]✓ Successfully installed mcp-vector-search[/green]"
100
+ )
101
+ return True
102
+
103
+ error_msg = result.stderr.strip() if result.stderr else "Unknown error"
104
+ console.print(f"[red]✗ Installation failed: {error_msg}[/red]")
105
+ return False
106
+
107
+ except subprocess.TimeoutExpired:
108
+ console.print("[red]✗ Installation timed out[/red]")
109
+ return False
110
+ except Exception as e:
111
+ console.print(f"[red]✗ Installation error: {e}[/red]")
112
+ return False
113
+
114
+ async def _install_via_pipx(self) -> bool:
115
+ """Install mcp-vector-search via pipx."""
116
+ import subprocess
117
+
118
+ try:
119
+ # Check if pipx is available
120
+ pipx_check = subprocess.run(
121
+ ["pipx", "--version"],
122
+ capture_output=True,
123
+ text=True,
124
+ timeout=5,
125
+ check=False,
126
+ )
127
+
128
+ if pipx_check.returncode != 0:
129
+ console.print("[red]✗ pipx is not installed[/red]")
130
+ console.print("Install pipx first: python -m pip install pipx")
131
+ return False
132
+
133
+ console.print("\n[cyan]📦 Installing mcp-vector-search via pipx...[/cyan]")
134
+ result = subprocess.run(
135
+ ["pipx", "install", "mcp-vector-search"],
136
+ capture_output=True,
137
+ text=True,
138
+ timeout=120,
139
+ check=False,
140
+ )
141
+
142
+ if result.returncode == 0:
143
+ console.print(
144
+ "[green]✓ Successfully installed mcp-vector-search[/green]"
145
+ )
146
+ return True
147
+
148
+ error_msg = result.stderr.strip() if result.stderr else "Unknown error"
149
+ console.print(f"[red]✗ Installation failed: {error_msg}[/red]")
150
+ return False
151
+
152
+ except FileNotFoundError:
153
+ console.print("[red]✗ pipx command not found[/red]")
154
+ console.print("Install pipx first: python -m pip install pipx")
155
+ return False
156
+ except subprocess.TimeoutExpired:
157
+ console.print("[red]✗ Installation timed out[/red]")
158
+ return False
159
+ except Exception as e:
160
+ console.print(f"[red]✗ Installation error: {e}[/red]")
161
+ return False
162
+
46
163
  async def search_code(
47
164
  self,
48
165
  query: str,
@@ -125,6 +242,12 @@ class MCPSearchInterface:
125
242
  if not self.mcp_gateway:
126
243
  await self.initialize()
127
244
 
245
+ # Check if vector search is available
246
+ if not self.vector_search_available:
247
+ return {
248
+ "error": "mcp-vector-search is not available. Use traditional grep/glob tools instead, or run command again to install."
249
+ }
250
+
128
251
  try:
129
252
  return await self.mcp_gateway.call_tool(tool_name, params)
130
253
  except Exception as e:
@@ -196,7 +319,6 @@ def display_search_results(results: Dict[str, Any], output_format: str = "rich")
196
319
  @click.option("--focus", multiple=True, help="Focus areas (with --context)")
197
320
  @click.option("--force", is_flag=True, help="Force reindexing (with --index)")
198
321
  @click.option("--json", "output_json", is_flag=True, help="Output results as JSON")
199
- @handle_async_errors
200
322
  async def search_command(
201
323
  query: Optional[str],
202
324
  similar: Optional[str],
@@ -228,8 +350,24 @@ async def search_command(
228
350
  output_format = "json" if output_json else "rich"
229
351
 
230
352
  try:
353
+ # Show first-time usage tips if vector search is available
354
+ if search.vector_search_available and not (index or status):
355
+ console.print(
356
+ "\n[dim]💡 Tip: Vector search provides semantic code understanding.[/dim]"
357
+ )
358
+ console.print(
359
+ "[dim] Run with --index first to index your project.[/dim]\n"
360
+ )
361
+
231
362
  # Handle different operation modes
232
363
  if index:
364
+ if not search.vector_search_available:
365
+ console.print("[red]✗ mcp-vector-search is required for indexing[/red]")
366
+ console.print(
367
+ "[dim]Install it or use traditional grep/glob for search[/dim]"
368
+ )
369
+ sys.exit(1)
370
+
233
371
  console.print("[cyan]Indexing project...[/cyan]")
234
372
  result = await search.index_project(
235
373
  force=force, file_extensions=list(extensions) if extensions else None
@@ -239,10 +377,23 @@ async def search_command(
239
377
  display_search_results(result, output_format)
240
378
 
241
379
  elif status:
380
+ if not search.vector_search_available:
381
+ console.print(
382
+ "[red]✗ mcp-vector-search is required for status check[/red]"
383
+ )
384
+ console.print("[dim]Install it to use vector search features[/dim]")
385
+ sys.exit(1)
386
+
242
387
  result = await search.get_status()
243
388
  display_search_results(result, output_format)
244
389
 
245
390
  elif similar:
391
+ if not search.vector_search_available:
392
+ console.print("[yellow]⚠️ Vector search not available[/yellow]")
393
+ console.print("[dim]Similarity search requires mcp-vector-search[/dim]")
394
+ console.print("[dim]Falling back to basic file search...[/dim]")
395
+ sys.exit(1)
396
+
246
397
  result = await search.search_similar(
247
398
  file_path=similar,
248
399
  function_name=function,
@@ -252,6 +403,12 @@ async def search_command(
252
403
  display_search_results(result, output_format)
253
404
 
254
405
  elif context:
406
+ if not search.vector_search_available:
407
+ console.print("[yellow]⚠️ Vector search not available[/yellow]")
408
+ console.print("[dim]Context search requires mcp-vector-search[/dim]")
409
+ console.print("[dim]Try using grep for text-based search instead[/dim]")
410
+ sys.exit(1)
411
+
255
412
  result = await search.search_context(
256
413
  description=context,
257
414
  focus_areas=list(focus) if focus else None,
@@ -260,6 +417,15 @@ async def search_command(
260
417
  display_search_results(result, output_format)
261
418
 
262
419
  elif query:
420
+ if not search.vector_search_available:
421
+ console.print("[yellow]⚠️ Vector search not available[/yellow]")
422
+ console.print("[dim]Code search requires mcp-vector-search[/dim]")
423
+ console.print(
424
+ "\n[cyan]Alternative: Use grep for pattern matching:[/cyan]"
425
+ )
426
+ console.print(f" grep -r '{query}' .")
427
+ sys.exit(1)
428
+
263
429
  result = await search.search_code(
264
430
  query=query,
265
431
  limit=limit,
@@ -323,6 +323,27 @@ class MCPGatewayOrchestrator:
323
323
  except Exception as e:
324
324
  self.logger.warning(f"Could not load KuzuMemoryService: {e}")
325
325
 
326
+ # MCP Vector Search Service (optional - will auto-install on first use)
327
+ try:
328
+ from .tools.external_mcp_services import MCPVectorSearchService
329
+
330
+ vector_search = MCPVectorSearchService()
331
+ # Try to initialize without interactive prompts during gateway startup
332
+ # This will only succeed if already installed
333
+ init_success = await vector_search.initialize(
334
+ auto_install=False, interactive=False
335
+ )
336
+
337
+ if init_success:
338
+ tools.append(vector_search)
339
+ self.logger.info("MCPVectorSearchService added to built-in tools")
340
+ else:
341
+ self.logger.debug(
342
+ "mcp-vector-search not installed - will be available via auto-install on first use"
343
+ )
344
+ except Exception as e:
345
+ self.logger.debug(f"Could not load MCPVectorSearchService: {e}")
346
+
326
347
  # Ticket tools removed - mcp-ticketer provides ticket functionality
327
348
 
328
349
  if not tools:
@@ -64,21 +64,28 @@ class ExternalMCPService(BaseToolAdapter):
64
64
  execution_time=0.0,
65
65
  )
66
66
 
67
- async def initialize(self) -> bool:
68
- """Initialize the external service."""
67
+ async def initialize(
68
+ self, auto_install: bool = True, interactive: bool = True
69
+ ) -> bool:
70
+ """Initialize the external service.
71
+
72
+ Args:
73
+ auto_install: Whether to automatically install if not found
74
+ interactive: Whether to prompt user for installation preferences
75
+ """
69
76
  try:
70
77
  # Check if package is installed
71
78
  self._is_installed = await self._check_installation()
72
79
 
73
- if not self._is_installed:
74
- self.logger.debug(
75
- f"{self.package_name} not installed - will attempt automatic installation if needed"
80
+ if not self._is_installed and auto_install:
81
+ self.logger.info(
82
+ f"{self.package_name} not installed - attempting installation"
76
83
  )
77
- await self._install_package()
84
+ await self._install_package(interactive=interactive)
78
85
  self._is_installed = await self._check_installation()
79
86
 
80
87
  if not self._is_installed:
81
- self.logger.error(f"Failed to install {self.package_name}")
88
+ self.logger.warning(f"{self.package_name} is not available")
82
89
  return False
83
90
 
84
91
  self.logger.info(f"{self.package_name} is available")
@@ -90,9 +97,21 @@ class ExternalMCPService(BaseToolAdapter):
90
97
 
91
98
  async def _check_installation(self) -> bool:
92
99
  """Check if the package is installed."""
100
+ # First check if importable (faster and more reliable)
101
+ import_name = self.package_name.replace("-", "_")
102
+ try:
103
+ import importlib.util
104
+
105
+ spec = importlib.util.find_spec(import_name)
106
+ if spec is not None:
107
+ return True
108
+ except (ImportError, ModuleNotFoundError, ValueError):
109
+ pass
110
+
111
+ # Fallback: try running as module
93
112
  try:
94
113
  result = subprocess.run(
95
- [sys.executable, "-m", self.package_name.replace("-", "_"), "--help"],
114
+ [sys.executable, "-m", import_name, "--help"],
96
115
  capture_output=True,
97
116
  text=True,
98
117
  timeout=5,
@@ -106,25 +125,133 @@ class ExternalMCPService(BaseToolAdapter):
106
125
  ):
107
126
  return False
108
127
 
109
- async def _install_package(self) -> bool:
110
- """Install the package using pip."""
128
+ async def _install_package(self, interactive: bool = True) -> bool:
129
+ """Install the package using pip or pipx.
130
+
131
+ Args:
132
+ interactive: Whether to prompt user for installation method choice
133
+ """
111
134
  try:
112
- self.logger.info(f"Installing {self.package_name}...")
135
+ install_method = None
136
+
137
+ if interactive:
138
+ # Show user-friendly installation prompt
139
+ print(f"\n⚠️ {self.package_name} not found")
140
+ print("This package enables enhanced functionality (optional).")
141
+ print("\nInstallation options:")
142
+ print("1. Install via pip (recommended for this project)")
143
+ print("2. Install via pipx (isolated, system-wide)")
144
+ print("3. Skip (continue without this package)")
145
+
146
+ try:
147
+ choice = input("\nChoose option (1/2/3) [1]: ").strip() or "1"
148
+ if choice == "1":
149
+ install_method = "pip"
150
+ elif choice == "2":
151
+ install_method = "pipx"
152
+ else:
153
+ self.logger.info(
154
+ f"Skipping installation of {self.package_name}"
155
+ )
156
+ return False
157
+ except (EOFError, KeyboardInterrupt):
158
+ print("\nInstallation cancelled")
159
+ return False
160
+ else:
161
+ # Non-interactive: default to pip
162
+ install_method = "pip"
163
+
164
+ # Install using selected method
165
+ if install_method == "pip":
166
+ return await self._install_via_pip()
167
+ if install_method == "pipx":
168
+ return await self._install_via_pipx()
169
+
170
+ return False
171
+
172
+ except Exception as e:
173
+ self.logger.error(f"Error installing {self.package_name}: {e}")
174
+ return False
175
+
176
+ async def _install_via_pip(self) -> bool:
177
+ """Install package via pip."""
178
+ try:
179
+ print(f"\n📦 Installing {self.package_name} via pip...")
113
180
  result = subprocess.run(
114
181
  [sys.executable, "-m", "pip", "install", self.package_name],
115
182
  capture_output=True,
116
183
  text=True,
117
- timeout=30,
184
+ timeout=120,
118
185
  check=False,
119
186
  )
120
187
 
121
188
  if result.returncode == 0:
122
- self.logger.info(f"Successfully installed {self.package_name}")
189
+ print(f"Successfully installed {self.package_name}")
190
+ self.logger.info(f"Successfully installed {self.package_name} via pip")
123
191
  return True
124
- self.logger.error(f"Failed to install {self.package_name}: {result.stderr}")
192
+
193
+ error_msg = result.stderr.strip() if result.stderr else "Unknown error"
194
+ print(f"✗ Installation failed: {error_msg}")
195
+ self.logger.error(f"Failed to install {self.package_name}: {error_msg}")
125
196
  return False
126
197
 
198
+ except subprocess.TimeoutExpired:
199
+ print("✗ Installation timed out")
200
+ self.logger.error(f"Installation of {self.package_name} timed out")
201
+ return False
202
+ except Exception as e:
203
+ print(f"✗ Installation error: {e}")
204
+ self.logger.error(f"Error installing {self.package_name}: {e}")
205
+ return False
206
+
207
+ async def _install_via_pipx(self) -> bool:
208
+ """Install package via pipx."""
209
+ try:
210
+ # Check if pipx is available
211
+ pipx_check = subprocess.run(
212
+ ["pipx", "--version"],
213
+ capture_output=True,
214
+ text=True,
215
+ timeout=5,
216
+ check=False,
217
+ )
218
+
219
+ if pipx_check.returncode != 0:
220
+ print("✗ pipx is not installed")
221
+ print("Install pipx first: python -m pip install pipx")
222
+ self.logger.error("pipx not available for installation")
223
+ return False
224
+
225
+ print(f"\n📦 Installing {self.package_name} via pipx...")
226
+ result = subprocess.run(
227
+ ["pipx", "install", self.package_name],
228
+ capture_output=True,
229
+ text=True,
230
+ timeout=120,
231
+ check=False,
232
+ )
233
+
234
+ if result.returncode == 0:
235
+ print(f"✓ Successfully installed {self.package_name}")
236
+ self.logger.info(f"Successfully installed {self.package_name} via pipx")
237
+ return True
238
+
239
+ error_msg = result.stderr.strip() if result.stderr else "Unknown error"
240
+ print(f"✗ Installation failed: {error_msg}")
241
+ self.logger.error(f"Failed to install {self.package_name}: {error_msg}")
242
+ return False
243
+
244
+ except FileNotFoundError:
245
+ print("✗ pipx command not found")
246
+ print("Install pipx first: python -m pip install pipx")
247
+ self.logger.error("pipx command not found")
248
+ return False
249
+ except subprocess.TimeoutExpired:
250
+ print("✗ Installation timed out")
251
+ self.logger.error(f"Installation of {self.package_name} timed out")
252
+ return False
127
253
  except Exception as e:
254
+ print(f"✗ Installation error: {e}")
128
255
  self.logger.error(f"Error installing {self.package_name}: {e}")
129
256
  return False
130
257
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-mpm
3
- Version: 4.9.0
3
+ Version: 4.10.0
4
4
  Summary: Claude Multi-Agent Project Manager - Orchestrate Claude with agent delegation and ticket tracking
5
5
  Author-email: Bob Matsuoka <bob@matsuoka.com>
6
6
  Maintainer: Claude MPM Team
@@ -160,7 +160,8 @@ A powerful orchestration framework for **Claude Code (CLI)** that enables multi-
160
160
  - 🧠 **Persistent Knowledge System**: Project-specific kuzu-memory integration for intelligent context retention
161
161
  - 🔄 **Session Management**: Resume previous sessions with `--resume`
162
162
  - 📊 **Real-Time Monitoring**: Live dashboard with `--monitor` flag
163
- - 🔌 **Optional MCP Services**: mcp-vector-search and kuzu-memory with automatic fallback installation
163
+ - 🔌 **Smart MCP Services**: Interactive auto-install for mcp-vector-search on first use (pip/pipx choice)
164
+ - 🔍 **Semantic Code Search**: Optional vector search with graceful fallback to grep/glob
164
165
  - 📁 **Multi-Project Support**: Per-session working directories with persistent knowledge graphs
165
166
  - 🔍 **Git Integration**: View diffs and track changes across projects
166
167
  - 🎯 **Smart Task Orchestration**: PM agent intelligently routes work to specialists
@@ -197,7 +198,8 @@ claude-mpm mcp-pipx-config
197
198
  - `[monitor]` - Full monitoring dashboard with Socket.IO and async web server components
198
199
  - **Combine both**: Use `"claude-mpm[mcp,monitor]"` to install all features
199
200
  - **Note**: kuzu-memory is now a required dependency, always included with Claude MPM
200
- - Without optional MCP dependencies, other MCP services auto-install on first use via pipx
201
+ - **Auto-Install**: mcp-vector-search offers interactive installation on first use (pip/pipx choice)
202
+ - Without pre-installed MCP dependencies, services install on-demand with user confirmation
201
203
 
202
204
  **🎉 Pipx Support Now Fully Functional!** Recent improvements ensure complete compatibility:
203
205
  - ✅ Socket.IO daemon script path resolution (fixed)
@@ -216,6 +218,11 @@ claude-mpm
216
218
  # Start with monitoring dashboard
217
219
  claude-mpm run --monitor
218
220
 
221
+ # Use semantic code search (auto-installs mcp-vector-search on first use)
222
+ claude-mpm search "authentication logic"
223
+ # or inside Claude Code session:
224
+ /mpm-search "authentication logic"
225
+
219
226
  # Use MCP Gateway for external tool integration
220
227
  claude-mpm mcp
221
228
 
@@ -1,5 +1,5 @@
1
1
  claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
2
- claude_mpm/VERSION,sha256=ucY14U7h_QVbv4d5sg77hbXv8X1m3zQsRzVoMpc3MXY,6
2
+ claude_mpm/VERSION,sha256=9StPgaDGDNmI-MzJoDM-IGtffkHdD1KGxqtfe_LVM18,7
3
3
  claude_mpm/__init__.py,sha256=UCw6j9e_tZQ3kJtTqmdfNv7MHyw9nD1jkj80WurwM2g,2064
4
4
  claude_mpm/__main__.py,sha256=Ro5UBWBoQaSAIoSqWAr7zkbLyvi4sSy28WShqAhKJG0,723
5
5
  claude_mpm/constants.py,sha256=sLjJF6Kw7H4V9WWeaEYltM-77TgXqzEMX5vx4ukM5-0,5977
@@ -54,7 +54,7 @@ claude_mpm/agents/templates/python_engineer.json,sha256=SeTvI1EXS-RTIJzVHX0zu0FS
54
54
  claude_mpm/agents/templates/qa.json,sha256=bccjpuC93a7msGei3LKsCe88UiFMQzk1W40TvEYIHOg,10661
55
55
  claude_mpm/agents/templates/react_engineer.json,sha256=ihmqRAgiU81UVpw3ToSHvUigEZ7MMpoPhUbyXSmfbAo,13151
56
56
  claude_mpm/agents/templates/refactoring_engineer.json,sha256=qmhZdl4aXNyQEjZ-yieSa2NfEaPPi7Z4bYUZ4ohWJiI,12130
57
- claude_mpm/agents/templates/research.json,sha256=0i0FsMT13cQvynOXdtcWuVMrpFtV560Grr2N3mXUOvI,12406
57
+ claude_mpm/agents/templates/research.json,sha256=-U7cDwH0kiffMSvrAuIe_AiA6OmWQbI5MLNjgvUhmhc,14336
58
58
  claude_mpm/agents/templates/ruby-engineer.json,sha256=FDdEGTbXzzAwbeucXH9Ve91mCnD9fGh3J26zbrKi9qs,12412
59
59
  claude_mpm/agents/templates/rust_engineer.json,sha256=0HKDrRGJxyvO5GWqby8d45Trw9IaAoJkeX5ZIkN10xE,12317
60
60
  claude_mpm/agents/templates/security.json,sha256=ekwiFj-TzVDTEj70QfV5Oix1x7zAeCdl-zZ8-QGJIXg,24556
@@ -103,7 +103,7 @@ claude_mpm/cli/commands/monitor.py,sha256=Fjb68hf3dEwTFek2LV8Nh6iU0qEkY7qYlOn32I
103
103
  claude_mpm/cli/commands/mpm_init.py,sha256=OtdJMsFn7E9Ck56wWPrCvqw6j5dsN_VI098C3bteitc,63888
104
104
  claude_mpm/cli/commands/mpm_init_handler.py,sha256=b1CSwZYJ89wMorKzPOKS-RVxOKR2kT9yv9KQLvKkd2U,3532
105
105
  claude_mpm/cli/commands/run.py,sha256=PB2H55piOPTy4yo4OBgbUCjMlcz9K79wbwpxQVc9m5Q,48225
106
- claude_mpm/cli/commands/search.py,sha256=_0qbUnop8v758MHsB0fAop8FVxwygD59tec_-iN7pLE,9806
106
+ claude_mpm/cli/commands/search.py,sha256=alv6udvKcn-xkqeBlLuPRvfSDV1yxEX4n9mjjRT5uLM,16581
107
107
  claude_mpm/cli/commands/tickets.py,sha256=kl2dklTBnG3Y4jUUJ_PcEVsTx4CtVJfkGWboWBx_mQM,21234
108
108
  claude_mpm/cli/commands/uninstall.py,sha256=KGlVG6veEs1efLVjrZ3wSty7e1zVR9wpt-VXQA1RzWw,5945
109
109
  claude_mpm/cli/commands/upgrade.py,sha256=NYMVONNlj78WHoQ6eyVInroE95AeQxUY2_TpjYFTdYE,5409
@@ -632,7 +632,7 @@ claude_mpm/services/infrastructure/monitoring/resources.py,sha256=7Mt9zvNAYGf7OT
632
632
  claude_mpm/services/infrastructure/monitoring/service.py,sha256=guYB6rJtU18T2kPhZbKKg85l96lm2f7XVtPnBt1O3So,12613
633
633
  claude_mpm/services/mcp_gateway/__init__.py,sha256=4fiMsd7i2QzZpEXCUeo0Vk_CXRi35TE94gPvwyuz2es,5099
634
634
  claude_mpm/services/mcp_gateway/auto_configure.py,sha256=JNos01nGb2qXACXNHC-UkLccqQ-p8GFUElXqBLUQl7A,12163
635
- claude_mpm/services/mcp_gateway/main.py,sha256=lczjLqieS5eHhwWO5VXlqURDLAgXgOg6i-724oa590A,18189
635
+ claude_mpm/services/mcp_gateway/main.py,sha256=1e_-NGwVNr8cFtwWC_2NhZS-EYwC--MSfiZTx15x3ao,19121
636
636
  claude_mpm/services/mcp_gateway/config/__init__.py,sha256=MpFgHfaT3dQz5QyEdpfbulD6tXUOY325LkovAYsdkAg,386
637
637
  claude_mpm/services/mcp_gateway/config/config_loader.py,sha256=jM0LCQGnyAezQHLqfLWtPn5P3GpGMxGltKlTIKCL24M,9427
638
638
  claude_mpm/services/mcp_gateway/config/config_schema.py,sha256=eSPyHmYJWBpGxJ8l0vBjEGod_PEnbGyHi3fcNLS4mH0,9475
@@ -654,7 +654,7 @@ claude_mpm/services/mcp_gateway/server/stdio_server.py,sha256=k_VHLZ17zdZzP6XOg6
654
654
  claude_mpm/services/mcp_gateway/tools/__init__.py,sha256=Ga0kbvNOi8peBRZk5MUnO5bo3jWDCpHFko7mO21Vix4,754
655
655
  claude_mpm/services/mcp_gateway/tools/base_adapter.py,sha256=na1MdyBCtVmKzgIcFJ5MuAUJ1LJrtA4yxkuqLnejiD8,16029
656
656
  claude_mpm/services/mcp_gateway/tools/document_summarizer.py,sha256=F86qgDIFW2UXljGV8Tx9CapypqnXFNu3qFvi8XHlcZg,28223
657
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py,sha256=PCw6egI7Vy7I-2l9ya9BZGusOdnQ3bY0uIJVSVnY_YA,18614
657
+ claude_mpm/services/mcp_gateway/tools/external_mcp_services.py,sha256=PSnes4mVOyAdqJ5o_YU9lmyTiXeXwXzE_x1pQeadpbs,23635
658
658
  claude_mpm/services/mcp_gateway/tools/health_check_tool.py,sha256=SIrGt2uZGR4EGsH2_0UgkmHUV895M8zq9suNkRSteRA,16457
659
659
  claude_mpm/services/mcp_gateway/tools/hello_world.py,sha256=L45ph8b0iLPpksrkf0ELrfl6CwVD3W3YLigwUKjIOoY,20291
660
660
  claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py,sha256=qc9vYJtN3OYXqb-aXZpkx3FtkM9ivUm9AcWKUgeGdG4,17745
@@ -797,9 +797,9 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
797
797
  claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
798
798
  claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
799
799
  claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
800
- claude_mpm-4.9.0.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
801
- claude_mpm-4.9.0.dist-info/METADATA,sha256=spXmDr3uBGSclzDSE5Clu2uTb4tQJ1bsMHcOpcf8r3Q,17584
802
- claude_mpm-4.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
803
- claude_mpm-4.9.0.dist-info/entry_points.txt,sha256=Vlw3GNi-OtTpKSrez04iNrPmxNxYDpIWxmJCxiZ5Tx8,526
804
- claude_mpm-4.9.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
805
- claude_mpm-4.9.0.dist-info/RECORD,,
800
+ claude_mpm-4.10.0.dist-info/licenses/LICENSE,sha256=lpaivOlPuBZW1ds05uQLJJswy8Rp_HMNieJEbFlqvLk,1072
801
+ claude_mpm-4.10.0.dist-info/METADATA,sha256=k0Zv4w5f9JRyt9zBPKr0C1Np9CetMfRascM9u-26Tgo,17967
802
+ claude_mpm-4.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
803
+ claude_mpm-4.10.0.dist-info/entry_points.txt,sha256=Vlw3GNi-OtTpKSrez04iNrPmxNxYDpIWxmJCxiZ5Tx8,526
804
+ claude_mpm-4.10.0.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
805
+ claude_mpm-4.10.0.dist-info/RECORD,,