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
  """Config command for MCP Vector Search CLI."""
2
2
 
3
3
  from pathlib import Path
4
- from typing import Optional
5
4
 
6
5
  import typer
7
6
  from loguru import logger
@@ -24,6 +23,16 @@ config_app = typer.Typer(help="Manage project configuration")
24
23
  @config_app.command()
25
24
  def show(
26
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
+ ),
27
36
  json_output: bool = typer.Option(
28
37
  False,
29
38
  "--json",
@@ -32,23 +41,23 @@ def show(
32
41
  ) -> None:
33
42
  """Show current project configuration."""
34
43
  try:
35
- project_root = ctx.obj.get("project_root") or Path.cwd()
44
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
36
45
  project_manager = ProjectManager(project_root)
37
-
46
+
38
47
  if not project_manager.is_initialized():
39
48
  raise ProjectNotFoundError(
40
49
  f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
41
50
  )
42
-
51
+
43
52
  config = project_manager.load_config()
44
53
  config_dict = config.dict()
45
-
54
+
46
55
  if json_output:
47
56
  print_json(config_dict, title="Project Configuration")
48
57
  else:
49
58
  console.print("[bold blue]Project Configuration[/bold blue]\n")
50
59
  print_config(config_dict)
51
-
60
+
52
61
  except ProjectNotFoundError as e:
53
62
  print_error(str(e))
54
63
  raise typer.Exit(1)
@@ -63,28 +72,38 @@ def set(
63
72
  ctx: typer.Context,
64
73
  key: str = typer.Argument(..., help="Configuration key to set"),
65
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
+ ),
66
85
  ) -> None:
67
86
  """Set a configuration value.
68
-
87
+
69
88
  Examples:
70
89
  mcp-vector-search config set similarity_threshold 0.8
71
90
  mcp-vector-search config set embedding_model microsoft/unixcoder-base
72
91
  mcp-vector-search config set cache_embeddings true
73
92
  """
74
93
  try:
75
- project_root = ctx.obj.get("project_root") or Path.cwd()
94
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
76
95
  project_manager = ProjectManager(project_root)
77
-
96
+
78
97
  if not project_manager.is_initialized():
79
98
  raise ProjectNotFoundError(
80
99
  f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
81
100
  )
82
-
101
+
83
102
  config = project_manager.load_config()
84
-
103
+
85
104
  # Parse and validate the value
86
105
  parsed_value = _parse_config_value(key, value)
87
-
106
+
88
107
  # Update configuration
89
108
  if hasattr(config, key):
90
109
  setattr(config, key, parsed_value)
@@ -94,7 +113,7 @@ def set(
94
113
  print_error(f"Unknown configuration key: {key}")
95
114
  _show_available_keys()
96
115
  raise typer.Exit(1)
97
-
116
+
98
117
  except (ProjectNotFoundError, ConfigurationError) as e:
99
118
  print_error(str(e))
100
119
  raise typer.Exit(1)
@@ -108,19 +127,29 @@ def set(
108
127
  def get(
109
128
  ctx: typer.Context,
110
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
+ ),
111
140
  ) -> None:
112
141
  """Get a specific configuration value."""
113
142
  try:
114
- project_root = ctx.obj.get("project_root") or Path.cwd()
143
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
115
144
  project_manager = ProjectManager(project_root)
116
-
145
+
117
146
  if not project_manager.is_initialized():
118
147
  raise ProjectNotFoundError(
119
148
  f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
120
149
  )
121
-
150
+
122
151
  config = project_manager.load_config()
123
-
152
+
124
153
  if hasattr(config, key):
125
154
  value = getattr(config, key)
126
155
  console.print(f"[cyan]{key}[/cyan]: {value}")
@@ -128,7 +157,7 @@ def get(
128
157
  print_error(f"Unknown configuration key: {key}")
129
158
  _show_available_keys()
130
159
  raise typer.Exit(1)
131
-
160
+
132
161
  except ProjectNotFoundError as e:
133
162
  print_error(str(e))
134
163
  raise typer.Exit(1)
@@ -141,7 +170,19 @@ def get(
141
170
  @config_app.command()
142
171
  def reset(
143
172
  ctx: typer.Context,
144
- key: Optional[str] = typer.Argument(None, help="Configuration key to reset (resets all if not specified)"),
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
+ ),
145
186
  confirm: bool = typer.Option(
146
187
  False,
147
188
  "--yes",
@@ -151,30 +192,31 @@ def reset(
151
192
  ) -> None:
152
193
  """Reset configuration to defaults."""
153
194
  try:
154
- project_root = ctx.obj.get("project_root") or Path.cwd()
195
+ project_root = project_root or ctx.obj.get("project_root") or Path.cwd()
155
196
  project_manager = ProjectManager(project_root)
156
-
197
+
157
198
  if not project_manager.is_initialized():
158
199
  raise ProjectNotFoundError(
159
200
  f"Project not initialized at {project_root}. Run 'mcp-vector-search init' first."
160
201
  )
161
-
202
+
162
203
  if not confirm:
163
204
  from ..output import confirm_action
205
+
164
206
  if key:
165
207
  message = f"Reset '{key}' to default value?"
166
208
  else:
167
209
  message = "Reset all configuration to defaults?"
168
-
210
+
169
211
  if not confirm_action(message, default=False):
170
212
  print_info("Reset cancelled")
171
213
  raise typer.Exit(0)
172
-
214
+
173
215
  if key:
174
216
  # Reset specific key
175
217
  config = project_manager.load_config()
176
218
  default_value = _get_default_value(key)
177
-
219
+
178
220
  if hasattr(config, key):
179
221
  setattr(config, key, default_value)
180
222
  project_manager.save_config(config)
@@ -184,8 +226,11 @@ def reset(
184
226
  raise typer.Exit(1)
185
227
  else:
186
228
  # Reset all configuration by re-initializing
187
- from ...config.defaults import DEFAULT_EMBEDDING_MODELS, DEFAULT_FILE_EXTENSIONS
188
-
229
+ from ...config.defaults import (
230
+ DEFAULT_EMBEDDING_MODELS,
231
+ DEFAULT_FILE_EXTENSIONS,
232
+ )
233
+
189
234
  config = project_manager.initialize(
190
235
  file_extensions=DEFAULT_FILE_EXTENSIONS,
191
236
  embedding_model=DEFAULT_EMBEDDING_MODELS["code"],
@@ -193,7 +238,7 @@ def reset(
193
238
  force=True,
194
239
  )
195
240
  print_success("Reset all configuration to defaults")
196
-
241
+
197
242
  except (ProjectNotFoundError, ConfigurationError) as e:
198
243
  print_error(str(e))
199
244
  raise typer.Exit(1)
@@ -214,7 +259,7 @@ def _parse_config_value(key: str, value: str):
214
259
  # Boolean values
215
260
  if key in ["cache_embeddings", "watch_files"]:
216
261
  return value.lower() in ("true", "yes", "1", "on")
217
-
262
+
218
263
  # Float values
219
264
  if key in ["similarity_threshold"]:
220
265
  try:
@@ -224,7 +269,7 @@ def _parse_config_value(key: str, value: str):
224
269
  return parsed
225
270
  except ValueError as e:
226
271
  raise ConfigurationError(f"Invalid float value for {key}: {value}") from e
227
-
272
+
228
273
  # Integer values
229
274
  if key in ["max_chunk_size", "max_cache_size"]:
230
275
  try:
@@ -234,12 +279,13 @@ def _parse_config_value(key: str, value: str):
234
279
  return parsed
235
280
  except ValueError as e:
236
281
  raise ConfigurationError(f"Invalid integer value for {key}: {value}") from e
237
-
282
+
238
283
  # List values
239
284
  if key in ["file_extensions", "languages"]:
240
285
  if value.startswith("[") and value.endswith("]"):
241
286
  # JSON-style list
242
287
  import json
288
+
243
289
  try:
244
290
  return json.loads(value)
245
291
  except json.JSONDecodeError as e:
@@ -251,11 +297,11 @@ def _parse_config_value(key: str, value: str):
251
297
  # Ensure extensions start with dot
252
298
  items = [ext if ext.startswith(".") else f".{ext}" for ext in items]
253
299
  return items
254
-
300
+
255
301
  # Path values
256
302
  if key in ["project_root", "index_path"]:
257
303
  return Path(value)
258
-
304
+
259
305
  # String values (default)
260
306
  return value
261
307
 
@@ -263,25 +309,25 @@ def _parse_config_value(key: str, value: str):
263
309
  def _get_default_value(key: str):
264
310
  """Get default value for a configuration key."""
265
311
  from ...config.defaults import DEFAULT_EMBEDDING_MODELS, DEFAULT_FILE_EXTENSIONS
266
-
312
+
267
313
  defaults = {
268
314
  "file_extensions": DEFAULT_FILE_EXTENSIONS,
269
315
  "embedding_model": DEFAULT_EMBEDDING_MODELS["code"],
270
- "similarity_threshold": 0.75,
316
+ "similarity_threshold": 0.5,
271
317
  "max_chunk_size": 512,
272
318
  "languages": [],
273
319
  "watch_files": False,
274
320
  "cache_embeddings": True,
275
321
  "max_cache_size": 1000,
276
322
  }
277
-
323
+
278
324
  return defaults.get(key, "")
279
325
 
280
326
 
281
327
  def _show_available_keys() -> None:
282
328
  """Show all available configuration keys."""
283
329
  console.print("\n[bold blue]Available Configuration Keys:[/bold blue]")
284
-
330
+
285
331
  keys_info = [
286
332
  ("file_extensions", "List of file extensions to index", "list"),
287
333
  ("embedding_model", "Embedding model name", "string"),
@@ -292,11 +338,13 @@ def _show_available_keys() -> None:
292
338
  ("cache_embeddings", "Enable embedding caching", "boolean"),
293
339
  ("max_cache_size", "Maximum cache size", "integer"),
294
340
  ]
295
-
341
+
296
342
  for key, description, value_type in keys_info:
297
343
  console.print(f" [cyan]{key}[/cyan] ({value_type}): {description}")
298
-
299
- console.print("\n[dim]Use 'mcp-vector-search config set <key> <value>' to change values[/dim]")
344
+
345
+ console.print(
346
+ "\n[dim]Use 'mcp-vector-search config set <key> <value>' to change values[/dim]"
347
+ )
300
348
 
301
349
 
302
350
  if __name__ == "__main__":