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.
Files changed (35) hide show
  1. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/PKG-INFO +3 -3
  2. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/README.md +2 -2
  3. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/pyproject.toml +1 -1
  4. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/git_hook_handler.py +48 -31
  5. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/LICENSE +0 -0
  6. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/__init__.py +0 -0
  7. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/__main__.py +0 -0
  8. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/ask_handler.py +0 -0
  9. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/claude_api_handler.py +0 -0
  10. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/cleanup_manager.py +0 -0
  11. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/data/stop_words_english.txt +0 -0
  12. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/__init__.py +0 -0
  13. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/connection_health.py +0 -0
  14. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/database.py +0 -0
  15. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/exceptions.py +0 -0
  16. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/models.py +0 -0
  17. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/database/retry_executor.py +0 -0
  18. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/deepask_handler.py +0 -0
  19. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/error_handler.py +0 -0
  20. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/file_scanner.py +0 -0
  21. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/logging_config.py +0 -0
  22. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/main.py +0 -0
  23. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/middleware/__init__.py +0 -0
  24. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/middleware/error_middleware.py +0 -0
  25. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/001_initial.sql +0 -0
  26. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/002_performance_indexes.sql +0 -0
  27. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/003_project_overviews.sql +0 -0
  28. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/004_remove_branch_dependency.sql +0 -0
  29. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/migrations/005_remove_git_remotes.sql +0 -0
  30. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/query_preprocessor.py +0 -0
  31. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/server/__init__.py +0 -0
  32. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/server/mcp_server.py +0 -0
  33. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/tiktoken_cache/9b5ad71b2ce5302211f9c61530b329a4922fc6a4 +0 -0
  34. {mcp_code_indexer-3.4.0 → mcp_code_indexer-3.4.1}/src/mcp_code_indexer/token_counter.py +0 -0
  35. {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.0
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
- [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?31)](https://badge.fury.io/py/mcp-code-indexer)
44
- [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?31)](https://pypi.org/project/mcp-code-indexer/)
43
+ [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?32)](https://badge.fury.io/py/mcp-code-indexer)
44
+ [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?32)](https://pypi.org/project/mcp-code-indexer/)
45
45
  [![License](https://img.shields.io/badge/License-MIT-blue.svg)](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
- [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?31)](https://badge.fury.io/py/mcp-code-indexer)
4
- [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?31)](https://pypi.org/project/mcp-code-indexer/)
3
+ [![PyPI version](https://badge.fury.io/py/mcp-code-indexer.svg?32)](https://badge.fury.io/py/mcp-code-indexer)
4
+ [![Python](https://img.shields.io/pypi/pyversions/mcp-code-indexer.svg?32)](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 = "3.4.0"
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.logger.info("=== Git Hook Analysis Started ===")
121
+ self._log_and_print("=== Git Hook Analysis Started ===")
107
122
  if commit_hash:
108
- self.logger.info(f"Mode: Single commit ({commit_hash})")
123
+ self._log_and_print(f"Mode: Single commit ({commit_hash})")
109
124
  elif commit_range:
110
- self.logger.info(
125
+ self._log_and_print(
111
126
  f"Mode: Commit range ({commit_range[0]}..{commit_range[1]})"
112
127
  )
113
128
  else:
114
- self.logger.info("Mode: Staged changes")
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.logger.info(
119
- f"Project identified: {project_info.get('name', 'Unknown')} "
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.logger.info("Skipping git hook update - no git diff")
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.logger.info(f"Git diff: {diff_tokens} tokens")
158
+ self._log_and_print(f"Analyzing diff: {diff_tokens:,} tokens")
145
159
 
146
160
  # Fetch current state
147
- self.logger.info("Fetching current project state...")
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.logger.info("No changed files detected in git diff")
167
+ self._log_and_print("No files changed, skipping analysis")
154
168
  return
155
169
 
156
- self.logger.info(
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
- self.logger.info(
180
- f"Git hook update completed successfully for {len(changed_files)} files"
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.logger.error(f"Git hook mode failed: {e}")
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.logger.info("Using single-stage analysis (within token limit)")
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.logger.info(
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.logger.info(
254
- "Two-stage analysis failed due to size, "
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.logger.info(
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.logger.info(f"Using chunk size of {chunk_size} files per chunk")
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.logger.info(
679
+ self._log_and_print(
663
680
  f"Processing chunk {chunk_number}/{total_chunks} "
664
681
  f"({len(chunk_files)} files)"
665
682
  )