feat: complete redesign to v2.4.0 - Claude's ultimate development partner

Major redesign of Gemini MCP Server with modular architecture:

- Removed all emoji characters from tool outputs for clean terminal display
- Kept review category emojis (🔴🟠🟡🟢) per user preference
- Added 4 specialized tools:
  - think_deeper: Extended reasoning and problem-solving (temp 0.7)
  - review_code: Professional code review with severity levels (temp 0.2)
  - debug_issue: Root cause analysis and debugging (temp 0.2)
  - analyze: General-purpose file analysis (temp 0.2)
- Modular architecture with base tool class and Pydantic models
- Verbose tool descriptions with natural language triggers
- Updated README with comprehensive examples and real-world use cases
- All 25 tests passing, type checking clean, critical linting clean

BREAKING CHANGE: Removed analyze_code tool in favor of specialized tools

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Fahad
2025-06-08 22:30:45 +04:00
parent 8754f3c544
commit 1aa19548d1
25 changed files with 2059 additions and 1828 deletions

13
utils/__init__.py Normal file
View File

@@ -0,0 +1,13 @@
"""
Utility functions for Gemini MCP Server
"""
from .file_utils import read_files, read_file_content
from .token_utils import estimate_tokens, check_token_limit
__all__ = [
"read_files",
"read_file_content",
"estimate_tokens",
"check_token_limit",
]

63
utils/file_utils.py Normal file
View File

@@ -0,0 +1,63 @@
"""
File reading utilities
"""
from pathlib import Path
from typing import List, Tuple, Optional
def read_file_content(file_path: str) -> str:
"""Read a single file and format it for Gemini"""
path = Path(file_path)
try:
# Check if path exists and is a file
if not path.exists():
return f"\n--- FILE NOT FOUND: {file_path} ---\nError: File does not exist\n--- END FILE ---\n"
if not path.is_file():
return f"\n--- NOT A FILE: {file_path} ---\nError: Path is not a file\n--- END FILE ---\n"
# Read the file
with open(path, "r", encoding="utf-8") as f:
content = f.read()
# Format with clear delimiters for Gemini
return f"\n--- BEGIN FILE: {file_path} ---\n{content}\n--- END FILE: {file_path} ---\n"
except Exception as e:
return f"\n--- ERROR READING FILE: {file_path} ---\nError: {str(e)}\n--- END FILE ---\n"
def read_files(
file_paths: List[str], code: Optional[str] = None
) -> Tuple[str, str]:
"""
Read multiple files and optional direct code.
Returns: (full_content, brief_summary)
"""
content_parts = []
summary_parts = []
# Process files
if file_paths:
summary_parts.append(f"Reading {len(file_paths)} file(s)")
for file_path in file_paths:
content = read_file_content(file_path)
content_parts.append(content)
# Add direct code if provided
if code:
formatted_code = (
f"\n--- BEGIN DIRECT CODE ---\n{code}\n--- END DIRECT CODE ---\n"
)
content_parts.append(formatted_code)
code_preview = code[:50] + "..." if len(code) > 50 else code
summary_parts.append(f"Direct code: {code_preview}")
full_content = "\n\n".join(content_parts)
summary = (
" | ".join(summary_parts) if summary_parts else "No input provided"
)
return full_content, summary

20
utils/token_utils.py Normal file
View File

@@ -0,0 +1,20 @@
"""
Token counting utilities
"""
from typing import Tuple
from config import MAX_CONTEXT_TOKENS
def estimate_tokens(text: str) -> int:
"""Estimate token count (rough: 1 token ≈ 4 characters)"""
return len(text) // 4
def check_token_limit(text: str) -> Tuple[bool, int]:
"""
Check if text exceeds token limit.
Returns: (is_within_limit, estimated_tokens)
"""
estimated = estimate_tokens(text)
return estimated <= MAX_CONTEXT_TOKENS, estimated