mcp-vector-search 0.9.3__py3-none-any.whl → 0.12.1__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 +2 -2
- mcp_vector_search/cli/commands/index.py +44 -22
- mcp_vector_search/cli/commands/install.py +502 -523
- mcp_vector_search/cli/commands/install_old.py +696 -0
- mcp_vector_search/cli/commands/status.py +7 -5
- mcp_vector_search/cli/commands/uninstall.py +485 -0
- mcp_vector_search/cli/commands/visualize.py +677 -53
- mcp_vector_search/cli/didyoumean.py +10 -0
- mcp_vector_search/cli/main.py +39 -21
- mcp_vector_search/core/connection_pool.py +49 -11
- mcp_vector_search/core/database.py +61 -28
- mcp_vector_search/core/directory_index.py +318 -0
- mcp_vector_search/core/indexer.py +146 -19
- mcp_vector_search/core/models.py +61 -0
- mcp_vector_search/core/project.py +16 -5
- mcp_vector_search/parsers/base.py +54 -18
- mcp_vector_search/parsers/javascript.py +41 -20
- mcp_vector_search/parsers/python.py +19 -11
- mcp_vector_search/parsers/registry.py +3 -2
- mcp_vector_search/utils/gitignore.py +17 -5
- mcp_vector_search/visualization/index.html +658 -0
- {mcp_vector_search-0.9.3.dist-info → mcp_vector_search-0.12.1.dist-info}/METADATA +87 -24
- {mcp_vector_search-0.9.3.dist-info → mcp_vector_search-0.12.1.dist-info}/RECORD +26 -22
- {mcp_vector_search-0.9.3.dist-info → mcp_vector_search-0.12.1.dist-info}/WHEEL +0 -0
- {mcp_vector_search-0.9.3.dist-info → mcp_vector_search-0.12.1.dist-info}/entry_points.txt +0 -0
- {mcp_vector_search-0.9.3.dist-info → mcp_vector_search-0.12.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,22 +1,40 @@
|
|
|
1
|
-
"""Install
|
|
1
|
+
"""Install and integration commands for MCP Vector Search CLI.
|
|
2
|
+
|
|
3
|
+
This module provides installation commands for:
|
|
4
|
+
1. Project initialization (main command)
|
|
5
|
+
2. Platform-specific MCP integrations (subcommands)
|
|
6
|
+
|
|
7
|
+
Examples:
|
|
8
|
+
# Install in current project
|
|
9
|
+
$ mcp-vector-search install
|
|
10
|
+
|
|
11
|
+
# Install Claude Code integration
|
|
12
|
+
$ mcp-vector-search install claude-code
|
|
13
|
+
|
|
14
|
+
# Install all available integrations
|
|
15
|
+
$ mcp-vector-search install --all
|
|
16
|
+
"""
|
|
2
17
|
|
|
3
18
|
import asyncio
|
|
4
19
|
import json
|
|
5
20
|
import shutil
|
|
6
|
-
import subprocess
|
|
7
|
-
import sys
|
|
8
21
|
from pathlib import Path
|
|
22
|
+
from typing import Any
|
|
9
23
|
|
|
10
24
|
import typer
|
|
11
25
|
from loguru import logger
|
|
12
26
|
from rich.console import Console
|
|
13
27
|
from rich.panel import Panel
|
|
14
|
-
from rich.
|
|
28
|
+
from rich.table import Table
|
|
15
29
|
|
|
30
|
+
from ...config.defaults import DEFAULT_EMBEDDING_MODELS, DEFAULT_FILE_EXTENSIONS
|
|
31
|
+
from ...core.exceptions import ProjectInitializationError
|
|
16
32
|
from ...core.project import ProjectManager
|
|
33
|
+
from ..didyoumean import create_enhanced_typer
|
|
17
34
|
from ..output import (
|
|
18
35
|
print_error,
|
|
19
36
|
print_info,
|
|
37
|
+
print_next_steps,
|
|
20
38
|
print_success,
|
|
21
39
|
print_warning,
|
|
22
40
|
)
|
|
@@ -24,115 +42,200 @@ from ..output import (
|
|
|
24
42
|
# Create console for rich output
|
|
25
43
|
console = Console()
|
|
26
44
|
|
|
27
|
-
# Create install
|
|
28
|
-
install_app =
|
|
29
|
-
|
|
45
|
+
# Create install app with subcommands
|
|
46
|
+
install_app = create_enhanced_typer(
|
|
47
|
+
help="""📦 Install mcp-vector-search and MCP integrations
|
|
48
|
+
|
|
49
|
+
[bold cyan]Usage Patterns:[/bold cyan]
|
|
50
|
+
|
|
51
|
+
[green]1. Project Installation (Primary)[/green]
|
|
52
|
+
Install mcp-vector-search in the current project:
|
|
53
|
+
[code]$ mcp-vector-search install[/code]
|
|
54
|
+
|
|
55
|
+
[green]2. MCP Platform Integration[/green]
|
|
56
|
+
Add MCP integration for specific platforms:
|
|
57
|
+
[code]$ mcp-vector-search install claude-code[/code]
|
|
58
|
+
[code]$ mcp-vector-search install cursor[/code]
|
|
59
|
+
[code]$ mcp-vector-search install windsurf[/code]
|
|
60
|
+
|
|
61
|
+
[green]3. Complete Setup[/green]
|
|
62
|
+
Install project + all MCP integrations:
|
|
63
|
+
[code]$ mcp-vector-search install --with-mcp[/code]
|
|
64
|
+
|
|
65
|
+
[bold cyan]Supported Platforms:[/bold cyan]
|
|
66
|
+
• [green]claude-code[/green] - Claude Code (project-scoped .mcp.json)
|
|
67
|
+
• [green]claude-desktop[/green] - Claude Desktop (~/.claude/config.json)
|
|
68
|
+
• [green]cursor[/green] - Cursor IDE (~/.cursor/mcp.json)
|
|
69
|
+
• [green]windsurf[/green] - Windsurf IDE (~/.codeium/windsurf/mcp_config.json)
|
|
70
|
+
• [green]vscode[/green] - VS Code (~/.vscode/mcp.json)
|
|
71
|
+
|
|
72
|
+
[dim]💡 Use 'mcp-vector-search uninstall <platform>' to remove integrations[/dim]
|
|
73
|
+
""",
|
|
74
|
+
invoke_without_command=True,
|
|
75
|
+
no_args_is_help=False,
|
|
76
|
+
)
|
|
30
77
|
|
|
31
|
-
# ============================================================================
|
|
32
|
-
# MCP Multi-Tool Integration Helpers
|
|
33
|
-
# ============================================================================
|
|
34
78
|
|
|
79
|
+
# ==============================================================================
|
|
80
|
+
# Platform Configuration
|
|
81
|
+
# ==============================================================================
|
|
82
|
+
|
|
83
|
+
SUPPORTED_PLATFORMS = {
|
|
84
|
+
"claude-code": {
|
|
85
|
+
"name": "Claude Code",
|
|
86
|
+
"config_path": ".mcp.json", # Project-scoped
|
|
87
|
+
"description": "Claude Code with project-scoped configuration",
|
|
88
|
+
"scope": "project",
|
|
89
|
+
},
|
|
90
|
+
"claude-desktop": {
|
|
91
|
+
"name": "Claude Desktop",
|
|
92
|
+
"config_path": "~/Library/Application Support/Claude/claude_desktop_config.json",
|
|
93
|
+
"description": "Claude Desktop application",
|
|
94
|
+
"scope": "global",
|
|
95
|
+
},
|
|
96
|
+
"cursor": {
|
|
97
|
+
"name": "Cursor",
|
|
98
|
+
"config_path": "~/.cursor/mcp.json",
|
|
99
|
+
"description": "Cursor IDE",
|
|
100
|
+
"scope": "global",
|
|
101
|
+
},
|
|
102
|
+
"windsurf": {
|
|
103
|
+
"name": "Windsurf",
|
|
104
|
+
"config_path": "~/.codeium/windsurf/mcp_config.json",
|
|
105
|
+
"description": "Windsurf IDE",
|
|
106
|
+
"scope": "global",
|
|
107
|
+
},
|
|
108
|
+
"vscode": {
|
|
109
|
+
"name": "VS Code",
|
|
110
|
+
"config_path": "~/.vscode/mcp.json",
|
|
111
|
+
"description": "Visual Studio Code",
|
|
112
|
+
"scope": "global",
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def get_platform_config_path(platform: str, project_root: Path) -> Path:
|
|
118
|
+
"""Get the configuration file path for a platform.
|
|
35
119
|
|
|
36
|
-
|
|
37
|
-
|
|
120
|
+
Args:
|
|
121
|
+
platform: Platform name (e.g., "claude-code", "cursor")
|
|
122
|
+
project_root: Project root directory (for project-scoped configs)
|
|
38
123
|
|
|
39
124
|
Returns:
|
|
40
|
-
|
|
41
|
-
For Claude Code, returns a placeholder path since it uses project-scoped .mcp.json
|
|
125
|
+
Path to the configuration file
|
|
42
126
|
"""
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
config_locations = {
|
|
46
|
-
"claude-desktop": home
|
|
47
|
-
/ "Library"
|
|
48
|
-
/ "Application Support"
|
|
49
|
-
/ "Claude"
|
|
50
|
-
/ "claude_desktop_config.json",
|
|
51
|
-
"cursor": home / ".cursor" / "mcp.json",
|
|
52
|
-
"windsurf": home / ".codeium" / "windsurf" / "mcp_config.json",
|
|
53
|
-
"vscode": home / ".vscode" / "mcp.json",
|
|
54
|
-
}
|
|
127
|
+
if platform not in SUPPORTED_PLATFORMS:
|
|
128
|
+
raise ValueError(f"Unsupported platform: {platform}")
|
|
55
129
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
for tool_name, config_path in config_locations.items():
|
|
59
|
-
if config_path.exists():
|
|
60
|
-
detected_tools[tool_name] = config_path
|
|
130
|
+
config_info = SUPPORTED_PLATFORMS[platform]
|
|
131
|
+
config_path_str = config_info["config_path"]
|
|
61
132
|
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return detected_tools
|
|
133
|
+
# Resolve project-scoped vs global paths
|
|
134
|
+
if config_info["scope"] == "project":
|
|
135
|
+
return project_root / config_path_str
|
|
136
|
+
else:
|
|
137
|
+
return Path(config_path_str).expanduser()
|
|
68
138
|
|
|
69
139
|
|
|
70
140
|
def get_mcp_server_config(
|
|
71
|
-
project_root: Path,
|
|
72
|
-
|
|
73
|
-
|
|
141
|
+
project_root: Path,
|
|
142
|
+
platform: str,
|
|
143
|
+
enable_watch: bool = True,
|
|
144
|
+
) -> dict[str, Any]:
|
|
145
|
+
"""Generate MCP server configuration for a platform.
|
|
74
146
|
|
|
75
147
|
Args:
|
|
76
|
-
project_root:
|
|
77
|
-
|
|
78
|
-
|
|
148
|
+
project_root: Project root directory
|
|
149
|
+
platform: Platform name
|
|
150
|
+
enable_watch: Whether to enable file watching
|
|
79
151
|
|
|
80
152
|
Returns:
|
|
81
|
-
Dictionary containing MCP server configuration
|
|
153
|
+
Dictionary containing MCP server configuration
|
|
82
154
|
"""
|
|
83
|
-
# Base configuration
|
|
84
|
-
config = {
|
|
155
|
+
# Base configuration using uv for compatibility
|
|
156
|
+
config: dict[str, Any] = {
|
|
85
157
|
"command": "uv",
|
|
86
158
|
"args": ["run", "mcp-vector-search", "mcp"],
|
|
87
|
-
"env": {
|
|
159
|
+
"env": {
|
|
160
|
+
"MCP_ENABLE_FILE_WATCHING": "true" if enable_watch else "false",
|
|
161
|
+
},
|
|
88
162
|
}
|
|
89
163
|
|
|
90
|
-
#
|
|
91
|
-
if
|
|
164
|
+
# Platform-specific adjustments
|
|
165
|
+
if platform in ("claude-code", "cursor", "windsurf", "vscode"):
|
|
166
|
+
# These platforms require "type": "stdio"
|
|
92
167
|
config["type"] = "stdio"
|
|
93
168
|
|
|
94
|
-
#
|
|
95
|
-
if
|
|
169
|
+
# Only add cwd for global-scope platforms (not project-scoped)
|
|
170
|
+
if SUPPORTED_PLATFORMS[platform]["scope"] == "global":
|
|
96
171
|
config["cwd"] = str(project_root.absolute())
|
|
97
172
|
|
|
98
173
|
return config
|
|
99
174
|
|
|
100
175
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
|
|
176
|
+
def detect_installed_platforms() -> dict[str, Path]:
|
|
177
|
+
"""Detect which MCP platforms are installed on the system.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
Dictionary mapping platform names to their config paths
|
|
181
|
+
"""
|
|
182
|
+
detected = {}
|
|
183
|
+
|
|
184
|
+
for platform, info in SUPPORTED_PLATFORMS.items():
|
|
185
|
+
# For project-scoped platforms, always include them
|
|
186
|
+
if info["scope"] == "project":
|
|
187
|
+
detected[platform] = Path(info["config_path"])
|
|
188
|
+
continue
|
|
189
|
+
|
|
190
|
+
# For global platforms, check if config directory exists
|
|
191
|
+
config_path = Path(info["config_path"]).expanduser()
|
|
192
|
+
if config_path.parent.exists():
|
|
193
|
+
detected[platform] = config_path
|
|
194
|
+
|
|
195
|
+
return detected
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def configure_platform(
|
|
199
|
+
platform: str,
|
|
104
200
|
project_root: Path,
|
|
105
201
|
server_name: str = "mcp-vector-search",
|
|
106
202
|
enable_watch: bool = True,
|
|
203
|
+
force: bool = False,
|
|
107
204
|
) -> bool:
|
|
108
|
-
"""
|
|
205
|
+
"""Configure MCP integration for a specific platform.
|
|
109
206
|
|
|
110
207
|
Args:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
project_root: Path to the project root directory
|
|
208
|
+
platform: Platform name (e.g., "claude-code", "cursor")
|
|
209
|
+
project_root: Project root directory
|
|
114
210
|
server_name: Name for the MCP server entry
|
|
115
211
|
enable_watch: Whether to enable file watching
|
|
212
|
+
force: Whether to overwrite existing configuration
|
|
116
213
|
|
|
117
214
|
Returns:
|
|
118
|
-
True if configuration was successful, False otherwise
|
|
215
|
+
True if configuration was successful, False otherwise
|
|
119
216
|
"""
|
|
120
217
|
try:
|
|
121
|
-
|
|
122
|
-
if tool_name == "claude-code":
|
|
123
|
-
# Override config_path to project-scoped .mcp.json
|
|
124
|
-
config_path = project_root / ".mcp.json"
|
|
218
|
+
config_path = get_platform_config_path(platform, project_root)
|
|
125
219
|
|
|
126
|
-
# Create backup
|
|
127
|
-
backup_path = config_path.with_suffix(config_path.suffix + ".backup")
|
|
128
|
-
|
|
129
|
-
# Load existing config or create new one
|
|
220
|
+
# Create backup if file exists
|
|
130
221
|
if config_path.exists():
|
|
222
|
+
backup_path = config_path.with_suffix(config_path.suffix + ".backup")
|
|
131
223
|
shutil.copy2(config_path, backup_path)
|
|
224
|
+
|
|
225
|
+
# Load existing config
|
|
132
226
|
with open(config_path) as f:
|
|
133
227
|
config = json.load(f)
|
|
228
|
+
|
|
229
|
+
# Check if server already exists
|
|
230
|
+
if "mcpServers" in config and server_name in config["mcpServers"]:
|
|
231
|
+
if not force:
|
|
232
|
+
print_warning(
|
|
233
|
+
f" ⚠️ Server '{server_name}' already exists in {platform} config"
|
|
234
|
+
)
|
|
235
|
+
print_info(" Use --force to overwrite")
|
|
236
|
+
return False
|
|
134
237
|
else:
|
|
135
|
-
# Create
|
|
238
|
+
# Create new config
|
|
136
239
|
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
137
240
|
config = {}
|
|
138
241
|
|
|
@@ -140,556 +243,432 @@ def configure_mcp_for_tool(
|
|
|
140
243
|
if "mcpServers" not in config:
|
|
141
244
|
config["mcpServers"] = {}
|
|
142
245
|
|
|
143
|
-
# Get the MCP server configuration with tool-specific settings
|
|
144
|
-
server_config = get_mcp_server_config(project_root, enable_watch, tool_name)
|
|
145
|
-
|
|
146
246
|
# Add server configuration
|
|
247
|
+
server_config = get_mcp_server_config(project_root, platform, enable_watch)
|
|
147
248
|
config["mcpServers"][server_name] = server_config
|
|
148
249
|
|
|
149
|
-
# Write
|
|
250
|
+
# Write configuration
|
|
150
251
|
with open(config_path, "w") as f:
|
|
151
252
|
json.dump(config, f, indent=2)
|
|
152
253
|
|
|
153
|
-
|
|
254
|
+
platform_name = SUPPORTED_PLATFORMS[platform]["name"]
|
|
255
|
+
print_success(f" ✅ Configured {platform_name}")
|
|
256
|
+
print_info(f" Config: {config_path}")
|
|
257
|
+
|
|
154
258
|
return True
|
|
155
259
|
|
|
156
260
|
except Exception as e:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if backup_path.exists():
|
|
160
|
-
shutil.copy2(backup_path, config_path)
|
|
261
|
+
logger.error(f"Failed to configure {platform}: {e}")
|
|
262
|
+
print_error(f" ❌ Failed to configure {platform}: {e}")
|
|
161
263
|
return False
|
|
162
264
|
|
|
163
265
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
enable_watch: bool = True,
|
|
168
|
-
interactive: bool = True,
|
|
169
|
-
) -> dict[str, bool]:
|
|
170
|
-
"""Setup MCP integration for one or more AI tools.
|
|
171
|
-
|
|
172
|
-
Args:
|
|
173
|
-
project_root: Path to the project root directory
|
|
174
|
-
mcp_tool: Specific tool to configure (None for interactive selection)
|
|
175
|
-
enable_watch: Whether to enable file watching
|
|
176
|
-
interactive: Whether to prompt user for tool selection
|
|
177
|
-
|
|
178
|
-
Returns:
|
|
179
|
-
Dictionary mapping tool names to success status.
|
|
180
|
-
"""
|
|
181
|
-
detected_tools = detect_ai_tools()
|
|
182
|
-
|
|
183
|
-
if not detected_tools:
|
|
184
|
-
print_warning("No AI coding tools detected on this system.")
|
|
185
|
-
print_info(
|
|
186
|
-
"Supported tools: Claude Code, Claude Desktop, Cursor, Windsurf, VS Code"
|
|
187
|
-
)
|
|
188
|
-
print_info("Install one of these tools and try again.")
|
|
189
|
-
return {}
|
|
190
|
-
|
|
191
|
-
# Determine which tools to configure
|
|
192
|
-
tools_to_configure = {}
|
|
193
|
-
|
|
194
|
-
if mcp_tool:
|
|
195
|
-
# Specific tool requested
|
|
196
|
-
if mcp_tool in detected_tools:
|
|
197
|
-
tools_to_configure[mcp_tool] = detected_tools[mcp_tool]
|
|
198
|
-
else:
|
|
199
|
-
print_error(f"Tool '{mcp_tool}' not found or not installed.")
|
|
200
|
-
print_info(f"Detected tools: {', '.join(detected_tools.keys())}")
|
|
201
|
-
return {}
|
|
202
|
-
elif interactive and len(detected_tools) > 1:
|
|
203
|
-
# Multiple tools detected, prompt user
|
|
204
|
-
console.print("\n[bold blue]🔍 Detected AI coding tools:[/bold blue]")
|
|
205
|
-
for i, tool_name in enumerate(detected_tools.keys(), 1):
|
|
206
|
-
console.print(f" {i}. {tool_name}")
|
|
207
|
-
|
|
208
|
-
console.print("\n[bold]Configure MCP integration for:[/bold]")
|
|
209
|
-
console.print(" [1] All detected tools")
|
|
210
|
-
console.print(" [2] Choose specific tool(s)")
|
|
211
|
-
console.print(" [3] Skip MCP setup")
|
|
212
|
-
|
|
213
|
-
choice = typer.prompt("\nSelect option", type=int, default=1)
|
|
214
|
-
|
|
215
|
-
if choice == 1:
|
|
216
|
-
# Configure all tools
|
|
217
|
-
tools_to_configure = detected_tools
|
|
218
|
-
elif choice == 2:
|
|
219
|
-
# Let user choose specific tools
|
|
220
|
-
console.print(
|
|
221
|
-
"\n[bold]Select tools to configure (comma-separated numbers):[/bold]"
|
|
222
|
-
)
|
|
223
|
-
tool_list = list(detected_tools.keys())
|
|
224
|
-
for i, tool_name in enumerate(tool_list, 1):
|
|
225
|
-
console.print(f" {i}. {tool_name}")
|
|
226
|
-
|
|
227
|
-
selections = typer.prompt("Tool numbers").strip()
|
|
228
|
-
for num_str in selections.split(","):
|
|
229
|
-
try:
|
|
230
|
-
idx = int(num_str.strip()) - 1
|
|
231
|
-
if 0 <= idx < len(tool_list):
|
|
232
|
-
tool_name = tool_list[idx]
|
|
233
|
-
tools_to_configure[tool_name] = detected_tools[tool_name]
|
|
234
|
-
except ValueError:
|
|
235
|
-
print_warning(f"Invalid selection: {num_str}")
|
|
236
|
-
else:
|
|
237
|
-
# Skip MCP setup
|
|
238
|
-
print_info("Skipping MCP setup")
|
|
239
|
-
return {}
|
|
240
|
-
else:
|
|
241
|
-
# Single tool or non-interactive mode - configure all
|
|
242
|
-
tools_to_configure = detected_tools
|
|
243
|
-
|
|
244
|
-
# Configure selected tools
|
|
245
|
-
results = {}
|
|
246
|
-
|
|
247
|
-
if tools_to_configure:
|
|
248
|
-
console.print("\n[bold blue]🔗 Configuring MCP integration...[/bold blue]")
|
|
249
|
-
|
|
250
|
-
for tool_name, config_path in tools_to_configure.items():
|
|
251
|
-
results[tool_name] = configure_mcp_for_tool(
|
|
252
|
-
tool_name=tool_name,
|
|
253
|
-
config_path=config_path,
|
|
254
|
-
project_root=project_root,
|
|
255
|
-
server_name="mcp-vector-search",
|
|
256
|
-
enable_watch=enable_watch,
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
return results
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
def print_next_steps(
|
|
263
|
-
project_root: Path,
|
|
264
|
-
indexed: bool,
|
|
265
|
-
mcp_results: dict[str, bool],
|
|
266
|
-
) -> None:
|
|
267
|
-
"""Print helpful next steps after installation.
|
|
268
|
-
|
|
269
|
-
Args:
|
|
270
|
-
project_root: Path to the project root
|
|
271
|
-
indexed: Whether the codebase was indexed
|
|
272
|
-
mcp_results: Results of MCP integration (tool_name -> success)
|
|
273
|
-
"""
|
|
274
|
-
console.print("\n[bold green]🎉 Installation Complete![/bold green]")
|
|
275
|
-
|
|
276
|
-
# Show what was completed
|
|
277
|
-
console.print("\n[bold blue]✨ Setup Summary:[/bold blue]")
|
|
278
|
-
console.print(" ✅ Vector database initialized")
|
|
279
|
-
if indexed:
|
|
280
|
-
console.print(" ✅ Codebase indexed and searchable")
|
|
281
|
-
else:
|
|
282
|
-
console.print(" ⏭️ Indexing skipped (use --no-index flag)")
|
|
283
|
-
|
|
284
|
-
if mcp_results:
|
|
285
|
-
successful_tools = [tool for tool, success in mcp_results.items() if success]
|
|
286
|
-
if successful_tools:
|
|
287
|
-
console.print(
|
|
288
|
-
f" ✅ MCP integration configured for: {', '.join(successful_tools)}"
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
# Next steps
|
|
292
|
-
console.print("\n[bold green]🚀 Ready to use:[/bold green]")
|
|
293
|
-
console.print(
|
|
294
|
-
" • Search your code: [code]mcp-vector-search search 'your query'[/code]"
|
|
295
|
-
)
|
|
296
|
-
console.print(" • Check status: [code]mcp-vector-search status[/code]")
|
|
297
|
-
|
|
298
|
-
if mcp_results:
|
|
299
|
-
console.print("\n[bold blue]🤖 Using MCP Integration:[/bold blue]")
|
|
300
|
-
if "claude-code" in mcp_results and mcp_results["claude-code"]:
|
|
301
|
-
console.print(" • Open Claude Code in this project directory")
|
|
302
|
-
console.print(" • Use: 'Search my code for authentication functions'")
|
|
303
|
-
if "cursor" in mcp_results and mcp_results["cursor"]:
|
|
304
|
-
console.print(" • Open Cursor in this project directory")
|
|
305
|
-
console.print(" • MCP tools should be available automatically")
|
|
306
|
-
if "claude-desktop" in mcp_results and mcp_results["claude-desktop"]:
|
|
307
|
-
console.print(" • Restart Claude Desktop")
|
|
308
|
-
console.print(" • The mcp-vector-search server will be available")
|
|
309
|
-
|
|
310
|
-
console.print(
|
|
311
|
-
"\n[dim]💡 Tip: Run 'mcp-vector-search --help' for more commands[/dim]"
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
# ============================================================================
|
|
316
|
-
# Main Install Command
|
|
317
|
-
# ============================================================================
|
|
266
|
+
# ==============================================================================
|
|
267
|
+
# Main Install Command (Project Installation)
|
|
268
|
+
# ==============================================================================
|
|
318
269
|
|
|
319
270
|
|
|
271
|
+
@install_app.callback()
|
|
320
272
|
def main(
|
|
321
273
|
ctx: typer.Context,
|
|
322
|
-
project_path: Path = typer.Argument(
|
|
323
|
-
...,
|
|
324
|
-
help="Project directory to initialize and index",
|
|
325
|
-
),
|
|
326
274
|
extensions: str | None = typer.Option(
|
|
327
275
|
None,
|
|
328
276
|
"--extensions",
|
|
329
277
|
"-e",
|
|
330
|
-
help="Comma-separated file extensions (e.g., .py,.js,.ts
|
|
331
|
-
|
|
332
|
-
no_index: bool = typer.Option(
|
|
333
|
-
False,
|
|
334
|
-
"--no-index",
|
|
335
|
-
help="Skip initial indexing",
|
|
336
|
-
),
|
|
337
|
-
no_mcp: bool = typer.Option(
|
|
338
|
-
False,
|
|
339
|
-
"--no-mcp",
|
|
340
|
-
help="Skip MCP integration setup",
|
|
341
|
-
),
|
|
342
|
-
mcp_tool: str | None = typer.Option(
|
|
343
|
-
None,
|
|
344
|
-
"--mcp-tool",
|
|
345
|
-
help="Specific AI tool for MCP integration (claude-code, cursor, etc.)",
|
|
346
|
-
),
|
|
347
|
-
no_watch: bool = typer.Option(
|
|
348
|
-
False,
|
|
349
|
-
"--no-watch",
|
|
350
|
-
help="Disable file watching for MCP integration",
|
|
278
|
+
help="Comma-separated file extensions (e.g., .py,.js,.ts)",
|
|
279
|
+
rich_help_panel="📁 Configuration",
|
|
351
280
|
),
|
|
352
281
|
embedding_model: str = typer.Option(
|
|
353
|
-
"
|
|
282
|
+
DEFAULT_EMBEDDING_MODELS["code"],
|
|
354
283
|
"--embedding-model",
|
|
355
284
|
"-m",
|
|
356
|
-
help="Embedding model
|
|
285
|
+
help="Embedding model for semantic search",
|
|
286
|
+
rich_help_panel="🧠 Model Settings",
|
|
357
287
|
),
|
|
358
288
|
similarity_threshold: float = typer.Option(
|
|
359
289
|
0.5,
|
|
360
290
|
"--similarity-threshold",
|
|
361
291
|
"-s",
|
|
362
|
-
help="Similarity threshold
|
|
292
|
+
help="Similarity threshold (0.0-1.0)",
|
|
363
293
|
min=0.0,
|
|
364
294
|
max=1.0,
|
|
295
|
+
rich_help_panel="🧠 Model Settings",
|
|
296
|
+
),
|
|
297
|
+
auto_index: bool = typer.Option(
|
|
298
|
+
True,
|
|
299
|
+
"--auto-index/--no-auto-index",
|
|
300
|
+
help="Automatically index after initialization",
|
|
301
|
+
rich_help_panel="🚀 Workflow",
|
|
302
|
+
),
|
|
303
|
+
with_mcp: bool = typer.Option(
|
|
304
|
+
False,
|
|
305
|
+
"--with-mcp",
|
|
306
|
+
help="Install all available MCP integrations",
|
|
307
|
+
rich_help_panel="🚀 Workflow",
|
|
365
308
|
),
|
|
366
309
|
force: bool = typer.Option(
|
|
367
310
|
False,
|
|
368
311
|
"--force",
|
|
369
312
|
"-f",
|
|
370
|
-
help="Force re-
|
|
313
|
+
help="Force re-initialization",
|
|
314
|
+
rich_help_panel="⚙️ Advanced",
|
|
371
315
|
),
|
|
372
316
|
) -> None:
|
|
373
|
-
"""Install mcp-vector-search
|
|
317
|
+
"""📦 Install mcp-vector-search in the current project.
|
|
374
318
|
|
|
375
|
-
This command
|
|
319
|
+
This command initializes mcp-vector-search with:
|
|
320
|
+
✅ Vector database setup
|
|
321
|
+
✅ Configuration file creation
|
|
322
|
+
✅ Automatic code indexing
|
|
323
|
+
✅ Ready-to-use semantic search
|
|
376
324
|
|
|
377
|
-
|
|
378
|
-
✅ Auto-detects programming languages and file types
|
|
379
|
-
✅ Indexes the codebase for semantic search
|
|
380
|
-
✅ Configures MCP integration for multiple AI tools
|
|
381
|
-
✅ Sets up file watching for automatic updates
|
|
325
|
+
[bold cyan]Examples:[/bold cyan]
|
|
382
326
|
|
|
383
|
-
|
|
327
|
+
[green]Basic installation:[/green]
|
|
328
|
+
$ mcp-vector-search install
|
|
384
329
|
|
|
385
|
-
|
|
386
|
-
mcp-vector-search install .
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
mcp-vector-search install
|
|
390
|
-
|
|
391
|
-
|
|
330
|
+
[green]Custom file types:[/green]
|
|
331
|
+
$ mcp-vector-search install --extensions .py,.js,.ts
|
|
332
|
+
|
|
333
|
+
[green]Install with MCP integrations:[/green]
|
|
334
|
+
$ mcp-vector-search install --with-mcp
|
|
335
|
+
|
|
336
|
+
[green]Skip auto-indexing:[/green]
|
|
337
|
+
$ mcp-vector-search install --no-auto-index
|
|
338
|
+
|
|
339
|
+
[dim]💡 After installation, use 'mcp-vector-search search' to search your code[/dim]
|
|
392
340
|
"""
|
|
341
|
+
# Only run main logic if no subcommand was invoked
|
|
342
|
+
if ctx.invoked_subcommand is not None:
|
|
343
|
+
return
|
|
344
|
+
|
|
393
345
|
try:
|
|
394
|
-
|
|
395
|
-
project_root = project_path.resolve()
|
|
346
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
396
347
|
|
|
397
|
-
# Show installation header
|
|
398
348
|
console.print(
|
|
399
349
|
Panel.fit(
|
|
400
|
-
f"[bold
|
|
401
|
-
f"📁 Project:
|
|
402
|
-
|
|
403
|
-
border_style="blue",
|
|
350
|
+
f"[bold cyan]Installing mcp-vector-search[/bold cyan]\n"
|
|
351
|
+
f"📁 Project: {project_root}",
|
|
352
|
+
border_style="cyan",
|
|
404
353
|
)
|
|
405
354
|
)
|
|
406
355
|
|
|
407
|
-
# Check if project directory exists
|
|
408
|
-
if not project_root.exists():
|
|
409
|
-
print_error(f"Project directory does not exist: {project_root}")
|
|
410
|
-
raise typer.Exit(1)
|
|
411
|
-
|
|
412
356
|
# Check if already initialized
|
|
413
357
|
project_manager = ProjectManager(project_root)
|
|
414
358
|
if project_manager.is_initialized() and not force:
|
|
415
|
-
print_success("✅ Project
|
|
416
|
-
print_info("
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
# Show MCP configuration option
|
|
420
|
-
if not no_mcp:
|
|
421
|
-
console.print("\n[bold blue]💡 MCP Integration:[/bold blue]")
|
|
422
|
-
console.print(
|
|
423
|
-
" Run install again with --force to reconfigure MCP integration"
|
|
424
|
-
)
|
|
425
|
-
|
|
426
|
-
return
|
|
359
|
+
print_success("✅ Project already initialized!")
|
|
360
|
+
print_info(" Use --force to re-initialize")
|
|
361
|
+
raise typer.Exit(0)
|
|
427
362
|
|
|
428
363
|
# Parse file extensions
|
|
429
364
|
file_extensions = None
|
|
430
365
|
if extensions:
|
|
431
|
-
file_extensions = [ext.strip() for ext in extensions.split(",")]
|
|
432
|
-
# Ensure extensions start with dot
|
|
433
366
|
file_extensions = [
|
|
434
|
-
ext if ext.startswith(".") else f".{ext}"
|
|
367
|
+
ext.strip() if ext.startswith(".") else f".{ext.strip()}"
|
|
368
|
+
for ext in extensions.split(",")
|
|
435
369
|
]
|
|
370
|
+
else:
|
|
371
|
+
file_extensions = DEFAULT_FILE_EXTENSIONS
|
|
372
|
+
|
|
373
|
+
# Show configuration
|
|
374
|
+
console.print("\n[bold blue]Configuration:[/bold blue]")
|
|
375
|
+
console.print(f" 📄 Extensions: {', '.join(file_extensions)}")
|
|
376
|
+
console.print(f" 🧠 Model: {embedding_model}")
|
|
377
|
+
console.print(f" 🎯 Threshold: {similarity_threshold}")
|
|
378
|
+
console.print(f" 🔍 Auto-index: {'✅' if auto_index else '❌'}")
|
|
379
|
+
console.print(f" 🔗 With MCP: {'✅' if with_mcp else '❌'}")
|
|
380
|
+
|
|
381
|
+
# Initialize project
|
|
382
|
+
console.print("\n[bold]Initializing project...[/bold]")
|
|
383
|
+
project_manager.initialize(
|
|
384
|
+
file_extensions=file_extensions,
|
|
385
|
+
embedding_model=embedding_model,
|
|
386
|
+
similarity_threshold=similarity_threshold,
|
|
387
|
+
force=force,
|
|
388
|
+
)
|
|
389
|
+
print_success("✅ Project initialized")
|
|
390
|
+
|
|
391
|
+
# Auto-index if requested
|
|
392
|
+
if auto_index:
|
|
393
|
+
console.print("\n[bold]🔍 Indexing codebase...[/bold]")
|
|
394
|
+
from .index import run_indexing
|
|
395
|
+
|
|
396
|
+
try:
|
|
397
|
+
asyncio.run(
|
|
398
|
+
run_indexing(
|
|
399
|
+
project_root=project_root,
|
|
400
|
+
force_reindex=False,
|
|
401
|
+
show_progress=True,
|
|
402
|
+
)
|
|
403
|
+
)
|
|
404
|
+
print_success("✅ Indexing completed")
|
|
405
|
+
except Exception as e:
|
|
406
|
+
print_error(f"❌ Indexing failed: {e}")
|
|
407
|
+
print_info(" Run 'mcp-vector-search index' to index later")
|
|
408
|
+
|
|
409
|
+
# Install MCP integrations if requested
|
|
410
|
+
if with_mcp:
|
|
411
|
+
console.print("\n[bold blue]🔗 Installing MCP integrations...[/bold blue]")
|
|
412
|
+
detected = detect_installed_platforms()
|
|
413
|
+
|
|
414
|
+
if detected:
|
|
415
|
+
for platform in detected:
|
|
416
|
+
configure_platform(platform, project_root, enable_watch=True)
|
|
417
|
+
else:
|
|
418
|
+
print_warning("No MCP platforms detected")
|
|
419
|
+
print_info("Install platforms manually using:")
|
|
420
|
+
print_info(" mcp-vector-search install <platform>")
|
|
436
421
|
|
|
437
|
-
#
|
|
438
|
-
|
|
439
|
-
# ========================================================================
|
|
440
|
-
with Progress(
|
|
441
|
-
SpinnerColumn(),
|
|
442
|
-
TextColumn("[progress.description]{task.description}"),
|
|
443
|
-
console=console,
|
|
444
|
-
) as progress:
|
|
445
|
-
task = progress.add_task("📁 Initializing project...", total=None)
|
|
446
|
-
|
|
447
|
-
# Initialize the project
|
|
448
|
-
project_manager.initialize(
|
|
449
|
-
file_extensions=file_extensions,
|
|
450
|
-
embedding_model=embedding_model,
|
|
451
|
-
similarity_threshold=similarity_threshold,
|
|
452
|
-
force=force,
|
|
453
|
-
)
|
|
422
|
+
# Success message
|
|
423
|
+
console.print("\n[bold green]🎉 Installation Complete![/bold green]")
|
|
454
424
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
with Progress(
|
|
464
|
-
SpinnerColumn(),
|
|
465
|
-
TextColumn("[progress.description]{task.description}"),
|
|
466
|
-
console=console,
|
|
467
|
-
) as progress:
|
|
468
|
-
task = progress.add_task("🔍 Indexing codebase...", total=None)
|
|
469
|
-
|
|
470
|
-
# Import and run indexing
|
|
471
|
-
from .index import run_indexing
|
|
472
|
-
|
|
473
|
-
try:
|
|
474
|
-
asyncio.run(
|
|
475
|
-
run_indexing(
|
|
476
|
-
project_root=project_root,
|
|
477
|
-
force_reindex=False,
|
|
478
|
-
show_progress=False, # We handle progress here
|
|
479
|
-
)
|
|
480
|
-
)
|
|
481
|
-
indexed = True
|
|
482
|
-
progress.update(task, completed=True)
|
|
483
|
-
print_success("✅ Codebase indexed successfully")
|
|
484
|
-
except Exception as e:
|
|
485
|
-
print_error(f"❌ Indexing failed: {e}")
|
|
486
|
-
print_info("You can run 'mcp-vector-search index' later")
|
|
487
|
-
else:
|
|
488
|
-
print_info("⏭️ Indexing skipped (--no-index)")
|
|
489
|
-
|
|
490
|
-
# ========================================================================
|
|
491
|
-
# STEP 3: Configure MCP Integration (unless --no-mcp)
|
|
492
|
-
# ========================================================================
|
|
493
|
-
mcp_results = {}
|
|
494
|
-
if not no_mcp:
|
|
495
|
-
enable_watch = not no_watch
|
|
496
|
-
mcp_results = setup_mcp_integration(
|
|
497
|
-
project_root=project_root,
|
|
498
|
-
mcp_tool=mcp_tool,
|
|
499
|
-
enable_watch=enable_watch,
|
|
500
|
-
interactive=True, # Allow interactive tool selection
|
|
425
|
+
next_steps = [
|
|
426
|
+
"[cyan]mcp-vector-search search 'your query'[/cyan] - Search your code",
|
|
427
|
+
"[cyan]mcp-vector-search status[/cyan] - View project status",
|
|
428
|
+
]
|
|
429
|
+
|
|
430
|
+
if not with_mcp:
|
|
431
|
+
next_steps.append(
|
|
432
|
+
"[cyan]mcp-vector-search install claude-code[/cyan] - Add MCP integration"
|
|
501
433
|
)
|
|
502
434
|
|
|
503
|
-
|
|
504
|
-
print_info("⏭️ MCP integration skipped")
|
|
505
|
-
else:
|
|
506
|
-
print_info("⏭️ MCP integration skipped (--no-mcp)")
|
|
435
|
+
print_next_steps(next_steps, title="Ready to Use")
|
|
507
436
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
437
|
+
except ProjectInitializationError as e:
|
|
438
|
+
print_error(f"Installation failed: {e}")
|
|
439
|
+
raise typer.Exit(1)
|
|
440
|
+
except Exception as e:
|
|
441
|
+
logger.error(f"Unexpected error during installation: {e}")
|
|
442
|
+
print_error(f"Unexpected error: {e}")
|
|
443
|
+
raise typer.Exit(1)
|
|
512
444
|
|
|
513
|
-
# Check project initialized
|
|
514
|
-
if project_manager.is_initialized():
|
|
515
|
-
print_success(" ✅ Project configuration created")
|
|
516
445
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
446
|
+
# ==============================================================================
|
|
447
|
+
# Platform-Specific Installation Commands
|
|
448
|
+
# ==============================================================================
|
|
520
449
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
450
|
+
|
|
451
|
+
@install_app.command("claude-code")
|
|
452
|
+
def install_claude_code(
|
|
453
|
+
ctx: typer.Context,
|
|
454
|
+
enable_watch: bool = typer.Option(
|
|
455
|
+
True,
|
|
456
|
+
"--watch/--no-watch",
|
|
457
|
+
help="Enable file watching for auto-reindex",
|
|
458
|
+
),
|
|
459
|
+
force: bool = typer.Option(
|
|
460
|
+
False,
|
|
461
|
+
"--force",
|
|
462
|
+
"-f",
|
|
463
|
+
help="Force overwrite existing configuration",
|
|
464
|
+
),
|
|
465
|
+
) -> None:
|
|
466
|
+
"""Install Claude Code MCP integration (project-scoped).
|
|
467
|
+
|
|
468
|
+
Creates .mcp.json in the project root for team sharing.
|
|
469
|
+
This file should be committed to version control.
|
|
470
|
+
"""
|
|
471
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
472
|
+
|
|
473
|
+
console.print(
|
|
474
|
+
Panel.fit(
|
|
475
|
+
"[bold cyan]Installing Claude Code Integration[/bold cyan]\n"
|
|
476
|
+
"📁 Project-scoped configuration",
|
|
477
|
+
border_style="cyan",
|
|
536
478
|
)
|
|
479
|
+
)
|
|
537
480
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
481
|
+
success = configure_platform(
|
|
482
|
+
"claude-code", project_root, enable_watch=enable_watch, force=force
|
|
483
|
+
)
|
|
541
484
|
|
|
542
|
-
|
|
543
|
-
console.print("\n[bold]Recovery steps:[/bold]")
|
|
544
|
-
console.print(" 1. Check that the project directory exists and is writable")
|
|
485
|
+
if success:
|
|
545
486
|
console.print(
|
|
546
|
-
"
|
|
487
|
+
"\n[bold green]✨ Claude Code Integration Installed![/bold green]"
|
|
547
488
|
)
|
|
548
|
-
console.print(
|
|
549
|
-
|
|
489
|
+
console.print("\n[bold blue]Next Steps:[/bold blue]")
|
|
490
|
+
console.print(" 1. Open Claude Code in this project directory")
|
|
491
|
+
console.print(" 2. The MCP server will be available automatically")
|
|
492
|
+
console.print(" 3. Try: 'Search my code for authentication functions'")
|
|
493
|
+
console.print("\n[dim]💡 Commit .mcp.json to share with your team[/dim]")
|
|
494
|
+
else:
|
|
495
|
+
raise typer.Exit(1)
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
@install_app.command("cursor")
|
|
499
|
+
def install_cursor(
|
|
500
|
+
ctx: typer.Context,
|
|
501
|
+
enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
|
|
502
|
+
force: bool = typer.Option(False, "--force", "-f"),
|
|
503
|
+
) -> None:
|
|
504
|
+
"""Install Cursor IDE MCP integration (global)."""
|
|
505
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
506
|
+
|
|
507
|
+
console.print(
|
|
508
|
+
Panel.fit(
|
|
509
|
+
"[bold cyan]Installing Cursor Integration[/bold cyan]\n"
|
|
510
|
+
"🌐 Global configuration (~/.cursor/mcp.json)",
|
|
511
|
+
border_style="cyan",
|
|
550
512
|
)
|
|
551
|
-
|
|
513
|
+
)
|
|
552
514
|
|
|
515
|
+
success = configure_platform(
|
|
516
|
+
"cursor", project_root, enable_watch=enable_watch, force=force
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
if success:
|
|
520
|
+
console.print("\n[bold green]✨ Cursor Integration Installed![/bold green]")
|
|
521
|
+
console.print("\n[bold blue]Next Steps:[/bold blue]")
|
|
522
|
+
console.print(" 1. Restart Cursor IDE")
|
|
523
|
+
console.print(" 2. Open this project in Cursor")
|
|
524
|
+
console.print(" 3. MCP tools should be available")
|
|
525
|
+
else:
|
|
553
526
|
raise typer.Exit(1)
|
|
554
527
|
|
|
555
528
|
|
|
556
|
-
@install_app.command("
|
|
557
|
-
def
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
"-p",
|
|
562
|
-
help="Project root directory (auto-detected if not specified)",
|
|
563
|
-
exists=True,
|
|
564
|
-
file_okay=False,
|
|
565
|
-
dir_okay=True,
|
|
566
|
-
readable=True,
|
|
567
|
-
),
|
|
529
|
+
@install_app.command("windsurf")
|
|
530
|
+
def install_windsurf(
|
|
531
|
+
ctx: typer.Context,
|
|
532
|
+
enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
|
|
533
|
+
force: bool = typer.Option(False, "--force", "-f"),
|
|
568
534
|
) -> None:
|
|
569
|
-
"""
|
|
570
|
-
|
|
571
|
-
|
|
535
|
+
"""Install Windsurf IDE MCP integration (global)."""
|
|
536
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
537
|
+
|
|
538
|
+
console.print(
|
|
539
|
+
Panel.fit(
|
|
540
|
+
"[bold cyan]Installing Windsurf Integration[/bold cyan]\n"
|
|
541
|
+
"🌐 Global configuration (~/.codeium/windsurf/mcp_config.json)",
|
|
542
|
+
border_style="cyan",
|
|
543
|
+
)
|
|
544
|
+
)
|
|
572
545
|
|
|
573
|
-
|
|
546
|
+
success = configure_platform(
|
|
547
|
+
"windsurf", project_root, enable_watch=enable_watch, force=force
|
|
548
|
+
)
|
|
574
549
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
550
|
+
if success:
|
|
551
|
+
console.print("\n[bold green]✨ Windsurf Integration Installed![/bold green]")
|
|
552
|
+
console.print("\n[bold blue]Next Steps:[/bold blue]")
|
|
553
|
+
console.print(" 1. Restart Windsurf IDE")
|
|
554
|
+
console.print(" 2. Open this project in Windsurf")
|
|
555
|
+
console.print(" 3. MCP tools should be available")
|
|
556
|
+
else:
|
|
557
|
+
raise typer.Exit(1)
|
|
579
558
|
|
|
580
|
-
# Create sample files
|
|
581
|
-
(demo_dir / "main.py").write_text("""
|
|
582
|
-
def main():
|
|
583
|
-
'''Main entry point for the application.'''
|
|
584
|
-
print("Hello, World!")
|
|
585
|
-
user_service = UserService()
|
|
586
|
-
user_service.create_user("Alice", "alice@example.com")
|
|
587
559
|
|
|
588
|
-
|
|
589
|
-
|
|
560
|
+
@install_app.command("claude-desktop")
|
|
561
|
+
def install_claude_desktop(
|
|
562
|
+
ctx: typer.Context,
|
|
563
|
+
enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
|
|
564
|
+
force: bool = typer.Option(False, "--force", "-f"),
|
|
565
|
+
) -> None:
|
|
566
|
+
"""Install Claude Desktop MCP integration (global)."""
|
|
567
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
568
|
+
|
|
569
|
+
console.print(
|
|
570
|
+
Panel.fit(
|
|
571
|
+
"[bold cyan]Installing Claude Desktop Integration[/bold cyan]\n"
|
|
572
|
+
"🌐 Global configuration (~/.claude/config.json)",
|
|
573
|
+
border_style="cyan",
|
|
574
|
+
)
|
|
575
|
+
)
|
|
576
|
+
|
|
577
|
+
success = configure_platform(
|
|
578
|
+
"claude-desktop", project_root, enable_watch=enable_watch, force=force
|
|
579
|
+
)
|
|
590
580
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
581
|
+
if success:
|
|
582
|
+
console.print(
|
|
583
|
+
"\n[bold green]✨ Claude Desktop Integration Installed![/bold green]"
|
|
584
|
+
)
|
|
585
|
+
console.print("\n[bold blue]Next Steps:[/bold blue]")
|
|
586
|
+
console.print(" 1. Restart Claude Desktop")
|
|
587
|
+
console.print(" 2. The mcp-vector-search server will be available")
|
|
588
|
+
console.print(" 3. Open conversations in the project directory")
|
|
589
|
+
else:
|
|
590
|
+
raise typer.Exit(1)
|
|
595
591
|
|
|
596
|
-
def authenticate_user(self, email: str, password: str):
|
|
597
|
-
'''Authenticate user with email and password.'''
|
|
598
|
-
# Simple authentication logic
|
|
599
|
-
return email.endswith("@example.com")
|
|
600
592
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
593
|
+
@install_app.command("vscode")
|
|
594
|
+
def install_vscode(
|
|
595
|
+
ctx: typer.Context,
|
|
596
|
+
enable_watch: bool = typer.Option(True, "--watch/--no-watch"),
|
|
597
|
+
force: bool = typer.Option(False, "--force", "-f"),
|
|
598
|
+
) -> None:
|
|
599
|
+
"""Install VS Code MCP integration (global)."""
|
|
600
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
604
601
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
602
|
+
console.print(
|
|
603
|
+
Panel.fit(
|
|
604
|
+
"[bold cyan]Installing VS Code Integration[/bold cyan]\n"
|
|
605
|
+
"🌐 Global configuration (~/.vscode/mcp.json)",
|
|
606
|
+
border_style="cyan",
|
|
607
|
+
)
|
|
608
|
+
)
|
|
608
609
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
return json.load(f)
|
|
610
|
+
success = configure_platform(
|
|
611
|
+
"vscode", project_root, enable_watch=enable_watch, force=force
|
|
612
|
+
)
|
|
613
613
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
614
|
+
if success:
|
|
615
|
+
console.print("\n[bold green]✨ VS Code Integration Installed![/bold green]")
|
|
616
|
+
console.print("\n[bold blue]Next Steps:[/bold blue]")
|
|
617
|
+
console.print(" 1. Restart VS Code")
|
|
618
|
+
console.print(" 2. Open this project in VS Code")
|
|
619
|
+
console.print(" 3. MCP tools should be available")
|
|
620
|
+
else:
|
|
621
|
+
raise typer.Exit(1)
|
|
617
622
|
|
|
618
|
-
def hash_password(password: str) -> str:
|
|
619
|
-
'''Hash password for secure storage.'''
|
|
620
|
-
import hashlib
|
|
621
|
-
return hashlib.sha256(password.encode()).hexdigest()
|
|
622
|
-
""")
|
|
623
623
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
624
|
+
@install_app.command("list")
|
|
625
|
+
def list_platforms(ctx: typer.Context) -> None:
|
|
626
|
+
"""List all supported MCP platforms and their installation status."""
|
|
627
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
627
628
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
# Use subprocess to run the install command
|
|
632
|
-
result = subprocess.run(
|
|
633
|
-
[
|
|
634
|
-
sys.executable,
|
|
635
|
-
"-m",
|
|
636
|
-
"mcp_vector_search.cli.main",
|
|
637
|
-
"--project-root",
|
|
638
|
-
str(demo_dir),
|
|
639
|
-
"install",
|
|
640
|
-
str(demo_dir),
|
|
641
|
-
"--extensions",
|
|
642
|
-
".py",
|
|
643
|
-
"--no-mcp", # Skip MCP for demo
|
|
644
|
-
],
|
|
645
|
-
capture_output=True,
|
|
646
|
-
text=True,
|
|
647
|
-
)
|
|
629
|
+
console.print(
|
|
630
|
+
Panel.fit("[bold cyan]MCP Platform Status[/bold cyan]", border_style="cyan")
|
|
631
|
+
)
|
|
648
632
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
search_result = subprocess.run(
|
|
656
|
-
[
|
|
657
|
-
sys.executable,
|
|
658
|
-
"-m",
|
|
659
|
-
"mcp_vector_search.cli.main",
|
|
660
|
-
"--project-root",
|
|
661
|
-
str(demo_dir),
|
|
662
|
-
"search",
|
|
663
|
-
"user authentication",
|
|
664
|
-
"--limit",
|
|
665
|
-
"3",
|
|
666
|
-
],
|
|
667
|
-
capture_output=True,
|
|
668
|
-
text=True,
|
|
669
|
-
)
|
|
633
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
634
|
+
table.add_column("Platform", style="cyan")
|
|
635
|
+
table.add_column("Name")
|
|
636
|
+
table.add_column("Status")
|
|
637
|
+
table.add_column("Config Location")
|
|
670
638
|
|
|
671
|
-
|
|
672
|
-
console.print(
|
|
673
|
-
"\n[bold green]🔍 Sample search results:[/bold green]"
|
|
674
|
-
)
|
|
675
|
-
console.print(search_result.stdout)
|
|
676
|
-
else:
|
|
677
|
-
print_warning("Search demo failed, but installation was successful")
|
|
678
|
-
|
|
679
|
-
console.print("\n[bold blue]🎉 Demo completed![/bold blue]")
|
|
680
|
-
console.print(f"Demo project was created at: [cyan]{demo_dir}[/cyan]")
|
|
681
|
-
console.print(
|
|
682
|
-
"The temporary directory will be cleaned up automatically."
|
|
683
|
-
)
|
|
639
|
+
detected = detect_installed_platforms()
|
|
684
640
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
raise typer.Exit(1)
|
|
641
|
+
for platform, info in SUPPORTED_PLATFORMS.items():
|
|
642
|
+
config_path = get_platform_config_path(platform, project_root)
|
|
688
643
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
644
|
+
# Check if configured
|
|
645
|
+
is_configured = False
|
|
646
|
+
if config_path.exists():
|
|
647
|
+
try:
|
|
648
|
+
with open(config_path) as f:
|
|
649
|
+
config = json.load(f)
|
|
650
|
+
is_configured = "mcp-vector-search" in config.get("mcpServers", {})
|
|
651
|
+
except Exception:
|
|
652
|
+
pass
|
|
653
|
+
|
|
654
|
+
status = (
|
|
655
|
+
"✅ Configured"
|
|
656
|
+
if is_configured
|
|
657
|
+
else ("⚠️ Available" if platform in detected else "❌ Not Found")
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
table.add_row(
|
|
661
|
+
platform,
|
|
662
|
+
info["name"],
|
|
663
|
+
status,
|
|
664
|
+
str(config_path) if info["scope"] == "project" else info["config_path"],
|
|
665
|
+
)
|
|
666
|
+
|
|
667
|
+
console.print(table)
|
|
668
|
+
|
|
669
|
+
console.print("\n[bold blue]Installation Commands:[/bold blue]")
|
|
670
|
+
for platform in SUPPORTED_PLATFORMS:
|
|
671
|
+
console.print(f" mcp-vector-search install {platform}")
|
|
693
672
|
|
|
694
673
|
|
|
695
674
|
if __name__ == "__main__":
|