mcp-code-indexer 1.1.0__py3-none-any.whl → 1.1.2__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.
- mcp_code_indexer/database/database.py +20 -5
- mcp_code_indexer/server/mcp_server.py +66 -8
- {mcp_code_indexer-1.1.0.dist-info → mcp_code_indexer-1.1.2.dist-info}/METADATA +1 -1
- {mcp_code_indexer-1.1.0.dist-info → mcp_code_indexer-1.1.2.dist-info}/RECORD +8 -8
- {mcp_code_indexer-1.1.0.dist-info → mcp_code_indexer-1.1.2.dist-info}/WHEEL +0 -0
- {mcp_code_indexer-1.1.0.dist-info → mcp_code_indexer-1.1.2.dist-info}/entry_points.txt +0 -0
- {mcp_code_indexer-1.1.0.dist-info → mcp_code_indexer-1.1.2.dist-info}/licenses/LICENSE +0 -0
- {mcp_code_indexer-1.1.0.dist-info → mcp_code_indexer-1.1.2.dist-info}/top_level.txt +0 -0
@@ -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
|
-
|
373
|
-
FROM file_descriptions_fts
|
374
|
-
JOIN file_descriptions fd ON fd.rowid =
|
375
|
-
WHERE
|
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
|
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=
|
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=
|
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
|
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=
|
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=
|
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=
|
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=
|
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":
|
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.
|
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
|
@@ -6,17 +6,17 @@ mcp_code_indexer/main.py,sha256=Rou-mAN9-12PPP8jC7dIs2_UNambJuC2F8BF--j-0m8,3715
|
|
6
6
|
mcp_code_indexer/merge_handler.py,sha256=lJR8eVq2qSrF6MW9mR3Fy8UzrNAaQ7RsI2FMNXne3vQ,14692
|
7
7
|
mcp_code_indexer/token_counter.py,sha256=WrifOkbF99nWWHlRlhCHAB2KN7qr83GOHl7apE-hJcE,8460
|
8
8
|
mcp_code_indexer/database/__init__.py,sha256=aPq_aaRp0aSwOBIq9GkuMNjmLxA411zg2vhdrAuHm-w,38
|
9
|
-
mcp_code_indexer/database/database.py,sha256=
|
9
|
+
mcp_code_indexer/database/database.py,sha256=eG2xY5cd-oxRZ6mgGkqqBiJJfGCPqJgzoFq6kR99WfA,20300
|
10
10
|
mcp_code_indexer/database/models.py,sha256=3wOxHKb6j3zKPWFSwB5g1TLpI507vLNZcqsxZR4VuRs,5528
|
11
11
|
mcp_code_indexer/middleware/__init__.py,sha256=p-mP0pMsfiU2yajCPvokCUxUEkh_lu4XJP1LyyMW2ug,220
|
12
12
|
mcp_code_indexer/middleware/error_middleware.py,sha256=v6jaHmPxf3qerYdb85X1tHIXLxgcbybpitKVakFLQTA,10109
|
13
13
|
mcp_code_indexer/server/__init__.py,sha256=16xMcuriUOBlawRqWNBk6niwrvtv_JD5xvI36X1Vsmk,41
|
14
|
-
mcp_code_indexer/server/mcp_server.py,sha256=
|
14
|
+
mcp_code_indexer/server/mcp_server.py,sha256=pa7CIwokah5T8Wi28FlxzzgiozOjabY-u51VoevOHy0,46414
|
15
15
|
mcp_code_indexer/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4,sha256=Ijkht27pm96ZW3_3OFE-7xAPtR0YyTWXoRO8_-hlsqc,1681126
|
16
16
|
mcp_code_indexer/tools/__init__.py,sha256=m01mxML2UdD7y5rih_XNhNSCMzQTz7WQ_T1TeOcYlnE,49
|
17
|
-
mcp_code_indexer-1.1.
|
18
|
-
mcp_code_indexer-1.1.
|
19
|
-
mcp_code_indexer-1.1.
|
20
|
-
mcp_code_indexer-1.1.
|
21
|
-
mcp_code_indexer-1.1.
|
22
|
-
mcp_code_indexer-1.1.
|
17
|
+
mcp_code_indexer-1.1.2.dist-info/licenses/LICENSE,sha256=JN9dyPPgYwH9C-UjYM7FLNZjQ6BF7kAzpF3_4PwY4rY,1086
|
18
|
+
mcp_code_indexer-1.1.2.dist-info/METADATA,sha256=GKi-NMcH93vJanUrHiABIojml8pQRdD2jTx4umQulMw,11930
|
19
|
+
mcp_code_indexer-1.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
20
|
+
mcp_code_indexer-1.1.2.dist-info/entry_points.txt,sha256=8HqWOw1Is7jOP1bvIgaSwouvT9z_Boe-9hd4NzyJOhY,68
|
21
|
+
mcp_code_indexer-1.1.2.dist-info/top_level.txt,sha256=yKYCM-gMGt-cnupGfAhnZaoEsROLB6DQ1KFUuyKx4rw,17
|
22
|
+
mcp_code_indexer-1.1.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|