mcp-code-indexer 4.2.4__tar.gz → 4.2.6__tar.gz

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.
Files changed (64) hide show
  1. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/PKG-INFO +3 -3
  2. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/README.md +2 -2
  3. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/pyproject.toml +1 -1
  4. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/__init__.py +2 -1
  5. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/daemon.py +37 -14
  6. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/LICENSE +0 -0
  7. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/__init__.py +0 -0
  8. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/__main__.py +0 -0
  9. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/ask_handler.py +0 -0
  10. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/claude_api_handler.py +0 -0
  11. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/cleanup_manager.py +0 -0
  12. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/commands/__init__.py +0 -0
  13. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/commands/makelocal.py +0 -0
  14. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/data/stop_words_english.txt +0 -0
  15. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/__init__.py +0 -0
  16. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/connection_health.py +0 -0
  17. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/database.py +0 -0
  18. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/database_factory.py +0 -0
  19. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/exceptions.py +0 -0
  20. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/models.py +0 -0
  21. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/path_resolver.py +0 -0
  22. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/database/retry_executor.py +0 -0
  23. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/deepask_handler.py +0 -0
  24. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/error_handler.py +0 -0
  25. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/file_scanner.py +0 -0
  26. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/git_hook_handler.py +0 -0
  27. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/logging_config.py +0 -0
  28. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/main.py +0 -0
  29. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/middleware/__init__.py +0 -0
  30. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/middleware/auth.py +0 -0
  31. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/middleware/error_middleware.py +0 -0
  32. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/middleware/logging.py +0 -0
  33. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/middleware/security.py +0 -0
  34. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/migrations/001_initial.sql +0 -0
  35. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/migrations/002_performance_indexes.sql +0 -0
  36. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/migrations/003_project_overviews.sql +0 -0
  37. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/migrations/004_remove_branch_dependency.sql +0 -0
  38. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/migrations/005_remove_git_remotes.sql +0 -0
  39. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/migrations/006_vector_mode.sql +0 -0
  40. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/query_preprocessor.py +0 -0
  41. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/server/__init__.py +0 -0
  42. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/server/mcp_server.py +0 -0
  43. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  44. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/token_counter.py +0 -0
  45. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/tools/__init__.py +0 -0
  46. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/transport/__init__.py +0 -0
  47. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/transport/base.py +0 -0
  48. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/transport/http_transport.py +0 -0
  49. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/transport/stdio_transport.py +0 -0
  50. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/chunking/__init__.py +0 -0
  51. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/chunking/ast_chunker.py +0 -0
  52. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/chunking/chunk_optimizer.py +0 -0
  53. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/chunking/language_handlers.py +0 -0
  54. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/config.py +0 -0
  55. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/monitoring/__init__.py +0 -0
  56. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/monitoring/change_detector.py +0 -0
  57. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/monitoring/file_watcher.py +0 -0
  58. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/monitoring/merkle_tree.py +0 -0
  59. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/providers/__init__.py +0 -0
  60. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/providers/turbopuffer_client.py +0 -0
  61. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/providers/voyage_client.py +0 -0
  62. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/security/__init__.py +0 -0
  63. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/security/patterns.py +0 -0
  64. {mcp_code_indexer-4.2.4 → mcp_code_indexer-4.2.6}/src/mcp_code_indexer/vector_mode/security/redactor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mcp-code-indexer
3
- Version: 4.2.4
3
+ Version: 4.2.6
4
4
  Summary: MCP server that tracks file descriptions across codebases, enabling AI agents to efficiently navigate and understand code through searchable summaries and token-aware overviews.
5
5
  License: MIT
6
6
  Keywords: mcp,model-context-protocol,code-indexer,ai-tools,codebase-navigation,file-descriptions,llm-tools
@@ -48,8 +48,8 @@ Description-Content-Type: text/markdown
48
48
 
49
49
  # MCP Code Indexer 🚀
50
50
 
51
- [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?51)](https://badge.fury.io/py/mcp-code-indexer)
52
- [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?51)](https://pypi.org/project/mcp-code-indexer/)
51
+ [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?53)](https://badge.fury.io/py/mcp-code-indexer)
52
+ [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?53)](https://pypi.org/project/mcp-code-indexer/)
53
53
  [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
54
54
 
55
55
  A production-ready **Model Context Protocol (MCP) server** that revolutionizes how AI agents navigate and understand codebases. Built for high-concurrency environments with advanced database resilience, the server provides instant access to intelligent descriptions, semantic search, and context-aware recommendations while maintaining 800+ writes/sec throughput.
@@ -1,7 +1,7 @@
1
1
  # MCP Code Indexer 🚀
2
2
 
3
- [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?51)](https://badge.fury.io/py/mcp-code-indexer)
4
- [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?51)](https://pypi.org/project/mcp-code-indexer/)
3
+ [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?53)](https://badge.fury.io/py/mcp-code-indexer)
4
+ [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?53)](https://pypi.org/project/mcp-code-indexer/)
5
5
  [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
7
  A production-ready **Model Context Protocol (MCP) server** that revolutionizes how AI agents navigate and understand codebases. Built for high-concurrency environments with advanced database resilience, the server provides instant access to intelligent descriptions, semantic search, and context-aware recommendations while maintaining 800+ writes/sec throughput.
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "mcp-code-indexer"
7
- version = "4.2.4"
7
+ version = "4.2.6"
8
8
  description = "MCP server that tracks file descriptions across codebases, enabling AI agents to efficiently navigate and understand code through searchable summaries and token-aware overviews."
9
9
  authors = ["MCP Code Indexer Contributors"]
10
10
  maintainers = ["MCP Code Indexer Contributors"]
@@ -18,9 +18,10 @@ def is_vector_mode_available() -> bool:
18
18
  import turbopuffer
19
19
  import tree_sitter
20
20
  import watchdog
21
+ # PyYAML package provides yaml module
21
22
  import yaml
22
23
  return True
23
- except ImportError:
24
+ except ImportError as e:
24
25
  return False
25
26
 
26
27
  def get_vector_config_path() -> Path:
@@ -39,11 +39,13 @@ class VectorDaemon:
39
39
  self.cache_dir = cache_dir
40
40
  self.is_running = False
41
41
  self.shutdown_requested = False
42
+ self.shutdown_event = asyncio.Event()
42
43
 
43
44
  # Process tracking
44
45
  self.monitored_projects: Set[str] = set()
45
46
  self.processing_queue: asyncio.Queue = asyncio.Queue(maxsize=config.max_queue_size)
46
47
  self.workers: list[asyncio.Task] = []
48
+ self.monitor_tasks: list[asyncio.Task] = []
47
49
 
48
50
  # Statistics
49
51
  self.stats = {
@@ -54,23 +56,24 @@ class VectorDaemon:
54
56
  "last_activity": time.time(),
55
57
  }
56
58
 
57
- # Setup signal handlers
58
- self._setup_signal_handlers()
59
+ # Setup signal handlers will be done in start() method to access event loop
59
60
 
60
61
  def _setup_signal_handlers(self) -> None:
61
62
  """Setup signal handlers for graceful shutdown."""
62
63
  try:
63
- signal.signal(signal.SIGTERM, self._signal_handler)
64
- signal.signal(signal.SIGINT, self._signal_handler)
64
+ loop = asyncio.get_running_loop()
65
+ for sig in [signal.SIGTERM, signal.SIGINT]:
66
+ loop.add_signal_handler(sig, self._signal_handler, sig)
65
67
  if hasattr(signal, 'SIGHUP'):
66
- signal.signal(signal.SIGHUP, self._signal_handler)
68
+ loop.add_signal_handler(signal.SIGHUP, self._signal_handler, signal.SIGHUP)
67
69
  except Exception as e:
68
70
  logger.warning(f"Could not setup signal handlers: {e}")
69
71
 
70
- def _signal_handler(self, signum: int, frame) -> None:
72
+ def _signal_handler(self, signum: int) -> None:
71
73
  """Handle shutdown signals."""
72
74
  logger.info(f"Received signal {signum}, initiating graceful shutdown")
73
75
  self.shutdown_requested = True
76
+ self.shutdown_event.set()
74
77
 
75
78
  async def start(self) -> None:
76
79
  """Start the vector daemon."""
@@ -79,6 +82,10 @@ class VectorDaemon:
79
82
  return
80
83
 
81
84
  self.is_running = True
85
+
86
+ # Setup signal handlers now that we have an event loop
87
+ self._setup_signal_handlers()
88
+
82
89
  logger.info(
83
90
  "Starting vector daemon",
84
91
  extra={
@@ -101,6 +108,7 @@ class VectorDaemon:
101
108
  # Start monitoring tasks
102
109
  monitor_task = asyncio.create_task(self._monitor_projects())
103
110
  stats_task = asyncio.create_task(self._stats_reporter())
111
+ self.monitor_tasks.extend([monitor_task, stats_task])
104
112
 
105
113
  # Wait for shutdown signal
106
114
  await self._run_until_shutdown()
@@ -111,13 +119,13 @@ class VectorDaemon:
111
119
  finally:
112
120
  await self._cleanup()
113
121
 
122
+ async def _notify_shutdown(self) -> None:
123
+ """Notify shutdown event (called from signal handler)."""
124
+ self.shutdown_event.set()
125
+
114
126
  async def _run_until_shutdown(self) -> None:
115
127
  """Run daemon until shutdown is requested."""
116
- while not self.shutdown_requested:
117
- try:
118
- await asyncio.sleep(1.0)
119
- except asyncio.CancelledError:
120
- break
128
+ await self.shutdown_event.wait()
121
129
 
122
130
  async def _monitor_projects(self) -> None:
123
131
  """Monitor projects for vector indexing requirements."""
@@ -141,6 +149,9 @@ class VectorDaemon:
141
149
 
142
150
  await asyncio.sleep(self.config.daemon_poll_interval)
143
151
 
152
+ except asyncio.CancelledError:
153
+ logger.info("Project monitoring cancelled")
154
+ break
144
155
  except Exception as e:
145
156
  logger.error(f"Error in project monitoring: {e}")
146
157
  self.stats["errors_count"] += 1
@@ -180,6 +191,9 @@ class VectorDaemon:
180
191
  await self._process_task(task, worker_id)
181
192
  self.stats["last_activity"] = time.time()
182
193
 
194
+ except asyncio.CancelledError:
195
+ logger.info(f"Worker {worker_id} cancelled")
196
+ break
183
197
  except Exception as e:
184
198
  logger.error(f"Worker {worker_id} error: {e}")
185
199
  self.stats["errors_count"] += 1
@@ -251,6 +265,9 @@ class VectorDaemon:
251
265
 
252
266
  await asyncio.sleep(60.0) # Report every minute
253
267
 
268
+ except asyncio.CancelledError:
269
+ logger.info("Stats reporting cancelled")
270
+ break
254
271
  except Exception as e:
255
272
  logger.error(f"Error in stats reporting: {e}")
256
273
  await asyncio.sleep(10.0)
@@ -264,9 +281,14 @@ class VectorDaemon:
264
281
  for worker in self.workers:
265
282
  worker.cancel()
266
283
 
267
- # Wait for workers to finish
268
- if self.workers:
269
- await asyncio.gather(*self.workers, return_exceptions=True)
284
+ # Cancel monitor tasks
285
+ for task in self.monitor_tasks:
286
+ task.cancel()
287
+
288
+ # Wait for all tasks to finish
289
+ all_tasks = self.workers + self.monitor_tasks
290
+ if all_tasks:
291
+ await asyncio.gather(*all_tasks, return_exceptions=True)
270
292
 
271
293
  logger.info("Vector daemon shutdown complete")
272
294
 
@@ -330,6 +352,7 @@ def main() -> None:
330
352
  asyncio.run(start_vector_daemon(args.config, args.db_path, args.cache_dir))
331
353
  except KeyboardInterrupt:
332
354
  logger.info("Daemon interrupted by user")
355
+ sys.exit(0)
333
356
  except Exception as e:
334
357
  logger.error(f"Daemon failed: {e}", exc_info=True)
335
358
  sys.exit(1)