Some checks are pending
Test Dashboard / test-and-dashboard (push) Waiting to run
Named for Milton Waddams, who was relocated to the basement with boxes of legacy documents. He handles the .doc and .xls files from 1997 that nobody else wants to touch. - Rename package from mcp-office-tools to mcwaddams - Update author to Ryan Malloy - Update all imports and references - Add Office Space themed README narrative - All 53 tests passing
257 lines
7.7 KiB
Python
257 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify MCP Office Tools installation and basic functionality."""
|
|
|
|
import asyncio
|
|
import sys
|
|
import tempfile
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# Add the package to Python path for local testing
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
|
|
|
|
|
def create_sample_csv():
|
|
"""Create a sample CSV file for testing."""
|
|
temp_file = tempfile.NamedTemporaryFile(suffix='.csv', delete=False, mode='w')
|
|
temp_file.write("""Name,Age,Department,Salary
|
|
John Smith,30,Engineering,75000
|
|
Jane Doe,25,Marketing,65000
|
|
Bob Johnson,35,Sales,70000
|
|
Alice Brown,28,Engineering,80000
|
|
Charlie Wilson,32,HR,60000""")
|
|
temp_file.close()
|
|
return temp_file.name
|
|
|
|
|
|
def test_import():
|
|
"""Test that the package can be imported."""
|
|
print("🔍 Testing package import...")
|
|
|
|
try:
|
|
import mcwaddams
|
|
print(f"✅ Package imported successfully - Version: {mcwaddams.__version__}")
|
|
|
|
# Test server import
|
|
from mcwaddams.server import app
|
|
print("✅ Server module imported successfully")
|
|
|
|
# Test utils import
|
|
from mcwaddams.utils import OfficeFileError, get_supported_extensions
|
|
print("✅ Utils module imported successfully")
|
|
|
|
# Test supported extensions
|
|
extensions = get_supported_extensions()
|
|
print(f"✅ Supported extensions: {', '.join(extensions)}")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Import failed: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
async def test_utils():
|
|
"""Test utility functions."""
|
|
print("\n🔧 Testing utility functions...")
|
|
|
|
try:
|
|
from mcwaddams.utils import (
|
|
detect_file_format,
|
|
validate_office_path,
|
|
OfficeFileError
|
|
)
|
|
|
|
# Test format detection with a CSV file
|
|
csv_file = create_sample_csv()
|
|
|
|
try:
|
|
# Test file path validation
|
|
validated_path = validate_office_path(csv_file)
|
|
print(f"✅ File path validation successful: {os.path.basename(validated_path)}")
|
|
|
|
# Test format detection
|
|
format_info = detect_file_format(csv_file)
|
|
print(f"✅ Format detection successful: {format_info['format_name']}")
|
|
print(f"📂 Category: {format_info['category']}")
|
|
print(f"📊 File size: {format_info['file_size']} bytes")
|
|
|
|
# Test invalid file handling
|
|
try:
|
|
validate_office_path("/nonexistent/file.docx")
|
|
print("❌ Should have raised error for nonexistent file")
|
|
return False
|
|
except OfficeFileError:
|
|
print("✅ Correctly handles nonexistent files")
|
|
|
|
return True
|
|
|
|
finally:
|
|
os.unlink(csv_file)
|
|
|
|
except Exception as e:
|
|
print(f"❌ Utils test failed: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
def test_server_structure():
|
|
"""Test server structure and tools."""
|
|
print("\n🖥️ Testing server structure...")
|
|
|
|
try:
|
|
from mcwaddams.server import app
|
|
|
|
# Check that app has tools
|
|
if hasattr(app, '_tools'):
|
|
tools = app._tools
|
|
print(f"✅ Server has {len(tools)} tools registered")
|
|
|
|
# List tool names
|
|
tool_names = list(tools.keys()) if isinstance(tools, dict) else [str(tool) for tool in tools]
|
|
print(f"🔧 Available tools: {', '.join(tool_names[:5])}...") # Show first 5
|
|
|
|
else:
|
|
print("⚠️ Cannot access tool registry (FastMCP internal structure)")
|
|
|
|
# Test that the app can be created
|
|
print("✅ FastMCP app structure is valid")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Server structure test failed: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
async def test_caching():
|
|
"""Test caching functionality."""
|
|
print("\n📦 Testing caching functionality...")
|
|
|
|
try:
|
|
from mcwaddams.utils.caching import OfficeFileCache, get_cache
|
|
|
|
# Test cache creation
|
|
cache = get_cache()
|
|
print("✅ Cache instance created successfully")
|
|
|
|
# Test cache stats
|
|
stats = cache.get_cache_stats()
|
|
print(f"✅ Cache stats: {stats['total_files']} files, {stats['total_size_mb']} MB")
|
|
|
|
# Test URL validation
|
|
from mcwaddams.utils.validation import is_url
|
|
|
|
assert is_url("https://example.com/file.docx")
|
|
assert not is_url("/local/path/file.docx")
|
|
print("✅ URL validation working correctly")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Caching test failed: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
def test_dependencies():
|
|
"""Test that key dependencies are available."""
|
|
print("\n📚 Testing dependencies...")
|
|
|
|
dependencies = [
|
|
("fastmcp", "FastMCP framework"),
|
|
("docx", "python-docx for Word documents"),
|
|
("openpyxl", "openpyxl for Excel files"),
|
|
("pptx", "python-pptx for PowerPoint files"),
|
|
("pandas", "pandas for data processing"),
|
|
("aiohttp", "aiohttp for async HTTP"),
|
|
("aiofiles", "aiofiles for async file operations"),
|
|
("PIL", "Pillow for image processing")
|
|
]
|
|
|
|
success_count = 0
|
|
|
|
for module_name, description in dependencies:
|
|
try:
|
|
__import__(module_name)
|
|
print(f"✅ {description}")
|
|
success_count += 1
|
|
except ImportError:
|
|
print(f"❌ {description} - NOT AVAILABLE")
|
|
|
|
optional_dependencies = [
|
|
("magic", "python-magic for MIME detection (optional)"),
|
|
("olefile", "olefile for legacy Office formats"),
|
|
("mammoth", "mammoth for enhanced Word processing"),
|
|
("xlrd", "xlrd for legacy Excel files")
|
|
]
|
|
|
|
for module_name, description in optional_dependencies:
|
|
try:
|
|
__import__(module_name)
|
|
print(f"✅ {description}")
|
|
except ImportError:
|
|
print(f"⚠️ {description} - OPTIONAL")
|
|
|
|
return success_count == len(dependencies)
|
|
|
|
|
|
async def main():
|
|
"""Main verification function."""
|
|
print("🚀 MCP Office Tools - Installation Verification")
|
|
print("=" * 60)
|
|
|
|
success_count = 0
|
|
total_tests = 0
|
|
|
|
# Test import
|
|
total_tests += 1
|
|
if test_import():
|
|
success_count += 1
|
|
|
|
# Test utilities
|
|
total_tests += 1
|
|
if await test_utils():
|
|
success_count += 1
|
|
|
|
# Test server structure
|
|
total_tests += 1
|
|
if test_server_structure():
|
|
success_count += 1
|
|
|
|
# Test caching
|
|
total_tests += 1
|
|
if await test_caching():
|
|
success_count += 1
|
|
|
|
# Test dependencies
|
|
total_tests += 1
|
|
if test_dependencies():
|
|
success_count += 1
|
|
|
|
# Summary
|
|
print("\n" + "=" * 60)
|
|
print(f"📊 Verification Results: {success_count}/{total_tests} tests passed")
|
|
|
|
if success_count == total_tests:
|
|
print("🎉 Installation verified successfully!")
|
|
print("✅ MCP Office Tools is ready to use.")
|
|
print("\n🚀 Next steps:")
|
|
print(" 1. Run the MCP server: uv run mcwaddams")
|
|
print(" 2. Add to Claude Desktop config")
|
|
print(" 3. Test with Office documents")
|
|
return 0
|
|
else:
|
|
print("⚠️ Some verification tests failed.")
|
|
print("📝 Check the output above for details.")
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
exit_code = asyncio.run(main()) |