mcp-code-indexer 3.4.0__tar.gz → 3.4.1__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-3.4.0 → mcp_code_indexer-3.4.1}/PKG-INFO +3 -3
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/README.md +2 -2
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/pyproject.toml +1 -1
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/git_hook_handler.py +48 -31
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/LICENSE +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/__init__.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/__main__.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/ask_handler.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/claude_api_handler.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/cleanup_manager.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/data/stop_words_english.txt +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/__init__.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/connection_health.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/database.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/exceptions.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/models.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/retry_executor.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/deepask_handler.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/error_handler.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/file_scanner.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/logging_config.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/main.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/middleware/__init__.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/middleware/error_middleware.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/001_initial.sql +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/002_performance_indexes.sql +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/003_project_overviews.sql +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/004_remove_branch_dependency.sql +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/005_remove_git_remotes.sql +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/query_preprocessor.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/server/__init__.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/server/mcp_server.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/token_counter.py +0 -0
- {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/tools/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: mcp-code-indexer
|
3
|
-
Version: 3.4.
|
3
|
+
Version: 3.4.1
|
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
|
@@ -40,8 +40,8 @@ Description-Content-Type: text/markdown
|
|
40
40
|
|
41
41
|
# MCP Code Indexer 🚀
|
42
42
|
|
43
|
-
[](https://badge.fury.io/py/mcp-code-indexer)
|
44
|
+
[](https://pypi.org/project/mcp-code-indexer/)
|
45
45
|
[](https://opensource.org/licenses/MIT)
|
46
46
|
|
47
47
|
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
|
-
[](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. 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 = "3.4.
|
7
|
+
version = "3.4.1"
|
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"]
|
@@ -88,6 +88,21 @@ class GitHookHandler:
|
|
88
88
|
"OPENROUTER_API_KEY environment variable is required for git hook mode"
|
89
89
|
)
|
90
90
|
|
91
|
+
def _log_and_print(self, message: str, level: str = "info") -> None:
|
92
|
+
"""
|
93
|
+
Log message and also print to stdout for user visibility.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
message: Message to log and print
|
97
|
+
level: Log level (info, warning, error)
|
98
|
+
"""
|
99
|
+
# Log to logger
|
100
|
+
getattr(self.logger, level)(message)
|
101
|
+
|
102
|
+
# Also print to stdout with prefix for visibility
|
103
|
+
prefix = "🔍" if level == "info" else "⚠️" if level == "warning" else "❌"
|
104
|
+
print(f"{prefix} {message}")
|
105
|
+
|
91
106
|
async def run_githook_mode(
|
92
107
|
self,
|
93
108
|
commit_hash: Optional[str] = None,
|
@@ -103,21 +118,20 @@ class GitHookHandler:
|
|
103
118
|
This is the main entry point for git hook functionality.
|
104
119
|
"""
|
105
120
|
try:
|
106
|
-
self.
|
121
|
+
self._log_and_print("=== Git Hook Analysis Started ===")
|
107
122
|
if commit_hash:
|
108
|
-
self.
|
123
|
+
self._log_and_print(f"Mode: Single commit ({commit_hash})")
|
109
124
|
elif commit_range:
|
110
|
-
self.
|
125
|
+
self._log_and_print(
|
111
126
|
f"Mode: Commit range ({commit_range[0]}..{commit_range[1]})"
|
112
127
|
)
|
113
128
|
else:
|
114
|
-
self.
|
129
|
+
self._log_and_print("Mode: Staged changes")
|
115
130
|
|
116
131
|
# Get git info from current directory
|
117
132
|
project_info = await self._identify_project_from_git()
|
118
|
-
self.
|
119
|
-
f"Project
|
120
|
-
f"at {project_info.get('folderPath', 'Unknown')}"
|
133
|
+
self._log_and_print(
|
134
|
+
f"Project: {project_info.get('name', 'Unknown')}"
|
121
135
|
)
|
122
136
|
|
123
137
|
# Get git diff and commit message based on mode
|
@@ -137,25 +151,23 @@ class GitHookHandler:
|
|
137
151
|
|
138
152
|
# Log diff details
|
139
153
|
if not git_diff:
|
140
|
-
self.
|
154
|
+
self._log_and_print("No changes detected, skipping analysis")
|
141
155
|
return
|
142
156
|
|
143
157
|
diff_tokens = self.token_counter.count_tokens(git_diff)
|
144
|
-
self.
|
158
|
+
self._log_and_print(f"Analyzing diff: {diff_tokens:,} tokens")
|
145
159
|
|
146
160
|
# Fetch current state
|
147
|
-
self.
|
161
|
+
self._log_and_print("Fetching current project state...")
|
148
162
|
current_overview = await self._get_project_overview(project_info)
|
149
163
|
current_descriptions = await self._get_all_descriptions(project_info)
|
150
164
|
changed_files = self._extract_changed_files(git_diff)
|
151
165
|
|
152
166
|
if not changed_files:
|
153
|
-
self.
|
167
|
+
self._log_and_print("No files changed, skipping analysis")
|
154
168
|
return
|
155
169
|
|
156
|
-
self.
|
157
|
-
f"Found {len(changed_files)} changed files: {', '.join(changed_files)}"
|
158
|
-
)
|
170
|
+
self._log_and_print(f"Found {len(changed_files)} changed files")
|
159
171
|
overview_tokens = (
|
160
172
|
self.token_counter.count_tokens(current_overview)
|
161
173
|
if current_overview
|
@@ -175,13 +187,23 @@ class GitHookHandler:
|
|
175
187
|
|
176
188
|
# Apply updates to database
|
177
189
|
await self._apply_updates(project_info, updates)
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
)
|
190
|
+
|
191
|
+
# Count actual updates
|
192
|
+
file_update_count = len(updates.get("file_updates", {}))
|
193
|
+
overview_updated = bool(updates.get("overview_update"))
|
194
|
+
|
195
|
+
if file_update_count > 0 or overview_updated:
|
196
|
+
update_parts = []
|
197
|
+
if file_update_count > 0:
|
198
|
+
update_parts.append(f"{file_update_count} file descriptions")
|
199
|
+
if overview_updated:
|
200
|
+
update_parts.append("project overview")
|
201
|
+
self._log_and_print(f"✅ Updated {' and '.join(update_parts)}")
|
202
|
+
else:
|
203
|
+
self._log_and_print("✅ Analysis complete, no updates needed")
|
182
204
|
|
183
205
|
except Exception as e:
|
184
|
-
self.
|
206
|
+
self._log_and_print(f"Git hook analysis failed: {e}", "error")
|
185
207
|
self.logger.error(f"Exception details: {type(e).__name__}: {str(e)}")
|
186
208
|
import traceback
|
187
209
|
|
@@ -230,16 +252,12 @@ class GitHookHandler:
|
|
230
252
|
|
231
253
|
if prompt_tokens <= token_limit:
|
232
254
|
# Use single-stage approach
|
233
|
-
self.
|
255
|
+
self._log_and_print("Using single-stage analysis")
|
234
256
|
result = await self._call_openrouter(single_stage_prompt)
|
235
|
-
self.logger.info("Single-stage analysis completed")
|
236
257
|
return result
|
237
258
|
else:
|
238
259
|
# Fall back to two-stage approach
|
239
|
-
self.
|
240
|
-
f"Single-stage prompt too large ({prompt_tokens} tokens), "
|
241
|
-
f"falling back to two-stage analysis"
|
242
|
-
)
|
260
|
+
self._log_and_print("Using two-stage analysis (large diff)")
|
243
261
|
|
244
262
|
# Try two-stage analysis first
|
245
263
|
try:
|
@@ -250,9 +268,8 @@ class GitHookHandler:
|
|
250
268
|
except GitHookError as e:
|
251
269
|
if "too large" in str(e).lower():
|
252
270
|
# Fall back to chunked processing
|
253
|
-
self.
|
254
|
-
"
|
255
|
-
"falling back to chunked processing"
|
271
|
+
self._log_and_print(
|
272
|
+
"Using chunked processing (very large diff)"
|
256
273
|
)
|
257
274
|
return await self._analyze_with_chunking(
|
258
275
|
git_diff, commit_message, current_overview,
|
@@ -634,7 +651,7 @@ Return ONLY a JSON object:
|
|
634
651
|
Returns:
|
635
652
|
Dict containing file_updates and overview_update
|
636
653
|
"""
|
637
|
-
self.
|
654
|
+
self._log_and_print(
|
638
655
|
f"Starting chunked processing for {len(changed_files)} files"
|
639
656
|
)
|
640
657
|
|
@@ -650,7 +667,7 @@ Return ONLY a JSON object:
|
|
650
667
|
git_diff, changed_files
|
651
668
|
)
|
652
669
|
|
653
|
-
self.
|
670
|
+
self._log_and_print(f"Processing in {chunk_size}-file chunks")
|
654
671
|
|
655
672
|
all_file_updates = {}
|
656
673
|
|
@@ -659,7 +676,7 @@ Return ONLY a JSON object:
|
|
659
676
|
chunk_number = (i // chunk_size) + 1
|
660
677
|
total_chunks = (len(changed_files) + chunk_size - 1) // chunk_size
|
661
678
|
|
662
|
-
self.
|
679
|
+
self._log_and_print(
|
663
680
|
f"Processing chunk {chunk_number}/{total_chunks} "
|
664
681
|
f"({len(chunk_files)} files)"
|
665
682
|
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/claude_api_handler.py
RENAMED
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/data/stop_words_english.txt
RENAMED
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/connection_health.py
RENAMED
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/exceptions.py
RENAMED
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/retry_executor.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/middleware/__init__.py
RENAMED
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/001_initial.sql
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/query_preprocessor.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|