mcp-code-indexer 1.6.1__tar.gz → 1.6.3__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.
- {mcp_code_indexer-1.6.1/src/mcp_code_indexer.egg-info → mcp_code_indexer-1.6.3}/PKG-INFO +3 -3
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/README.md +2 -2
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/pyproject.toml +1 -1
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/setup.py +1 -1
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/git_hook_handler.py +55 -7
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/server/mcp_server.py +58 -1
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3/src/mcp_code_indexer.egg-info}/PKG-INFO +3 -3
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/LICENSE +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/MANIFEST.in +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/docs/api-reference.md +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/docs/architecture.md +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/docs/configuration.md +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/docs/contributing.md +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/docs/git-hook-setup.md +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/migrations/001_initial.sql +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/migrations/002_performance_indexes.sql +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/migrations/003_project_overviews.sql +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/requirements.txt +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/setup.cfg +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/__init__.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/__main__.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/data/stop_words_english.txt +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/database/__init__.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/database/database.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/database/models.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/error_handler.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/file_scanner.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/logging_config.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/main.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/merge_handler.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/middleware/__init__.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/middleware/error_middleware.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/server/__init__.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/token_counter.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/tools/__init__.py +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/SOURCES.txt +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/dependency_links.txt +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/entry_points.txt +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/requires.txt +0 -0
- {mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/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.6.
|
3
|
+
Version: 1.6.3
|
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
|
@@ -57,8 +57,8 @@ Dynamic: requires-python
|
|
57
57
|
|
58
58
|
# MCP Code Indexer 🚀
|
59
59
|
|
60
|
-
[](https://badge.fury.io/py/mcp-code-indexer)
|
61
|
+
[](https://pypi.org/project/mcp-code-indexer/)
|
62
62
|
[](https://opensource.org/licenses/MIT)
|
63
63
|
|
64
64
|
A production-ready **Model Context Protocol (MCP) server** that revolutionizes how AI agents navigate and understand codebases. Instead of repeatedly scanning files, agents get instant access to intelligent descriptions, semantic search, and context-aware recommendations.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# MCP Code Indexer 🚀
|
2
2
|
|
3
|
-
[](https://badge.fury.io/py/mcp-code-indexer)
|
4
|
+
[](https://pypi.org/project/mcp-code-indexer/)
|
5
5
|
[](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. Instead of repeatedly scanning files, agents get instant access to intelligent descriptions, semantic search, and context-aware recommendations.
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "mcp-code-indexer"
|
7
|
-
version = "1.6.
|
7
|
+
version = "1.6.3"
|
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"}
|
@@ -90,8 +90,17 @@ class GitHookHandler:
|
|
90
90
|
This is the main entry point for git hook functionality.
|
91
91
|
"""
|
92
92
|
try:
|
93
|
+
self.logger.info(f"=== Git Hook Analysis Started ===")
|
94
|
+
if commit_hash:
|
95
|
+
self.logger.info(f"Mode: Single commit ({commit_hash})")
|
96
|
+
elif commit_range:
|
97
|
+
self.logger.info(f"Mode: Commit range ({commit_range[0]}..{commit_range[1]})")
|
98
|
+
else:
|
99
|
+
self.logger.info(f"Mode: Staged changes")
|
100
|
+
|
93
101
|
# Get git info from current directory
|
94
102
|
project_info = await self._identify_project_from_git()
|
103
|
+
self.logger.info(f"Project identified: {project_info.get('name', 'Unknown')} at {project_info.get('folderPath', 'Unknown')}")
|
95
104
|
|
96
105
|
# Get git diff and commit message based on mode
|
97
106
|
if commit_hash:
|
@@ -104,17 +113,17 @@ class GitHookHandler:
|
|
104
113
|
git_diff = await self._get_git_diff()
|
105
114
|
commit_message = await self._get_commit_message()
|
106
115
|
|
116
|
+
# Log diff details
|
107
117
|
if not git_diff:
|
108
118
|
self.logger.info(f"Skipping git hook update - no git diff")
|
109
119
|
return
|
110
|
-
|
111
|
-
|
120
|
+
|
121
|
+
diff_chars = len(git_diff)
|
112
122
|
diff_tokens = self.token_counter.count_tokens(git_diff)
|
113
|
-
|
114
|
-
self.logger.info(f"Skipping git hook update - diff too large ({diff_tokens} tokens > {self.config['max_diff_tokens']} limit)")
|
115
|
-
return
|
123
|
+
self.logger.info(f"Git diff: {diff_chars} characters, {diff_tokens} tokens")
|
116
124
|
|
117
125
|
# Fetch current state
|
126
|
+
self.logger.info("Fetching current project state...")
|
118
127
|
current_overview = await self._get_project_overview(project_info)
|
119
128
|
current_descriptions = await self._get_all_descriptions(project_info)
|
120
129
|
changed_files = self._extract_changed_files(git_diff)
|
@@ -123,7 +132,12 @@ class GitHookHandler:
|
|
123
132
|
self.logger.info("No changed files detected in git diff")
|
124
133
|
return
|
125
134
|
|
135
|
+
self.logger.info(f"Found {len(changed_files)} changed files: {', '.join(changed_files)}")
|
136
|
+
self.logger.info(f"Current overview length: {len(current_overview) if current_overview else 0} characters")
|
137
|
+
self.logger.info(f"Current descriptions count: {len(current_descriptions)}")
|
138
|
+
|
126
139
|
# Build prompt for OpenRouter
|
140
|
+
self.logger.info("Building analysis prompt...")
|
127
141
|
prompt = self._build_githook_prompt(
|
128
142
|
git_diff,
|
129
143
|
commit_message,
|
@@ -132,16 +146,33 @@ class GitHookHandler:
|
|
132
146
|
changed_files
|
133
147
|
)
|
134
148
|
|
149
|
+
# Log prompt details
|
150
|
+
prompt_chars = len(prompt)
|
151
|
+
prompt_tokens = self.token_counter.count_tokens(prompt)
|
152
|
+
self.logger.info(f"Analysis prompt: {prompt_chars} characters, {prompt_tokens} tokens")
|
153
|
+
|
154
|
+
# Check total prompt token count
|
155
|
+
if prompt_tokens > self.config["max_diff_tokens"]:
|
156
|
+
self.logger.info(f"Skipping git hook update - prompt too large ({prompt_tokens} tokens > {self.config['max_diff_tokens']} limit)")
|
157
|
+
return
|
158
|
+
|
159
|
+
self.logger.info(f"Prompt size OK ({prompt_tokens} <= {self.config['max_diff_tokens']} tokens), calling OpenRouter...")
|
160
|
+
|
135
161
|
# Call OpenRouter API
|
136
162
|
updates = await self._call_openrouter(prompt)
|
137
163
|
|
164
|
+
self.logger.info(f"OpenRouter response received, processing updates...")
|
165
|
+
|
138
166
|
# Apply updates to database
|
139
167
|
await self._apply_updates(project_info, updates)
|
140
168
|
|
141
|
-
self.logger.info(f"Git hook update completed for {len(changed_files)} files")
|
169
|
+
self.logger.info(f"Git hook update completed successfully for {len(changed_files)} files")
|
142
170
|
|
143
171
|
except Exception as e:
|
144
172
|
self.logger.error(f"Git hook mode failed: {e}")
|
173
|
+
self.logger.error(f"Exception details: {type(e).__name__}: {str(e)}")
|
174
|
+
import traceback
|
175
|
+
self.logger.error(f"Full traceback:\n{traceback.format_exc()}")
|
145
176
|
# Don't fail the git operation - just log the error
|
146
177
|
raise GitHookError(f"Git hook processing failed: {e}")
|
147
178
|
|
@@ -543,8 +574,16 @@ Return ONLY the JSON, no other text."""
|
|
543
574
|
"max_tokens": 24000,
|
544
575
|
}
|
545
576
|
|
577
|
+
|
578
|
+
|
546
579
|
timeout = aiohttp.ClientTimeout(total=self.config["timeout"])
|
547
580
|
|
581
|
+
self.logger.info(f"Sending request to OpenRouter API...")
|
582
|
+
self.logger.info(f" Model: {self.config['model']}")
|
583
|
+
self.logger.info(f" Temperature: {self.config['temperature']}")
|
584
|
+
self.logger.info(f" Max tokens: 24000")
|
585
|
+
self.logger.info(f" Timeout: {self.config['timeout']}s")
|
586
|
+
|
548
587
|
try:
|
549
588
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
550
589
|
async with session.post(
|
@@ -553,8 +592,11 @@ Return ONLY the JSON, no other text."""
|
|
553
592
|
json=payload
|
554
593
|
) as response:
|
555
594
|
|
595
|
+
self.logger.info(f"OpenRouter API response status: {response.status}")
|
596
|
+
|
556
597
|
if response.status == 429:
|
557
598
|
retry_after = int(response.headers.get("Retry-After", 60))
|
599
|
+
self.logger.warning(f"Rate limited by OpenRouter, retry after {retry_after}s")
|
558
600
|
raise ThrottlingError(f"Rate limited. Retry after {retry_after}s")
|
559
601
|
|
560
602
|
response.raise_for_status()
|
@@ -562,14 +604,20 @@ Return ONLY the JSON, no other text."""
|
|
562
604
|
response_data = await response.json()
|
563
605
|
|
564
606
|
if "choices" not in response_data:
|
607
|
+
self.logger.error(f"Invalid API response format: {response_data}")
|
565
608
|
raise GitHookError(f"Invalid API response format: {response_data}")
|
566
609
|
|
567
610
|
content = response_data["choices"][0]["message"]["content"]
|
611
|
+
self.logger.info(f"OpenRouter response content length: {len(content)} characters")
|
612
|
+
|
568
613
|
return self._validate_githook_response(content)
|
569
614
|
|
570
615
|
except aiohttp.ClientError as e:
|
616
|
+
self.logger.error(f"OpenRouter API request failed: {e}")
|
617
|
+
self.logger.error(f"ClientError details: {type(e).__name__}: {str(e)}")
|
571
618
|
raise GitHookError(f"OpenRouter API request failed: {e}")
|
572
|
-
except asyncio.TimeoutError:
|
619
|
+
except asyncio.TimeoutError as e:
|
620
|
+
self.logger.error(f"OpenRouter API request timed out after {self.config['timeout']}s")
|
573
621
|
raise GitHookError("OpenRouter API request timed out")
|
574
622
|
|
575
623
|
def _validate_githook_response(self, response_text: str) -> Dict[str, Any]:
|
@@ -437,6 +437,12 @@ src/
|
|
437
437
|
@self.server.call_tool()
|
438
438
|
async def call_tool(name: str, arguments: Dict[str, Any]) -> List[types.TextContent]:
|
439
439
|
"""Handle tool calls with middleware."""
|
440
|
+
import time
|
441
|
+
start_time = time.time()
|
442
|
+
|
443
|
+
logger.info(f"=== MCP Tool Call: {name} ===")
|
444
|
+
logger.info(f"Arguments: {', '.join(arguments.keys())}")
|
445
|
+
|
440
446
|
# Map tool names to handler methods
|
441
447
|
tool_handlers = {
|
442
448
|
"get_file_description": self._handle_get_file_description,
|
@@ -452,6 +458,7 @@ src/
|
|
452
458
|
}
|
453
459
|
|
454
460
|
if name not in tool_handlers:
|
461
|
+
logger.error(f"Unknown tool requested: {name}")
|
455
462
|
from ..error_handler import ValidationError
|
456
463
|
raise ValidationError(f"Unknown tool: {name}")
|
457
464
|
|
@@ -460,7 +467,18 @@ src/
|
|
460
467
|
lambda args: self._execute_tool_handler(tool_handlers[name], args)
|
461
468
|
)
|
462
469
|
|
463
|
-
|
470
|
+
try:
|
471
|
+
result = await wrapped_handler(arguments)
|
472
|
+
|
473
|
+
elapsed_time = time.time() - start_time
|
474
|
+
logger.info(f"MCP Tool '{name}' completed successfully in {elapsed_time:.2f}s")
|
475
|
+
|
476
|
+
return result
|
477
|
+
except Exception as e:
|
478
|
+
elapsed_time = time.time() - start_time
|
479
|
+
logger.error(f"MCP Tool '{name}' failed after {elapsed_time:.2f}s: {e}")
|
480
|
+
logger.error(f"Exception details: {type(e).__name__}: {str(e)}")
|
481
|
+
raise
|
464
482
|
|
465
483
|
async def _execute_tool_handler(self, handler, arguments: Dict[str, Any]) -> List[types.TextContent]:
|
466
484
|
"""Execute a tool handler and format the result."""
|
@@ -758,9 +776,18 @@ src/
|
|
758
776
|
|
759
777
|
async def _handle_update_file_description(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
760
778
|
"""Handle update_file_description tool calls."""
|
779
|
+
logger.info(f"Updating file description for: {arguments['filePath']}")
|
780
|
+
logger.info(f"Project: {arguments.get('projectName', 'Unknown')}")
|
781
|
+
logger.info(f"Branch: {arguments.get('branch', 'Unknown')}")
|
782
|
+
|
783
|
+
description_length = len(arguments.get("description", ""))
|
784
|
+
logger.info(f"Description length: {description_length} characters")
|
785
|
+
|
761
786
|
project_id = await self._get_or_create_project_id(arguments)
|
762
787
|
resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
|
763
788
|
|
789
|
+
logger.info(f"Resolved project_id: {project_id}, branch: {resolved_branch}")
|
790
|
+
|
764
791
|
file_desc = FileDescription(
|
765
792
|
project_id=project_id,
|
766
793
|
branch=resolved_branch,
|
@@ -773,6 +800,8 @@ src/
|
|
773
800
|
|
774
801
|
await self.db_manager.create_file_description(file_desc)
|
775
802
|
|
803
|
+
logger.info(f"Successfully updated description for: {arguments['filePath']}")
|
804
|
+
|
776
805
|
return {
|
777
806
|
"success": True,
|
778
807
|
"message": f"Description updated for {arguments['filePath']}",
|
@@ -782,31 +811,46 @@ src/
|
|
782
811
|
|
783
812
|
async def _handle_check_codebase_size(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
784
813
|
"""Handle check_codebase_size tool calls."""
|
814
|
+
logger.info(f"Checking codebase size for: {arguments.get('projectName', 'Unknown')}")
|
815
|
+
logger.info(f"Folder path: {arguments.get('folderPath', 'Unknown')}")
|
816
|
+
logger.info(f"Branch: {arguments.get('branch', 'Unknown')}")
|
817
|
+
|
785
818
|
project_id = await self._get_or_create_project_id(arguments)
|
786
819
|
resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
|
787
820
|
folder_path = Path(arguments["folderPath"])
|
788
821
|
|
822
|
+
logger.info(f"Resolved project_id: {project_id}, branch: {resolved_branch}")
|
823
|
+
|
789
824
|
# Clean up descriptions for files that no longer exist
|
825
|
+
logger.info("Cleaning up descriptions for missing files...")
|
790
826
|
cleaned_up_files = await self.db_manager.cleanup_missing_files(
|
791
827
|
project_id=project_id,
|
792
828
|
branch=resolved_branch,
|
793
829
|
project_root=folder_path
|
794
830
|
)
|
831
|
+
logger.info(f"Cleaned up {len(cleaned_up_files)} missing files")
|
795
832
|
|
796
833
|
# Get file descriptions for this project/branch (after cleanup)
|
834
|
+
logger.info("Retrieving file descriptions...")
|
797
835
|
file_descriptions = await self.db_manager.get_all_file_descriptions(
|
798
836
|
project_id=project_id,
|
799
837
|
branch=resolved_branch
|
800
838
|
)
|
839
|
+
logger.info(f"Found {len(file_descriptions)} file descriptions")
|
801
840
|
|
802
841
|
# Use provided token limit or fall back to server default
|
803
842
|
token_limit = arguments.get("tokenLimit", self.token_limit)
|
804
843
|
|
805
844
|
# Calculate total tokens
|
845
|
+
logger.info("Calculating total token count...")
|
806
846
|
total_tokens = self.token_counter.calculate_codebase_tokens(file_descriptions)
|
807
847
|
is_large = total_tokens > token_limit
|
808
848
|
recommendation = "use_search" if is_large else "use_overview"
|
809
849
|
|
850
|
+
logger.info(f"Codebase analysis complete: {total_tokens} tokens, {len(file_descriptions)} files")
|
851
|
+
logger.info(f"Size assessment: {'LARGE' if is_large else 'SMALL'} (limit: {token_limit})")
|
852
|
+
logger.info(f"Recommendation: {recommendation}")
|
853
|
+
|
810
854
|
return {
|
811
855
|
"totalTokens": total_tokens,
|
812
856
|
"isLarge": is_large,
|
@@ -819,20 +863,29 @@ src/
|
|
819
863
|
|
820
864
|
async def _handle_find_missing_descriptions(self, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
821
865
|
"""Handle find_missing_descriptions tool calls."""
|
866
|
+
logger.info(f"Finding missing descriptions for: {arguments.get('projectName', 'Unknown')}")
|
867
|
+
logger.info(f"Folder path: {arguments.get('folderPath', 'Unknown')}")
|
868
|
+
|
822
869
|
project_id = await self._get_or_create_project_id(arguments)
|
823
870
|
resolved_branch = await self._resolve_branch(project_id, arguments["branch"])
|
824
871
|
folder_path = Path(arguments["folderPath"])
|
825
872
|
|
873
|
+
logger.info(f"Resolved project_id: {project_id}, branch: {resolved_branch}")
|
874
|
+
|
826
875
|
# Get existing file descriptions
|
876
|
+
logger.info("Retrieving existing file descriptions...")
|
827
877
|
existing_descriptions = await self.db_manager.get_all_file_descriptions(
|
828
878
|
project_id=project_id,
|
829
879
|
branch=resolved_branch
|
830
880
|
)
|
831
881
|
existing_paths = {desc.file_path for desc in existing_descriptions}
|
882
|
+
logger.info(f"Found {len(existing_paths)} existing descriptions")
|
832
883
|
|
833
884
|
# Scan directory for files
|
885
|
+
logger.info(f"Scanning project directory: {folder_path}")
|
834
886
|
scanner = FileScanner(folder_path)
|
835
887
|
if not scanner.is_valid_project_directory():
|
888
|
+
logger.error(f"Invalid or inaccessible project directory: {folder_path}")
|
836
889
|
return {
|
837
890
|
"error": f"Invalid or inaccessible project directory: {folder_path}"
|
838
891
|
}
|
@@ -840,14 +893,18 @@ src/
|
|
840
893
|
missing_files = scanner.find_missing_files(existing_paths)
|
841
894
|
missing_paths = [scanner.get_relative_path(f) for f in missing_files]
|
842
895
|
|
896
|
+
logger.info(f"Found {len(missing_paths)} files without descriptions")
|
897
|
+
|
843
898
|
# Apply limit if specified
|
844
899
|
limit = arguments.get("limit")
|
845
900
|
total_missing = len(missing_paths)
|
846
901
|
if limit is not None and isinstance(limit, int) and limit > 0:
|
847
902
|
missing_paths = missing_paths[:limit]
|
903
|
+
logger.info(f"Applied limit {limit}, returning {len(missing_paths)} files")
|
848
904
|
|
849
905
|
# Get project stats
|
850
906
|
stats = scanner.get_project_stats()
|
907
|
+
logger.info(f"Project stats: {stats.get('total_files', 0)} total files")
|
851
908
|
|
852
909
|
return {
|
853
910
|
"missingFiles": missing_paths,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-code-indexer
|
3
|
-
Version: 1.6.
|
3
|
+
Version: 1.6.3
|
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
|
@@ -57,8 +57,8 @@ Dynamic: requires-python
|
|
57
57
|
|
58
58
|
# MCP Code Indexer 🚀
|
59
59
|
|
60
|
-
[](https://badge.fury.io/py/mcp-code-indexer)
|
61
|
+
[](https://pypi.org/project/mcp-code-indexer/)
|
62
62
|
[](https://opensource.org/licenses/MIT)
|
63
63
|
|
64
64
|
A production-ready **Model Context Protocol (MCP) server** that revolutionizes how AI agents navigate and understand codebases. Instead of repeatedly scanning files, agents get instant access to intelligent descriptions, semantic search, and context-aware recommendations.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/data/stop_words_english.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer/middleware/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/dependency_links.txt
RENAMED
File without changes
|
{mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/entry_points.txt
RENAMED
File without changes
|
{mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/requires.txt
RENAMED
File without changes
|
{mcp_code_indexer-1.6.1 → mcp_code_indexer-1.6.3}/src/mcp_code_indexer.egg-info/top_level.txt
RENAMED
File without changes
|