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
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"""MCP integration commands for Claude Code."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import shutil
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
import click
|
|
13
|
+
from loguru import logger
|
|
14
|
+
from rich.console import Console
|
|
15
|
+
from rich.panel import Panel
|
|
16
|
+
from rich.table import Table
|
|
17
|
+
|
|
18
|
+
from ...core.exceptions import ProjectNotFoundError
|
|
19
|
+
from ...core.project import ProjectManager
|
|
20
|
+
from ..didyoumean import create_enhanced_typer
|
|
21
|
+
from ..output import print_error, print_info, print_success, print_warning
|
|
22
|
+
|
|
23
|
+
# Create MCP subcommand app with "did you mean" functionality
|
|
24
|
+
mcp_app = create_enhanced_typer(help="Manage Claude Code MCP integration")
|
|
25
|
+
|
|
26
|
+
console = Console()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_claude_command() -> Optional[str]:
|
|
30
|
+
"""Get the Claude Code command path."""
|
|
31
|
+
# Check if claude command is available
|
|
32
|
+
claude_cmd = shutil.which("claude")
|
|
33
|
+
if claude_cmd:
|
|
34
|
+
return "claude"
|
|
35
|
+
|
|
36
|
+
# Check common installation paths
|
|
37
|
+
possible_paths = [
|
|
38
|
+
"/usr/local/bin/claude",
|
|
39
|
+
"/opt/homebrew/bin/claude",
|
|
40
|
+
os.path.expanduser("~/.local/bin/claude"),
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
for path in possible_paths:
|
|
44
|
+
if os.path.exists(path) and os.access(path, os.X_OK):
|
|
45
|
+
return path
|
|
46
|
+
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def check_claude_code_available() -> bool:
|
|
51
|
+
"""Check if Claude Code is available."""
|
|
52
|
+
claude_cmd = get_claude_command()
|
|
53
|
+
if not claude_cmd:
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
result = subprocess.run(
|
|
58
|
+
[claude_cmd, "--version"],
|
|
59
|
+
capture_output=True,
|
|
60
|
+
text=True,
|
|
61
|
+
timeout=10
|
|
62
|
+
)
|
|
63
|
+
return result.returncode == 0
|
|
64
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_mcp_server_command(project_root: Path, enable_file_watching: bool = True) -> str:
|
|
69
|
+
"""Get the command to run the MCP server.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
project_root: Path to the project root directory
|
|
73
|
+
enable_file_watching: Whether to enable file watching (default: True)
|
|
74
|
+
"""
|
|
75
|
+
# Always use the current Python executable for project-scoped installation
|
|
76
|
+
python_exe = sys.executable
|
|
77
|
+
watch_flag = "" if enable_file_watching else " --no-watch"
|
|
78
|
+
return f"{python_exe} -m mcp_vector_search.mcp.server{watch_flag} {project_root}"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def create_project_claude_config(project_root: Path, server_name: str, enable_file_watching: bool = True) -> None:
|
|
84
|
+
"""Create or update project-level .claude/settings.local.json file.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
project_root: Path to the project root directory
|
|
88
|
+
server_name: Name for the MCP server
|
|
89
|
+
enable_file_watching: Whether to enable file watching (default: True)
|
|
90
|
+
"""
|
|
91
|
+
# Create .claude directory if it doesn't exist
|
|
92
|
+
claude_dir = project_root / ".claude"
|
|
93
|
+
claude_dir.mkdir(exist_ok=True)
|
|
94
|
+
|
|
95
|
+
# Path to settings.local.json in .claude directory
|
|
96
|
+
settings_path = claude_dir / "settings.local.json"
|
|
97
|
+
|
|
98
|
+
# Load existing config or create new one
|
|
99
|
+
if settings_path.exists():
|
|
100
|
+
with open(settings_path, 'r') as f:
|
|
101
|
+
config = json.load(f)
|
|
102
|
+
else:
|
|
103
|
+
config = {}
|
|
104
|
+
|
|
105
|
+
# Ensure mcpServers section exists
|
|
106
|
+
if "mcpServers" not in config:
|
|
107
|
+
config["mcpServers"] = {}
|
|
108
|
+
|
|
109
|
+
# Get the MCP server command
|
|
110
|
+
server_command = get_mcp_server_command(project_root, enable_file_watching)
|
|
111
|
+
command_parts = server_command.split()
|
|
112
|
+
|
|
113
|
+
# Add the server configuration with required "type": "stdio"
|
|
114
|
+
config["mcpServers"][server_name] = {
|
|
115
|
+
"type": "stdio",
|
|
116
|
+
"command": command_parts[0],
|
|
117
|
+
"args": command_parts[1:],
|
|
118
|
+
"env": {
|
|
119
|
+
"MCP_ENABLE_FILE_WATCHING": "true" if enable_file_watching else "false"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
# Write the config
|
|
124
|
+
with open(settings_path, 'w') as f:
|
|
125
|
+
json.dump(config, f, indent=2)
|
|
126
|
+
|
|
127
|
+
print_success(f"Created project-level .claude/settings.local.json with MCP server configuration")
|
|
128
|
+
if enable_file_watching:
|
|
129
|
+
print_info("File watching is enabled for automatic reindexing")
|
|
130
|
+
else:
|
|
131
|
+
print_info("File watching is disabled")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@mcp_app.command("install")
|
|
135
|
+
@mcp_app.command("init", hidden=False) # Add 'init' as an alias
|
|
136
|
+
def install_mcp_integration(
|
|
137
|
+
ctx: typer.Context,
|
|
138
|
+
server_name: str = typer.Option(
|
|
139
|
+
"mcp-vector-search",
|
|
140
|
+
"--name",
|
|
141
|
+
help="Name for the MCP server"
|
|
142
|
+
),
|
|
143
|
+
force: bool = typer.Option(
|
|
144
|
+
False,
|
|
145
|
+
"--force",
|
|
146
|
+
"-f",
|
|
147
|
+
help="Force installation even if server already exists"
|
|
148
|
+
),
|
|
149
|
+
no_watch: bool = typer.Option(
|
|
150
|
+
False,
|
|
151
|
+
"--no-watch",
|
|
152
|
+
help="Disable file watching for automatic reindexing"
|
|
153
|
+
)
|
|
154
|
+
) -> None:
|
|
155
|
+
"""Install MCP integration for Claude Code in the current project.
|
|
156
|
+
|
|
157
|
+
Creates .claude/settings.local.json in the current directory to enable semantic code search
|
|
158
|
+
for this specific project. This tool is designed to index and search
|
|
159
|
+
project-specific files.
|
|
160
|
+
"""
|
|
161
|
+
try:
|
|
162
|
+
# Get project root for checking initialization
|
|
163
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
164
|
+
|
|
165
|
+
# Check if project is initialized
|
|
166
|
+
project_manager = ProjectManager(project_root)
|
|
167
|
+
if not project_manager.is_initialized():
|
|
168
|
+
print_error("Project not initialized. Run 'mcp-vector-search init' first.")
|
|
169
|
+
raise typer.Exit(1)
|
|
170
|
+
|
|
171
|
+
# Always create config in current working directory (project scope only)
|
|
172
|
+
config_dir = Path.cwd()
|
|
173
|
+
claude_dir = config_dir / ".claude"
|
|
174
|
+
|
|
175
|
+
# Check if .claude/settings.local.json already has the server in current directory
|
|
176
|
+
settings_path = claude_dir / "settings.local.json"
|
|
177
|
+
if settings_path.exists() and not force:
|
|
178
|
+
with open(settings_path, 'r') as f:
|
|
179
|
+
config = json.load(f)
|
|
180
|
+
if config.get("mcpServers", {}).get(server_name):
|
|
181
|
+
print_warning(f"MCP server '{server_name}' already exists in project config.")
|
|
182
|
+
print_info("Use --force to overwrite")
|
|
183
|
+
raise typer.Exit(1)
|
|
184
|
+
|
|
185
|
+
# Create configuration in current working directory, but server command uses project_root
|
|
186
|
+
enable_file_watching = not no_watch
|
|
187
|
+
create_project_claude_config(config_dir, server_name, enable_file_watching)
|
|
188
|
+
|
|
189
|
+
print_info(f"MCP server '{server_name}' installed in project configuration at {claude_dir}")
|
|
190
|
+
print_info("Claude Code will automatically detect the server when you open this project")
|
|
191
|
+
|
|
192
|
+
# Test the server (using project_root for the server command)
|
|
193
|
+
print_info("Testing server startup...")
|
|
194
|
+
|
|
195
|
+
# Get the server command
|
|
196
|
+
server_command = get_mcp_server_command(project_root, enable_file_watching)
|
|
197
|
+
test_process = subprocess.Popen(
|
|
198
|
+
server_command.split(),
|
|
199
|
+
stdin=subprocess.PIPE,
|
|
200
|
+
stdout=subprocess.PIPE,
|
|
201
|
+
stderr=subprocess.PIPE,
|
|
202
|
+
text=True
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
# Send a simple initialization request
|
|
206
|
+
init_request = {
|
|
207
|
+
"jsonrpc": "2.0",
|
|
208
|
+
"id": 1,
|
|
209
|
+
"method": "initialize",
|
|
210
|
+
"params": {
|
|
211
|
+
"protocolVersion": "2024-11-05",
|
|
212
|
+
"capabilities": {},
|
|
213
|
+
"clientInfo": {"name": "test", "version": "1.0.0"}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
try:
|
|
218
|
+
test_process.stdin.write(json.dumps(init_request) + "\n")
|
|
219
|
+
test_process.stdin.flush()
|
|
220
|
+
|
|
221
|
+
# Wait for response with timeout
|
|
222
|
+
test_process.wait(timeout=5)
|
|
223
|
+
|
|
224
|
+
if test_process.returncode == 0:
|
|
225
|
+
print_success("✅ MCP server starts successfully")
|
|
226
|
+
else:
|
|
227
|
+
stderr_output = test_process.stderr.read()
|
|
228
|
+
print_warning(f"⚠️ Server startup test inconclusive: {stderr_output}")
|
|
229
|
+
|
|
230
|
+
except subprocess.TimeoutExpired:
|
|
231
|
+
test_process.terminate()
|
|
232
|
+
print_success("✅ MCP server is responsive")
|
|
233
|
+
|
|
234
|
+
# Show available tools
|
|
235
|
+
table = Table(title="Available MCP Tools")
|
|
236
|
+
table.add_column("Tool", style="cyan")
|
|
237
|
+
table.add_column("Description", style="white")
|
|
238
|
+
|
|
239
|
+
table.add_row("search_code", "Search for code using semantic similarity")
|
|
240
|
+
table.add_row("search_similar", "Find code similar to a specific file or function")
|
|
241
|
+
table.add_row("search_context", "Search for code based on contextual description")
|
|
242
|
+
table.add_row("get_project_status", "Get project indexing status and statistics")
|
|
243
|
+
table.add_row("index_project", "Index or reindex the project codebase")
|
|
244
|
+
|
|
245
|
+
if enable_file_watching:
|
|
246
|
+
console.print("\n[green]✅ File watching is enabled[/green] - Changes will be automatically indexed")
|
|
247
|
+
else:
|
|
248
|
+
console.print("\n[yellow]⚠️ File watching is disabled[/yellow] - Manual reindexing required for changes")
|
|
249
|
+
|
|
250
|
+
console.print(table)
|
|
251
|
+
|
|
252
|
+
print_info("\nTo test the integration, run: mcp-vector-search mcp test")
|
|
253
|
+
|
|
254
|
+
except ProjectNotFoundError:
|
|
255
|
+
print_error(f"Project not initialized at {project_root}")
|
|
256
|
+
print_info("Run 'mcp-vector-search init' in the project directory first")
|
|
257
|
+
raise typer.Exit(1)
|
|
258
|
+
except Exception as e:
|
|
259
|
+
print_error(f"Installation failed: {e}")
|
|
260
|
+
raise typer.Exit(1)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@mcp_app.command("test")
|
|
264
|
+
def test_mcp_integration(
|
|
265
|
+
ctx: typer.Context,
|
|
266
|
+
server_name: str = typer.Option(
|
|
267
|
+
"mcp-vector-search",
|
|
268
|
+
"--name",
|
|
269
|
+
help="Name of the MCP server to test"
|
|
270
|
+
)
|
|
271
|
+
) -> None:
|
|
272
|
+
"""Test the MCP integration."""
|
|
273
|
+
try:
|
|
274
|
+
# Get project root
|
|
275
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
276
|
+
|
|
277
|
+
# Check if Claude Code is available
|
|
278
|
+
if not check_claude_code_available():
|
|
279
|
+
print_error("Claude Code not found. Please install Claude Code first.")
|
|
280
|
+
raise typer.Exit(1)
|
|
281
|
+
|
|
282
|
+
claude_cmd = get_claude_command()
|
|
283
|
+
|
|
284
|
+
# Check if server exists
|
|
285
|
+
print_info(f"Testing MCP server '{server_name}'...")
|
|
286
|
+
|
|
287
|
+
try:
|
|
288
|
+
result = subprocess.run(
|
|
289
|
+
[claude_cmd, "mcp", "get", server_name],
|
|
290
|
+
capture_output=True,
|
|
291
|
+
text=True,
|
|
292
|
+
timeout=10
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
if result.returncode != 0:
|
|
296
|
+
print_error(f"MCP server '{server_name}' not found.")
|
|
297
|
+
print_info("Run 'mcp-vector-search mcp install' or 'mcp-vector-search mcp init' first")
|
|
298
|
+
raise typer.Exit(1)
|
|
299
|
+
|
|
300
|
+
print_success(f"✅ MCP server '{server_name}' is configured")
|
|
301
|
+
|
|
302
|
+
# Test if we can run the server directly
|
|
303
|
+
print_info("Testing server startup...")
|
|
304
|
+
|
|
305
|
+
server_command = get_mcp_server_command(project_root)
|
|
306
|
+
test_process = subprocess.Popen(
|
|
307
|
+
server_command.split(),
|
|
308
|
+
stdin=subprocess.PIPE,
|
|
309
|
+
stdout=subprocess.PIPE,
|
|
310
|
+
stderr=subprocess.PIPE,
|
|
311
|
+
text=True
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# Send a simple initialization request
|
|
315
|
+
init_request = {
|
|
316
|
+
"jsonrpc": "2.0",
|
|
317
|
+
"id": 1,
|
|
318
|
+
"method": "initialize",
|
|
319
|
+
"params": {
|
|
320
|
+
"protocolVersion": "2024-11-05",
|
|
321
|
+
"capabilities": {},
|
|
322
|
+
"clientInfo": {"name": "test", "version": "1.0.0"}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
try:
|
|
327
|
+
test_process.stdin.write(json.dumps(init_request) + "\n")
|
|
328
|
+
test_process.stdin.flush()
|
|
329
|
+
|
|
330
|
+
# Wait for response with timeout
|
|
331
|
+
test_process.wait(timeout=5)
|
|
332
|
+
|
|
333
|
+
if test_process.returncode == 0:
|
|
334
|
+
print_success("✅ MCP server starts successfully")
|
|
335
|
+
else:
|
|
336
|
+
stderr_output = test_process.stderr.read()
|
|
337
|
+
print_warning(f"⚠️ Server startup test inconclusive: {stderr_output}")
|
|
338
|
+
|
|
339
|
+
except subprocess.TimeoutExpired:
|
|
340
|
+
test_process.terminate()
|
|
341
|
+
print_success("✅ MCP server is responsive")
|
|
342
|
+
|
|
343
|
+
print_success("🎉 MCP integration test completed!")
|
|
344
|
+
print_info("You can now use the vector search tools in Claude Code.")
|
|
345
|
+
|
|
346
|
+
except subprocess.TimeoutExpired:
|
|
347
|
+
print_error("Timeout testing MCP server")
|
|
348
|
+
raise typer.Exit(1)
|
|
349
|
+
|
|
350
|
+
except Exception as e:
|
|
351
|
+
print_error(f"Test failed: {e}")
|
|
352
|
+
raise typer.Exit(1)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
@mcp_app.command("remove")
|
|
356
|
+
def remove_mcp_integration(
|
|
357
|
+
ctx: typer.Context,
|
|
358
|
+
server_name: str = typer.Option(
|
|
359
|
+
"mcp-vector-search",
|
|
360
|
+
"--name",
|
|
361
|
+
help="Name of the MCP server to remove"
|
|
362
|
+
),
|
|
363
|
+
confirm: bool = typer.Option(
|
|
364
|
+
False,
|
|
365
|
+
"--yes",
|
|
366
|
+
"-y",
|
|
367
|
+
help="Skip confirmation prompt"
|
|
368
|
+
)
|
|
369
|
+
) -> None:
|
|
370
|
+
"""Remove MCP integration from the current project.
|
|
371
|
+
|
|
372
|
+
Removes the server configuration from .claude/settings.local.json in the current directory.
|
|
373
|
+
"""
|
|
374
|
+
try:
|
|
375
|
+
# Always use project scope - .claude/settings.local.json in current directory
|
|
376
|
+
claude_dir = Path.cwd() / ".claude"
|
|
377
|
+
settings_path = claude_dir / "settings.local.json"
|
|
378
|
+
config_location = "project configuration"
|
|
379
|
+
|
|
380
|
+
# Check if settings file exists
|
|
381
|
+
if not settings_path.exists():
|
|
382
|
+
print_warning(f"No {config_location} found at {settings_path}")
|
|
383
|
+
return
|
|
384
|
+
|
|
385
|
+
# Load configuration
|
|
386
|
+
with open(settings_path, 'r') as f:
|
|
387
|
+
config = json.load(f)
|
|
388
|
+
|
|
389
|
+
# Check if server exists in configuration
|
|
390
|
+
if "mcpServers" not in config or server_name not in config["mcpServers"]:
|
|
391
|
+
print_warning(f"MCP server '{server_name}' not found in {config_location}.")
|
|
392
|
+
return
|
|
393
|
+
|
|
394
|
+
# Confirm removal
|
|
395
|
+
if not confirm:
|
|
396
|
+
confirmed = typer.confirm(
|
|
397
|
+
f"Remove MCP server '{server_name}' from {config_location}?"
|
|
398
|
+
)
|
|
399
|
+
if not confirmed:
|
|
400
|
+
print_info("Removal cancelled.")
|
|
401
|
+
return
|
|
402
|
+
|
|
403
|
+
# Remove the MCP server from configuration
|
|
404
|
+
print_info(f"Removing MCP server '{server_name}' from {config_location}...")
|
|
405
|
+
|
|
406
|
+
del config["mcpServers"][server_name]
|
|
407
|
+
|
|
408
|
+
# Clean up empty mcpServers section
|
|
409
|
+
if not config["mcpServers"]:
|
|
410
|
+
del config["mcpServers"]
|
|
411
|
+
|
|
412
|
+
# Write updated configuration
|
|
413
|
+
with open(settings_path, 'w') as f:
|
|
414
|
+
json.dump(config, f, indent=2)
|
|
415
|
+
|
|
416
|
+
print_success(f"✅ MCP server '{server_name}' removed from {config_location}!")
|
|
417
|
+
print_info("The server is no longer available for this project")
|
|
418
|
+
|
|
419
|
+
except Exception as e:
|
|
420
|
+
print_error(f"Removal failed: {e}")
|
|
421
|
+
raise typer.Exit(1)
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
@mcp_app.command("status")
|
|
425
|
+
def show_mcp_status(
|
|
426
|
+
ctx: typer.Context,
|
|
427
|
+
server_name: str = typer.Option(
|
|
428
|
+
"mcp-vector-search",
|
|
429
|
+
"--name",
|
|
430
|
+
help="Name of the MCP server to check"
|
|
431
|
+
)
|
|
432
|
+
) -> None:
|
|
433
|
+
"""Show MCP integration status."""
|
|
434
|
+
try:
|
|
435
|
+
# Check if Claude Code is available
|
|
436
|
+
claude_available = check_claude_code_available()
|
|
437
|
+
|
|
438
|
+
# Create status panel
|
|
439
|
+
status_lines = []
|
|
440
|
+
|
|
441
|
+
if claude_available:
|
|
442
|
+
status_lines.append("✅ Claude Code: Available")
|
|
443
|
+
else:
|
|
444
|
+
status_lines.append("❌ Claude Code: Not available")
|
|
445
|
+
status_lines.append(" Install from: https://claude.ai/download")
|
|
446
|
+
|
|
447
|
+
# Check project configuration
|
|
448
|
+
claude_dir = Path.cwd() / ".claude"
|
|
449
|
+
project_settings_path = claude_dir / "settings.local.json"
|
|
450
|
+
if project_settings_path.exists():
|
|
451
|
+
with open(project_settings_path, 'r') as f:
|
|
452
|
+
project_config = json.load(f)
|
|
453
|
+
|
|
454
|
+
if "mcpServers" in project_config and server_name in project_config["mcpServers"]:
|
|
455
|
+
status_lines.append(f"✅ Project Config (.claude/settings.local.json): Server '{server_name}' installed")
|
|
456
|
+
server_info = project_config["mcpServers"][server_name]
|
|
457
|
+
if "command" in server_info:
|
|
458
|
+
status_lines.append(f" Command: {server_info['command']}")
|
|
459
|
+
if "args" in server_info:
|
|
460
|
+
status_lines.append(f" Args: {' '.join(server_info['args'])}")
|
|
461
|
+
if "env" in server_info:
|
|
462
|
+
file_watching = server_info['env'].get('MCP_ENABLE_FILE_WATCHING', 'true')
|
|
463
|
+
if file_watching.lower() in ('true', '1', 'yes', 'on'):
|
|
464
|
+
status_lines.append(" File Watching: ✅ Enabled")
|
|
465
|
+
else:
|
|
466
|
+
status_lines.append(" File Watching: ❌ Disabled")
|
|
467
|
+
else:
|
|
468
|
+
status_lines.append(f"❌ Project Config (.claude/settings.local.json): Server '{server_name}' not found")
|
|
469
|
+
else:
|
|
470
|
+
status_lines.append("❌ Project Config (.claude/settings.local.json): Not found")
|
|
471
|
+
|
|
472
|
+
# Check project status
|
|
473
|
+
project_root = ctx.obj.get("project_root") or Path.cwd()
|
|
474
|
+
project_manager = ProjectManager(project_root)
|
|
475
|
+
|
|
476
|
+
if project_manager.is_initialized():
|
|
477
|
+
status_lines.append(f"✅ Project: Initialized at {project_root}")
|
|
478
|
+
else:
|
|
479
|
+
status_lines.append(f"❌ Project: Not initialized at {project_root}")
|
|
480
|
+
|
|
481
|
+
# Display status
|
|
482
|
+
panel = Panel(
|
|
483
|
+
"\n".join(status_lines),
|
|
484
|
+
title="MCP Integration Status",
|
|
485
|
+
border_style="blue"
|
|
486
|
+
)
|
|
487
|
+
console.print(panel)
|
|
488
|
+
|
|
489
|
+
except Exception as e:
|
|
490
|
+
print_error(f"Status check failed: {e}")
|
|
491
|
+
raise typer.Exit(1)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
if __name__ == "__main__":
|
|
495
|
+
mcp_app()
|