- Comprehensive Microsoft Office document processing server
- Support for Word (.docx, .doc), Excel (.xlsx, .xls), PowerPoint (.pptx, .ppt), CSV
- 6 universal tools: extract_text, extract_images, extract_metadata, detect_office_format, analyze_document_health, get_supported_formats
- Multi-library fallback system for robust processing
- URL support with intelligent caching
- Legacy Office format support (97-2003)
- FastMCP integration with async architecture
- Production ready with comprehensive documentation
🤖 Generated with Claude Code (claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
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 mcp_office_tools
|
|
print(f"✅ Package imported successfully - Version: {mcp_office_tools.__version__}")
|
|
|
|
# Test server import
|
|
from mcp_office_tools.server import app
|
|
print("✅ Server module imported successfully")
|
|
|
|
# Test utils import
|
|
from mcp_office_tools.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 mcp_office_tools.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 mcp_office_tools.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 mcp_office_tools.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 mcp_office_tools.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 mcp-office-tools")
|
|
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()) |