mcp-vector-search 0.12.6__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.
Files changed (68) hide show
  1. mcp_vector_search/__init__.py +10 -0
  2. mcp_vector_search/cli/__init__.py +1 -0
  3. mcp_vector_search/cli/commands/__init__.py +1 -0
  4. mcp_vector_search/cli/commands/auto_index.py +397 -0
  5. mcp_vector_search/cli/commands/config.py +393 -0
  6. mcp_vector_search/cli/commands/demo.py +358 -0
  7. mcp_vector_search/cli/commands/index.py +744 -0
  8. mcp_vector_search/cli/commands/init.py +645 -0
  9. mcp_vector_search/cli/commands/install.py +675 -0
  10. mcp_vector_search/cli/commands/install_old.py +696 -0
  11. mcp_vector_search/cli/commands/mcp.py +1182 -0
  12. mcp_vector_search/cli/commands/reset.py +393 -0
  13. mcp_vector_search/cli/commands/search.py +773 -0
  14. mcp_vector_search/cli/commands/status.py +549 -0
  15. mcp_vector_search/cli/commands/uninstall.py +485 -0
  16. mcp_vector_search/cli/commands/visualize.py +1467 -0
  17. mcp_vector_search/cli/commands/watch.py +287 -0
  18. mcp_vector_search/cli/didyoumean.py +500 -0
  19. mcp_vector_search/cli/export.py +320 -0
  20. mcp_vector_search/cli/history.py +295 -0
  21. mcp_vector_search/cli/interactive.py +342 -0
  22. mcp_vector_search/cli/main.py +461 -0
  23. mcp_vector_search/cli/output.py +412 -0
  24. mcp_vector_search/cli/suggestions.py +375 -0
  25. mcp_vector_search/config/__init__.py +1 -0
  26. mcp_vector_search/config/constants.py +24 -0
  27. mcp_vector_search/config/defaults.py +200 -0
  28. mcp_vector_search/config/settings.py +134 -0
  29. mcp_vector_search/core/__init__.py +1 -0
  30. mcp_vector_search/core/auto_indexer.py +298 -0
  31. mcp_vector_search/core/connection_pool.py +360 -0
  32. mcp_vector_search/core/database.py +1214 -0
  33. mcp_vector_search/core/directory_index.py +318 -0
  34. mcp_vector_search/core/embeddings.py +294 -0
  35. mcp_vector_search/core/exceptions.py +89 -0
  36. mcp_vector_search/core/factory.py +318 -0
  37. mcp_vector_search/core/git_hooks.py +345 -0
  38. mcp_vector_search/core/indexer.py +1002 -0
  39. mcp_vector_search/core/models.py +294 -0
  40. mcp_vector_search/core/project.py +333 -0
  41. mcp_vector_search/core/scheduler.py +330 -0
  42. mcp_vector_search/core/search.py +952 -0
  43. mcp_vector_search/core/watcher.py +322 -0
  44. mcp_vector_search/mcp/__init__.py +5 -0
  45. mcp_vector_search/mcp/__main__.py +25 -0
  46. mcp_vector_search/mcp/server.py +733 -0
  47. mcp_vector_search/parsers/__init__.py +8 -0
  48. mcp_vector_search/parsers/base.py +296 -0
  49. mcp_vector_search/parsers/dart.py +605 -0
  50. mcp_vector_search/parsers/html.py +413 -0
  51. mcp_vector_search/parsers/javascript.py +643 -0
  52. mcp_vector_search/parsers/php.py +694 -0
  53. mcp_vector_search/parsers/python.py +502 -0
  54. mcp_vector_search/parsers/registry.py +223 -0
  55. mcp_vector_search/parsers/ruby.py +678 -0
  56. mcp_vector_search/parsers/text.py +186 -0
  57. mcp_vector_search/parsers/utils.py +265 -0
  58. mcp_vector_search/py.typed +1 -0
  59. mcp_vector_search/utils/__init__.py +40 -0
  60. mcp_vector_search/utils/gitignore.py +250 -0
  61. mcp_vector_search/utils/monorepo.py +277 -0
  62. mcp_vector_search/utils/timing.py +334 -0
  63. mcp_vector_search/utils/version.py +47 -0
  64. mcp_vector_search-0.12.6.dist-info/METADATA +754 -0
  65. mcp_vector_search-0.12.6.dist-info/RECORD +68 -0
  66. mcp_vector_search-0.12.6.dist-info/WHEEL +4 -0
  67. mcp_vector_search-0.12.6.dist-info/entry_points.txt +2 -0
  68. mcp_vector_search-0.12.6.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,675 @@
1
+ """Install and integration commands for MCP Vector Search CLI.
2
+
3
+ This module provides installation commands for:
4
+ 1. Project initialization (main command)
5
+ 2. Platform-specific MCP integrations (subcommands)
6
+
7
+ Examples:
8
+ # Install in current project
9
+ $ mcp-vector-search install
10
+
11
+ # Install Claude Code integration
12
+ $ mcp-vector-search install claude-code
13
+
14
+ # Install all available integrations
15
+ $ mcp-vector-search install --all
16
+ """
17
+
18
+ import asyncio
19
+ import json
20
+ import shutil
21
+ from pathlib import Path
22
+ from typing import Any
23
+
24
+ import typer
25
+ from loguru import logger
26
+ from rich.console import Console
27
+ from rich.panel import Panel
28
+ from rich.table import Table
29
+
30
+ from ...config.defaults import DEFAULT_EMBEDDING_MODELS, DEFAULT_FILE_EXTENSIONS
31
+ from ...core.exceptions import ProjectInitializationError
32
+ from ...core.project import ProjectManager
33
+ from ..didyoumean import create_enhanced_typer
34
+ from ..output import (
35
+ print_error,
36
+ print_info,
37
+ print_next_steps,
38
+ print_success,
39
+ print_warning,
40
+ )
41
+
42
+ # Create console for rich output
43
+ console = Console()
44
+
45
+ # Create install app with subcommands
46
+ install_app = create_enhanced_typer(
47
+ help="""📦 Install mcp-vector-search and MCP integrations
48
+
49
+ [bold cyan]Usage Patterns:[/bold cyan]
50
+
51
+ [green]1. Project Installation (Primary)[/green]
52
+ Install mcp-vector-search in the current project:
53
+ [code]$ mcp-vector-search install[/code]
54
+
55
+ [green]2. MCP Platform Integration[/green]
56
+ Add MCP integration for specific platforms:
57
+ [code]$ mcp-vector-search install claude-code[/code]
58
+ [code]$ mcp-vector-search install cursor[/code]
59
+ [code]$ mcp-vector-search install windsurf[/code]
60
+
61
+ [green]3. Complete Setup[/green]
62
+ Install project + all MCP integrations:
63
+ [code]$ mcp-vector-search install --with-mcp[/code]
64
+
65
+ [bold cyan]Supported Platforms:[/bold cyan]
66
+ • [green]claude-code[/green] - Claude Code (project-scoped .mcp.json)
67
+ • [green]claude-desktop[/green] - Claude Desktop (~/.claude/config.json)
68
+ • [green]cursor[/green] - Cursor IDE (~/.cursor/mcp.json)
69
+ • [green]windsurf[/green] - Windsurf IDE (~/.codeium/windsurf/mcp_config.json)
70
+ • [green]vscode[/green] - VS Code (~/.vscode/mcp.json)
71
+
72
+ [dim]💡 Use 'mcp-vector-search uninstall <platform>' to remove integrations[/dim]
73
+ """,
74
+ invoke_without_command=True,
75
+ no_args_is_help=False,
76
+ )
77
+
78
+
79
+ # ==============================================================================
80
+ # Platform Configuration
81
+ # ==============================================================================
82
+
83
+ SUPPORTED_PLATFORMS = {
84
+ "claude-code": {
85
+ "name": "Claude Code",
86
+ "config_path": ".mcp.json", # Project-scoped
87
+ "description": "Claude Code with project-scoped configuration",
88
+ "scope": "project",
89
+ },
90
+ "claude-desktop": {
91
+ "name": "Claude Desktop",
92
+ "config_path": "~/Library/Application Support/Claude/claude_desktop_config.json",
93
+ "description": "Claude Desktop application",
94
+ "scope": "global",
95
+ },
96
+ "cursor": {
97
+ "name": "Cursor",
98
+ "config_path": "~/.cursor/mcp.json",
99
+ "description": "Cursor IDE",
100
+ "scope": "global",
101
+ },
102
+ "windsurf": {
103
+ "name": "Windsurf",
104
+ "config_path": "~/.codeium/windsurf/mcp_config.json",
105
+ "description": "Windsurf IDE",
106
+ "scope": "global",
107
+ },
108
+ "vscode": {
109
+ "name": "VS Code",
110
+ "config_path": "~/.vscode/mcp.json",
111
+ "description": "Visual Studio Code",
112
+ "scope": "global",
113
+ },
114
+ }
115
+
116
+
117
+ def get_platform_config_path(platform: str, project_root: Path) -> Path:
118
+ """Get the configuration file path for a platform.
119
+
120
+ Args:
121
+ platform: Platform name (e.g., "claude-code", "cursor")
122
+ project_root: Project root directory (for project-scoped configs)
123
+
124
+ Returns:
125
+ Path to the configuration file
126
+ """
127
+ if platform not in SUPPORTED_PLATFORMS:
128
+ raise ValueError(f"Unsupported platform: {platform}")
129
+
130
+ config_info = SUPPORTED_PLATFORMS[platform]
131
+ config_path_str = config_info["config_path"]
132
+
133
+ # Resolve project-scoped vs global paths
134
+ if config_info["scope"] == "project":
135
+ return project_root / config_path_str
136
+ else:
137
+ return Path(config_path_str).expanduser()
138
+
139
+
140
+ def get_mcp_server_config(
141
+ project_root: Path,
142
+ platform: str,
143
+ enable_watch: bool = True,
144
+ ) -> dict[str, Any]:
145
+ """Generate MCP server configuration for a platform.
146
+
147
+ Args:
148
+ project_root: Project root directory
149
+ platform: Platform name
150
+ enable_watch: Whether to enable file watching
151
+
152
+ Returns:
153
+ Dictionary containing MCP server configuration
154
+ """
155
+ # Base configuration using uv for compatibility
156
+ config: dict[str, Any] = {
157
+ "command": "uv",
158
+ "args": ["run", "mcp-vector-search", "mcp"],
159
+ "env": {
160
+ "MCP_ENABLE_FILE_WATCHING": "true" if enable_watch else "false",
161
+ },
162
+ }
163
+
164
+ # Platform-specific adjustments
165
+ if platform in ("claude-code", "cursor", "windsurf", "vscode"):
166
+ # These platforms require "type": "stdio"
167
+ config["type"] = "stdio"
168
+
169
+ # Only add cwd for global-scope platforms (not project-scoped)
170
+ if SUPPORTED_PLATFORMS[platform]["scope"] == "global":
171
+ config["cwd"] = str(project_root.absolute())
172
+
173
+ return config
174
+
175
+
176
+ def detect_installed_platforms() -> dict[str, Path]:
177
+ """Detect which MCP platforms are installed on the system.
178
+
179
+ Returns:
180
+ Dictionary mapping platform names to their config paths
181
+ """
182
+ detected = {}
183
+
184
+ for platform, info in SUPPORTED_PLATFORMS.items():
185
+ # For project-scoped platforms, always include them
186
+ if info["scope"] == "project":
187
+ detected[platform] = Path(info["config_path"])
188
+ continue
189
+
190
+ # For global platforms, check if config directory exists
191
+ config_path = Path(info["config_path"]).expanduser()
192
+ if config_path.parent.exists():
193
+ detected[platform] = config_path
194
+
195
+ return detected
196
+
197
+
198
+ def configure_platform(
199
+ platform: str,
200
+ project_root: Path,
201
+ server_name: str = "mcp-vector-search",
202
+ enable_watch: bool = True,
203
+ force: bool = False,
204
+ ) -> bool:
205
+ """Configure MCP integration for a specific platform.
206
+
207
+ Args:
208
+ platform: Platform name (e.g., "claude-code", "cursor")
209
+ project_root: Project root directory
210
+ server_name: Name for the MCP server entry
211
+ enable_watch: Whether to enable file watching
212
+ force: Whether to overwrite existing configuration
213
+
214
+ Returns:
215
+ True if configuration was successful, False otherwise
216
+ """
217
+ try:
218
+ config_path = get_platform_config_path(platform, project_root)
219
+
220
+ # Create backup if file exists
221
+ if config_path.exists():
222
+ backup_path = config_path.with_suffix(config_path.suffix + ".backup")
223
+ shutil.copy2(config_path, backup_path)
224
+
225
+ # Load existing config
226
+ with open(config_path) as f:
227
+ config = json.load(f)
228
+
229
+ # Check if server already exists
230
+ if "mcpServers" in config and server_name in config["mcpServers"]:
231
+ if not force:
232
+ print_warning(
233
+ f" ⚠️ Server '{server_name}' already exists in {platform} config"
234
+ )
235
+ print_info(" Use --force to overwrite")
236
+ return False
237
+ else:
238
+ # Create new config
239
+ config_path.parent.mkdir(parents=True, exist_ok=True)
240
+ config = {}
241
+
242
+ # Ensure mcpServers section exists
243
+ if "mcpServers" not in config:
244
+ config["mcpServers"] = {}
245
+
246
+ # Add server configuration
247
+ server_config = get_mcp_server_config(project_root, platform, enable_watch)
248
+ config["mcpServers"][server_name] = server_config
249
+
250
+ # Write configuration
251
+ with open(config_path, "w") as f:
252
+ json.dump(config, f, indent=2)
253
+
254
+ platform_name = SUPPORTED_PLATFORMS[platform]["name"]
255
+ print_success(f" ✅ Configured {platform_name}")
256
+ print_info(f" Config: {config_path}")
257
+
258
+ return True
259
+
260
+ except Exception as e:
261
+ logger.error(f"Failed to configure {platform}: {e}")
262
+ print_error(f" ❌ Failed to configure {platform}: {e}")
263
+ return False
264
+
265
+
266
+ # ==============================================================================
267
+ # Main Install Command (Project Installation)
268
+ # ==============================================================================
269
+
270
+
271
+ @install_app.callback()
272
+ def main(
273
+ ctx: typer.Context,
274
+ extensions: str | None = typer.Option(
275
+ None,
276
+ "--extensions",
277
+ "-e",
278
+ help="Comma-separated file extensions (e.g., .py,.js,.ts)",
279
+ rich_help_panel="📁 Configuration",
280
+ ),
281
+ embedding_model: str = typer.Option(
282
+ DEFAULT_EMBEDDING_MODELS["code"],
283
+ "--embedding-model",
284
+ "-m",
285
+ help="Embedding model for semantic search",
286
+ rich_help_panel="🧠 Model Settings",
287
+ ),
288
+ similarity_threshold: float = typer.Option(
289
+ 0.5,
290
+ "--similarity-threshold",
291
+ "-s",
292
+ help="Similarity threshold (0.0-1.0)",
293
+ min=0.0,
294
+ max=1.0,
295
+ rich_help_panel="🧠 Model Settings",
296
+ ),
297
+ auto_index: bool = typer.Option(
298
+ True,
299
+ "--auto-index/--no-auto-index",
300
+ help="Automatically index after initialization",
301
+ rich_help_panel="🚀 Workflow",
302
+ ),
303
+ with_mcp: bool = typer.Option(
304
+ False,
305
+ "--with-mcp",
306
+ help="Install all available MCP integrations",
307
+ rich_help_panel="🚀 Workflow",
308
+ ),
309
+ force: bool = typer.Option(
310
+ False,
311
+ "--force",
312
+ "-f",
313
+ help="Force re-initialization",
314
+ rich_help_panel="⚙️ Advanced",
315
+ ),
316
+ ) -> None:
317
+ """📦 Install mcp-vector-search in the current project.
318
+
319
+ This command initializes mcp-vector-search with:
320
+ ✅ Vector database setup
321
+ ✅ Configuration file creation
322
+ ✅ Automatic code indexing
323
+ ✅ Ready-to-use semantic search
324
+
325
+ [bold cyan]Examples:[/bold cyan]
326
+
327
+ [green]Basic installation:[/green]
328
+ $ mcp-vector-search install
329
+
330
+ [green]Custom file types:[/green]
331
+ $ mcp-vector-search install --extensions .py,.js,.ts
332
+
333
+ [green]Install with MCP integrations:[/green]
334
+ $ mcp-vector-search install --with-mcp
335
+
336
+ [green]Skip auto-indexing:[/green]
337
+ $ mcp-vector-search install --no-auto-index
338
+
339
+ [dim]💡 After installation, use 'mcp-vector-search search' to search your code[/dim]
340
+ """
341
+ # Only run main logic if no subcommand was invoked
342
+ if ctx.invoked_subcommand is not None:
343
+ return
344
+
345
+ try:
346
+ project_root = ctx.obj.get("project_root") or Path.cwd()
347
+
348
+ console.print(
349
+ Panel.fit(
350
+ f"[bold cyan]Installing mcp-vector-search[/bold cyan]\n"
351
+ f"📁 Project: {project_root}",
352
+ border_style="cyan",
353
+ )
354
+ )
355
+
356
+ # Check if already initialized
357
+ project_manager = ProjectManager(project_root)
358
+ if project_manager.is_initialized() and not force:
359
+ print_success("✅ Project already initialized!")
360
+ print_info(" Use --force to re-initialize")
361
+ raise typer.Exit(0)
362
+
363
+ # Parse file extensions
364
+ file_extensions = None
365
+ if extensions:
366
+ file_extensions = [
367
+ ext.strip() if ext.startswith(".") else f".{ext.strip()}"
368
+ for ext in extensions.split(",")
369
+ ]
370
+ else:
371
+ file_extensions = DEFAULT_FILE_EXTENSIONS
372
+
373
+ # Show configuration
374
+ console.print("\n[bold blue]Configuration:[/bold blue]")
375
+ console.print(f" 📄 Extensions: {', '.join(file_extensions)}")
376
+ console.print(f" 🧠 Model: {embedding_model}")
377
+ console.print(f" 🎯 Threshold: {similarity_threshold}")
378
+ console.print(f" 🔍 Auto-index: {'✅' if auto_index else '❌'}")
379
+ console.print(f" 🔗 With MCP: {'✅' if with_mcp else '❌'}")
380
+
381
+ # Initialize project
382
+ console.print("\n[bold]Initializing project...[/bold]")
383
+ project_manager.initialize(
384
+ file_extensions=file_extensions,
385
+ embedding_model=embedding_model,
386
+ similarity_threshold=similarity_threshold,
387
+ force=force,
388
+ )
389
+ print_success("✅ Project initialized")
390
+
391
+ # Auto-index if requested
392
+ if auto_index:
393
+ console.print("\n[bold]🔍 Indexing codebase...[/bold]")
394
+ from .index import run_indexing
395
+
396
+ try:
397
+ asyncio.run(
398
+ run_indexing(
399
+ project_root=project_root,
400
+ force_reindex=False,
401
+ show_progress=True,
402
+ )
403
+ )
404
+ print_success("✅ Indexing completed")
405
+ except Exception as e:
406
+ print_error(f"❌ Indexing failed: {e}")
407
+ print_info(" Run 'mcp-vector-search index' to index later")
408
+
409
+ # Install MCP integrations if requested
410
+ if with_mcp:
411
+ console.print("\n[bold blue]🔗 Installing MCP integrations...[/bold blue]")
412
+ detected = detect_installed_platforms()
413
+
414
+ if detected:
415
+ for platform in detected:
416
+ configure_platform(platform, project_root, enable_watch=True)
417
+ else:
418
+ print_warning("No MCP platforms detected")
419
+ print_info("Install platforms manually using:")
420
+ print_info(" mcp-vector-search install <platform>")
421
+
422
+ # Success message
423
+ console.print("\n[bold green]🎉 Installation Complete![/bold green]")
424
+
425
+ next_steps = [
426
+ "[cyan]mcp-vector-search search 'your query'[/cyan] - Search your code",
427
+ "[cyan]mcp-vector-search status[/cyan] - View project status",
428
+ ]
429
+
430
+ if not with_mcp:
431
+ next_steps.append(
432
+ "[cyan]mcp-vector-search install claude-code[/cyan] - Add MCP integration"
433
+ )
434
+
435
+ print_next_steps(next_steps, title="Ready to Use")
436
+
437
+ except ProjectInitializationError as e:
438
+ print_error(f"Installation failed: {e}")
439
+ raise typer.Exit(1)
440
+ except Exception as e:
441
+ logger.error(f"Unexpected error during installation: {e}")
442
+ print_error(f"Unexpected error: {e}")
443
+ raise typer.Exit(1)
444
+
445
+
446
+ # ==============================================================================
447
+ # Platform-Specific Installation Commands
448
+ # ==============================================================================
449
+
450
+
451
+ @install_app.command("claude-code")
452
+ def install_claude_code(
453
+ ctx: typer.Context,
454
+ enable_watch: bool = typer.Option(
455
+ True,
456
+ "--watch/--no-watch",
457
+ help="Enable file watching for auto-reindex",
458
+ ),
459
+ force: bool = typer.Option(
460
+ False,
461
+ "--force",
462
+ "-f",
463
+ help="Force overwrite existing configuration",
464
+ ),
465
+ ) -> None:
466
+ """Install Claude Code MCP integration (project-scoped).
467
+
468
+ Creates .mcp.json in the project root for team sharing.
469
+ This file should be committed to version control.
470
+ """
471
+ project_root = ctx.obj.get("project_root") or Path.cwd()
472
+
473
+ console.print(
474
+ Panel.fit(
475
+ "[bold cyan]Installing Claude Code Integration[/bold cyan]\n"
476
+ "📁 Project-scoped configuration",
477
+ border_style="cyan",
478
+ )
479
+ )
480
+
481
+ success = configure_platform(
482
+ "claude-code", project_root, enable_watch=enable_watch, force=force
483
+ )
484
+
485
+ if success:
486
+ console.print(
487
+ "\n[bold green]✨ Claude Code Integration Installed![/bold green]"
488
+ )
489
+ console.print("\n[bold blue]Next Steps:[/bold blue]")
490
+ console.print(" 1. Open Claude Code in this project directory")
491
+ console.print(" 2. The MCP server will be available automatically")
492
+ console.print(" 3. Try: 'Search my code for authentication functions'")
493
+ console.print("\n[dim]💡 Commit .mcp.json to share with your team[/dim]")
494
+ else:
495
+ raise typer.Exit(1)
496
+
497
+
498
+ @install_app.command("cursor")
499
+ def install_cursor(
500
+ ctx: typer.Context,
501
+ enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
502
+ force: bool = typer.Option(False, "--force", "-f"),
503
+ ) -> None:
504
+ """Install Cursor IDE MCP integration (global)."""
505
+ project_root = ctx.obj.get("project_root") or Path.cwd()
506
+
507
+ console.print(
508
+ Panel.fit(
509
+ "[bold cyan]Installing Cursor Integration[/bold cyan]\n"
510
+ "🌐 Global configuration (~/.cursor/mcp.json)",
511
+ border_style="cyan",
512
+ )
513
+ )
514
+
515
+ success = configure_platform(
516
+ "cursor", project_root, enable_watch=enable_watch, force=force
517
+ )
518
+
519
+ if success:
520
+ console.print("\n[bold green]✨ Cursor Integration Installed![/bold green]")
521
+ console.print("\n[bold blue]Next Steps:[/bold blue]")
522
+ console.print(" 1. Restart Cursor IDE")
523
+ console.print(" 2. Open this project in Cursor")
524
+ console.print(" 3. MCP tools should be available")
525
+ else:
526
+ raise typer.Exit(1)
527
+
528
+
529
+ @install_app.command("windsurf")
530
+ def install_windsurf(
531
+ ctx: typer.Context,
532
+ enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
533
+ force: bool = typer.Option(False, "--force", "-f"),
534
+ ) -> None:
535
+ """Install Windsurf IDE MCP integration (global)."""
536
+ project_root = ctx.obj.get("project_root") or Path.cwd()
537
+
538
+ console.print(
539
+ Panel.fit(
540
+ "[bold cyan]Installing Windsurf Integration[/bold cyan]\n"
541
+ "🌐 Global configuration (~/.codeium/windsurf/mcp_config.json)",
542
+ border_style="cyan",
543
+ )
544
+ )
545
+
546
+ success = configure_platform(
547
+ "windsurf", project_root, enable_watch=enable_watch, force=force
548
+ )
549
+
550
+ if success:
551
+ console.print("\n[bold green]✨ Windsurf Integration Installed![/bold green]")
552
+ console.print("\n[bold blue]Next Steps:[/bold blue]")
553
+ console.print(" 1. Restart Windsurf IDE")
554
+ console.print(" 2. Open this project in Windsurf")
555
+ console.print(" 3. MCP tools should be available")
556
+ else:
557
+ raise typer.Exit(1)
558
+
559
+
560
+ @install_app.command("claude-desktop")
561
+ def install_claude_desktop(
562
+ ctx: typer.Context,
563
+ enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
564
+ force: bool = typer.Option(False, "--force", "-f"),
565
+ ) -> None:
566
+ """Install Claude Desktop MCP integration (global)."""
567
+ project_root = ctx.obj.get("project_root") or Path.cwd()
568
+
569
+ console.print(
570
+ Panel.fit(
571
+ "[bold cyan]Installing Claude Desktop Integration[/bold cyan]\n"
572
+ "🌐 Global configuration (~/.claude/config.json)",
573
+ border_style="cyan",
574
+ )
575
+ )
576
+
577
+ success = configure_platform(
578
+ "claude-desktop", project_root, enable_watch=enable_watch, force=force
579
+ )
580
+
581
+ if success:
582
+ console.print(
583
+ "\n[bold green]✨ Claude Desktop Integration Installed![/bold green]"
584
+ )
585
+ console.print("\n[bold blue]Next Steps:[/bold blue]")
586
+ console.print(" 1. Restart Claude Desktop")
587
+ console.print(" 2. The mcp-vector-search server will be available")
588
+ console.print(" 3. Open conversations in the project directory")
589
+ else:
590
+ raise typer.Exit(1)
591
+
592
+
593
+ @install_app.command("vscode")
594
+ def install_vscode(
595
+ ctx: typer.Context,
596
+ enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
597
+ force: bool = typer.Option(False, "--force", "-f"),
598
+ ) -> None:
599
+ """Install VS Code MCP integration (global)."""
600
+ project_root = ctx.obj.get("project_root") or Path.cwd()
601
+
602
+ console.print(
603
+ Panel.fit(
604
+ "[bold cyan]Installing VS Code Integration[/bold cyan]\n"
605
+ "🌐 Global configuration (~/.vscode/mcp.json)",
606
+ border_style="cyan",
607
+ )
608
+ )
609
+
610
+ success = configure_platform(
611
+ "vscode", project_root, enable_watch=enable_watch, force=force
612
+ )
613
+
614
+ if success:
615
+ console.print("\n[bold green]✨ VS Code Integration Installed![/bold green]")
616
+ console.print("\n[bold blue]Next Steps:[/bold blue]")
617
+ console.print(" 1. Restart VS Code")
618
+ console.print(" 2. Open this project in VS Code")
619
+ console.print(" 3. MCP tools should be available")
620
+ else:
621
+ raise typer.Exit(1)
622
+
623
+
624
+ @install_app.command("list")
625
+ def list_platforms(ctx: typer.Context) -> None:
626
+ """List all supported MCP platforms and their installation status."""
627
+ project_root = ctx.obj.get("project_root") or Path.cwd()
628
+
629
+ console.print(
630
+ Panel.fit("[bold cyan]MCP Platform Status[/bold cyan]", border_style="cyan")
631
+ )
632
+
633
+ table = Table(show_header=True, header_style="bold cyan")
634
+ table.add_column("Platform", style="cyan")
635
+ table.add_column("Name")
636
+ table.add_column("Status")
637
+ table.add_column("Config Location")
638
+
639
+ detected = detect_installed_platforms()
640
+
641
+ for platform, info in SUPPORTED_PLATFORMS.items():
642
+ config_path = get_platform_config_path(platform, project_root)
643
+
644
+ # Check if configured
645
+ is_configured = False
646
+ if config_path.exists():
647
+ try:
648
+ with open(config_path) as f:
649
+ config = json.load(f)
650
+ is_configured = "mcp-vector-search" in config.get("mcpServers", {})
651
+ except Exception:
652
+ pass
653
+
654
+ status = (
655
+ "✅ Configured"
656
+ if is_configured
657
+ else ("⚠️ Available" if platform in detected else "❌ Not Found")
658
+ )
659
+
660
+ table.add_row(
661
+ platform,
662
+ info["name"],
663
+ status,
664
+ str(config_path) if info["scope"] == "project" else info["config_path"],
665
+ )
666
+
667
+ console.print(table)
668
+
669
+ console.print("\n[bold blue]Installation Commands:[/bold blue]")
670
+ for platform in SUPPORTED_PLATFORMS:
671
+ console.print(f" mcp-vector-search install {platform}")
672
+
673
+
674
+ if __name__ == "__main__":
675
+ install_app()