mcp-vector-search 0.15.7__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 (86) 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/chat.py +534 -0
  6. mcp_vector_search/cli/commands/config.py +393 -0
  7. mcp_vector_search/cli/commands/demo.py +358 -0
  8. mcp_vector_search/cli/commands/index.py +762 -0
  9. mcp_vector_search/cli/commands/init.py +658 -0
  10. mcp_vector_search/cli/commands/install.py +869 -0
  11. mcp_vector_search/cli/commands/install_old.py +700 -0
  12. mcp_vector_search/cli/commands/mcp.py +1254 -0
  13. mcp_vector_search/cli/commands/reset.py +393 -0
  14. mcp_vector_search/cli/commands/search.py +796 -0
  15. mcp_vector_search/cli/commands/setup.py +1133 -0
  16. mcp_vector_search/cli/commands/status.py +584 -0
  17. mcp_vector_search/cli/commands/uninstall.py +404 -0
  18. mcp_vector_search/cli/commands/visualize/__init__.py +39 -0
  19. mcp_vector_search/cli/commands/visualize/cli.py +265 -0
  20. mcp_vector_search/cli/commands/visualize/exporters/__init__.py +12 -0
  21. mcp_vector_search/cli/commands/visualize/exporters/html_exporter.py +33 -0
  22. mcp_vector_search/cli/commands/visualize/exporters/json_exporter.py +29 -0
  23. mcp_vector_search/cli/commands/visualize/graph_builder.py +709 -0
  24. mcp_vector_search/cli/commands/visualize/layout_engine.py +469 -0
  25. mcp_vector_search/cli/commands/visualize/server.py +201 -0
  26. mcp_vector_search/cli/commands/visualize/state_manager.py +428 -0
  27. mcp_vector_search/cli/commands/visualize/templates/__init__.py +16 -0
  28. mcp_vector_search/cli/commands/visualize/templates/base.py +218 -0
  29. mcp_vector_search/cli/commands/visualize/templates/scripts.py +3670 -0
  30. mcp_vector_search/cli/commands/visualize/templates/styles.py +779 -0
  31. mcp_vector_search/cli/commands/visualize.py.original +2536 -0
  32. mcp_vector_search/cli/commands/watch.py +287 -0
  33. mcp_vector_search/cli/didyoumean.py +520 -0
  34. mcp_vector_search/cli/export.py +320 -0
  35. mcp_vector_search/cli/history.py +295 -0
  36. mcp_vector_search/cli/interactive.py +342 -0
  37. mcp_vector_search/cli/main.py +484 -0
  38. mcp_vector_search/cli/output.py +414 -0
  39. mcp_vector_search/cli/suggestions.py +375 -0
  40. mcp_vector_search/config/__init__.py +1 -0
  41. mcp_vector_search/config/constants.py +24 -0
  42. mcp_vector_search/config/defaults.py +200 -0
  43. mcp_vector_search/config/settings.py +146 -0
  44. mcp_vector_search/core/__init__.py +1 -0
  45. mcp_vector_search/core/auto_indexer.py +298 -0
  46. mcp_vector_search/core/config_utils.py +394 -0
  47. mcp_vector_search/core/connection_pool.py +360 -0
  48. mcp_vector_search/core/database.py +1237 -0
  49. mcp_vector_search/core/directory_index.py +318 -0
  50. mcp_vector_search/core/embeddings.py +294 -0
  51. mcp_vector_search/core/exceptions.py +89 -0
  52. mcp_vector_search/core/factory.py +318 -0
  53. mcp_vector_search/core/git_hooks.py +345 -0
  54. mcp_vector_search/core/indexer.py +1002 -0
  55. mcp_vector_search/core/llm_client.py +453 -0
  56. mcp_vector_search/core/models.py +294 -0
  57. mcp_vector_search/core/project.py +350 -0
  58. mcp_vector_search/core/scheduler.py +330 -0
  59. mcp_vector_search/core/search.py +952 -0
  60. mcp_vector_search/core/watcher.py +322 -0
  61. mcp_vector_search/mcp/__init__.py +5 -0
  62. mcp_vector_search/mcp/__main__.py +25 -0
  63. mcp_vector_search/mcp/server.py +752 -0
  64. mcp_vector_search/parsers/__init__.py +8 -0
  65. mcp_vector_search/parsers/base.py +296 -0
  66. mcp_vector_search/parsers/dart.py +605 -0
  67. mcp_vector_search/parsers/html.py +413 -0
  68. mcp_vector_search/parsers/javascript.py +643 -0
  69. mcp_vector_search/parsers/php.py +694 -0
  70. mcp_vector_search/parsers/python.py +502 -0
  71. mcp_vector_search/parsers/registry.py +223 -0
  72. mcp_vector_search/parsers/ruby.py +678 -0
  73. mcp_vector_search/parsers/text.py +186 -0
  74. mcp_vector_search/parsers/utils.py +265 -0
  75. mcp_vector_search/py.typed +1 -0
  76. mcp_vector_search/utils/__init__.py +42 -0
  77. mcp_vector_search/utils/gitignore.py +250 -0
  78. mcp_vector_search/utils/gitignore_updater.py +212 -0
  79. mcp_vector_search/utils/monorepo.py +339 -0
  80. mcp_vector_search/utils/timing.py +338 -0
  81. mcp_vector_search/utils/version.py +47 -0
  82. mcp_vector_search-0.15.7.dist-info/METADATA +884 -0
  83. mcp_vector_search-0.15.7.dist-info/RECORD +86 -0
  84. mcp_vector_search-0.15.7.dist-info/WHEEL +4 -0
  85. mcp_vector_search-0.15.7.dist-info/entry_points.txt +3 -0
  86. mcp_vector_search-0.15.7.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,520 @@
1
+ """Enhanced CLI with 'did you mean' functionality for better user experience."""
2
+
3
+ import difflib
4
+
5
+ import click
6
+ import typer
7
+ from click_didyoumean import DYMGroup
8
+
9
+
10
+ class EnhancedDidYouMeanTyper(typer.Typer):
11
+ """Enhanced Typer class with advanced 'did you mean' functionality."""
12
+
13
+ def __init__(self, *args, **kwargs):
14
+ """Initialize with enhanced did-you-mean support."""
15
+ # Extract Typer-specific kwargs
16
+ typer_kwargs = {}
17
+ click_kwargs = {}
18
+
19
+ # Separate Typer and Click kwargs
20
+ typer_specific = {
21
+ "name",
22
+ "help",
23
+ "epilog",
24
+ "short_help",
25
+ "options_metavar",
26
+ "add_completion",
27
+ "context_settings",
28
+ "callback",
29
+ "invoke_without_command",
30
+ "no_args_is_help",
31
+ "subcommand_metavar",
32
+ "chain",
33
+ "result_callback",
34
+ "deprecated",
35
+ "rich_markup_mode",
36
+ "rich_help_panel",
37
+ "pretty_exceptions_enable",
38
+ "pretty_exceptions_show_locals",
39
+ "pretty_exceptions_short",
40
+ }
41
+
42
+ for key, value in kwargs.items():
43
+ if key in typer_specific:
44
+ typer_kwargs[key] = value
45
+ else:
46
+ click_kwargs[key] = value
47
+
48
+ # Initialize Typer with its specific kwargs
49
+ super().__init__(*args, **typer_kwargs)
50
+
51
+ # Store click kwargs for later use
52
+ self._click_kwargs = click_kwargs
53
+ self.command_aliases = {} # Store command aliases
54
+
55
+ def __call__(self, *args, **kwargs):
56
+ """Override call to use enhanced DYMGroup."""
57
+ # Get the underlying click group
58
+ click_group = super().__call__(*args, **kwargs)
59
+
60
+ # If click_group is None (command already executed), return None
61
+ # This happens after command execution completes successfully
62
+ if click_group is None:
63
+ return None
64
+
65
+ # Create enhanced DYM group with original group's properties
66
+ enhanced_group = EnhancedDidYouMeanGroup(
67
+ name=click_group.name,
68
+ commands=click_group.commands,
69
+ callback=click_group.callback,
70
+ params=click_group.params,
71
+ help=click_group.help,
72
+ epilog=click_group.epilog,
73
+ short_help=click_group.short_help,
74
+ add_help_option=click_group.add_help_option,
75
+ context_settings=click_group.context_settings,
76
+ invoke_without_command=click_group.invoke_without_command,
77
+ no_args_is_help=click_group.no_args_is_help,
78
+ subcommand_metavar=click_group.subcommand_metavar,
79
+ chain=click_group.chain,
80
+ result_callback=click_group.result_callback,
81
+ deprecated=click_group.deprecated,
82
+ **self._click_kwargs,
83
+ )
84
+
85
+ # Additional attributes that might be needed
86
+ if hasattr(click_group, "options_metavar"):
87
+ enhanced_group.options_metavar = click_group.options_metavar
88
+
89
+ return enhanced_group
90
+
91
+ def add_alias(self, command_name: str, alias: str) -> None:
92
+ """Add an alias for a command.
93
+
94
+ Args:
95
+ command_name: The original command name
96
+ alias: The alias to add
97
+ """
98
+ self.command_aliases[alias] = command_name
99
+
100
+
101
+ class EnhancedDidYouMeanGroup(DYMGroup):
102
+ """Enhanced Click group with advanced 'did you mean' functionality."""
103
+
104
+ def __init__(self, *args, **kwargs):
105
+ """Initialize with better error messages and fuzzy matching."""
106
+ super().__init__(*args, **kwargs)
107
+ self.max_suggestions = 3 # Maximum number of suggestions to show
108
+
109
+ def resolve_command(self, ctx: click.Context, args: list) -> tuple:
110
+ """Resolve command with enhanced error handling and suggestions."""
111
+ try:
112
+ return super().resolve_command(ctx, args)
113
+ except click.UsageError as e:
114
+ # Enhanced error handling with better suggestions
115
+ if "No such command" in str(e) and args:
116
+ command_name = args[0]
117
+
118
+ # Use our enhanced suggestion system
119
+ add_common_suggestions(ctx, command_name)
120
+
121
+ # Re-raise with original message (suggestions already printed)
122
+ raise click.UsageError(str(e), ctx=ctx)
123
+ raise
124
+
125
+ def get_command(self, ctx: click.Context, cmd_name: str):
126
+ """Get command with support for aliases and shortcuts."""
127
+ # First try exact match
128
+ rv = super().get_command(ctx, cmd_name)
129
+ if rv is not None:
130
+ return rv
131
+
132
+ # Try common typo mappings
133
+ suggestion = COMMON_TYPOS.get(cmd_name.lower())
134
+ if suggestion and " " not in suggestion: # Only single commands, not flags
135
+ return super().get_command(ctx, suggestion)
136
+
137
+ return None
138
+
139
+
140
+ def create_enhanced_typer(**kwargs) -> typer.Typer:
141
+ """Create a Typer instance with enhanced 'did you mean' functionality."""
142
+ # Set default values for better UX
143
+ defaults = {
144
+ "no_args_is_help": True,
145
+ "add_completion": False,
146
+ "rich_markup_mode": "rich",
147
+ }
148
+
149
+ # Merge with provided kwargs
150
+ final_kwargs = {**defaults, **kwargs}
151
+
152
+ # Create the enhanced Typer
153
+ app = EnhancedDidYouMeanTyper(**final_kwargs)
154
+
155
+ return app
156
+
157
+
158
+ def enhance_existing_typer(app: typer.Typer) -> typer.Typer:
159
+ """Enhance an existing Typer app with advanced 'did you mean' functionality."""
160
+ # This is a bit tricky since we need to modify the underlying Click group
161
+ # We'll create a wrapper that intercepts the click group creation
162
+
163
+ original_call = app.__call__
164
+
165
+ def enhanced_call(*args, **kwargs):
166
+ """Enhanced call that uses EnhancedDidYouMeanGroup."""
167
+ click_group = original_call(*args, **kwargs)
168
+
169
+ # If click_group is None (command already executed), return None
170
+ # This happens after command execution completes successfully
171
+ if click_group is None:
172
+ return None
173
+
174
+ # Create enhanced group
175
+ enhanced_group = EnhancedDidYouMeanGroup(
176
+ name=click_group.name,
177
+ commands=click_group.commands,
178
+ callback=click_group.callback,
179
+ params=click_group.params,
180
+ help=click_group.help,
181
+ epilog=click_group.epilog,
182
+ short_help=click_group.short_help,
183
+ options_metavar=click_group.options_metavar,
184
+ add_help_option=click_group.add_help_option,
185
+ context_settings=click_group.context_settings,
186
+ invoke_without_command=click_group.invoke_without_command,
187
+ no_args_is_help=click_group.no_args_is_help,
188
+ subcommand_metavar=click_group.subcommand_metavar,
189
+ chain=click_group.chain,
190
+ result_callback=click_group.result_callback,
191
+ deprecated=click_group.deprecated,
192
+ )
193
+
194
+ return enhanced_group
195
+
196
+ app.__call__ = enhanced_call
197
+ return app
198
+
199
+
200
+ # Enhanced typo mapping with comprehensive variations
201
+ COMMON_TYPOS = {
202
+ # Search command variations
203
+ "serach": "search",
204
+ "seach": "search",
205
+ "searh": "search",
206
+ "sarch": "search",
207
+ "serch": "search",
208
+ "searhc": "search",
209
+ "find": "search",
210
+ "query": "search",
211
+ "lookup": "search",
212
+ "grep": "search",
213
+ "s": "search", # Single letter shortcut
214
+ "f": "search", # Alternative shortcut for find
215
+ # Chat command variations
216
+ "cht": "chat",
217
+ "caht": "chat",
218
+ "chta": "chat",
219
+ "ask": "chat",
220
+ "question": "chat",
221
+ "qa": "chat",
222
+ "llm": "chat",
223
+ "gpt": "chat",
224
+ "explain": "chat",
225
+ "answer": "chat",
226
+ # Index command variations
227
+ "indx": "index",
228
+ "idx": "index",
229
+ "indexx": "index",
230
+ "indez": "index",
231
+ "inedx": "index",
232
+ "reindex": "index --force",
233
+ "rebuild": "index --force",
234
+ "refresh": "index --force",
235
+ "scan": "index",
236
+ "build": "index",
237
+ "i": "index", # Single letter shortcut
238
+ "b": "index", # Alternative shortcut for build
239
+ # Status command variations
240
+ "stat": "status",
241
+ "stats": "status",
242
+ "info": "status",
243
+ "information": "status",
244
+ "details": "status",
245
+ "summary": "status",
246
+ "overview": "status",
247
+ "st": "status", # Common abbreviation
248
+ "status": "status",
249
+ # Config command variations
250
+ "conf": "config",
251
+ "cfg": "config",
252
+ "configure": "config",
253
+ "configuration": "config",
254
+ "setting": "config",
255
+ "settings": "config",
256
+ "preferences": "config",
257
+ "prefs": "config",
258
+ "c": "config", # Single letter shortcut
259
+ # Init command variations
260
+ "initialize": "init",
261
+ "setup": "init",
262
+ "start": "init",
263
+ "create": "init",
264
+ "new": "init",
265
+ "begin": "init",
266
+ "initalize": "init", # Common misspelling
267
+ "initalise": "init",
268
+ "initialise": "init",
269
+ # Watch command variations
270
+ "monitor": "watch",
271
+ "observe": "watch",
272
+ "track": "watch",
273
+ "listen": "watch",
274
+ "follow": "watch",
275
+ "w": "watch", # Single letter shortcut
276
+ # Auto-index command variations
277
+ "auto": "auto-index",
278
+ "automatic": "auto-index",
279
+ "autoindex": "auto-index",
280
+ "auto_index": "auto-index",
281
+ "ai": "auto-index", # Abbreviation
282
+ # MCP command variations
283
+ "claude": "mcp",
284
+ "server": "mcp",
285
+ "protocol": "mcp",
286
+ "model-context": "mcp",
287
+ "context": "mcp",
288
+ "m": "mcp", # Single letter shortcut
289
+ # Install command variations
290
+ "deploy": "install",
291
+ "add": "install",
292
+ "instal": "install", # Common typo
293
+ "install": "install",
294
+ # Demo command variations
295
+ "example": "demo",
296
+ "sample": "demo",
297
+ "test": "demo",
298
+ "try": "demo",
299
+ "d": "demo", # Single letter shortcut
300
+ # Health/Doctor command variations
301
+ "check": "doctor",
302
+ "health": "doctor",
303
+ "diagnose": "doctor",
304
+ "verify": "doctor",
305
+ "validate": "doctor",
306
+ "repair": "doctor",
307
+ "fix": "doctor",
308
+ "dr": "doctor", # Common abbreviation
309
+ # Version command variations
310
+ "ver": "version",
311
+ "v": "version",
312
+ "--version": "version",
313
+ "-v": "version",
314
+ # Help command variations
315
+ "help": "--help",
316
+ "h": "--help",
317
+ "--help": "--help",
318
+ "-h": "--help",
319
+ "?": "--help",
320
+ # History command variations
321
+ "hist": "history",
322
+ "log": "history",
323
+ "logs": "history",
324
+ "recent": "history",
325
+ # Reset command variations
326
+ "clear": "reset",
327
+ "clean": "reset",
328
+ "purge": "reset",
329
+ "wipe": "reset",
330
+ "remove": "reset",
331
+ "delete": "reset",
332
+ # Interactive command variations
333
+ "interact": "interactive",
334
+ "session": "interactive",
335
+ "repl": "interactive",
336
+ "console": "interactive",
337
+ "ui": "interactive",
338
+ }
339
+
340
+ # Command descriptions and examples for better error messages
341
+ COMMAND_INFO = {
342
+ "search": {
343
+ "description": "Search for code patterns semantically",
344
+ "examples": [
345
+ 'mcp-vector-search search "authentication function"',
346
+ 'mcp-vector-search search "error handling" --limit 5',
347
+ 'mcp-vector-search search --files "*.ts" "query"',
348
+ ],
349
+ "related": ["chat", "index", "status"],
350
+ },
351
+ "chat": {
352
+ "description": "Ask AI questions about your code (requires API key)",
353
+ "examples": [
354
+ 'mcp-vector-search chat "where is the database configured?"',
355
+ 'mcp-vector-search chat "how does authentication work?"',
356
+ 'mcp-vector-search chat --limit 3 "explain error handling"',
357
+ ],
358
+ "related": ["search", "status", "index"],
359
+ },
360
+ "index": {
361
+ "description": "Index codebase for semantic search",
362
+ "examples": [
363
+ "mcp-vector-search index",
364
+ "mcp-vector-search index --force",
365
+ 'mcp-vector-search index --include "*.py,*.js"',
366
+ ],
367
+ "related": ["auto-index", "watch", "reset"],
368
+ },
369
+ "status": {
370
+ "description": "Show project status and statistics",
371
+ "examples": ["mcp-vector-search status", "mcp-vector-search status --verbose"],
372
+ "related": ["doctor", "history", "version"],
373
+ },
374
+ "config": {
375
+ "description": "Manage project configuration",
376
+ "examples": [
377
+ "mcp-vector-search config show",
378
+ "mcp-vector-search config set model all-MiniLM-L6-v2",
379
+ ],
380
+ "related": ["init", "status"],
381
+ },
382
+ "init": {
383
+ "description": "Initialize project for semantic search",
384
+ "examples": [
385
+ "mcp-vector-search init",
386
+ "mcp-vector-search init --model sentence-transformers/all-MiniLM-L6-v2",
387
+ ],
388
+ "related": ["config", "install", "index"],
389
+ },
390
+ "mcp": {
391
+ "description": "Manage Claude Code MCP integration",
392
+ "examples": ["mcp-vector-search mcp", "mcp-vector-search mcp test"],
393
+ "related": ["init-mcp", "install"],
394
+ },
395
+ "doctor": {
396
+ "description": "Check system dependencies and configuration",
397
+ "examples": [
398
+ "mcp-vector-search doctor",
399
+ ],
400
+ "related": ["status", "health"],
401
+ },
402
+ "version": {
403
+ "description": "Show version information",
404
+ "examples": ["mcp-vector-search version", "mcp-vector-search --version"],
405
+ "related": ["status", "doctor"],
406
+ },
407
+ }
408
+
409
+
410
+ def get_fuzzy_matches(
411
+ command: str, available_commands: list[str], cutoff: float = 0.6
412
+ ) -> list[tuple[str, float]]:
413
+ """Get fuzzy matches for a command using difflib.
414
+
415
+ Args:
416
+ command: The command to match
417
+ available_commands: List of available commands
418
+ cutoff: Minimum similarity ratio (0.0 to 1.0)
419
+
420
+ Returns:
421
+ List of tuples (command, similarity_ratio) sorted by similarity
422
+ """
423
+ matches = []
424
+ for cmd in available_commands:
425
+ ratio = difflib.SequenceMatcher(None, command.lower(), cmd.lower()).ratio()
426
+ if ratio >= cutoff:
427
+ matches.append((cmd, ratio))
428
+
429
+ # Sort by similarity ratio (highest first)
430
+ return sorted(matches, key=lambda x: x[1], reverse=True)
431
+
432
+
433
+ def format_command_suggestion(command: str, show_examples: bool = True) -> str:
434
+ """Format a command suggestion with description and examples.
435
+
436
+ Args:
437
+ command: The command to format
438
+ show_examples: Whether to include usage examples
439
+
440
+ Returns:
441
+ Formatted suggestion string
442
+ """
443
+ if command in COMMAND_INFO:
444
+ info = COMMAND_INFO[command]
445
+ suggestion = f" [bold cyan]{command}[/bold cyan] - {info['description']}"
446
+
447
+ if show_examples and info["examples"]:
448
+ suggestion += f"\n Example: [dim]{info['examples'][0]}[/dim]"
449
+
450
+ return suggestion
451
+ else:
452
+ return f" [bold cyan]{command}[/bold cyan]"
453
+
454
+
455
+ def add_common_suggestions(ctx: click.Context, command_name: str) -> None:
456
+ """Add enhanced command suggestions to error messages.
457
+
458
+ Args:
459
+ ctx: Click context
460
+ command_name: The invalid command name that was entered
461
+ """
462
+ from rich.console import Console
463
+
464
+ console = Console(stderr=True)
465
+
466
+ # First, check for exact typo matches
467
+ direct_suggestion = COMMON_TYPOS.get(command_name.lower())
468
+ if direct_suggestion:
469
+ console.print("\n[yellow]Did you mean:[/yellow]")
470
+ console.print(format_command_suggestion(direct_suggestion.split()[0]))
471
+
472
+ if "--" not in direct_suggestion: # Don't show examples for flags
473
+ console.print(
474
+ f"\n[dim]Try: [bold]mcp-vector-search {direct_suggestion}[/bold][/dim]"
475
+ )
476
+ return
477
+
478
+ # Get available commands from the context
479
+ available_commands = []
480
+ if hasattr(ctx, "command") and hasattr(ctx.command, "commands"):
481
+ available_commands = list(ctx.command.commands.keys())
482
+
483
+ if not available_commands:
484
+ # Fallback to common commands
485
+ available_commands = [
486
+ "search",
487
+ "index",
488
+ "status",
489
+ "config",
490
+ "init",
491
+ "mcp",
492
+ "doctor",
493
+ "version",
494
+ ]
495
+
496
+ # Get fuzzy matches
497
+ fuzzy_matches = get_fuzzy_matches(command_name, available_commands, cutoff=0.4)
498
+
499
+ if fuzzy_matches:
500
+ console.print("\n[yellow]Did you mean one of these?[/yellow]")
501
+
502
+ # Show up to 3 best matches
503
+ for cmd, _ratio in fuzzy_matches[:3]:
504
+ console.print(format_command_suggestion(cmd, show_examples=False))
505
+
506
+ # Show example for the best match
507
+ if fuzzy_matches:
508
+ best_match = fuzzy_matches[0][0]
509
+ if best_match in COMMAND_INFO and COMMAND_INFO[best_match]["examples"]:
510
+ console.print(
511
+ f"\n[dim]Example: [bold]{COMMAND_INFO[best_match]['examples'][0]}[/bold][/dim]"
512
+ )
513
+
514
+ # Show related commands for context
515
+ console.print(
516
+ f"\n[dim]Available commands: {', '.join(sorted(available_commands))}[/dim]"
517
+ )
518
+ console.print(
519
+ "[dim]Use [bold]mcp-vector-search --help[/bold] for more information[/dim]"
520
+ )