mcp-code-indexer 1.1.0__tar.gz → 1.1.2__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 (36) hide show
  1. {mcp_code_indexer-1.1.0/src/mcp_code_indexer.egg-info → mcp_code_indexer-1.1.2}/PKG-INFO +1 -1
  2. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/pyproject.toml +1 -1
  3. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/database/database.py +20 -5
  4. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/server/mcp_server.py +66 -8
  5. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2/src/mcp_code_indexer.egg-info}/PKG-INFO +1 -1
  6. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/LICENSE +0 -0
  7. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/MANIFEST.in +0 -0
  8. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/README.md +0 -0
  9. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/docs/api-reference.md +0 -0
  10. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/docs/architecture.md +0 -0
  11. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/docs/configuration.md +0 -0
  12. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/docs/contributing.md +0 -0
  13. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/migrations/001_initial.sql +0 -0
  14. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/migrations/002_performance_indexes.sql +0 -0
  15. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/requirements.txt +0 -0
  16. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/setup.cfg +0 -0
  17. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/setup.py +0 -0
  18. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/__init__.py +0 -0
  19. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/database/__init__.py +0 -0
  20. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/database/models.py +0 -0
  21. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/error_handler.py +0 -0
  22. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/file_scanner.py +0 -0
  23. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/logging_config.py +0 -0
  24. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/main.py +0 -0
  25. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/merge_handler.py +0 -0
  26. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/middleware/__init__.py +0 -0
  27. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/middleware/error_middleware.py +0 -0
  28. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/server/__init__.py +0 -0
  29. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  30. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/token_counter.py +0 -0
  31. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer/tools/__init__.py +0 -0
  32. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer.egg-info/SOURCES.txt +0 -0
  33. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer.egg-info/dependency_links.txt +0 -0
  34. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer.egg-info/entry_points.txt +0 -0
  35. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer.egg-info/requires.txt +0 -0
  36. {mcp_code_indexer-1.1.0 → mcp_code_indexer-1.1.2}/src/mcp_code_indexer.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-code-indexer
3
- Version: 1.1.0
3
+ Version: 1.1.2
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
  Author: MCP Code Indexer Contributors
6
6
  Maintainer: MCP Code Indexer Contributors
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mcp-code-indexer"
7
- version = "1.1.0"
7
+ version = "1.1.2"
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
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -234,6 +234,21 @@ class DatabaseManager:
234
234
 
235
235
  return projects
236
236
 
237
+ async def get_branch_file_counts(self, project_id: str) -> Dict[str, int]:
238
+ """Get file counts per branch for a project."""
239
+ async with self.get_connection() as db:
240
+ cursor = await db.execute(
241
+ """
242
+ SELECT branch, COUNT(*) as file_count
243
+ FROM file_descriptions
244
+ WHERE project_id = ?
245
+ GROUP BY branch
246
+ """,
247
+ (project_id,)
248
+ )
249
+ rows = await cursor.fetchall()
250
+ return {row[0]: row[1] for row in rows}
251
+
237
252
  # File description operations
238
253
 
239
254
  async def create_file_description(self, file_desc: FileDescription) -> None:
@@ -369,13 +384,13 @@ class DatabaseManager:
369
384
  fd.branch,
370
385
  fd.file_path,
371
386
  fd.description,
372
- fts.rank
373
- FROM file_descriptions_fts fts
374
- JOIN file_descriptions fd ON fd.rowid = fts.rowid
375
- WHERE fts MATCH ?
387
+ bm25(file_descriptions_fts) as rank
388
+ FROM file_descriptions_fts
389
+ JOIN file_descriptions fd ON fd.rowid = file_descriptions_fts.rowid
390
+ WHERE file_descriptions_fts MATCH ?
376
391
  AND fd.project_id = ?
377
392
  AND fd.branch = ?
378
- ORDER BY fts.rank
393
+ ORDER BY bm25(file_descriptions_fts)
379
394
  LIMIT ?
380
395
  """,
381
396
  (query, project_id, branch, max_results)
@@ -473,13 +473,65 @@ class MCPCodeIndexServer:
473
473
  await self.db_manager.update_project(project)
474
474
  logger.debug(f"Updated project metadata for {project.name}")
475
475
 
476
+ async def _resolve_branch(self, project_id: str, requested_branch: str) -> str:
477
+ """
478
+ Resolve the actual branch to use for operations.
479
+
480
+ For new projects or branches with no existing files, uses the requested branch.
481
+ For existing projects, tries to find a consistent branch to avoid data fragmentation.
482
+
483
+ Returns the resolved branch name.
484
+ """
485
+ try:
486
+ # Get all branches and their file counts for this project
487
+ branch_counts = await self.db_manager.get_branch_file_counts(project_id)
488
+
489
+ # If no existing data, use the requested branch
490
+ if not branch_counts:
491
+ return requested_branch
492
+
493
+ # If requested branch has files, use it
494
+ if requested_branch in branch_counts and branch_counts[requested_branch] > 0:
495
+ return requested_branch
496
+
497
+ # Try common branch name variations to find existing data
498
+ common_variations = {
499
+ 'main': ['master', 'develop', 'development', 'dev'],
500
+ 'master': ['main', 'develop', 'development', 'dev'],
501
+ 'develop': ['development', 'main', 'master', 'dev'],
502
+ 'development': ['develop', 'main', 'master', 'dev'],
503
+ 'dev': ['develop', 'development', 'main', 'master']
504
+ }
505
+
506
+ # Try variations of the requested branch
507
+ if requested_branch.lower() in common_variations:
508
+ for variation in common_variations[requested_branch.lower()]:
509
+ if variation in branch_counts and branch_counts[variation] > 0:
510
+ logger.info(f"Resolved branch '{requested_branch}' to existing branch '{variation}' with {branch_counts[variation]} files")
511
+ return variation
512
+
513
+ # If no variations found, check if we should use the main data branch
514
+ # (to avoid fragmenting data across multiple branches)
515
+ best_branch = max(branch_counts.items(), key=lambda x: x[1])
516
+ if best_branch[1] > 10: # Only if there's substantial existing data
517
+ logger.info(f"Using primary branch '{best_branch[0]}' instead of '{requested_branch}' to avoid data fragmentation")
518
+ return best_branch[0]
519
+
520
+ # Fall back to requested branch for new/small projects
521
+ return requested_branch
522
+
523
+ except Exception as e:
524
+ logger.warning(f"Error resolving branch: {e}")
525
+ return requested_branch
526
+
476
527
  async def _handle_get_file_description(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
477
528
  """Handle get_file_description tool calls."""
478
529
  project_id = await self._get_or_create_project_id(arguments)
530
+ resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
479
531
 
480
532
  file_desc = await self.db_manager.get_file_description(
481
533
  project_id=project_id,
482
- branch=arguments["branch"],
534
+ branch=resolved_branch,
483
535
  file_path=arguments["filePath"]
484
536
  )
485
537
 
@@ -500,10 +552,11 @@ class MCPCodeIndexServer:
500
552
  async def _handle_update_file_description(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
501
553
  """Handle update_file_description tool calls."""
502
554
  project_id = await self._get_or_create_project_id(arguments)
555
+ resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
503
556
 
504
557
  file_desc = FileDescription(
505
558
  project_id=project_id,
506
- branch=arguments["branch"],
559
+ branch=resolved_branch,
507
560
  file_path=arguments["filePath"],
508
561
  description=arguments["description"],
509
562
  file_hash=arguments.get("fileHash"),
@@ -523,11 +576,12 @@ class MCPCodeIndexServer:
523
576
  async def _handle_check_codebase_size(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
524
577
  """Handle check_codebase_size tool calls."""
525
578
  project_id = await self._get_or_create_project_id(arguments)
579
+ resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
526
580
 
527
- # Get all file descriptions for this project/branch
581
+ # Get file descriptions for this project/branch
528
582
  file_descriptions = await self.db_manager.get_all_file_descriptions(
529
583
  project_id=project_id,
530
- branch=arguments["branch"]
584
+ branch=resolved_branch
531
585
  )
532
586
 
533
587
  # Calculate total tokens
@@ -546,12 +600,13 @@ class MCPCodeIndexServer:
546
600
  async def _handle_find_missing_descriptions(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
547
601
  """Handle find_missing_descriptions tool calls."""
548
602
  project_id = await self._get_or_create_project_id(arguments)
603
+ resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
549
604
  folder_path = Path(arguments["folderPath"])
550
605
 
551
606
  # Get existing file descriptions
552
607
  existing_descriptions = await self.db_manager.get_all_file_descriptions(
553
608
  project_id=project_id,
554
- branch=arguments["branch"]
609
+ branch=resolved_branch
555
610
  )
556
611
  existing_paths = {desc.file_path for desc in existing_descriptions}
557
612
 
@@ -585,12 +640,13 @@ class MCPCodeIndexServer:
585
640
  async def _handle_search_descriptions(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
586
641
  """Handle search_descriptions tool calls."""
587
642
  project_id = await self._get_or_create_project_id(arguments)
643
+ resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
588
644
  max_results = arguments.get("maxResults", 20)
589
645
 
590
646
  # Perform search
591
647
  search_results = await self.db_manager.search_file_descriptions(
592
648
  project_id=project_id,
593
- branch=arguments["branch"],
649
+ branch=resolved_branch,
594
650
  query=arguments["query"],
595
651
  max_results=max_results
596
652
  )
@@ -614,11 +670,12 @@ class MCPCodeIndexServer:
614
670
  async def _handle_get_codebase_overview(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
615
671
  """Handle get_codebase_overview tool calls."""
616
672
  project_id = await self._get_or_create_project_id(arguments)
673
+ resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
617
674
 
618
675
  # Get all file descriptions
619
676
  file_descriptions = await self.db_manager.get_all_file_descriptions(
620
677
  project_id=project_id,
621
- branch=arguments["branch"]
678
+ branch=resolved_branch
622
679
  )
623
680
 
624
681
  # Calculate total tokens
@@ -641,7 +698,8 @@ class MCPCodeIndexServer:
641
698
 
642
699
  return {
643
700
  "projectName": arguments["projectName"],
644
- "branch": arguments["branch"],
701
+ "branch": resolved_branch,
702
+ "requestedBranch": arguments["branch"] if arguments["branch"] != resolved_branch else None,
645
703
  "totalFiles": len(file_descriptions),
646
704
  "totalTokens": total_tokens,
647
705
  "isLarge": is_large,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-code-indexer
3
- Version: 1.1.0
3
+ Version: 1.1.2
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
  Author: MCP Code Indexer Contributors
6
6
  Maintainer: MCP Code Indexer Contributors