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