mcp-vector-search 0.12.6__py3-none-any.whl → 1.0.3__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.
- mcp_vector_search/__init__.py +2 -2
- mcp_vector_search/analysis/__init__.py +64 -0
- mcp_vector_search/analysis/collectors/__init__.py +39 -0
- mcp_vector_search/analysis/collectors/base.py +164 -0
- mcp_vector_search/analysis/collectors/complexity.py +743 -0
- mcp_vector_search/analysis/metrics.py +341 -0
- mcp_vector_search/analysis/reporters/__init__.py +5 -0
- mcp_vector_search/analysis/reporters/console.py +222 -0
- mcp_vector_search/cli/commands/analyze.py +408 -0
- mcp_vector_search/cli/commands/chat.py +1262 -0
- mcp_vector_search/cli/commands/index.py +21 -3
- mcp_vector_search/cli/commands/init.py +13 -0
- mcp_vector_search/cli/commands/install.py +597 -335
- mcp_vector_search/cli/commands/install_old.py +8 -4
- mcp_vector_search/cli/commands/mcp.py +78 -6
- mcp_vector_search/cli/commands/reset.py +68 -26
- mcp_vector_search/cli/commands/search.py +30 -7
- mcp_vector_search/cli/commands/setup.py +1133 -0
- mcp_vector_search/cli/commands/status.py +37 -2
- mcp_vector_search/cli/commands/uninstall.py +276 -357
- mcp_vector_search/cli/commands/visualize/__init__.py +39 -0
- mcp_vector_search/cli/commands/visualize/cli.py +276 -0
- mcp_vector_search/cli/commands/visualize/exporters/__init__.py +12 -0
- mcp_vector_search/cli/commands/visualize/exporters/html_exporter.py +33 -0
- mcp_vector_search/cli/commands/visualize/exporters/json_exporter.py +29 -0
- mcp_vector_search/cli/commands/visualize/graph_builder.py +714 -0
- mcp_vector_search/cli/commands/visualize/layout_engine.py +469 -0
- mcp_vector_search/cli/commands/visualize/server.py +311 -0
- mcp_vector_search/cli/commands/visualize/state_manager.py +428 -0
- mcp_vector_search/cli/commands/visualize/templates/__init__.py +16 -0
- mcp_vector_search/cli/commands/visualize/templates/base.py +180 -0
- mcp_vector_search/cli/commands/visualize/templates/scripts.py +2507 -0
- mcp_vector_search/cli/commands/visualize/templates/styles.py +1313 -0
- mcp_vector_search/cli/commands/visualize.py.original +2536 -0
- mcp_vector_search/cli/didyoumean.py +22 -2
- mcp_vector_search/cli/main.py +115 -159
- mcp_vector_search/cli/output.py +24 -8
- mcp_vector_search/config/__init__.py +4 -0
- mcp_vector_search/config/default_thresholds.yaml +52 -0
- mcp_vector_search/config/settings.py +12 -0
- mcp_vector_search/config/thresholds.py +185 -0
- mcp_vector_search/core/auto_indexer.py +3 -3
- mcp_vector_search/core/boilerplate.py +186 -0
- mcp_vector_search/core/config_utils.py +394 -0
- mcp_vector_search/core/database.py +369 -94
- mcp_vector_search/core/exceptions.py +11 -0
- mcp_vector_search/core/git_hooks.py +4 -4
- mcp_vector_search/core/indexer.py +221 -4
- mcp_vector_search/core/llm_client.py +751 -0
- mcp_vector_search/core/models.py +3 -0
- mcp_vector_search/core/project.py +17 -0
- mcp_vector_search/core/scheduler.py +11 -11
- mcp_vector_search/core/search.py +179 -29
- mcp_vector_search/mcp/server.py +24 -5
- mcp_vector_search/utils/__init__.py +2 -0
- mcp_vector_search/utils/gitignore_updater.py +212 -0
- mcp_vector_search/utils/monorepo.py +66 -4
- mcp_vector_search/utils/timing.py +10 -6
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/METADATA +182 -52
- mcp_vector_search-1.0.3.dist-info/RECORD +97 -0
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/WHEEL +1 -1
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/entry_points.txt +1 -0
- mcp_vector_search/cli/commands/visualize.py +0 -1467
- mcp_vector_search-0.12.6.dist-info/RECORD +0 -68
- {mcp_vector_search-0.12.6.dist-info → mcp_vector_search-1.0.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,27 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
This module provides installation commands for:
|
|
4
4
|
1. Project initialization (main command)
|
|
5
|
-
2. Platform-specific MCP integrations
|
|
5
|
+
2. Platform-specific MCP integrations using py-mcp-installer library
|
|
6
6
|
|
|
7
7
|
Examples:
|
|
8
8
|
# Install in current project
|
|
9
9
|
$ mcp-vector-search install
|
|
10
10
|
|
|
11
|
-
# Install
|
|
12
|
-
$ mcp-vector-search install
|
|
11
|
+
# Install MCP integration (auto-detect platforms)
|
|
12
|
+
$ mcp-vector-search install mcp
|
|
13
13
|
|
|
14
|
-
# Install
|
|
15
|
-
$ mcp-vector-search install --
|
|
14
|
+
# Install to specific platform
|
|
15
|
+
$ mcp-vector-search install mcp --platform cursor
|
|
16
|
+
|
|
17
|
+
# Install to all detected platforms
|
|
18
|
+
$ mcp-vector-search install mcp --all
|
|
16
19
|
"""
|
|
17
20
|
|
|
18
21
|
import asyncio
|
|
19
|
-
import json
|
|
20
|
-
import shutil
|
|
21
22
|
from pathlib import Path
|
|
22
|
-
from typing import Any
|
|
23
23
|
|
|
24
24
|
import typer
|
|
25
25
|
from loguru import logger
|
|
26
|
+
|
|
27
|
+
# Import from py-mcp-installer library
|
|
28
|
+
from py_mcp_installer import (
|
|
29
|
+
InstallationError,
|
|
30
|
+
InstallationResult,
|
|
31
|
+
MCPInspector,
|
|
32
|
+
MCPInstaller,
|
|
33
|
+
MCPServerConfig,
|
|
34
|
+
Platform,
|
|
35
|
+
PlatformDetector,
|
|
36
|
+
PlatformInfo,
|
|
37
|
+
)
|
|
26
38
|
from rich.console import Console
|
|
27
39
|
from rich.panel import Panel
|
|
28
40
|
from rich.table import Table
|
|
@@ -53,23 +65,25 @@ install_app = create_enhanced_typer(
|
|
|
53
65
|
[code]$ mcp-vector-search install[/code]
|
|
54
66
|
|
|
55
67
|
[green]2. MCP Platform Integration[/green]
|
|
56
|
-
Add MCP integration
|
|
57
|
-
[code]$ mcp-vector-search install
|
|
58
|
-
[code]$ mcp-vector-search install cursor[/code]
|
|
59
|
-
[code]$ mcp-vector-search install
|
|
68
|
+
Add MCP integration with auto-detection:
|
|
69
|
+
[code]$ mcp-vector-search install mcp[/code]
|
|
70
|
+
[code]$ mcp-vector-search install mcp --platform cursor[/code]
|
|
71
|
+
[code]$ mcp-vector-search install mcp --all[/code]
|
|
60
72
|
|
|
61
73
|
[green]3. Complete Setup[/green]
|
|
62
74
|
Install project + all MCP integrations:
|
|
63
75
|
[code]$ mcp-vector-search install --with-mcp[/code]
|
|
64
76
|
|
|
65
77
|
[bold cyan]Supported Platforms:[/bold cyan]
|
|
66
|
-
• [green]claude-code[/green] - Claude Code
|
|
67
|
-
• [green]claude-desktop[/green] - Claude Desktop
|
|
68
|
-
• [green]cursor[/green] - Cursor IDE
|
|
69
|
-
• [green]
|
|
70
|
-
• [green]
|
|
71
|
-
|
|
72
|
-
[
|
|
78
|
+
• [green]claude-code[/green] - Claude Code
|
|
79
|
+
• [green]claude-desktop[/green] - Claude Desktop
|
|
80
|
+
• [green]cursor[/green] - Cursor IDE
|
|
81
|
+
• [green]auggie[/green] - Auggie
|
|
82
|
+
• [green]codex[/green] - Codex
|
|
83
|
+
• [green]windsurf[/green] - Windsurf IDE
|
|
84
|
+
• [green]gemini-cli[/green] - Gemini CLI
|
|
85
|
+
|
|
86
|
+
[dim]💡 Use 'mcp-vector-search uninstall mcp' to remove integrations[/dim]
|
|
73
87
|
""",
|
|
74
88
|
invoke_without_command=True,
|
|
75
89
|
no_args_is_help=False,
|
|
@@ -77,190 +91,184 @@ install_app = create_enhanced_typer(
|
|
|
77
91
|
|
|
78
92
|
|
|
79
93
|
# ==============================================================================
|
|
80
|
-
#
|
|
94
|
+
# Helper Functions
|
|
81
95
|
# ==============================================================================
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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.
|
|
97
|
+
|
|
98
|
+
def detect_project_root(start_path: Path | None = None) -> Path:
|
|
99
|
+
"""Auto-detect project root directory.
|
|
100
|
+
|
|
101
|
+
Detection priority:
|
|
102
|
+
1. Directory with .mcp-vector-search/ (project initialized)
|
|
103
|
+
2. Git repository root
|
|
104
|
+
3. Current working directory (fallback)
|
|
119
105
|
|
|
120
106
|
Args:
|
|
121
|
-
|
|
122
|
-
project_root: Project root directory (for project-scoped configs)
|
|
107
|
+
start_path: Starting path for detection (default: current directory)
|
|
123
108
|
|
|
124
109
|
Returns:
|
|
125
|
-
Path to
|
|
110
|
+
Path to detected project root
|
|
126
111
|
"""
|
|
127
|
-
|
|
128
|
-
raise ValueError(f"Unsupported platform: {platform}")
|
|
112
|
+
current = start_path or Path.cwd()
|
|
129
113
|
|
|
130
|
-
|
|
131
|
-
|
|
114
|
+
# Check for .mcp-vector-search directory (initialized project)
|
|
115
|
+
if (current / ".mcp-vector-search").exists():
|
|
116
|
+
logger.debug(f"Detected project root via .mcp-vector-search: {current}")
|
|
117
|
+
return current
|
|
132
118
|
|
|
133
|
-
#
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return
|
|
119
|
+
# Check if we're in a git repository
|
|
120
|
+
git_root = find_git_root(current)
|
|
121
|
+
if git_root and (git_root / ".mcp-vector-search").exists():
|
|
122
|
+
logger.debug(f"Detected project root via git + .mcp-vector-search: {git_root}")
|
|
123
|
+
return git_root
|
|
124
|
+
|
|
125
|
+
# Fallback to current directory
|
|
126
|
+
logger.debug(f"Using current directory as project root: {current}")
|
|
127
|
+
return current
|
|
138
128
|
|
|
139
129
|
|
|
140
|
-
def
|
|
141
|
-
|
|
142
|
-
platform: str,
|
|
143
|
-
enable_watch: bool = True,
|
|
144
|
-
) -> dict[str, Any]:
|
|
145
|
-
"""Generate MCP server configuration for a platform.
|
|
130
|
+
def find_git_root(path: Path) -> Path | None:
|
|
131
|
+
"""Find git repository root by walking up directory tree.
|
|
146
132
|
|
|
147
133
|
Args:
|
|
148
|
-
|
|
149
|
-
platform: Platform name
|
|
150
|
-
enable_watch: Whether to enable file watching
|
|
134
|
+
path: Starting path
|
|
151
135
|
|
|
152
136
|
Returns:
|
|
153
|
-
|
|
137
|
+
Path to git root or None if not in a git repo
|
|
154
138
|
"""
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
"
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
139
|
+
current = path.resolve()
|
|
140
|
+
while current != current.parent:
|
|
141
|
+
if (current / ".git").exists():
|
|
142
|
+
logger.debug(f"Found git root: {current}")
|
|
143
|
+
return current
|
|
144
|
+
current = current.parent
|
|
145
|
+
return None
|
|
146
|
+
|
|
163
147
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
# These platforms require "type": "stdio"
|
|
167
|
-
config["type"] = "stdio"
|
|
148
|
+
def _get_claude_desktop_config_path() -> Path | None:
|
|
149
|
+
"""Get the default config path for Claude Desktop based on OS.
|
|
168
150
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
151
|
+
Returns:
|
|
152
|
+
Path to Claude Desktop config or None if unknown OS
|
|
153
|
+
"""
|
|
154
|
+
import sys
|
|
155
|
+
|
|
156
|
+
if sys.platform == "darwin":
|
|
157
|
+
# macOS
|
|
158
|
+
return (
|
|
159
|
+
Path.home()
|
|
160
|
+
/ "Library"
|
|
161
|
+
/ "Application Support"
|
|
162
|
+
/ "Claude"
|
|
163
|
+
/ "claude_desktop_config.json"
|
|
164
|
+
)
|
|
165
|
+
elif sys.platform == "win32":
|
|
166
|
+
# Windows
|
|
167
|
+
import os
|
|
172
168
|
|
|
173
|
-
|
|
169
|
+
appdata = os.environ.get("APPDATA", "")
|
|
170
|
+
if appdata:
|
|
171
|
+
return Path(appdata) / "Claude" / "claude_desktop_config.json"
|
|
172
|
+
else:
|
|
173
|
+
# Linux
|
|
174
|
+
return Path.home() / ".config" / "Claude" / "claude_desktop_config.json"
|
|
175
|
+
return None
|
|
174
176
|
|
|
175
177
|
|
|
176
|
-
def
|
|
177
|
-
"""Detect
|
|
178
|
+
def detect_all_platforms() -> list[PlatformInfo]:
|
|
179
|
+
"""Detect all available platforms on the system.
|
|
178
180
|
|
|
179
181
|
Returns:
|
|
180
|
-
|
|
182
|
+
List of detected platforms with confidence scores
|
|
181
183
|
"""
|
|
182
|
-
|
|
184
|
+
detector = PlatformDetector()
|
|
185
|
+
detected_platforms = []
|
|
186
|
+
|
|
187
|
+
# Try to detect each platform
|
|
188
|
+
platform_detectors = {
|
|
189
|
+
Platform.CLAUDE_CODE: detector.detect_claude_code,
|
|
190
|
+
Platform.CLAUDE_DESKTOP: detector.detect_claude_desktop,
|
|
191
|
+
Platform.CURSOR: detector.detect_cursor,
|
|
192
|
+
Platform.AUGGIE: detector.detect_auggie,
|
|
193
|
+
Platform.CODEX: detector.detect_codex,
|
|
194
|
+
Platform.WINDSURF: detector.detect_windsurf,
|
|
195
|
+
Platform.GEMINI_CLI: detector.detect_gemini_cli,
|
|
196
|
+
}
|
|
183
197
|
|
|
184
|
-
for
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
for platform_enum, detector_func in platform_detectors.items():
|
|
199
|
+
try:
|
|
200
|
+
confidence, config_path = detector_func()
|
|
201
|
+
|
|
202
|
+
# Determine CLI availability
|
|
203
|
+
cli_available = False
|
|
204
|
+
from py_mcp_installer.utils import resolve_command_path
|
|
205
|
+
|
|
206
|
+
if platform_enum in (Platform.CLAUDE_CODE, Platform.CLAUDE_DESKTOP):
|
|
207
|
+
cli_available = resolve_command_path("claude") is not None
|
|
208
|
+
elif platform_enum == Platform.CURSOR:
|
|
209
|
+
cli_available = resolve_command_path("cursor") is not None
|
|
210
|
+
|
|
211
|
+
# Include platform if:
|
|
212
|
+
# 1. Has config file with confidence > 0, OR
|
|
213
|
+
# 2. Has CLI available (can create config)
|
|
214
|
+
# For CLI-based platforms, we can configure even without existing config
|
|
215
|
+
if confidence > 0.0 and config_path:
|
|
216
|
+
# Has existing config file
|
|
217
|
+
platform_info = PlatformInfo(
|
|
218
|
+
platform=platform_enum,
|
|
219
|
+
confidence=confidence,
|
|
220
|
+
config_path=config_path,
|
|
221
|
+
cli_available=cli_available,
|
|
222
|
+
)
|
|
223
|
+
detected_platforms.append(platform_info)
|
|
224
|
+
elif cli_available and platform_enum in (
|
|
225
|
+
Platform.CLAUDE_CODE,
|
|
226
|
+
Platform.CLAUDE_DESKTOP,
|
|
227
|
+
Platform.CURSOR,
|
|
228
|
+
):
|
|
229
|
+
# CLI available but no config yet - we can still configure it
|
|
230
|
+
# Use default config path for the platform
|
|
231
|
+
default_config_paths = {
|
|
232
|
+
Platform.CLAUDE_CODE: Path.home()
|
|
233
|
+
/ ".config"
|
|
234
|
+
/ "claude"
|
|
235
|
+
/ "mcp.json",
|
|
236
|
+
Platform.CLAUDE_DESKTOP: _get_claude_desktop_config_path(),
|
|
237
|
+
Platform.CURSOR: Path.home() / ".cursor" / "mcp.json",
|
|
238
|
+
}
|
|
239
|
+
platform_info = PlatformInfo(
|
|
240
|
+
platform=platform_enum,
|
|
241
|
+
confidence=0.2, # Low confidence since no config exists yet
|
|
242
|
+
config_path=default_config_paths.get(platform_enum),
|
|
243
|
+
cli_available=cli_available,
|
|
244
|
+
)
|
|
245
|
+
detected_platforms.append(platform_info)
|
|
246
|
+
except Exception as e:
|
|
247
|
+
logger.debug(f"Failed to detect {platform_enum.value}: {e}")
|
|
188
248
|
continue
|
|
189
249
|
|
|
190
|
-
|
|
191
|
-
config_path = Path(info["config_path"]).expanduser()
|
|
192
|
-
if config_path.parent.exists():
|
|
193
|
-
detected[platform] = config_path
|
|
194
|
-
|
|
195
|
-
return detected
|
|
250
|
+
return detected_platforms
|
|
196
251
|
|
|
197
252
|
|
|
198
|
-
def
|
|
199
|
-
platform
|
|
200
|
-
project_root: Path,
|
|
201
|
-
server_name: str = "mcp-vector-search",
|
|
202
|
-
enable_watch: bool = True,
|
|
203
|
-
force: bool = False,
|
|
204
|
-
) -> bool:
|
|
205
|
-
"""Configure MCP integration for a specific platform.
|
|
253
|
+
def platform_name_to_enum(name: str) -> Platform | None:
|
|
254
|
+
"""Convert platform name to enum.
|
|
206
255
|
|
|
207
256
|
Args:
|
|
208
|
-
|
|
209
|
-
project_root: Project root directory
|
|
210
|
-
server_name: Name for the MCP server entry
|
|
211
|
-
enable_watch: Whether to enable file watching
|
|
212
|
-
force: Whether to overwrite existing configuration
|
|
257
|
+
name: Platform name (e.g., "cursor", "claude-code")
|
|
213
258
|
|
|
214
259
|
Returns:
|
|
215
|
-
|
|
260
|
+
Platform enum or None if not found
|
|
216
261
|
"""
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
|
237
|
-
else:
|
|
238
|
-
# Create new config
|
|
239
|
-
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
240
|
-
config = {}
|
|
241
|
-
|
|
242
|
-
# Ensure mcpServers section exists
|
|
243
|
-
if "mcpServers" not in config:
|
|
244
|
-
config["mcpServers"] = {}
|
|
245
|
-
|
|
246
|
-
# Add server configuration
|
|
247
|
-
server_config = get_mcp_server_config(project_root, platform, enable_watch)
|
|
248
|
-
config["mcpServers"][server_name] = server_config
|
|
249
|
-
|
|
250
|
-
# Write configuration
|
|
251
|
-
with open(config_path, "w") as f:
|
|
252
|
-
json.dump(config, f, indent=2)
|
|
253
|
-
|
|
254
|
-
platform_name = SUPPORTED_PLATFORMS[platform]["name"]
|
|
255
|
-
print_success(f" ✅ Configured {platform_name}")
|
|
256
|
-
print_info(f" Config: {config_path}")
|
|
257
|
-
|
|
258
|
-
return True
|
|
259
|
-
|
|
260
|
-
except Exception as e:
|
|
261
|
-
logger.error(f"Failed to configure {platform}: {e}")
|
|
262
|
-
print_error(f" ❌ Failed to configure {platform}: {e}")
|
|
263
|
-
return False
|
|
262
|
+
name_map = {
|
|
263
|
+
"claude-code": Platform.CLAUDE_CODE,
|
|
264
|
+
"claude-desktop": Platform.CLAUDE_DESKTOP,
|
|
265
|
+
"cursor": Platform.CURSOR,
|
|
266
|
+
"auggie": Platform.AUGGIE,
|
|
267
|
+
"codex": Platform.CODEX,
|
|
268
|
+
"windsurf": Platform.WINDSURF,
|
|
269
|
+
"gemini-cli": Platform.GEMINI_CLI,
|
|
270
|
+
}
|
|
271
|
+
return name_map.get(name.lower())
|
|
264
272
|
|
|
265
273
|
|
|
266
274
|
# ==============================================================================
|
|
@@ -409,15 +417,15 @@ def main(
|
|
|
409
417
|
# Install MCP integrations if requested
|
|
410
418
|
if with_mcp:
|
|
411
419
|
console.print("\n[bold blue]🔗 Installing MCP integrations...[/bold blue]")
|
|
412
|
-
detected =
|
|
420
|
+
detected = detect_all_platforms()
|
|
413
421
|
|
|
414
422
|
if detected:
|
|
415
|
-
for
|
|
416
|
-
|
|
423
|
+
for platform_info in detected:
|
|
424
|
+
_install_to_platform(platform_info, project_root)
|
|
417
425
|
else:
|
|
418
426
|
print_warning("No MCP platforms detected")
|
|
419
427
|
print_info("Install platforms manually using:")
|
|
420
|
-
print_info(" mcp-vector-search install <platform>")
|
|
428
|
+
print_info(" mcp-vector-search install mcp --platform <platform>")
|
|
421
429
|
|
|
422
430
|
# Success message
|
|
423
431
|
console.print("\n[bold green]🎉 Installation Complete![/bold green]")
|
|
@@ -429,11 +437,14 @@ def main(
|
|
|
429
437
|
|
|
430
438
|
if not with_mcp:
|
|
431
439
|
next_steps.append(
|
|
432
|
-
"[cyan]mcp-vector-search install
|
|
440
|
+
"[cyan]mcp-vector-search install mcp[/cyan] - Add MCP integration"
|
|
433
441
|
)
|
|
434
442
|
|
|
435
443
|
print_next_steps(next_steps, title="Ready to Use")
|
|
436
444
|
|
|
445
|
+
except typer.Exit:
|
|
446
|
+
# Re-raise typer.Exit to allow proper exit handling
|
|
447
|
+
raise
|
|
437
448
|
except ProjectInitializationError as e:
|
|
438
449
|
print_error(f"Installation failed: {e}")
|
|
439
450
|
raise typer.Exit(1)
|
|
@@ -444,231 +455,482 @@ def main(
|
|
|
444
455
|
|
|
445
456
|
|
|
446
457
|
# ==============================================================================
|
|
447
|
-
#
|
|
458
|
+
# MCP Installation Command
|
|
448
459
|
# ==============================================================================
|
|
449
460
|
|
|
450
461
|
|
|
451
|
-
|
|
452
|
-
|
|
462
|
+
def _install_to_platform(
|
|
463
|
+
platform_info: PlatformInfo, project_root: Path, force: bool = True
|
|
464
|
+
) -> bool:
|
|
465
|
+
"""Install to a specific platform.
|
|
466
|
+
|
|
467
|
+
Args:
|
|
468
|
+
platform_info: Platform information
|
|
469
|
+
project_root: Project root directory
|
|
470
|
+
force: If True, overwrite existing installation (default: True)
|
|
471
|
+
|
|
472
|
+
Returns:
|
|
473
|
+
True if installation succeeded
|
|
474
|
+
"""
|
|
475
|
+
import io
|
|
476
|
+
import sys
|
|
477
|
+
|
|
478
|
+
try:
|
|
479
|
+
# Create installer for this platform
|
|
480
|
+
installer = MCPInstaller(platform=platform_info.platform)
|
|
481
|
+
|
|
482
|
+
# Detect installation method (uv vs direct command)
|
|
483
|
+
import shutil
|
|
484
|
+
|
|
485
|
+
use_uv = shutil.which("uv") is not None
|
|
486
|
+
mcp_cmd = shutil.which("mcp-vector-search")
|
|
487
|
+
|
|
488
|
+
if use_uv:
|
|
489
|
+
# Development mode with uv
|
|
490
|
+
command = "uv"
|
|
491
|
+
args = ["run", "--directory", str(project_root), "mcp-vector-search", "mcp"]
|
|
492
|
+
elif mcp_cmd:
|
|
493
|
+
# Production mode with installed package
|
|
494
|
+
command = "mcp-vector-search"
|
|
495
|
+
args = ["mcp"]
|
|
496
|
+
else:
|
|
497
|
+
# Fallback to uv (will fail if not available)
|
|
498
|
+
command = "uv"
|
|
499
|
+
args = ["run", "mcp-vector-search", "mcp"]
|
|
500
|
+
|
|
501
|
+
# Create server configuration
|
|
502
|
+
server_config = MCPServerConfig(
|
|
503
|
+
name="mcp-vector-search",
|
|
504
|
+
command=command,
|
|
505
|
+
args=args,
|
|
506
|
+
env={
|
|
507
|
+
"PROJECT_ROOT": str(project_root.resolve()),
|
|
508
|
+
"MCP_PROJECT_ROOT": str(project_root.resolve()),
|
|
509
|
+
},
|
|
510
|
+
description=f"Semantic code search for {project_root.name}",
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
def do_install() -> InstallationResult:
|
|
514
|
+
"""Execute the installation."""
|
|
515
|
+
return installer.install_server(
|
|
516
|
+
name=server_config.name,
|
|
517
|
+
command=server_config.command,
|
|
518
|
+
args=server_config.args,
|
|
519
|
+
env=server_config.env,
|
|
520
|
+
description=server_config.description,
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
# Try to install, suppressing verbose stderr output from py-mcp-installer
|
|
524
|
+
try:
|
|
525
|
+
# Capture stderr to suppress verbose traceback output
|
|
526
|
+
old_stderr = sys.stderr
|
|
527
|
+
sys.stderr = io.StringIO()
|
|
528
|
+
try:
|
|
529
|
+
result = do_install()
|
|
530
|
+
finally:
|
|
531
|
+
captured_stderr = sys.stderr.getvalue()
|
|
532
|
+
sys.stderr = old_stderr
|
|
533
|
+
# Log captured output at debug level for troubleshooting
|
|
534
|
+
if captured_stderr.strip():
|
|
535
|
+
logger.debug(f"Installation stderr: {captured_stderr[:500]}")
|
|
536
|
+
except InstallationError as e:
|
|
537
|
+
# Restore stderr before handling error
|
|
538
|
+
if sys.stderr != old_stderr:
|
|
539
|
+
sys.stderr = old_stderr
|
|
540
|
+
|
|
541
|
+
# Check if it's an "already exists" error
|
|
542
|
+
error_msg = str(e).lower()
|
|
543
|
+
if "already exists" in error_msg and force:
|
|
544
|
+
# Silently uninstall first, then reinstall
|
|
545
|
+
logger.debug(
|
|
546
|
+
f"Server already exists on {platform_info.platform.value}, "
|
|
547
|
+
"removing and reinstalling..."
|
|
548
|
+
)
|
|
549
|
+
try:
|
|
550
|
+
# Suppress stderr during uninstall too
|
|
551
|
+
old_stderr = sys.stderr
|
|
552
|
+
sys.stderr = io.StringIO()
|
|
553
|
+
try:
|
|
554
|
+
installer.uninstall_server(server_config.name)
|
|
555
|
+
result = do_install()
|
|
556
|
+
finally:
|
|
557
|
+
sys.stderr = old_stderr
|
|
558
|
+
except Exception as uninstall_err:
|
|
559
|
+
logger.debug(
|
|
560
|
+
f"Failed to uninstall existing server: {uninstall_err}"
|
|
561
|
+
)
|
|
562
|
+
# Server already exists is not a failure - it's already configured
|
|
563
|
+
print_success(f" ✅ Installed to {platform_info.platform.value}")
|
|
564
|
+
if platform_info.config_path:
|
|
565
|
+
print_info(f" Config: {platform_info.config_path}")
|
|
566
|
+
return True
|
|
567
|
+
else:
|
|
568
|
+
raise
|
|
569
|
+
|
|
570
|
+
if result.success:
|
|
571
|
+
print_success(f" ✅ Installed to {platform_info.platform.value}")
|
|
572
|
+
if result.config_path:
|
|
573
|
+
print_info(f" Config: {result.config_path}")
|
|
574
|
+
|
|
575
|
+
# Validate installation
|
|
576
|
+
inspector = MCPInspector(platform_info)
|
|
577
|
+
report = inspector.inspect()
|
|
578
|
+
|
|
579
|
+
if report.has_errors():
|
|
580
|
+
print_warning(" ⚠️ Configuration has issues:")
|
|
581
|
+
for issue in report.issues:
|
|
582
|
+
if issue.severity == "error":
|
|
583
|
+
print_warning(f" • {issue.message}")
|
|
584
|
+
|
|
585
|
+
return True
|
|
586
|
+
else:
|
|
587
|
+
print_error(
|
|
588
|
+
f" ❌ Failed to install to {platform_info.platform.value}: {result.message}"
|
|
589
|
+
)
|
|
590
|
+
return False
|
|
591
|
+
|
|
592
|
+
except Exception as e:
|
|
593
|
+
logger.debug(f"Installation to {platform_info.platform.value} failed: {e}")
|
|
594
|
+
# Don't print full exception - just a clean error message
|
|
595
|
+
error_str = str(e)
|
|
596
|
+
# Extract just the main error message, not the full traceback
|
|
597
|
+
if "already exists" in error_str.lower():
|
|
598
|
+
# Already exists is a success case - server is configured
|
|
599
|
+
print_success(f" ✅ Installed to {platform_info.platform.value}")
|
|
600
|
+
if platform_info.config_path:
|
|
601
|
+
print_info(f" Config: {platform_info.config_path}")
|
|
602
|
+
return True
|
|
603
|
+
else:
|
|
604
|
+
# Extract first line of error for clean output
|
|
605
|
+
short_error = error_str.split("\n")[0][:100]
|
|
606
|
+
print_error(f" ❌ Failed: {platform_info.platform.value} - {short_error}")
|
|
607
|
+
return False
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
@install_app.command(name="mcp")
|
|
611
|
+
def install_mcp(
|
|
453
612
|
ctx: typer.Context,
|
|
454
|
-
|
|
613
|
+
platform: str | None = typer.Option(
|
|
614
|
+
None,
|
|
615
|
+
"--platform",
|
|
616
|
+
"-p",
|
|
617
|
+
help="Specific platform to install to (e.g., cursor, claude-code)",
|
|
618
|
+
),
|
|
619
|
+
all_platforms: bool = typer.Option(
|
|
620
|
+
False,
|
|
621
|
+
"--all",
|
|
622
|
+
"-a",
|
|
623
|
+
help="Install to all detected platforms",
|
|
624
|
+
),
|
|
625
|
+
auto: bool = typer.Option(
|
|
455
626
|
True,
|
|
456
|
-
"--
|
|
457
|
-
help="
|
|
627
|
+
"--auto/--no-auto",
|
|
628
|
+
help="Auto-detect project root (default: enabled)",
|
|
458
629
|
),
|
|
459
|
-
|
|
630
|
+
dry_run: bool = typer.Option(
|
|
460
631
|
False,
|
|
461
|
-
"--
|
|
462
|
-
"
|
|
463
|
-
help="Force overwrite existing configuration",
|
|
632
|
+
"--dry-run",
|
|
633
|
+
help="Preview changes without applying them",
|
|
464
634
|
),
|
|
465
635
|
) -> None:
|
|
466
|
-
"""Install
|
|
636
|
+
"""Install MCP integration to platforms.
|
|
637
|
+
|
|
638
|
+
Auto-detects available platforms and installs mcp-vector-search as an MCP server.
|
|
639
|
+
Automatically detects project root from current directory or git repository.
|
|
640
|
+
|
|
641
|
+
[bold cyan]Examples:[/bold cyan]
|
|
642
|
+
|
|
643
|
+
[green]Auto-detect and install (recommended):[/green]
|
|
644
|
+
$ mcp-vector-search install mcp
|
|
645
|
+
$ mcp-vector-search install mcp --auto
|
|
467
646
|
|
|
468
|
-
|
|
469
|
-
|
|
647
|
+
[green]Install to specific platform:[/green]
|
|
648
|
+
$ mcp-vector-search install mcp --platform cursor
|
|
649
|
+
|
|
650
|
+
[green]Install to all detected platforms:[/green]
|
|
651
|
+
$ mcp-vector-search install mcp --all
|
|
652
|
+
|
|
653
|
+
[green]Preview changes (dry run):[/green]
|
|
654
|
+
$ mcp-vector-search install mcp --dry-run
|
|
655
|
+
|
|
656
|
+
[green]Use current directory as project root (no auto-detection):[/green]
|
|
657
|
+
$ mcp-vector-search install mcp --no-auto
|
|
470
658
|
"""
|
|
471
|
-
|
|
659
|
+
# Auto-detect project root if enabled
|
|
660
|
+
if auto:
|
|
661
|
+
project_root = detect_project_root()
|
|
662
|
+
console.print(f"[dim]🔍 Auto-detected project root: {project_root}[/dim]\n")
|
|
663
|
+
else:
|
|
664
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
665
|
+
console.print(f"[dim]📁 Using project root: {project_root}[/dim]\n")
|
|
472
666
|
|
|
473
667
|
console.print(
|
|
474
668
|
Panel.fit(
|
|
475
|
-
"[bold cyan]Installing
|
|
476
|
-
"📁 Project
|
|
669
|
+
"[bold cyan]Installing MCP Integration[/bold cyan]\n"
|
|
670
|
+
f"📁 Project: {project_root}",
|
|
477
671
|
border_style="cyan",
|
|
478
672
|
)
|
|
479
673
|
)
|
|
480
674
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
675
|
+
try:
|
|
676
|
+
# Detect available platforms
|
|
677
|
+
print_info("🔍 Detecting available MCP platforms...")
|
|
678
|
+
detected = detect_all_platforms()
|
|
679
|
+
|
|
680
|
+
if not detected:
|
|
681
|
+
print_warning("No MCP platforms detected.")
|
|
682
|
+
print_info(
|
|
683
|
+
"Supported platforms: claude-code, claude-desktop, cursor, auggie, codex, windsurf, gemini-cli"
|
|
684
|
+
)
|
|
685
|
+
raise typer.Exit(0)
|
|
686
|
+
|
|
687
|
+
# Display detected platforms
|
|
688
|
+
table = Table(title="Detected MCP Platforms")
|
|
689
|
+
table.add_column("Platform", style="cyan")
|
|
690
|
+
table.add_column("Config Path", style="green")
|
|
691
|
+
table.add_column("Confidence", style="yellow")
|
|
692
|
+
table.add_column("CLI", style="magenta")
|
|
693
|
+
|
|
694
|
+
for p in detected:
|
|
695
|
+
table.add_row(
|
|
696
|
+
p.platform.value,
|
|
697
|
+
str(p.config_path) if p.config_path else "N/A",
|
|
698
|
+
f"{p.confidence:.2f}",
|
|
699
|
+
"✅" if p.cli_available else "❌",
|
|
700
|
+
)
|
|
701
|
+
|
|
702
|
+
console.print(table)
|
|
703
|
+
|
|
704
|
+
# Filter platforms
|
|
705
|
+
target_platforms = detected
|
|
706
|
+
|
|
707
|
+
if platform:
|
|
708
|
+
# Install to specific platform
|
|
709
|
+
platform_enum = platform_name_to_enum(platform)
|
|
710
|
+
if not platform_enum:
|
|
711
|
+
print_error(f"Unknown platform: {platform}")
|
|
712
|
+
print_info(
|
|
713
|
+
"Supported: claude-code, claude-desktop, cursor, auggie, codex, windsurf, gemini-cli"
|
|
714
|
+
)
|
|
715
|
+
raise typer.Exit(1)
|
|
716
|
+
|
|
717
|
+
target_platforms = [p for p in detected if p.platform == platform_enum]
|
|
718
|
+
|
|
719
|
+
if not target_platforms:
|
|
720
|
+
print_error(f"Platform '{platform}' not detected on this system")
|
|
721
|
+
raise typer.Exit(1)
|
|
722
|
+
|
|
723
|
+
elif not all_platforms:
|
|
724
|
+
# By default, install to highest confidence platform only
|
|
725
|
+
if detected:
|
|
726
|
+
max_confidence_platform = max(detected, key=lambda p: p.confidence)
|
|
727
|
+
target_platforms = [max_confidence_platform]
|
|
728
|
+
print_info(
|
|
729
|
+
f"Installing to highest confidence platform: {max_confidence_platform.platform.value}"
|
|
730
|
+
)
|
|
731
|
+
print_info("Use --all to install to all detected platforms")
|
|
732
|
+
|
|
733
|
+
# Show what will be installed
|
|
734
|
+
console.print("\n[bold]Target platforms:[/bold]")
|
|
735
|
+
for p in target_platforms:
|
|
736
|
+
console.print(f" • {p.platform.value}")
|
|
737
|
+
|
|
738
|
+
if dry_run:
|
|
739
|
+
console.print("\n[bold yellow]🔍 DRY RUN MODE[/bold yellow]")
|
|
740
|
+
print_info("No changes will be applied")
|
|
741
|
+
return
|
|
742
|
+
|
|
743
|
+
# Install to each platform
|
|
744
|
+
console.print("\n[bold]Installing...[/bold]")
|
|
745
|
+
successful = 0
|
|
746
|
+
failed = 0
|
|
747
|
+
|
|
748
|
+
for platform_info in target_platforms:
|
|
749
|
+
if _install_to_platform(platform_info, project_root):
|
|
750
|
+
successful += 1
|
|
751
|
+
else:
|
|
752
|
+
failed += 1
|
|
753
|
+
|
|
754
|
+
# Summary
|
|
755
|
+
console.print("\n[bold green]✨ Installation Summary[/bold green]")
|
|
756
|
+
console.print(f" ✅ Successful: {successful}")
|
|
757
|
+
if failed > 0:
|
|
758
|
+
console.print(f" ❌ Failed: {failed}")
|
|
484
759
|
|
|
485
|
-
if success:
|
|
486
|
-
console.print(
|
|
487
|
-
"\n[bold green]✨ Claude Code Integration Installed![/bold green]"
|
|
488
|
-
)
|
|
489
760
|
console.print("\n[bold blue]Next Steps:[/bold blue]")
|
|
490
|
-
console.print(" 1.
|
|
761
|
+
console.print(" 1. Restart your AI coding tool")
|
|
491
762
|
console.print(" 2. The MCP server will be available automatically")
|
|
492
763
|
console.print(" 3. Try: 'Search my code for authentication functions'")
|
|
493
|
-
|
|
494
|
-
|
|
764
|
+
|
|
765
|
+
except typer.Exit:
|
|
766
|
+
raise
|
|
767
|
+
except Exception as e:
|
|
768
|
+
logger.exception("MCP installation failed")
|
|
769
|
+
print_error(f"Installation failed: {e}")
|
|
495
770
|
raise typer.Exit(1)
|
|
496
771
|
|
|
497
772
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
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()
|
|
773
|
+
# ==============================================================================
|
|
774
|
+
# MCP Status Command
|
|
775
|
+
# ==============================================================================
|
|
506
776
|
|
|
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",
|
|
512
|
-
)
|
|
513
|
-
)
|
|
514
777
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
778
|
+
@install_app.command("mcp-status")
|
|
779
|
+
def mcp_status(ctx: typer.Context) -> None:
|
|
780
|
+
"""Show MCP integration status for all platforms.
|
|
518
781
|
|
|
519
|
-
|
|
520
|
-
|
|
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:
|
|
526
|
-
raise typer.Exit(1)
|
|
782
|
+
Displays which platforms have mcp-vector-search configured,
|
|
783
|
+
the detected project root, and configuration details.
|
|
527
784
|
|
|
785
|
+
[bold cyan]Examples:[/bold cyan]
|
|
528
786
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
) -> None:
|
|
535
|
-
"""Install Windsurf IDE MCP integration (global)."""
|
|
536
|
-
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
787
|
+
[green]Check status:[/green]
|
|
788
|
+
$ mcp-vector-search install mcp-status
|
|
789
|
+
"""
|
|
790
|
+
# Auto-detect project root
|
|
791
|
+
project_root = detect_project_root()
|
|
537
792
|
|
|
538
793
|
console.print(
|
|
539
794
|
Panel.fit(
|
|
540
|
-
"[bold cyan]
|
|
541
|
-
"
|
|
795
|
+
f"[bold cyan]MCP Integration Status[/bold cyan]\n"
|
|
796
|
+
f"📁 Detected Project: {project_root}",
|
|
542
797
|
border_style="cyan",
|
|
543
798
|
)
|
|
544
799
|
)
|
|
545
800
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
801
|
+
try:
|
|
802
|
+
# Detect all platforms
|
|
803
|
+
detected = detect_all_platforms()
|
|
549
804
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
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)
|
|
805
|
+
if not detected:
|
|
806
|
+
print_warning("No MCP platforms detected")
|
|
807
|
+
return
|
|
558
808
|
|
|
809
|
+
# Create status table
|
|
810
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
811
|
+
table.add_column("Platform", style="cyan")
|
|
812
|
+
table.add_column("Status", style="green")
|
|
813
|
+
table.add_column("Config Path")
|
|
814
|
+
table.add_column("Project Root")
|
|
559
815
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
816
|
+
for platform_info in detected:
|
|
817
|
+
try:
|
|
818
|
+
# Check if mcp-vector-search is configured
|
|
819
|
+
installer = MCPInstaller(platform=platform_info.platform)
|
|
820
|
+
server = installer.get_server("mcp-vector-search")
|
|
821
|
+
|
|
822
|
+
if server:
|
|
823
|
+
status = "✅ Configured"
|
|
824
|
+
# Extract project root from env
|
|
825
|
+
env = server.get("env", {})
|
|
826
|
+
configured_root = env.get("MCP_PROJECT_ROOT") or env.get(
|
|
827
|
+
"PROJECT_ROOT", "N/A"
|
|
828
|
+
)
|
|
568
829
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
830
|
+
# Check if it matches current project
|
|
831
|
+
if configured_root != "N/A":
|
|
832
|
+
configured_path = Path(configured_root)
|
|
833
|
+
if configured_path == project_root:
|
|
834
|
+
status = "✅ Configured (current project)"
|
|
835
|
+
else:
|
|
836
|
+
status = "⚠️ Configured (different project)"
|
|
837
|
+
else:
|
|
838
|
+
status = "❌ Not configured"
|
|
839
|
+
configured_root = "N/A"
|
|
576
840
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
841
|
+
except Exception as e:
|
|
842
|
+
logger.debug(f"Failed to check {platform_info.platform.value}: {e}")
|
|
843
|
+
status = "❓ Unknown"
|
|
844
|
+
configured_root = "N/A"
|
|
845
|
+
|
|
846
|
+
table.add_row(
|
|
847
|
+
platform_info.platform.value,
|
|
848
|
+
status,
|
|
849
|
+
str(platform_info.config_path) if platform_info.config_path else "N/A",
|
|
850
|
+
configured_root,
|
|
851
|
+
)
|
|
852
|
+
|
|
853
|
+
console.print(table)
|
|
580
854
|
|
|
581
|
-
|
|
855
|
+
# Show next steps
|
|
856
|
+
console.print("\n[bold blue]Quick Actions:[/bold blue]")
|
|
582
857
|
console.print(
|
|
583
|
-
"
|
|
858
|
+
" mcp-vector-search install mcp # Install to auto-detected platform"
|
|
584
859
|
)
|
|
585
|
-
console.print(
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
console.print(
|
|
589
|
-
|
|
590
|
-
raise typer.Exit(1)
|
|
591
|
-
|
|
592
|
-
|
|
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()
|
|
601
|
-
|
|
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",
|
|
860
|
+
console.print(
|
|
861
|
+
" mcp-vector-search install mcp --all # Install to all platforms"
|
|
862
|
+
)
|
|
863
|
+
console.print(
|
|
864
|
+
" mcp-vector-search install mcp --platform <name> # Install to specific platform"
|
|
607
865
|
)
|
|
608
|
-
)
|
|
609
|
-
|
|
610
|
-
success = configure_platform(
|
|
611
|
-
"vscode", project_root, enable_watch=enable_watch, force=force
|
|
612
|
-
)
|
|
613
866
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
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:
|
|
867
|
+
except Exception as e:
|
|
868
|
+
logger.exception("Failed to check MCP status")
|
|
869
|
+
print_error(f"Status check failed: {e}")
|
|
621
870
|
raise typer.Exit(1)
|
|
622
871
|
|
|
623
872
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
873
|
+
# ==============================================================================
|
|
874
|
+
# List Platforms Command
|
|
875
|
+
# ==============================================================================
|
|
628
876
|
|
|
877
|
+
|
|
878
|
+
@install_app.command("list-platforms")
|
|
879
|
+
def list_platforms(ctx: typer.Context) -> None:
|
|
880
|
+
"""List all detected MCP platforms and their status."""
|
|
629
881
|
console.print(
|
|
630
882
|
Panel.fit("[bold cyan]MCP Platform Status[/bold cyan]", border_style="cyan")
|
|
631
883
|
)
|
|
632
884
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
table.add_column("Name")
|
|
636
|
-
table.add_column("Status")
|
|
637
|
-
table.add_column("Config Location")
|
|
885
|
+
try:
|
|
886
|
+
detected = detect_all_platforms()
|
|
638
887
|
|
|
639
|
-
|
|
888
|
+
if not detected:
|
|
889
|
+
print_warning("No MCP platforms detected")
|
|
890
|
+
print_info(
|
|
891
|
+
"Supported platforms: claude-code, claude-desktop, cursor, auggie, codex, windsurf, gemini-cli"
|
|
892
|
+
)
|
|
893
|
+
return
|
|
640
894
|
|
|
641
|
-
|
|
642
|
-
|
|
895
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
896
|
+
table.add_column("Platform", style="cyan")
|
|
897
|
+
table.add_column("Status", style="green")
|
|
898
|
+
table.add_column("Config Path")
|
|
899
|
+
table.add_column("Confidence", style="yellow")
|
|
643
900
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
if config_path.exists():
|
|
901
|
+
for platform_info in detected:
|
|
902
|
+
# Check if mcp-vector-search is configured
|
|
647
903
|
try:
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
904
|
+
installer = MCPInstaller(platform=platform_info.platform)
|
|
905
|
+
server = installer.get_server("mcp-vector-search")
|
|
906
|
+
status = "✅ Configured" if server else "⚠️ Available"
|
|
651
907
|
except Exception:
|
|
652
|
-
|
|
908
|
+
status = "⚠️ Available"
|
|
653
909
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
910
|
+
table.add_row(
|
|
911
|
+
platform_info.platform.value,
|
|
912
|
+
status,
|
|
913
|
+
str(platform_info.config_path) if platform_info.config_path else "N/A",
|
|
914
|
+
f"{platform_info.confidence:.2f}",
|
|
915
|
+
)
|
|
659
916
|
|
|
660
|
-
|
|
661
|
-
platform,
|
|
662
|
-
info["name"],
|
|
663
|
-
status,
|
|
664
|
-
str(config_path) if info["scope"] == "project" else info["config_path"],
|
|
665
|
-
)
|
|
917
|
+
console.print(table)
|
|
666
918
|
|
|
667
|
-
|
|
919
|
+
console.print("\n[bold blue]Installation Commands:[/bold blue]")
|
|
920
|
+
console.print(
|
|
921
|
+
" mcp-vector-search install mcp # Auto-detect"
|
|
922
|
+
)
|
|
923
|
+
console.print(
|
|
924
|
+
" mcp-vector-search install mcp --platform <name> # Specific platform"
|
|
925
|
+
)
|
|
926
|
+
console.print(
|
|
927
|
+
" mcp-vector-search install mcp --all # All platforms"
|
|
928
|
+
)
|
|
668
929
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
930
|
+
except Exception as e:
|
|
931
|
+
logger.exception("Failed to list platforms")
|
|
932
|
+
print_error(f"Failed to list platforms: {e}")
|
|
933
|
+
raise typer.Exit(1)
|
|
672
934
|
|
|
673
935
|
|
|
674
936
|
if __name__ == "__main__":
|