mcp-vector-search 0.15.7__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 +10 -0
- mcp_vector_search/cli/__init__.py +1 -0
- mcp_vector_search/cli/commands/__init__.py +1 -0
- mcp_vector_search/cli/commands/auto_index.py +397 -0
- mcp_vector_search/cli/commands/chat.py +534 -0
- mcp_vector_search/cli/commands/config.py +393 -0
- mcp_vector_search/cli/commands/demo.py +358 -0
- mcp_vector_search/cli/commands/index.py +762 -0
- mcp_vector_search/cli/commands/init.py +658 -0
- mcp_vector_search/cli/commands/install.py +869 -0
- mcp_vector_search/cli/commands/install_old.py +700 -0
- mcp_vector_search/cli/commands/mcp.py +1254 -0
- mcp_vector_search/cli/commands/reset.py +393 -0
- mcp_vector_search/cli/commands/search.py +796 -0
- mcp_vector_search/cli/commands/setup.py +1133 -0
- mcp_vector_search/cli/commands/status.py +584 -0
- mcp_vector_search/cli/commands/uninstall.py +404 -0
- mcp_vector_search/cli/commands/visualize/__init__.py +39 -0
- mcp_vector_search/cli/commands/visualize/cli.py +265 -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 +709 -0
- mcp_vector_search/cli/commands/visualize/layout_engine.py +469 -0
- mcp_vector_search/cli/commands/visualize/server.py +201 -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 +218 -0
- mcp_vector_search/cli/commands/visualize/templates/scripts.py +3670 -0
- mcp_vector_search/cli/commands/visualize/templates/styles.py +779 -0
- mcp_vector_search/cli/commands/visualize.py.original +2536 -0
- mcp_vector_search/cli/commands/watch.py +287 -0
- mcp_vector_search/cli/didyoumean.py +520 -0
- mcp_vector_search/cli/export.py +320 -0
- mcp_vector_search/cli/history.py +295 -0
- mcp_vector_search/cli/interactive.py +342 -0
- mcp_vector_search/cli/main.py +484 -0
- mcp_vector_search/cli/output.py +414 -0
- mcp_vector_search/cli/suggestions.py +375 -0
- mcp_vector_search/config/__init__.py +1 -0
- mcp_vector_search/config/constants.py +24 -0
- mcp_vector_search/config/defaults.py +200 -0
- mcp_vector_search/config/settings.py +146 -0
- mcp_vector_search/core/__init__.py +1 -0
- mcp_vector_search/core/auto_indexer.py +298 -0
- mcp_vector_search/core/config_utils.py +394 -0
- mcp_vector_search/core/connection_pool.py +360 -0
- mcp_vector_search/core/database.py +1237 -0
- mcp_vector_search/core/directory_index.py +318 -0
- mcp_vector_search/core/embeddings.py +294 -0
- mcp_vector_search/core/exceptions.py +89 -0
- mcp_vector_search/core/factory.py +318 -0
- mcp_vector_search/core/git_hooks.py +345 -0
- mcp_vector_search/core/indexer.py +1002 -0
- mcp_vector_search/core/llm_client.py +453 -0
- mcp_vector_search/core/models.py +294 -0
- mcp_vector_search/core/project.py +350 -0
- mcp_vector_search/core/scheduler.py +330 -0
- mcp_vector_search/core/search.py +952 -0
- mcp_vector_search/core/watcher.py +322 -0
- mcp_vector_search/mcp/__init__.py +5 -0
- mcp_vector_search/mcp/__main__.py +25 -0
- mcp_vector_search/mcp/server.py +752 -0
- mcp_vector_search/parsers/__init__.py +8 -0
- mcp_vector_search/parsers/base.py +296 -0
- mcp_vector_search/parsers/dart.py +605 -0
- mcp_vector_search/parsers/html.py +413 -0
- mcp_vector_search/parsers/javascript.py +643 -0
- mcp_vector_search/parsers/php.py +694 -0
- mcp_vector_search/parsers/python.py +502 -0
- mcp_vector_search/parsers/registry.py +223 -0
- mcp_vector_search/parsers/ruby.py +678 -0
- mcp_vector_search/parsers/text.py +186 -0
- mcp_vector_search/parsers/utils.py +265 -0
- mcp_vector_search/py.typed +1 -0
- mcp_vector_search/utils/__init__.py +42 -0
- mcp_vector_search/utils/gitignore.py +250 -0
- mcp_vector_search/utils/gitignore_updater.py +212 -0
- mcp_vector_search/utils/monorepo.py +339 -0
- mcp_vector_search/utils/timing.py +338 -0
- mcp_vector_search/utils/version.py +47 -0
- mcp_vector_search-0.15.7.dist-info/METADATA +884 -0
- mcp_vector_search-0.15.7.dist-info/RECORD +86 -0
- mcp_vector_search-0.15.7.dist-info/WHEEL +4 -0
- mcp_vector_search-0.15.7.dist-info/entry_points.txt +3 -0
- mcp_vector_search-0.15.7.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"""Demo command for mcp-vector-search."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import tempfile
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
from loguru import logger
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from ..output import print_error, print_info, print_success
|
|
13
|
+
|
|
14
|
+
console = Console()
|
|
15
|
+
|
|
16
|
+
demo_app = typer.Typer(
|
|
17
|
+
name="demo",
|
|
18
|
+
help="🎬 Run interactive demo with sample project",
|
|
19
|
+
add_completion=False,
|
|
20
|
+
rich_markup_mode="rich",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@demo_app.callback(invoke_without_command=True)
|
|
25
|
+
def demo(
|
|
26
|
+
ctx: typer.Context,
|
|
27
|
+
quick: bool = typer.Option(
|
|
28
|
+
False,
|
|
29
|
+
"--quick",
|
|
30
|
+
"-q",
|
|
31
|
+
help="Skip search demo, only show installation",
|
|
32
|
+
),
|
|
33
|
+
keep_files: bool = typer.Option(
|
|
34
|
+
False,
|
|
35
|
+
"--keep",
|
|
36
|
+
"-k",
|
|
37
|
+
help="Keep demo files (don't auto-cleanup)",
|
|
38
|
+
),
|
|
39
|
+
) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Run installation demo with sample project.
|
|
42
|
+
|
|
43
|
+
[bold cyan]What this does:[/bold cyan]
|
|
44
|
+
1. Creates a temporary project with sample Python files
|
|
45
|
+
2. Initializes mcp-vector-search in the demo project
|
|
46
|
+
3. Indexes the sample code
|
|
47
|
+
4. Runs a sample semantic search
|
|
48
|
+
5. Shows you the results
|
|
49
|
+
|
|
50
|
+
[bold cyan]Examples:[/bold cyan]
|
|
51
|
+
[green]mcp-vector-search demo[/green]
|
|
52
|
+
Run full interactive demo
|
|
53
|
+
|
|
54
|
+
[green]mcp-vector-search demo --quick[/green]
|
|
55
|
+
Skip search demo, only show installation
|
|
56
|
+
|
|
57
|
+
[green]mcp-vector-search demo --keep[/green]
|
|
58
|
+
Keep demo files for inspection
|
|
59
|
+
|
|
60
|
+
[dim]Perfect for first-time users to see how semantic search works![/dim]
|
|
61
|
+
"""
|
|
62
|
+
# If subcommand was invoked, don't run the main demo
|
|
63
|
+
if ctx.invoked_subcommand is not None:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
print_info("🎬 Running mcp-vector-search installation demo...")
|
|
68
|
+
console.print(
|
|
69
|
+
"\n[bold]This demo will:[/bold]\n"
|
|
70
|
+
" 1. Create a sample Python project\n"
|
|
71
|
+
" 2. Initialize and index it\n"
|
|
72
|
+
" 3. Run a semantic search\n"
|
|
73
|
+
" 4. Show you the results\n"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# Create temporary demo directory
|
|
77
|
+
temp_context = tempfile.TemporaryDirectory(prefix="mcp-demo-")
|
|
78
|
+
temp_dir = temp_context.__enter__()
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
demo_dir = Path(temp_dir) / "demo-project"
|
|
82
|
+
demo_dir.mkdir()
|
|
83
|
+
|
|
84
|
+
# Create sample files
|
|
85
|
+
console.print("[bold blue]📝 Creating sample files...[/bold blue]")
|
|
86
|
+
|
|
87
|
+
(demo_dir / "main.py").write_text(
|
|
88
|
+
'''"""Main application module."""
|
|
89
|
+
|
|
90
|
+
def main():
|
|
91
|
+
"""Main entry point for the application."""
|
|
92
|
+
print("Hello, World!")
|
|
93
|
+
user_service = UserService()
|
|
94
|
+
user_service.create_user("Alice", "alice@example.com")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class UserService:
|
|
98
|
+
"""Service for managing users."""
|
|
99
|
+
|
|
100
|
+
def create_user(self, name: str, email: str):
|
|
101
|
+
"""Create a new user with the given name and email.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
name: The user's full name
|
|
105
|
+
email: The user's email address
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
dict: User object with name and email
|
|
109
|
+
"""
|
|
110
|
+
print(f"Creating user: {name} ({email})")
|
|
111
|
+
return {"name": name, "email": email}
|
|
112
|
+
|
|
113
|
+
def authenticate_user(self, email: str, password: str):
|
|
114
|
+
"""Authenticate user with email and password.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
email: User's email address
|
|
118
|
+
password: User's password
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
bool: True if authentication successful
|
|
122
|
+
"""
|
|
123
|
+
# Simple authentication logic
|
|
124
|
+
return email.endswith("@example.com")
|
|
125
|
+
|
|
126
|
+
def reset_password(self, email: str):
|
|
127
|
+
"""Send password reset email to user.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
email: User's email address
|
|
131
|
+
"""
|
|
132
|
+
print(f"Sending password reset to {email}")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
if __name__ == "__main__":
|
|
136
|
+
main()
|
|
137
|
+
'''
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
(demo_dir / "utils.py").write_text(
|
|
141
|
+
'''"""Utility functions for the application."""
|
|
142
|
+
|
|
143
|
+
import hashlib
|
|
144
|
+
import json
|
|
145
|
+
from typing import Any, Dict
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def load_config(config_path: str) -> Dict[str, Any]:
|
|
149
|
+
"""Load configuration from JSON file.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
config_path: Path to JSON configuration file
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
dict: Configuration dictionary
|
|
156
|
+
"""
|
|
157
|
+
with open(config_path, "r") as f:
|
|
158
|
+
return json.load(f)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def validate_email(email: str) -> bool:
|
|
162
|
+
"""Validate email address format.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
email: Email address to validate
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
bool: True if email format is valid
|
|
169
|
+
"""
|
|
170
|
+
return "@" in email and "." in email.split("@")[1]
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def hash_password(password: str) -> str:
|
|
174
|
+
"""Hash password for secure storage.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
password: Plain text password
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
str: Hexadecimal hash of password
|
|
181
|
+
"""
|
|
182
|
+
return hashlib.sha256(password.encode()).hexdigest()
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def validate_password_strength(password: str) -> bool:
|
|
186
|
+
"""Check if password meets security requirements.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
password: Password to validate
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
bool: True if password is strong enough
|
|
193
|
+
"""
|
|
194
|
+
return len(password) >= 8 and any(c.isdigit() for c in password)
|
|
195
|
+
'''
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
(demo_dir / "api.py").write_text(
|
|
199
|
+
'''"""API endpoints for user management."""
|
|
200
|
+
|
|
201
|
+
from typing import Dict, List
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class UserAPI:
|
|
205
|
+
"""REST API endpoints for user operations."""
|
|
206
|
+
|
|
207
|
+
def get_user(self, user_id: int) -> Dict:
|
|
208
|
+
"""Get user by ID.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
user_id: Unique user identifier
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
dict: User object
|
|
215
|
+
"""
|
|
216
|
+
return {"id": user_id, "name": "Example User"}
|
|
217
|
+
|
|
218
|
+
def list_users(self, limit: int = 10) -> List[Dict]:
|
|
219
|
+
"""List all users with pagination.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
limit: Maximum number of users to return
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
list: List of user objects
|
|
226
|
+
"""
|
|
227
|
+
return [{"id": i, "name": f"User {i}"} for i in range(limit)]
|
|
228
|
+
|
|
229
|
+
def create_user_endpoint(self, name: str, email: str) -> Dict:
|
|
230
|
+
"""Create a new user via API.
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
name: User's full name
|
|
234
|
+
email: User's email address
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
dict: Created user object with ID
|
|
238
|
+
"""
|
|
239
|
+
return {"id": 1, "name": name, "email": email}
|
|
240
|
+
'''
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
console.print(f"[green]✅ Created 3 sample files in:[/green] {demo_dir}\n")
|
|
244
|
+
|
|
245
|
+
# Run initialization
|
|
246
|
+
print_info("🔧 Initializing mcp-vector-search in demo project...")
|
|
247
|
+
|
|
248
|
+
result = subprocess.run(
|
|
249
|
+
[
|
|
250
|
+
sys.executable,
|
|
251
|
+
"-m",
|
|
252
|
+
"mcp_vector_search.cli.main",
|
|
253
|
+
"--project-root",
|
|
254
|
+
str(demo_dir),
|
|
255
|
+
"init",
|
|
256
|
+
"--extensions",
|
|
257
|
+
".py",
|
|
258
|
+
"--no-mcp", # Skip MCP for demo
|
|
259
|
+
"--auto-index", # Auto-index after init
|
|
260
|
+
],
|
|
261
|
+
input="y\n", # Auto-confirm the setup
|
|
262
|
+
capture_output=True,
|
|
263
|
+
text=True,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
if result.returncode != 0:
|
|
267
|
+
print_error(f"Demo initialization failed: {result.stderr}")
|
|
268
|
+
raise typer.Exit(1)
|
|
269
|
+
|
|
270
|
+
print_success("✅ Demo project initialized and indexed!")
|
|
271
|
+
|
|
272
|
+
if not quick:
|
|
273
|
+
# Give the index a moment to settle
|
|
274
|
+
import time
|
|
275
|
+
|
|
276
|
+
time.sleep(1)
|
|
277
|
+
|
|
278
|
+
# Run sample searches to demonstrate different features
|
|
279
|
+
searches = [
|
|
280
|
+
("user authentication", "Finding authentication-related code"),
|
|
281
|
+
("password", "Finding password-related functions"),
|
|
282
|
+
("email validation", "Finding email validation logic"),
|
|
283
|
+
]
|
|
284
|
+
|
|
285
|
+
for query, description in searches:
|
|
286
|
+
console.print(f"\n[bold blue]🔍 {description}:[/bold blue]")
|
|
287
|
+
console.print(f"[dim]Query: '{query}'[/dim]\n")
|
|
288
|
+
|
|
289
|
+
search_result = subprocess.run(
|
|
290
|
+
[
|
|
291
|
+
sys.executable,
|
|
292
|
+
"-m",
|
|
293
|
+
"mcp_vector_search.cli.main",
|
|
294
|
+
"--project-root",
|
|
295
|
+
str(demo_dir),
|
|
296
|
+
"search",
|
|
297
|
+
"--limit",
|
|
298
|
+
"2",
|
|
299
|
+
query,
|
|
300
|
+
],
|
|
301
|
+
capture_output=True,
|
|
302
|
+
text=True,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
if search_result.returncode == 0 and search_result.stdout.strip():
|
|
306
|
+
console.print(search_result.stdout)
|
|
307
|
+
else:
|
|
308
|
+
# Show a friendly message if search didn't return results
|
|
309
|
+
console.print(
|
|
310
|
+
"[dim]Note: Search completed but may need more time "
|
|
311
|
+
"for the index to fully settle.[/dim]"
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
# Show summary
|
|
315
|
+
console.print("\n" + "=" * 70)
|
|
316
|
+
console.print("[bold green]🎉 Demo completed successfully![/bold green]")
|
|
317
|
+
console.print("=" * 70 + "\n")
|
|
318
|
+
|
|
319
|
+
console.print("[bold]What you just saw:[/bold]")
|
|
320
|
+
console.print(" ✅ Sample project creation")
|
|
321
|
+
console.print(" ✅ Automatic code indexing")
|
|
322
|
+
if not quick:
|
|
323
|
+
console.print(" ✅ Semantic code search in action")
|
|
324
|
+
console.print(" ✅ Finding code by meaning (not just keywords)\n")
|
|
325
|
+
|
|
326
|
+
console.print("[bold cyan]Next steps to use in your project:[/bold cyan]")
|
|
327
|
+
console.print(" 1. [green]cd /your/project[/green]")
|
|
328
|
+
console.print(" 2. [green]mcp-vector-search init[/green]")
|
|
329
|
+
console.print(" 3. [green]mcp-vector-search search 'your query'[/green]\n")
|
|
330
|
+
|
|
331
|
+
if keep_files:
|
|
332
|
+
console.print(
|
|
333
|
+
f"[bold]Demo files saved at:[/bold] [cyan]{demo_dir}[/cyan]"
|
|
334
|
+
)
|
|
335
|
+
console.print(
|
|
336
|
+
"[yellow]Note: This is still in a temp directory, "
|
|
337
|
+
"copy files if you want to keep them![/yellow]\n"
|
|
338
|
+
)
|
|
339
|
+
else:
|
|
340
|
+
console.print(
|
|
341
|
+
"[dim]Demo files will be cleaned up automatically.[/dim]\n"
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
finally:
|
|
345
|
+
if not keep_files:
|
|
346
|
+
temp_context.__exit__(None, None, None)
|
|
347
|
+
else:
|
|
348
|
+
# Keep the context manager open
|
|
349
|
+
pass
|
|
350
|
+
|
|
351
|
+
except Exception as e:
|
|
352
|
+
logger.error(f"Demo failed: {e}")
|
|
353
|
+
print_error(f"Demo failed: {e}")
|
|
354
|
+
raise typer.Exit(1)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
if __name__ == "__main__":
|
|
358
|
+
demo_app()
|