mcp-vector-search 0.0.3__py3-none-any.whl → 0.4.11__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.

Potentially problematic release.


This version of mcp-vector-search might be problematic. Click here for more details.

Files changed (49) hide show
  1. mcp_vector_search/__init__.py +3 -2
  2. mcp_vector_search/cli/commands/auto_index.py +397 -0
  3. mcp_vector_search/cli/commands/config.py +88 -40
  4. mcp_vector_search/cli/commands/index.py +198 -52
  5. mcp_vector_search/cli/commands/init.py +472 -58
  6. mcp_vector_search/cli/commands/install.py +284 -0
  7. mcp_vector_search/cli/commands/mcp.py +495 -0
  8. mcp_vector_search/cli/commands/search.py +241 -87
  9. mcp_vector_search/cli/commands/status.py +184 -58
  10. mcp_vector_search/cli/commands/watch.py +34 -35
  11. mcp_vector_search/cli/didyoumean.py +184 -0
  12. mcp_vector_search/cli/export.py +320 -0
  13. mcp_vector_search/cli/history.py +292 -0
  14. mcp_vector_search/cli/interactive.py +342 -0
  15. mcp_vector_search/cli/main.py +163 -26
  16. mcp_vector_search/cli/output.py +63 -45
  17. mcp_vector_search/config/defaults.py +50 -36
  18. mcp_vector_search/config/settings.py +49 -35
  19. mcp_vector_search/core/auto_indexer.py +298 -0
  20. mcp_vector_search/core/connection_pool.py +322 -0
  21. mcp_vector_search/core/database.py +335 -25
  22. mcp_vector_search/core/embeddings.py +73 -29
  23. mcp_vector_search/core/exceptions.py +19 -2
  24. mcp_vector_search/core/factory.py +310 -0
  25. mcp_vector_search/core/git_hooks.py +345 -0
  26. mcp_vector_search/core/indexer.py +237 -73
  27. mcp_vector_search/core/models.py +21 -19
  28. mcp_vector_search/core/project.py +73 -58
  29. mcp_vector_search/core/scheduler.py +330 -0
  30. mcp_vector_search/core/search.py +574 -86
  31. mcp_vector_search/core/watcher.py +48 -46
  32. mcp_vector_search/mcp/__init__.py +4 -0
  33. mcp_vector_search/mcp/__main__.py +25 -0
  34. mcp_vector_search/mcp/server.py +701 -0
  35. mcp_vector_search/parsers/base.py +30 -31
  36. mcp_vector_search/parsers/javascript.py +74 -48
  37. mcp_vector_search/parsers/python.py +57 -49
  38. mcp_vector_search/parsers/registry.py +47 -32
  39. mcp_vector_search/parsers/text.py +179 -0
  40. mcp_vector_search/utils/__init__.py +40 -0
  41. mcp_vector_search/utils/gitignore.py +229 -0
  42. mcp_vector_search/utils/timing.py +334 -0
  43. mcp_vector_search/utils/version.py +47 -0
  44. {mcp_vector_search-0.0.3.dist-info → mcp_vector_search-0.4.11.dist-info}/METADATA +173 -7
  45. mcp_vector_search-0.4.11.dist-info/RECORD +54 -0
  46. mcp_vector_search-0.0.3.dist-info/RECORD +0 -35
  47. {mcp_vector_search-0.0.3.dist-info → mcp_vector_search-0.4.11.dist-info}/WHEEL +0 -0
  48. {mcp_vector_search-0.0.3.dist-info → mcp_vector_search-0.4.11.dist-info}/entry_points.txt +0 -0
  49. {mcp_vector_search-0.0.3.dist-info → mcp_vector_search-0.4.11.dist-info}/licenses/LICENSE +0 -0
@@ -1,7 +1,6 @@
1
1
  """Init command for MCP Vector Search CLI."""
2
2
 
3
3
  from pathlib import Path
4
- from typing import List, Optional
5
4
 
6
5
  import typer
7
6
  from loguru import logger
@@ -16,6 +15,7 @@ from ..output import (
16
15
  print_info,
17
16
  print_project_info,
18
17
  print_success,
18
+ print_warning,
19
19
  )
20
20
 
21
21
  # Create init subcommand app
@@ -25,7 +25,7 @@ init_app = typer.Typer(help="Initialize project for semantic search")
25
25
  @init_app.command()
26
26
  def main(
27
27
  ctx: typer.Context,
28
- config_file: Optional[Path] = typer.Option(
28
+ config_file: Path | None = typer.Option(
29
29
  None,
30
30
  "--config",
31
31
  "-c",
@@ -35,11 +35,11 @@ def main(
35
35
  dir_okay=False,
36
36
  readable=True,
37
37
  ),
38
- extensions: Optional[str] = typer.Option(
38
+ extensions: str | None = typer.Option(
39
39
  None,
40
40
  "--extensions",
41
41
  "-e",
42
- help="Comma-separated list of file extensions to index (e.g., '.py,.js,.ts')",
42
+ help="Comma-separated list of file extensions to index (e.g., '.py,.js,.ts,.txt,.md')",
43
43
  ),
44
44
  embedding_model: str = typer.Option(
45
45
  DEFAULT_EMBEDDING_MODELS["code"],
@@ -48,7 +48,7 @@ def main(
48
48
  help="Embedding model to use for semantic search",
49
49
  ),
50
50
  similarity_threshold: float = typer.Option(
51
- 0.75,
51
+ 0.5,
52
52
  "--similarity-threshold",
53
53
  "-s",
54
54
  help="Similarity threshold for search results (0.0 to 1.0)",
@@ -62,25 +62,40 @@ def main(
62
62
  help="Force re-initialization if project is already initialized",
63
63
  ),
64
64
  auto_index: bool = typer.Option(
65
- False,
66
- "--auto-index",
65
+ True,
66
+ "--auto-index/--no-auto-index",
67
67
  help="Automatically start indexing after initialization",
68
68
  ),
69
+ mcp: bool = typer.Option(
70
+ True,
71
+ "--mcp/--no-mcp",
72
+ help="Install Claude Code MCP integration after initialization",
73
+ ),
74
+ auto_indexing: bool = typer.Option(
75
+ True,
76
+ "--auto-indexing/--no-auto-indexing",
77
+ help="Set up automatic indexing for file changes",
78
+ ),
69
79
  ) -> None:
70
- """Initialize a project for semantic code search.
71
-
72
- This command sets up the necessary configuration and directory structure
73
- for MCP Vector Search in your project. It will:
74
-
75
- - Create a .mcp-vector-search directory for storing the index and configuration
76
- - Detect programming languages in your project
77
- - Set up default configuration based on your project structure
78
- - Optionally start indexing your codebase
79
-
80
+ """🚀 Complete project setup for semantic code search with MCP integration.
81
+
82
+ This command provides a comprehensive one-step installation that:
83
+
84
+ ✅ **Installs** mcp-vector-search in the current project
85
+ **Auto-detects** your project's programming languages and file types
86
+ **Initializes** vector database and configuration
87
+ **Indexes** your codebase automatically
88
+ **Sets up** auto-indexing for file changes
89
+ ✅ **Installs** Claude Code MCP integration with project-scoped .mcp.json
90
+ ✅ **Creates** shareable team configuration
91
+
92
+ Perfect for getting started quickly in any project!
93
+
80
94
  Examples:
81
- mcp-vector-search init
82
- mcp-vector-search init --extensions .py,.js,.ts --auto-index
83
- mcp-vector-search init --embedding-model microsoft/unixcoder-base --force
95
+ mcp-vector-search init main # Full setup with smart defaults
96
+ mcp-vector-search init main --no-mcp # Setup without MCP integration
97
+ mcp-vector-search init main --extensions .py,.js,.ts,.txt # Custom file types
98
+ mcp-vector-search init main --force # Re-initialize existing project
84
99
  """
85
100
  try:
86
101
  # Get project root from context or auto-detect
@@ -90,40 +105,103 @@ def main(
90
105
 
91
106
  print_info(f"Initializing project at: {project_root}")
92
107
 
108
+ # Step 1: Install mcp-vector-search in the current project
109
+ console.print("\n[bold blue]📦 Installing mcp-vector-search...[/bold blue]")
110
+
111
+ # Find the development source directory
112
+ import mcp_vector_search
113
+ dev_source_path = Path(mcp_vector_search.__file__).parent.parent.parent
114
+
115
+ try:
116
+ import subprocess
117
+ import sys
118
+ import shutil
119
+
120
+ # Try different installation methods based on available tools
121
+ install_success = False
122
+
123
+ # Method 1: Try pip directly
124
+ if shutil.which("pip"):
125
+ install_cmd = ["pip", "install", "-e", str(dev_source_path)]
126
+ try:
127
+ result = subprocess.run(install_cmd, capture_output=True, text=True, timeout=120)
128
+ if result.returncode == 0:
129
+ install_success = True
130
+ except:
131
+ pass
132
+
133
+ # Method 2: Try python -m pip
134
+ if not install_success:
135
+ install_cmd = [sys.executable, "-m", "pip", "install", "-e", str(dev_source_path)]
136
+ try:
137
+ result = subprocess.run(install_cmd, capture_output=True, text=True, timeout=120)
138
+ if result.returncode == 0:
139
+ install_success = True
140
+ except:
141
+ pass
142
+
143
+ # Method 3: Try uv if available
144
+ if not install_success and shutil.which("uv"):
145
+ install_cmd = ["uv", "add", "--editable", str(dev_source_path)]
146
+ try:
147
+ result = subprocess.run(install_cmd, capture_output=True, text=True, timeout=120)
148
+ if result.returncode == 0:
149
+ install_success = True
150
+ except:
151
+ pass
152
+
153
+ if install_success:
154
+ print_success("✅ mcp-vector-search installed successfully!")
155
+ else:
156
+ print_warning("⚠️ Could not install automatically - you may need to install manually")
157
+ print_info(f"💡 Try: pip install -e {dev_source_path}")
158
+ print_info("Continuing with setup...")
159
+
160
+ except Exception as e:
161
+ print_warning(f"⚠️ Installation encountered an issue: {e}")
162
+ print_info("Continuing with setup...")
163
+
93
164
  # Create project manager
94
165
  project_manager = ProjectManager(project_root)
95
166
 
96
167
  # Check if already initialized
97
168
  if project_manager.is_initialized() and not force:
98
- print_error("Project is already initialized")
99
- print_info("Use --force to re-initialize or run 'mcp-vector-search status' to see current configuration")
100
- raise typer.Exit(1)
169
+ print_success("Project is already initialized and ready to use!")
170
+ print_info("Your project has vector search capabilities enabled.")
171
+ print_info("Use --force to re-initialize or run 'mcp-vector-search status main' to see current configuration")
172
+ return # Exit gracefully without raising an exception
101
173
 
102
174
  # Parse file extensions
103
175
  file_extensions = None
104
176
  if extensions:
105
177
  file_extensions = [ext.strip() for ext in extensions.split(",")]
106
178
  # Ensure extensions start with dot
107
- file_extensions = [ext if ext.startswith(".") else f".{ext}" for ext in file_extensions]
179
+ file_extensions = [
180
+ ext if ext.startswith(".") else f".{ext}" for ext in file_extensions
181
+ ]
108
182
  else:
109
183
  file_extensions = DEFAULT_FILE_EXTENSIONS
110
184
 
111
185
  # Show what will be initialized
112
- console.print("\n[bold blue]Initialization Settings:[/bold blue]")
113
- console.print(f" Project Root: {project_root}")
114
- console.print(f" File Extensions: {', '.join(file_extensions)}")
115
- console.print(f" Embedding Model: {embedding_model}")
116
- console.print(f" Similarity Threshold: {similarity_threshold}")
186
+ console.print("\n[bold blue]🚀 MCP Vector Search Setup:[/bold blue]")
187
+ console.print(f" 📁 Project Root: {project_root}")
188
+ console.print(f" 📄 File Extensions: {', '.join(file_extensions)}")
189
+ console.print(f" 🧠 Embedding Model: {embedding_model}")
190
+ console.print(f" 🎯 Similarity Threshold: {similarity_threshold}")
191
+ console.print(f" 🔍 Auto-indexing: {'✅ Enabled' if auto_index else '❌ Disabled'}")
192
+ console.print(f" ⚡ File watching: {'✅ Enabled' if auto_indexing else '❌ Disabled'}")
193
+ console.print(f" 🔗 Claude Code MCP: {'✅ Enabled' if mcp else '❌ Disabled'}")
117
194
 
118
- # Confirm initialization
119
- if not force and not confirm_action("\nProceed with initialization?", default=True):
120
- print_info("Initialization cancelled")
121
- raise typer.Exit(0)
195
+ # Confirm initialization (only if not using defaults)
196
+ if not force and (not auto_index or not mcp or not auto_indexing):
197
+ if not confirm_action("\nProceed with setup?", default=True):
198
+ print_info("Setup cancelled")
199
+ raise typer.Exit(0)
122
200
 
123
201
  # Initialize project
124
202
  console.print("\n[bold]Initializing project...[/bold]")
125
-
126
- config = project_manager.initialize(
203
+
204
+ project_manager.initialize(
127
205
  file_extensions=file_extensions,
128
206
  embedding_model=embedding_model,
129
207
  similarity_threshold=similarity_threshold,
@@ -137,32 +215,110 @@ def main(
137
215
  project_info = project_manager.get_project_info()
138
216
  print_project_info(project_info)
139
217
 
140
- # Offer to start indexing
141
- if auto_index or confirm_action("\nStart indexing your codebase now?", default=True):
142
- console.print("\n[bold]Starting indexing...[/bold]")
218
+ # Start indexing if requested
219
+ if auto_index:
220
+ console.print("\n[bold]🔍 Indexing your codebase...[/bold]")
143
221
 
144
222
  # Import and run indexing (avoid circular imports)
145
223
  import asyncio
224
+
146
225
  from .index import run_indexing
147
226
 
148
227
  try:
149
- asyncio.run(run_indexing(
150
- project_root=project_root,
151
- force_reindex=False,
152
- show_progress=True,
153
- ))
154
- print_success("Indexing completed!")
228
+ asyncio.run(
229
+ run_indexing(
230
+ project_root=project_root,
231
+ force_reindex=False,
232
+ show_progress=True,
233
+ )
234
+ )
235
+ print_success("✅ Indexing completed!")
155
236
  except Exception as e:
156
- print_error(f"Indexing failed: {e}")
157
- print_info("You can run 'mcp-vector-search index' later to index your codebase")
237
+ print_error(f"Indexing failed: {e}")
238
+ print_info(
239
+ "You can run 'mcp-vector-search index' later to index your codebase"
240
+ )
158
241
  else:
159
- print_info("Run 'mcp-vector-search index' to index your codebase")
242
+ print_info("💡 Run 'mcp-vector-search index' to index your codebase when ready")
243
+
244
+ # Install MCP integration if requested
245
+ if mcp:
246
+ console.print("\n[bold]🔗 Installing Claude Code MCP integration...[/bold]")
247
+
248
+ try:
249
+ # Import MCP functionality
250
+ from .mcp import check_claude_code_available, get_claude_command, get_mcp_server_command
251
+ import subprocess
252
+
253
+ # Check if Claude Code is available
254
+ if not check_claude_code_available():
255
+ print_warning("Claude Code not found. Skipping MCP integration.")
256
+ print_info("Install Claude Code from: https://claude.ai/download")
257
+ else:
258
+ claude_cmd = get_claude_command()
259
+ server_command = get_mcp_server_command(project_root)
260
+
261
+ # Install MCP server with project scope for team sharing
262
+ cmd_args = [
263
+ claude_cmd, "mcp", "add",
264
+ "--scope=project", # Use project scope for team sharing
265
+ "mcp-vector-search",
266
+ "--",
267
+ ] + server_command.split()
268
+
269
+ result = subprocess.run(
270
+ cmd_args,
271
+ capture_output=True,
272
+ text=True,
273
+ timeout=30
274
+ )
160
275
 
161
- # Show next steps
162
- console.print("\n[bold green]Next Steps:[/bold green]")
163
- console.print(" 1. Run [code]mcp-vector-search index[/code] to index your codebase (if not done)")
164
- console.print(" 2. Run [code]mcp-vector-search search 'your query'[/code] to search your code")
165
- console.print(" 3. Run [code]mcp-vector-search status[/code] to check indexing status")
276
+ if result.returncode == 0:
277
+ print_success(" Claude Code MCP integration installed!")
278
+ print_info("📁 Created .mcp.json for team sharing - commit this file to your repo")
279
+
280
+ # Also set up auto-indexing if requested
281
+ if auto_indexing:
282
+ try:
283
+ import asyncio
284
+ from .auto_index import _setup_auto_indexing
285
+ asyncio.run(_setup_auto_indexing(project_root, "search", 60, 5))
286
+ print_success("⚡ Auto-indexing configured for file changes")
287
+ except Exception as e:
288
+ print_warning(f"Auto-indexing setup failed: {e}")
289
+ print_info("You can set it up later with: mcp-vector-search auto-index setup")
290
+ else:
291
+ print_warning(f"MCP integration failed: {result.stderr}")
292
+ print_info("You can install it later with: mcp-vector-search mcp install")
293
+
294
+ except Exception as e:
295
+ print_warning(f"MCP integration failed: {e}")
296
+ print_info("You can install it later with: mcp-vector-search mcp install")
297
+
298
+ # Show completion status and next steps
299
+ console.print("\n[bold green]🎉 Setup Complete![/bold green]")
300
+
301
+ if auto_index and mcp:
302
+ console.print("\n[bold blue]✨ Your project is fully configured:[/bold blue]")
303
+ console.print(" ✅ Vector database initialized")
304
+ console.print(" ✅ Codebase indexed and searchable")
305
+ console.print(" ✅ Auto-indexing enabled for file changes")
306
+ console.print(" ✅ Claude Code MCP integration installed")
307
+ console.print(" ✅ Team configuration saved in .mcp.json")
308
+
309
+ console.print("\n[bold green]🚀 Ready to use:[/bold green]")
310
+ console.print(" • Search your code: [code]mcp-vector-search search 'your query'[/code]")
311
+ console.print(" • Use in Claude Code with MCP tools")
312
+ console.print(" • Check status: [code]mcp-vector-search status[/code]")
313
+ console.print("\n[dim]💡 Tip: Commit .mcp.json to share MCP integration with your team![/dim]")
314
+ else:
315
+ console.print("\n[bold blue]Next steps:[/bold blue]")
316
+ if not auto_index:
317
+ console.print(" 1. Run [code]mcp-vector-search index[/code] to index your codebase")
318
+ console.print(" 2. Run [code]mcp-vector-search search 'your query'[/code] to search your code")
319
+ console.print(" 3. Run [code]mcp-vector-search status[/code] to check status")
320
+ if not mcp:
321
+ console.print(" 4. Run [code]mcp-vector-search mcp install[/code] for Claude Code integration")
166
322
 
167
323
  except ProjectInitializationError as e:
168
324
  print_error(f"Initialization failed: {e}")
@@ -179,10 +335,10 @@ def check_initialization(ctx: typer.Context) -> None:
179
335
  try:
180
336
  project_root = ctx.obj.get("project_root") or Path.cwd()
181
337
  project_manager = ProjectManager(project_root)
182
-
338
+
183
339
  if project_manager.is_initialized():
184
340
  print_success(f"Project is initialized at {project_root}")
185
-
341
+
186
342
  # Show project info
187
343
  project_info = project_manager.get_project_info()
188
344
  print_project_info(project_info)
@@ -190,22 +346,280 @@ def check_initialization(ctx: typer.Context) -> None:
190
346
  print_error(f"Project is not initialized at {project_root}")
191
347
  print_info("Run 'mcp-vector-search init' to initialize the project")
192
348
  raise typer.Exit(1)
193
-
349
+
194
350
  except Exception as e:
195
351
  logger.error(f"Error checking initialization: {e}")
196
352
  print_error(f"Error: {e}")
197
353
  raise typer.Exit(1)
198
354
 
199
355
 
356
+ async def run_init_setup(
357
+ project_root: Path,
358
+ file_extensions: list[str] | None = None,
359
+ embedding_model: str = "sentence-transformers/all-MiniLM-L6-v2",
360
+ similarity_threshold: float = 0.5,
361
+ mcp: bool = True,
362
+ auto_index: bool = True,
363
+ auto_indexing: bool = True,
364
+ force: bool = False,
365
+ ) -> None:
366
+ """Reusable initialization setup function.
367
+
368
+ This function contains the core initialization logic that can be used
369
+ by both the init command and the install command.
370
+ """
371
+ from ...config.defaults import DEFAULT_FILE_EXTENSIONS
372
+ from ...core.project import ProjectManager
373
+ from ..output import print_project_info
374
+
375
+ # Create project manager
376
+ project_manager = ProjectManager(project_root)
377
+
378
+ # Parse file extensions
379
+ if not file_extensions:
380
+ file_extensions = DEFAULT_FILE_EXTENSIONS
381
+
382
+ # Initialize project
383
+ project_manager.initialize(
384
+ file_extensions=file_extensions,
385
+ embedding_model=embedding_model,
386
+ similarity_threshold=similarity_threshold,
387
+ force=force,
388
+ )
389
+
390
+ print_success("Project initialized successfully!")
391
+
392
+ # Show project information
393
+ project_info = project_manager.get_project_info()
394
+ print_project_info(project_info)
395
+
396
+ # Start indexing if requested
397
+ if auto_index:
398
+ console.print("\n[bold]🔍 Indexing your codebase...[/bold]")
399
+
400
+ # Import and run indexing (avoid circular imports)
401
+ from .index import run_indexing
402
+
403
+ try:
404
+ await run_indexing(
405
+ project_root=project_root,
406
+ force_reindex=False,
407
+ show_progress=True,
408
+ )
409
+ print_success("✅ Indexing completed!")
410
+ except Exception as e:
411
+ print_error(f"❌ Indexing failed: {e}")
412
+ print_info(
413
+ "You can run 'mcp-vector-search index' later to index your codebase"
414
+ )
415
+ else:
416
+ print_info("💡 Run 'mcp-vector-search index' to index your codebase when ready")
417
+
418
+ # Install MCP integration if requested
419
+ if mcp:
420
+ console.print("\n[bold]🔗 Installing Claude Code MCP integration...[/bold]")
421
+
422
+ try:
423
+ # Import MCP functionality
424
+ from .mcp import check_claude_code_available, get_claude_command, get_mcp_server_command
425
+ import subprocess
426
+
427
+ # Check if Claude Code is available
428
+ if not check_claude_code_available():
429
+ print_warning("Claude Code not found. Skipping MCP integration.")
430
+ print_info("Install Claude Code from: https://claude.ai/download")
431
+ else:
432
+ claude_cmd = get_claude_command()
433
+ server_command = get_mcp_server_command(project_root)
434
+
435
+ # Install MCP server with project scope for team sharing
436
+ cmd_args = [
437
+ claude_cmd, "mcp", "add",
438
+ "--scope=project", # Use project scope for team sharing
439
+ "mcp-vector-search",
440
+ "--",
441
+ ] + server_command.split()
442
+
443
+ result = subprocess.run(
444
+ cmd_args,
445
+ capture_output=True,
446
+ text=True,
447
+ timeout=30
448
+ )
449
+
450
+ if result.returncode == 0:
451
+ print_success("✅ Claude Code MCP integration installed!")
452
+ print_info("📁 Created .mcp.json for team sharing - commit this file to your repo")
453
+
454
+ # Also set up auto-indexing if requested
455
+ if auto_indexing:
456
+ try:
457
+ from .auto_index import _setup_auto_indexing
458
+ await _setup_auto_indexing(project_root, "search", 60, 5)
459
+ print_success("⚡ Auto-indexing configured for file changes")
460
+ except Exception as e:
461
+ print_warning(f"Auto-indexing setup failed: {e}")
462
+ print_info("You can set it up later with: mcp-vector-search auto-index setup")
463
+ else:
464
+ print_warning(f"MCP integration failed: {result.stderr}")
465
+ print_info("You can install it later with: mcp-vector-search mcp install")
466
+
467
+ except Exception as e:
468
+ print_warning(f"MCP integration failed: {e}")
469
+ print_info("You can install it later with: mcp-vector-search mcp install")
470
+
471
+
472
+ @init_app.command("mcp")
473
+ def init_mcp_integration(
474
+ ctx: typer.Context,
475
+ server_name: str = typer.Option(
476
+ "mcp-vector-search",
477
+ "--name",
478
+ help="Name for the MCP server"
479
+ ),
480
+ force: bool = typer.Option(
481
+ False,
482
+ "--force",
483
+ "-f",
484
+ help="Force installation even if server already exists"
485
+ )
486
+ ) -> None:
487
+ """Install/fix Claude Code MCP integration for the current project.
488
+
489
+ This command sets up MCP integration by:
490
+ ✅ Creating project-level .claude.json configuration
491
+ ✅ Testing server startup and connectivity
492
+ ✅ Providing troubleshooting information if needed
493
+
494
+ Perfect for fixing MCP integration issues or setting up team-shared configuration.
495
+ """
496
+ try:
497
+ # Import MCP functions
498
+ from .mcp import (
499
+ check_claude_code_available,
500
+ create_project_claude_config,
501
+ get_mcp_server_command,
502
+ )
503
+ import subprocess
504
+ import json
505
+
506
+ # Get project root
507
+ project_root = ctx.obj.get("project_root") or Path.cwd()
508
+
509
+ # Check if project is initialized
510
+ project_manager = ProjectManager(project_root)
511
+ if not project_manager.is_initialized():
512
+ print_error("Project not initialized. Run 'mcp-vector-search init' first.")
513
+ raise typer.Exit(1)
514
+
515
+ print_info(f"Setting up MCP integration for project: {project_root}")
516
+
517
+ # Check if project-level .claude.json already has the server
518
+ claude_json_path = project_root / ".claude.json"
519
+ if claude_json_path.exists() and not force:
520
+ with open(claude_json_path, 'r') as f:
521
+ config = json.load(f)
522
+ if config.get("mcpServers", {}).get(server_name):
523
+ print_warning(f"MCP server '{server_name}' already exists in project config.")
524
+ print_info("Use --force to overwrite or try a different --name")
525
+
526
+ # Still test the existing configuration
527
+ print_info("Testing existing configuration...")
528
+ _test_mcp_server(project_root)
529
+ return
530
+
531
+ # Create project-level configuration
532
+ create_project_claude_config(project_root, server_name)
533
+
534
+ print_success(f"✅ MCP server '{server_name}' installed in project configuration")
535
+ print_info("📁 Created .claude.json for team sharing - commit this file to your repo")
536
+
537
+ # Test the server
538
+ print_info("Testing server startup...")
539
+ _test_mcp_server(project_root)
540
+
541
+ # Check if Claude Code is available and provide guidance
542
+ if not check_claude_code_available():
543
+ print_warning("⚠️ Claude Code not detected on this system")
544
+ print_info("📥 Install Claude Code from: https://claude.ai/download")
545
+ print_info("🔄 After installation, restart Claude Code to detect the MCP server")
546
+ else:
547
+ print_success("✅ Claude Code detected - server should be available automatically")
548
+ print_info("🔄 If Claude Code is running, restart it to detect the new server")
549
+
550
+ print_info("\n📋 Next steps:")
551
+ print_info(" 1. Restart Claude Code if it's currently running")
552
+ print_info(" 2. Open this project in Claude Code")
553
+ print_info(" 3. The MCP server should appear automatically in the tools list")
554
+ print_info(" 4. Test with: 'Search for functions that handle user authentication'")
555
+
556
+ except Exception as e:
557
+ logger.error(f"MCP integration setup failed: {e}")
558
+ print_error(f"MCP integration setup failed: {e}")
559
+ raise typer.Exit(1)
560
+
561
+
562
+ def _test_mcp_server(project_root: Path) -> None:
563
+ """Test MCP server startup and basic functionality."""
564
+ try:
565
+ from .mcp import get_mcp_server_command
566
+ import subprocess
567
+ import json
568
+
569
+ server_command = get_mcp_server_command(project_root)
570
+ test_process = subprocess.Popen(
571
+ server_command.split(),
572
+ stdin=subprocess.PIPE,
573
+ stdout=subprocess.PIPE,
574
+ stderr=subprocess.PIPE,
575
+ text=True
576
+ )
577
+
578
+ # Send a simple initialization request
579
+ init_request = {
580
+ "jsonrpc": "2.0",
581
+ "id": 1,
582
+ "method": "initialize",
583
+ "params": {
584
+ "protocolVersion": "2024-11-05",
585
+ "capabilities": {},
586
+ "clientInfo": {"name": "test", "version": "1.0.0"}
587
+ }
588
+ }
589
+
590
+ try:
591
+ stdout, stderr = test_process.communicate(
592
+ input=json.dumps(init_request) + "\n",
593
+ timeout=10
594
+ )
595
+
596
+ if test_process.returncode == 0:
597
+ print_success("✅ Server startup test passed")
598
+ else:
599
+ print_warning(f"⚠️ Server test failed with return code {test_process.returncode}")
600
+ if stderr:
601
+ print_info(f"Error output: {stderr}")
602
+
603
+ except subprocess.TimeoutExpired:
604
+ test_process.kill()
605
+ print_warning("⚠️ Server test timed out (this may be normal)")
606
+
607
+ except Exception as e:
608
+ print_warning(f"⚠️ Server test failed: {e}")
609
+ print_info("This may be normal - the server should still work with Claude Code")
610
+
611
+
200
612
  @init_app.command("models")
201
613
  def list_embedding_models() -> None:
202
614
  """List available embedding models."""
203
615
  console.print("[bold blue]Available Embedding Models:[/bold blue]\n")
204
-
616
+
205
617
  for category, model in DEFAULT_EMBEDDING_MODELS.items():
206
618
  console.print(f"[cyan]{category.title()}:[/cyan] {model}")
207
-
208
- console.print("\n[dim]You can also use any model from Hugging Face that's compatible with sentence-transformers[/dim]")
619
+
620
+ console.print(
621
+ "\n[dim]You can also use any model from Hugging Face that's compatible with sentence-transformers[/dim]"
622
+ )
209
623
 
210
624
 
211
625
  if __name__ == "__main__":