🏗️ Convert to modern src-layout structure and cleanup project
- Move enhanced_mcp package to src/enhanced_mcp/ (Python best practice) - Update pyproject.toml for src-layout configuration - Fix test imports and paths for new structure - Remove unnecessary directories: config/, scripts/ - Update CLAUDE.md documentation for src-layout - Maintain full functionality with 50+ tools across 14 modules Benefits: - Better separation between source and development files - Prevents accidental imports of development versions - Follows modern Python packaging standards - Improved testing isolation - Professional package structure ready for distribution
This commit is contained in:
parent
a6d3809cec
commit
3acc5fa9fd
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"comment": "Example configuration for Claude Desktop",
|
|
||||||
"comment2": "Copy this to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)",
|
|
||||||
"comment3": "or %APPDATA%\\Claude\\claude_desktop_config.json (Windows)",
|
|
||||||
"mcpServers": {
|
|
||||||
"enhanced-tools": {
|
|
||||||
"command": "enhanced-mcp",
|
|
||||||
"cwd": "/home/rpm/claude/enhanced-mcp-tools"
|
|
||||||
},
|
|
||||||
"enhanced-tools-uv": {
|
|
||||||
"comment": "Alternative using uv (if enhanced-mcp not in PATH)",
|
|
||||||
"command": "uv",
|
|
||||||
"args": ["run", "enhanced-mcp"],
|
|
||||||
"cwd": "/home/rpm/claude/enhanced-mcp-tools"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,6 +29,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["src"]
|
||||||
include = ["enhanced_mcp*"]
|
include = ["enhanced_mcp*"]
|
||||||
exclude = ["tests*", "docs*", "examples*", "scripts*", "config*"]
|
exclude = ["tests*", "docs*", "examples*", "scripts*", "config*"]
|
||||||
|
|
||||||
@ -88,8 +89,8 @@ ignore = [
|
|||||||
|
|
||||||
# Additional ignore patterns for star imports in specific files
|
# Additional ignore patterns for star imports in specific files
|
||||||
[tool.ruff.lint.per-file-ignores]
|
[tool.ruff.lint.per-file-ignores]
|
||||||
"enhanced_mcp/*/base.py" = ["F403", "F405"]
|
"src/enhanced_mcp/*/base.py" = ["F403", "F405"]
|
||||||
"enhanced_mcp/*" = ["F403", "F405"] # Allow star imports throughout the enhanced_mcp package
|
"src/enhanced_mcp/*" = ["F403", "F405"] # Allow star imports throughout the enhanced_mcp package
|
||||||
"tests/*" = ["E501", "F401", "F811", "F403", "F405"]
|
"tests/*" = ["E501", "F401", "F811", "F403", "F405"]
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
# Scripts
|
|
||||||
|
|
||||||
This directory contains utility and analysis scripts for the Enhanced MCP Tools project.
|
|
||||||
|
|
||||||
## Available Scripts
|
|
||||||
|
|
||||||
- **analyze_essential_files.py** - Analyzes essential project files and dependencies
|
|
||||||
- **compare_implementation.py** - Compares different implementation approaches
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Scripts can typically be run directly from the project root:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python scripts/analyze_essential_files.py
|
|
||||||
python scripts/compare_implementation.py
|
|
||||||
```
|
|
||||||
|
|
||||||
Some scripts may require specific dependencies or the virtual environment:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
uv sync # Install dependencies first
|
|
||||||
python scripts/analyze_essential_files.py
|
|
||||||
```
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
These scripts are development utilities for:
|
|
||||||
- Project analysis and validation
|
|
||||||
- Implementation comparison
|
|
||||||
- Development workflow automation
|
|
||||||
- Code quality assessment
|
|
@ -1,181 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Essential Files Analysis for Enhanced MCP Tools
|
|
||||||
|
|
||||||
This script analyzes which files are absolutely essential vs optional.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
def analyze_essential_files():
|
|
||||||
"""Analyze which files are essential for running the server"""
|
|
||||||
|
|
||||||
print("📦 Enhanced MCP Tools - Essential Files Analysis")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
enhanced_mcp_dir = Path("enhanced_mcp")
|
|
||||||
|
|
||||||
# Core Infrastructure (ABSOLUTELY ESSENTIAL)
|
|
||||||
core_essential = [
|
|
||||||
"enhanced_mcp/__init__.py",
|
|
||||||
"enhanced_mcp/base.py",
|
|
||||||
"enhanced_mcp/mcp_server.py",
|
|
||||||
]
|
|
||||||
|
|
||||||
print("\n🔴 ABSOLUTELY ESSENTIAL (Core Infrastructure):")
|
|
||||||
print("-" * 50)
|
|
||||||
for file_path in core_essential:
|
|
||||||
if os.path.exists(file_path):
|
|
||||||
size = os.path.getsize(file_path)
|
|
||||||
print(f"✅ {file_path:<35} ({size:,} bytes)")
|
|
||||||
else:
|
|
||||||
print(f"❌ {file_path:<35} (MISSING!)")
|
|
||||||
|
|
||||||
# Currently Required (due to imports in mcp_server.py)
|
|
||||||
currently_required = [
|
|
||||||
"enhanced_mcp/diff_patch.py",
|
|
||||||
"enhanced_mcp/intelligent_completion.py",
|
|
||||||
"enhanced_mcp/asciinema_integration.py",
|
|
||||||
"enhanced_mcp/sneller_analytics.py",
|
|
||||||
"enhanced_mcp/git_integration.py",
|
|
||||||
"enhanced_mcp/file_operations.py",
|
|
||||||
"enhanced_mcp/archive_compression.py",
|
|
||||||
"enhanced_mcp/workflow_tools.py",
|
|
||||||
]
|
|
||||||
|
|
||||||
print("\n🟡 CURRENTLY REQUIRED (due to imports):")
|
|
||||||
print("-" * 50)
|
|
||||||
total_size = 0
|
|
||||||
for file_path in currently_required:
|
|
||||||
if os.path.exists(file_path):
|
|
||||||
size = os.path.getsize(file_path)
|
|
||||||
total_size += size
|
|
||||||
print(f"✅ {file_path:<35} ({size:,} bytes)")
|
|
||||||
else:
|
|
||||||
print(f"❌ {file_path:<35} (MISSING!)")
|
|
||||||
|
|
||||||
print(f"\nTotal size of ALL modules: {total_size:,} bytes")
|
|
||||||
|
|
||||||
# Potentially Optional (could be made optional with refactoring)
|
|
||||||
potentially_optional = [
|
|
||||||
("asciinema_integration.py", "Terminal recording - specialized use case"),
|
|
||||||
("sneller_analytics.py", "High-performance SQL - specialized use case"),
|
|
||||||
("archive_compression.py", "Archive operations - can use standard tools"),
|
|
||||||
("diff_patch.py", "Diff/patch - basic functionality, could be optional"),
|
|
||||||
]
|
|
||||||
|
|
||||||
print("\n🟢 POTENTIALLY OPTIONAL (with refactoring):")
|
|
||||||
print("-" * 50)
|
|
||||||
for filename, description in potentially_optional:
|
|
||||||
file_path = f"enhanced_mcp/{filename}"
|
|
||||||
if os.path.exists(file_path):
|
|
||||||
size = os.path.getsize(file_path)
|
|
||||||
print(f"🔄 {filename:<35} - {description}")
|
|
||||||
print(f" {file_path:<35} ({size:,} bytes)")
|
|
||||||
|
|
||||||
# Most Essential Core
|
|
||||||
most_essential = [
|
|
||||||
("intelligent_completion.py", "AI-powered tool recommendations - core feature"),
|
|
||||||
("git_integration.py", "Git operations - fundamental for development"),
|
|
||||||
("file_operations.py", "File operations - basic functionality"),
|
|
||||||
("workflow_tools.py", "Development workflow - essential utilities"),
|
|
||||||
]
|
|
||||||
|
|
||||||
print("\n🔥 MOST ESSENTIAL (beyond core infrastructure):")
|
|
||||||
print("-" * 50)
|
|
||||||
essential_size = 0
|
|
||||||
for filename, description in most_essential:
|
|
||||||
file_path = f"enhanced_mcp/{filename}"
|
|
||||||
if os.path.exists(file_path):
|
|
||||||
size = os.path.getsize(file_path)
|
|
||||||
essential_size += size
|
|
||||||
print(f"⭐ {filename:<35} - {description}")
|
|
||||||
print(f" {file_path:<35} ({size:,} bytes)")
|
|
||||||
|
|
||||||
# Calculate minimal vs full
|
|
||||||
core_size = sum(os.path.getsize(f) for f in core_essential if os.path.exists(f))
|
|
||||||
|
|
||||||
print("\n📊 SIZE ANALYSIS:")
|
|
||||||
print("-" * 50)
|
|
||||||
print(f"Core Infrastructure Only: {core_size:,} bytes")
|
|
||||||
print(f"Minimal Essential: {core_size + essential_size:,} bytes")
|
|
||||||
print(f"Full System (Current): {core_size + total_size:,} bytes")
|
|
||||||
|
|
||||||
return {
|
|
||||||
"core_essential": core_essential,
|
|
||||||
"currently_required": currently_required,
|
|
||||||
"most_essential": [f"enhanced_mcp/{f}" for f, _ in most_essential],
|
|
||||||
"potentially_optional": [f"enhanced_mcp/{f}" for f, _ in potentially_optional],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def show_minimal_server_example():
|
|
||||||
"""Show how to create a minimal server"""
|
|
||||||
|
|
||||||
print("\n🚀 MINIMAL SERVER EXAMPLE:")
|
|
||||||
print("-" * 50)
|
|
||||||
|
|
||||||
minimal_example = '''
|
|
||||||
# minimal_mcp_server.py - Example of absolute minimum files needed
|
|
||||||
|
|
||||||
from enhanced_mcp.base import *
|
|
||||||
from enhanced_mcp.intelligent_completion import IntelligentCompletion
|
|
||||||
from enhanced_mcp.git_integration import GitIntegration
|
|
||||||
from enhanced_mcp.file_operations import EnhancedFileOperations
|
|
||||||
|
|
||||||
class MinimalMCPServer(MCPMixin):
|
|
||||||
"""Minimal MCP server with only essential tools"""
|
|
||||||
|
|
||||||
def __init__(self, name: str = "Minimal MCP Server"):
|
|
||||||
super().__init__()
|
|
||||||
self.name = name
|
|
||||||
|
|
||||||
# Only the most essential tools
|
|
||||||
self.completion = IntelligentCompletion() # AI recommendations
|
|
||||||
self.git = GitIntegration() # Git operations
|
|
||||||
self.file_ops = EnhancedFileOperations() # File operations
|
|
||||||
|
|
||||||
self.tools = {
|
|
||||||
'completion': self.completion,
|
|
||||||
'git': self.git,
|
|
||||||
'file_ops': self.file_ops
|
|
||||||
}
|
|
||||||
|
|
||||||
def create_minimal_server():
|
|
||||||
server = FastMCP("Minimal Enhanced MCP")
|
|
||||||
tool_server = MinimalMCPServer()
|
|
||||||
server.include_router(tool_server, prefix="tools")
|
|
||||||
return server
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
server = create_minimal_server()
|
|
||||||
server.run()
|
|
||||||
'''
|
|
||||||
|
|
||||||
print(minimal_example)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.chdir("/home/rpm/claude/enhanced-mcp-tools")
|
|
||||||
results = analyze_essential_files()
|
|
||||||
show_minimal_server_example()
|
|
||||||
|
|
||||||
print("\n🎯 SUMMARY:")
|
|
||||||
print("=" * 60)
|
|
||||||
print("✅ ABSOLUTE MINIMUM to run ANY server:")
|
|
||||||
for f in results["core_essential"]:
|
|
||||||
print(f" - {f}")
|
|
||||||
|
|
||||||
print("\n✅ PRACTICAL MINIMUM for useful server:")
|
|
||||||
for f in results["most_essential"]:
|
|
||||||
print(f" - {f}")
|
|
||||||
|
|
||||||
print("\n🔄 CURRENTLY ALL REQUIRED due to mcp_server.py imports:")
|
|
||||||
print(" - All 11 modules are imported and instantiated")
|
|
||||||
|
|
||||||
print("\n💡 TO MAKE MODULES OPTIONAL:")
|
|
||||||
print(" - Refactor mcp_server.py to use conditional imports")
|
|
||||||
print(" - Add configuration to enable/disable modules")
|
|
||||||
print(" - Use dependency injection pattern")
|
|
@ -1,91 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Comparison script to validate that all initial design functionality is implemented
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
def extract_tool_names_from_file(file_path):
|
|
||||||
"""Extract tool names from a Python file using regex"""
|
|
||||||
tools = []
|
|
||||||
try:
|
|
||||||
with open(file_path) as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Find all @mcp_tool decorators
|
|
||||||
tool_patterns = re.findall(r'@mcp_tool\(name="([^"]+)"', content)
|
|
||||||
tools.extend(tool_patterns)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error reading {file_path}: {e}")
|
|
||||||
|
|
||||||
return tools
|
|
||||||
|
|
||||||
|
|
||||||
def compare_implementations():
|
|
||||||
"""Compare the initial design with current implementation"""
|
|
||||||
|
|
||||||
print("Enhanced MCP Tools - Implementation Validation")
|
|
||||||
print("=" * 60)
|
|
||||||
|
|
||||||
# Extract tools from initial design
|
|
||||||
initial_design_file = Path("/home/rpm/claude/enhanced-mcp-tools/.initial-design/scaffold.py")
|
|
||||||
initial_tools = extract_tool_names_from_file(initial_design_file)
|
|
||||||
|
|
||||||
# Extract tools from current implementation (enhanced_mcp modules)
|
|
||||||
enhanced_mcp_dir = Path("/home/rpm/claude/enhanced-mcp-tools/enhanced_mcp")
|
|
||||||
current_tools = []
|
|
||||||
|
|
||||||
# Extract tools from all enhanced_mcp modules
|
|
||||||
for module_file in enhanced_mcp_dir.glob("*.py"):
|
|
||||||
if module_file.name != "__init__.py":
|
|
||||||
module_tools = extract_tool_names_from_file(module_file)
|
|
||||||
current_tools.extend(module_tools)
|
|
||||||
|
|
||||||
print(f"\nInitial Design Tools: {len(initial_tools)}")
|
|
||||||
print(f"Current Implementation Tools: {len(current_tools)}")
|
|
||||||
|
|
||||||
# Compare tools
|
|
||||||
initial_set = set(initial_tools)
|
|
||||||
current_set = set(current_tools)
|
|
||||||
|
|
||||||
missing_tools = initial_set - current_set
|
|
||||||
extra_tools = current_set - initial_set
|
|
||||||
common_tools = initial_set & current_set
|
|
||||||
|
|
||||||
print(f"\nCommon Tools: {len(common_tools)}")
|
|
||||||
print(f"Missing from Implementation: {len(missing_tools)}")
|
|
||||||
print(f"Extra in Implementation: {len(extra_tools)}")
|
|
||||||
|
|
||||||
if missing_tools:
|
|
||||||
print("\n❌ Missing Tools:")
|
|
||||||
for tool in sorted(missing_tools):
|
|
||||||
print(f" - {tool}")
|
|
||||||
|
|
||||||
if extra_tools:
|
|
||||||
print("\n✅ Extra Tools (improvements):")
|
|
||||||
for tool in sorted(extra_tools):
|
|
||||||
print(f" - {tool}")
|
|
||||||
|
|
||||||
if common_tools:
|
|
||||||
print(f"\n✅ Implemented Tools ({len(common_tools)}):")
|
|
||||||
for tool in sorted(common_tools):
|
|
||||||
print(f" - {tool}")
|
|
||||||
|
|
||||||
# Overall status
|
|
||||||
print("\n" + "=" * 60)
|
|
||||||
coverage = len(common_tools) / len(initial_tools) * 100 if initial_tools else 0
|
|
||||||
print(f"Implementation Coverage: {coverage:.1f}%")
|
|
||||||
|
|
||||||
if coverage >= 100:
|
|
||||||
print("✅ ALL initial design tools are implemented!")
|
|
||||||
elif coverage >= 80:
|
|
||||||
print("✅ Good coverage - most tools implemented")
|
|
||||||
else:
|
|
||||||
print("⚠️ Significant tools still need implementation")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
compare_implementations()
|
|
@ -11,11 +11,11 @@ def test_package_structure():
|
|||||||
"""Test that the package structure is correct."""
|
"""Test that the package structure is correct."""
|
||||||
print("=== Package Structure Test ===")
|
print("=== Package Structure Test ===")
|
||||||
|
|
||||||
# Check core files exist
|
# Check core files exist in src-layout
|
||||||
required_files = [
|
required_files = [
|
||||||
"enhanced_mcp/__init__.py",
|
"src/enhanced_mcp/__init__.py",
|
||||||
"enhanced_mcp/base.py",
|
"src/enhanced_mcp/base.py",
|
||||||
"enhanced_mcp/mcp_server.py",
|
"src/enhanced_mcp/mcp_server.py",
|
||||||
"pyproject.toml"
|
"pyproject.toml"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Add the project root to the Python path
|
# With src-layout, the package should be properly installed in development mode
|
||||||
project_root = Path(__file__).parent.parent # Go up one more level to get to project root
|
# project_root is still needed for file structure tests
|
||||||
sys.path.insert(0, str(project_root))
|
project_root = Path(__file__).parent.parent
|
||||||
|
|
||||||
|
|
||||||
def test_imports():
|
def test_imports():
|
||||||
@ -118,8 +118,8 @@ def test_structure():
|
|||||||
print("\n🧪 Testing architecture structure...")
|
print("\n🧪 Testing architecture structure...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Check that we have the expected file structure
|
# Check that we have the expected file structure in src-layout
|
||||||
enhanced_mcp_dir = project_root / "enhanced_mcp"
|
enhanced_mcp_dir = project_root / "src" / "enhanced_mcp"
|
||||||
expected_files = [
|
expected_files = [
|
||||||
"__init__.py",
|
"__init__.py",
|
||||||
"base.py",
|
"base.py",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user