mcp-code-indexer 4.2.17__tar.gz → 4.2.18__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 (71) hide show
  1. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/PKG-INFO +3 -3
  2. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/README.md +2 -2
  3. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/pyproject.toml +1 -1
  4. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/database.py +52 -2
  5. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/logging_config.py +16 -9
  6. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/LICENSE +0 -0
  7. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/__init__.py +0 -0
  8. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/__main__.py +0 -0
  9. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/ask_handler.py +0 -0
  10. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/claude_api_handler.py +0 -0
  11. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/cleanup_manager.py +0 -0
  12. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/commands/__init__.py +0 -0
  13. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/commands/makelocal.py +0 -0
  14. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/data/stop_words_english.txt +0 -0
  15. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/__init__.py +0 -0
  16. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/connection_health.py +0 -0
  17. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/database_factory.py +0 -0
  18. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/exceptions.py +0 -0
  19. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/models.py +0 -0
  20. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/path_resolver.py +0 -0
  21. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/database/retry_executor.py +0 -0
  22. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/deepask_handler.py +0 -0
  23. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/error_handler.py +0 -0
  24. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/file_scanner.py +0 -0
  25. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/git_hook_handler.py +0 -0
  26. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/main.py +0 -0
  27. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/middleware/__init__.py +0 -0
  28. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/middleware/auth.py +0 -0
  29. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/middleware/error_middleware.py +0 -0
  30. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/middleware/logging.py +0 -0
  31. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/middleware/security.py +0 -0
  32. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/migrations/001_initial.sql +0 -0
  33. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/migrations/002_performance_indexes.sql +0 -0
  34. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/migrations/003_project_overviews.sql +0 -0
  35. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/migrations/004_remove_branch_dependency.sql +0 -0
  36. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/migrations/005_remove_git_remotes.sql +0 -0
  37. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/migrations/006_vector_mode.sql +0 -0
  38. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/query_preprocessor.py +0 -0
  39. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/server/__init__.py +0 -0
  40. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/server/mcp_server.py +0 -0
  41. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  42. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/token_counter.py +0 -0
  43. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/tools/__init__.py +0 -0
  44. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/transport/__init__.py +0 -0
  45. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/transport/base.py +0 -0
  46. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/transport/http_transport.py +0 -0
  47. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/transport/stdio_transport.py +0 -0
  48. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/__init__.py +0 -0
  49. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/chunking/__init__.py +0 -0
  50. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/chunking/ast_chunker.py +0 -0
  51. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/chunking/chunk_optimizer.py +0 -0
  52. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/chunking/language_handlers.py +0 -0
  53. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/config.py +0 -0
  54. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/const.py +0 -0
  55. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/daemon.py +0 -0
  56. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/monitoring/__init__.py +0 -0
  57. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/monitoring/change_detector.py +0 -0
  58. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/monitoring/file_watcher.py +0 -0
  59. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/monitoring/merkle_tree.py +0 -0
  60. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/providers/__init__.py +0 -0
  61. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/providers/turbopuffer_client.py +0 -0
  62. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/providers/voyage_client.py +0 -0
  63. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/security/__init__.py +0 -0
  64. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/security/patterns.py +0 -0
  65. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/security/redactor.py +0 -0
  66. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/services/__init__.py +0 -0
  67. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/services/embedding_service.py +0 -0
  68. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/services/vector_mode_tools_service.py +0 -0
  69. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/services/vector_storage_service.py +0 -0
  70. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/types.py +0 -0
  71. {mcp_code_indexer-4.2.17 → mcp_code_indexer-4.2.18}/src/mcp_code_indexer/vector_mode/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-code-indexer
3
- Version: 4.2.17
3
+ Version: 4.2.18
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
  License-File: LICENSE
@@ -49,8 +49,8 @@ Description-Content-Type: text/markdown
49
49
 
50
50
  # MCP Code Indexer 🚀
51
51
 
52
- [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?64)](https://badge.fury.io/py/mcp-code-indexer)
53
- [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?64)](https://pypi.org/project/mcp-code-indexer/)
52
+ [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?65)](https://badge.fury.io/py/mcp-code-indexer)
53
+ [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?65)](https://pypi.org/project/mcp-code-indexer/)
54
54
  [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
55
55
 
56
56
  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?64)](https://badge.fury.io/py/mcp-code-indexer)
4
- [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?64)](https://pypi.org/project/mcp-code-indexer/)
3
+ [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?65)](https://badge.fury.io/py/mcp-code-indexer)
4
+ [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?65)](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.17"
7
+ version = "4.2.18"
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"]
@@ -409,14 +409,30 @@ class DatabaseManager:
409
409
  operation_name: Name of the operation for monitoring
410
410
  timeout_seconds: Transaction timeout in seconds
411
411
  """
412
+ import time
413
+ acquire_start = time.monotonic()
412
414
  async with self.get_write_connection_with_retry(operation_name) as conn:
415
+ write_lock_time = time.monotonic() - acquire_start
416
+ logger.debug(
417
+ f"[{operation_name}] Write lock acquired in {write_lock_time*1000:.1f}ms"
418
+ )
413
419
  try:
414
420
  # Start immediate transaction with timeout
421
+ begin_start = time.monotonic()
415
422
  await asyncio.wait_for(
416
423
  conn.execute("BEGIN IMMEDIATE"), timeout=timeout_seconds
417
424
  )
425
+ begin_time = time.monotonic() - begin_start
426
+ logger.debug(
427
+ f"[{operation_name}] BEGIN IMMEDIATE completed in {begin_time*1000:.1f}ms"
428
+ )
418
429
  yield conn
430
+ commit_start = time.monotonic()
419
431
  await conn.commit()
432
+ commit_time = time.monotonic() - commit_start
433
+ logger.debug(
434
+ f"[{operation_name}] COMMIT completed in {commit_time*1000:.1f}ms"
435
+ )
420
436
  except asyncio.TimeoutError:
421
437
  logger.warning(
422
438
  (
@@ -476,13 +492,34 @@ class DatabaseManager:
476
492
 
477
493
  async def execute_transaction() -> Any:
478
494
  """Inner function to execute transaction - retried by executor."""
495
+ import time
496
+ start_time = time.monotonic()
497
+ logger.debug(
498
+ f"[{operation_name}] Starting transaction "
499
+ f"(timeout={timeout_seconds}s, pool_size={len(self._connection_pool)})"
500
+ )
479
501
  try:
480
502
  async with self.get_immediate_transaction(
481
503
  operation_name, timeout_seconds
482
504
  ) as conn:
505
+ lock_acquired_time = time.monotonic()
506
+ logger.debug(
507
+ f"[{operation_name}] Lock acquired in "
508
+ f"{(lock_acquired_time - start_time)*1000:.1f}ms"
509
+ )
483
510
  result = await operation_func(conn)
511
+ exec_time = time.monotonic()
512
+ logger.debug(
513
+ f"[{operation_name}] Operation executed in "
514
+ f"{(exec_time - lock_acquired_time)*1000:.1f}ms"
515
+ )
484
516
 
485
517
  # Record successful operation metrics
518
+ total_time = time.monotonic() - start_time
519
+ logger.debug(
520
+ f"[{operation_name}] Transaction completed successfully "
521
+ f"in {total_time*1000:.1f}ms"
522
+ )
486
523
  if self._metrics_collector:
487
524
  self._metrics_collector.record_operation(
488
525
  operation_name,
@@ -494,17 +531,26 @@ class DatabaseManager:
494
531
  return result
495
532
 
496
533
  except aiosqlite.OperationalError as e:
497
- # Record locking event for metrics
534
+ elapsed = time.monotonic() - start_time
498
535
  error_msg = str(e).lower()
536
+ logger.debug(
537
+ f"[{operation_name}] OperationalError after {elapsed*1000:.1f}ms: {e}"
538
+ )
499
539
  if self._metrics_collector and "locked" in error_msg:
500
540
  self._metrics_collector.record_locking_event(operation_name, str(e))
501
541
 
502
542
  # For retryable errors (locked/busy), re-raise the ORIGINAL error
503
543
  # so tenacity can retry. Only classify non-retryable errors.
504
544
  if "locked" in error_msg or "busy" in error_msg:
545
+ logger.debug(
546
+ f"[{operation_name}] Retryable error, will retry: {e}"
547
+ )
505
548
  raise # Let tenacity retry this
506
549
 
507
550
  # Non-retryable OperationalError - classify and raise
551
+ logger.warning(
552
+ f"[{operation_name}] Non-retryable OperationalError: {e}"
553
+ )
508
554
  classified_error = classify_sqlite_error(e, operation_name)
509
555
  if self._metrics_collector:
510
556
  self._metrics_collector.record_operation(
@@ -516,7 +562,11 @@ class DatabaseManager:
516
562
  raise classified_error
517
563
 
518
564
  except asyncio.TimeoutError as e:
519
- # Timeout on BEGIN IMMEDIATE - this is retryable
565
+ elapsed = time.monotonic() - start_time
566
+ logger.warning(
567
+ f"[{operation_name}] Timeout after {elapsed*1000:.1f}ms "
568
+ f"waiting for database lock (timeout={timeout_seconds}s)"
569
+ )
520
570
  if self._metrics_collector:
521
571
  self._metrics_collector.record_locking_event(
522
572
  operation_name, "timeout waiting for lock"
@@ -81,22 +81,29 @@ def setup_logging(
81
81
  root_logger.warning(f"Failed to set up file logging: {e}")
82
82
 
83
83
  # Configure specific loggers
84
+ effective_level = getattr(logging, log_level.upper())
84
85
 
85
- # Quiet down noisy libraries
86
+ # Quiet down noisy libraries (always WARNING+)
86
87
  logging.getLogger("aiosqlite").setLevel(logging.WARNING)
87
88
  logging.getLogger("tiktoken").setLevel(logging.WARNING)
88
89
 
89
- # MCP specific loggers
90
+ # MCP specific loggers - respect the configured log level
90
91
  mcp_logger = logging.getLogger("mcp")
91
- mcp_logger.setLevel(logging.INFO)
92
+ mcp_logger.setLevel(effective_level)
92
93
 
93
- # Database logger
94
- db_logger = logging.getLogger("src.database")
95
- db_logger.setLevel(logging.INFO)
94
+ # Database logger - respect the configured log level
95
+ db_logger = logging.getLogger("mcp_code_indexer.database")
96
+ db_logger.setLevel(effective_level)
96
97
 
97
- # Server logger
98
- server_logger = logging.getLogger("src.server")
99
- server_logger.setLevel(logging.INFO)
98
+ # Also set the old logger names for backwards compatibility
99
+ logging.getLogger("src.database").setLevel(effective_level)
100
+
101
+ # Server logger - respect the configured log level
102
+ server_logger = logging.getLogger("mcp_code_indexer.server")
103
+ server_logger.setLevel(effective_level)
104
+
105
+ # Also set the old logger names for backwards compatibility
106
+ logging.getLogger("src.server").setLevel(effective_level)
100
107
 
101
108
  return root_logger
102
109