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,393 @@
1
+ """Config command for MCP Vector Search CLI."""
2
+
3
+ from pathlib import Path
4
+
5
+ import typer
6
+ from loguru import logger
7
+
8
+ from ...core.exceptions import ConfigurationError, ProjectNotFoundError
9
+ from ...core.project import ProjectManager
10
+ from ..output import (
11
+ console,
12
+ print_config,
13
+ print_error,
14
+ print_info,
15
+ print_json,
16
+ print_success,
17
+ )
18
+
19
+ # Create config subcommand app
20
+ config_app = typer.Typer(help="Manage project configuration")
21
+
22
+
23
+ @config_app.command()
24
+ def show(
25
+ ctx: typer.Context,
26
+ project_root: Path | None = typer.Option(
27
+ None,
28
+ "--project-root",
29
+ "-p",
30
+ help="Project root directory (auto-detected if not specified)",
31
+ exists=True,
32
+ file_okay=False,
33
+ dir_okay=True,
34
+ readable=True,
35
+ ),
36
+ json_output: bool = typer.Option(
37
+ False,
38
+ "--json",
39
+ help="Output configuration in JSON format",
40
+ ),
41
+ ) -> None:
42
+ """Show current project configuration."""
43
+ try:
44
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
45
+ project_manager = ProjectManager(project_root)
46
+
47
+ if not project_manager.is_initialized():
48
+ raise ProjectNotFoundError(
49
+ f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
50
+ )
51
+
52
+ config = project_manager.load_config()
53
+ config_dict = config.dict()
54
+
55
+ if json_output:
56
+ print_json(config_dict, title="Project Configuration")
57
+ else:
58
+ console.print("[bold blue]Project Configuration[/bold blue]\n")
59
+ print_config(config_dict)
60
+
61
+ except ProjectNotFoundError as e:
62
+ print_error(str(e))
63
+ raise typer.Exit(1)
64
+ except Exception as e:
65
+ logger.error(f"Failed to show configuration: {e}")
66
+ print_error(f"Failed to show configuration: {e}")
67
+ raise typer.Exit(1)
68
+
69
+
70
+ @config_app.command()
71
+ def set(
72
+ ctx: typer.Context,
73
+ key: str = typer.Argument(..., help="Configuration key to set"),
74
+ value: str = typer.Argument(..., help="Configuration value"),
75
+ project_root: Path | None = typer.Option(
76
+ None,
77
+ "--project-root",
78
+ "-p",
79
+ help="Project root directory (auto-detected if not specified)",
80
+ exists=True,
81
+ file_okay=False,
82
+ dir_okay=True,
83
+ readable=True,
84
+ ),
85
+ ) -> None:
86
+ """Set a configuration value.
87
+
88
+ Examples:
89
+ mcp-vector-search config set similarity_threshold 0.8
90
+ mcp-vector-search config set embedding_model microsoft/unixcoder-base
91
+ mcp-vector-search config set cache_embeddings true
92
+ """
93
+ try:
94
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
95
+ project_manager = ProjectManager(project_root)
96
+
97
+ if not project_manager.is_initialized():
98
+ raise ProjectNotFoundError(
99
+ f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
100
+ )
101
+
102
+ config = project_manager.load_config()
103
+
104
+ # Parse and validate the value
105
+ parsed_value = _parse_config_value(key, value)
106
+
107
+ # Update configuration
108
+ if hasattr(config, key):
109
+ setattr(config, key, parsed_value)
110
+ project_manager.save_config(config)
111
+ print_success(f"Set {key} = {parsed_value}")
112
+ else:
113
+ print_error(f"Unknown configuration key: {key}")
114
+ _show_available_keys()
115
+ raise typer.Exit(1)
116
+
117
+ except (ProjectNotFoundError, ConfigurationError) as e:
118
+ print_error(str(e))
119
+ raise typer.Exit(1)
120
+ except Exception as e:
121
+ logger.error(f"Failed to set configuration: {e}")
122
+ print_error(f"Failed to set configuration: {e}")
123
+ raise typer.Exit(1)
124
+
125
+
126
+ @config_app.command()
127
+ def get(
128
+ ctx: typer.Context,
129
+ key: str = typer.Argument(..., help="Configuration key to get"),
130
+ project_root: Path | None = typer.Option(
131
+ None,
132
+ "--project-root",
133
+ "-p",
134
+ help="Project root directory (auto-detected if not specified)",
135
+ exists=True,
136
+ file_okay=False,
137
+ dir_okay=True,
138
+ readable=True,
139
+ ),
140
+ ) -> None:
141
+ """Get a specific configuration value."""
142
+ try:
143
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
144
+ project_manager = ProjectManager(project_root)
145
+
146
+ if not project_manager.is_initialized():
147
+ raise ProjectNotFoundError(
148
+ f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
149
+ )
150
+
151
+ config = project_manager.load_config()
152
+
153
+ if hasattr(config, key):
154
+ value = getattr(config, key)
155
+ console.print(f"[cyan]{key}[/cyan]: {value}")
156
+ else:
157
+ print_error(f"Unknown configuration key: {key}")
158
+ _show_available_keys()
159
+ raise typer.Exit(1)
160
+
161
+ except ProjectNotFoundError as e:
162
+ print_error(str(e))
163
+ raise typer.Exit(1)
164
+ except Exception as e:
165
+ logger.error(f"Failed to get configuration: {e}")
166
+ print_error(f"Failed to get configuration: {e}")
167
+ raise typer.Exit(1)
168
+
169
+
170
+ @config_app.command()
171
+ def reset(
172
+ ctx: typer.Context,
173
+ key: str | None = typer.Argument(
174
+ None, help="Configuration key to reset (resets all if not specified)"
175
+ ),
176
+ project_root: Path | None = typer.Option(
177
+ None,
178
+ "--project-root",
179
+ "-p",
180
+ help="Project root directory (auto-detected if not specified)",
181
+ exists=True,
182
+ file_okay=False,
183
+ dir_okay=True,
184
+ readable=True,
185
+ ),
186
+ confirm: bool = typer.Option(
187
+ False,
188
+ "--yes",
189
+ "-y",
190
+ help="Skip confirmation prompt",
191
+ ),
192
+ ) -> None:
193
+ """Reset configuration to defaults."""
194
+ try:
195
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
196
+ project_manager = ProjectManager(project_root)
197
+
198
+ if not project_manager.is_initialized():
199
+ raise ProjectNotFoundError(
200
+ f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
201
+ )
202
+
203
+ if not confirm:
204
+ from ..output import confirm_action
205
+
206
+ if key:
207
+ message = f"Reset '{key}' to default value?"
208
+ else:
209
+ message = "Reset all configuration to defaults?"
210
+
211
+ if not confirm_action(message, default=False):
212
+ print_info("Reset cancelled")
213
+ raise typer.Exit(0)
214
+
215
+ if key:
216
+ # Reset specific key
217
+ config = project_manager.load_config()
218
+ default_value = _get_default_value(key)
219
+
220
+ if hasattr(config, key):
221
+ setattr(config, key, default_value)
222
+ project_manager.save_config(config)
223
+ print_success(f"Reset {key} to default value: {default_value}")
224
+ else:
225
+ print_error(f"Unknown configuration key: {key}")
226
+ raise typer.Exit(1)
227
+ else:
228
+ # Reset all configuration by re-initializing
229
+ from ...config.defaults import (
230
+ DEFAULT_EMBEDDING_MODELS,
231
+ DEFAULT_FILE_EXTENSIONS,
232
+ )
233
+
234
+ config = project_manager.initialize(
235
+ file_extensions=DEFAULT_FILE_EXTENSIONS,
236
+ embedding_model=DEFAULT_EMBEDDING_MODELS["code"],
237
+ similarity_threshold=0.75,
238
+ force=True,
239
+ )
240
+ print_success("Reset all configuration to defaults")
241
+
242
+ except (ProjectNotFoundError, ConfigurationError) as e:
243
+ print_error(str(e))
244
+ raise typer.Exit(1)
245
+ except Exception as e:
246
+ logger.error(f"Failed to reset configuration: {e}")
247
+ print_error(f"Failed to reset configuration: {e}")
248
+ raise typer.Exit(1)
249
+
250
+
251
+ @config_app.command("list-keys")
252
+ def list_keys() -> None:
253
+ """List all available configuration keys."""
254
+ _show_available_keys()
255
+
256
+
257
+ def _parse_config_value(key: str, value: str):
258
+ """Parse configuration value based on key type."""
259
+ # Boolean values
260
+ if key in [
261
+ "cache_embeddings",
262
+ "watch_files",
263
+ "skip_dotfiles",
264
+ "respect_gitignore",
265
+ "auto_reindex_on_upgrade",
266
+ ]:
267
+ return value.lower() in ("true", "yes", "1", "on")
268
+
269
+ # Float values
270
+ if key in ["similarity_threshold"]:
271
+ try:
272
+ parsed = float(value)
273
+ if key == "similarity_threshold" and not (0.0 <= parsed <= 1.0):
274
+ raise ValueError("Similarity threshold must be between 0.0 and 1.0")
275
+ return parsed
276
+ except ValueError as e:
277
+ raise ConfigurationError(f"Invalid float value for {key}: {value}") from e
278
+
279
+ # Integer values
280
+ if key in ["max_chunk_size", "max_cache_size"]:
281
+ try:
282
+ parsed = int(value)
283
+ if parsed <= 0:
284
+ raise ValueError("Value must be positive")
285
+ return parsed
286
+ except ValueError as e:
287
+ raise ConfigurationError(f"Invalid integer value for {key}: {value}") from e
288
+
289
+ # List values
290
+ if key in ["file_extensions", "languages"]:
291
+ if value.startswith("[") and value.endswith("]"):
292
+ # JSON-style list
293
+ import json
294
+
295
+ try:
296
+ return json.loads(value)
297
+ except json.JSONDecodeError as e:
298
+ raise ConfigurationError(f"Invalid JSON list for {key}: {value}") from e
299
+ else:
300
+ # Comma-separated list
301
+ items = [item.strip() for item in value.split(",")]
302
+ if key == "file_extensions":
303
+ # Ensure extensions start with dot
304
+ items = [ext if ext.startswith(".") else f".{ext}" for ext in items]
305
+ return items
306
+
307
+ # Path values
308
+ if key in ["project_root", "index_path"]:
309
+ return Path(value)
310
+
311
+ # String values (default)
312
+ return value
313
+
314
+
315
+ def _get_default_value(key: str):
316
+ """Get default value for a configuration key."""
317
+ from ...config.defaults import DEFAULT_EMBEDDING_MODELS, DEFAULT_FILE_EXTENSIONS
318
+
319
+ defaults = {
320
+ "file_extensions": DEFAULT_FILE_EXTENSIONS,
321
+ "embedding_model": DEFAULT_EMBEDDING_MODELS["code"],
322
+ "similarity_threshold": 0.5,
323
+ "max_chunk_size": 512,
324
+ "languages": [],
325
+ "watch_files": False,
326
+ "cache_embeddings": True,
327
+ "max_cache_size": 1000,
328
+ "skip_dotfiles": True,
329
+ "respect_gitignore": True,
330
+ "auto_reindex_on_upgrade": True,
331
+ }
332
+
333
+ return defaults.get(key, "")
334
+
335
+
336
+ def _show_available_keys() -> None:
337
+ """Show all available configuration keys."""
338
+ console.print("\n[bold blue]Available Configuration Keys:[/bold blue]")
339
+
340
+ keys_info = [
341
+ ("file_extensions", "List of file extensions to index", "list"),
342
+ ("embedding_model", "Embedding model name", "string"),
343
+ ("similarity_threshold", "Similarity threshold (0.0-1.0)", "float"),
344
+ ("max_chunk_size", "Maximum chunk size in tokens", "integer"),
345
+ ("languages", "Detected programming languages", "list"),
346
+ ("watch_files", "Enable file watching", "boolean"),
347
+ ("cache_embeddings", "Enable embedding caching", "boolean"),
348
+ ("max_cache_size", "Maximum cache size", "integer"),
349
+ ("skip_dotfiles", "Skip dotfiles/directories (except whitelisted)", "boolean"),
350
+ ("respect_gitignore", "Respect .gitignore patterns", "boolean"),
351
+ ("auto_reindex_on_upgrade", "Auto-reindex on version upgrade", "boolean"),
352
+ ]
353
+
354
+ for key, description, value_type in keys_info:
355
+ console.print(f" [cyan]{key}[/cyan] ({value_type}): {description}")
356
+
357
+ console.print(
358
+ "\n[dim]Use 'mcp-vector-search config set <key> <value>' to change values[/dim]"
359
+ )
360
+
361
+
362
+ # ============================================================================
363
+ # CONFIG SUBCOMMANDS
364
+ # ============================================================================
365
+
366
+
367
+ @config_app.command("models")
368
+ def list_embedding_models() -> None:
369
+ """📚 List available embedding models.
370
+
371
+ Shows all available embedding models that can be used for semantic search.
372
+ You can also use any model from Hugging Face that's compatible with sentence-transformers.
373
+
374
+ Examples:
375
+ mcp-vector-search config models
376
+ """
377
+ from ...config.defaults import DEFAULT_EMBEDDING_MODELS
378
+
379
+ console.print("[bold blue]Available Embedding Models:[/bold blue]\n")
380
+
381
+ for category, model in DEFAULT_EMBEDDING_MODELS.items():
382
+ console.print(f"[cyan]{category.title()}:[/cyan] {model}")
383
+
384
+ console.print(
385
+ "\n[dim]You can also use any model from Hugging Face that's compatible with sentence-transformers[/dim]"
386
+ )
387
+ console.print(
388
+ "[dim]Set model: [cyan]mcp-vector-search config set embedding_model MODEL_NAME[/cyan][/dim]"
389
+ )
390
+
391
+
392
+ if __name__ == "__main__":
393
+ config_app()