🏗️ 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:
Ryan Malloy 2025-09-22 10:38:08 -06:00
parent a6d3809cec
commit 3acc5fa9fd
18 changed files with 12 additions and 332 deletions

View File

@ -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"
}
}
}

View File

@ -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]

View File

@ -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

View File

@ -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")

View File

@ -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()

View File

@ -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"
] ]

View File

@ -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",