#!/usr/bin/env python3 """ Test script for MCP Python Project Manager Server. Run this to verify the server is working correctly. """ import asyncio import sys import json from pathlib import Path # Add parent directory to path for imports sys.path.insert(0, str(Path(__file__).parent)) from tools import PythonProjectTools, ToolResult from config import config async def test_tools(): """Test all tool implementations.""" print("๐Ÿงช Testing MCP Python Project Manager Tools\n") # Mock server object for testing class MockServer: def list_tools(self): def decorator(func): return func return decorator def call_tool(self): def decorator(func): return func return decorator mock_server = MockServer() tools = PythonProjectTools(mock_server) test_results = [] # Test 1: Get Python environment print("1. Testing get_python_env...") result = await tools.get_python_env() test_results.append(("get_python_env", result.success)) if result.success: print(f" โœ“ Python: {result.data.get('python_version', 'N/A')}") else: print(f" โœ— Error: {result.error}") # Test 2: List packages print("\n2. Testing list_packages...") result = await tools.list_packages(format="json") test_results.append(("list_packages", result.success)) if result.success and result.data: print(f" โœ“ Found {len(result.data)} packages") else: print(f" โš  Warning: {result.message}") # Test 3: Get project info (test with current directory) print("\n3. Testing get_project_info...") current_dir = str(Path(__file__).parent) result = await tools.get_project_info(current_dir) test_results.append(("get_project_info", result.success)) if result.success: print(f" โœ“ Project: {result.data.get('name', 'N/A')}") print(f" โœ“ Python files: {result.data.get('files', {}).get('python_files', 0)}") else: print(f" โœ— Error: {result.error}") # Test 4: List project files print("\n4. Testing list_project_files...") result = await tools.list_project_files(current_dir, pattern="*.py", recursive=False) test_results.append(("list_project_files", result.success)) if result.success: print(f" โœ“ Found {result.data.get('count', 0)} Python files") else: print(f" โœ— Error: {result.error}") # Test 5: Read a file print("\n5. Testing read_file...") config_file = str(Path(__file__).parent / "config.py") result = await tools.read_file(config_file, start_line=1, end_line=10) test_results.append(("read_file", result.success)) if result.success: lines = result.data.get("content", "").count("\n") + 1 print(f" โœ“ Read {lines} lines from config.py") else: print(f" โœ— Error: {result.error}") # Test 6: Lint code (check only) print("\n6. Testing lint_code (check mode)...") result = await tools.lint_code(current_dir, linter="flake8", fix=False) test_results.append(("lint_code", True)) # Success even if linting finds issues if result.success: print(f" โœ“ Linting completed") else: print(f" โš  Linting issues found (expected): {result.message}") # Test 7: Analyze dependencies print("\n7. Testing analyze_dependencies...") result = await tools.analyze_dependencies(current_dir) test_results.append(("analyze_dependencies", result.success)) if result.success: files = result.data.get("files", []) print(f" โœ“ Analyzed {len(files)} requirements file(s)") else: print(f" โš  {result.message}") # Test 8: Get debug info print("\n8. Testing get_debug_info...") result = await tools.get_debug_info() test_results.append(("get_debug_info", result.success)) if result.success: procs = result.data.get("python_processes", []) print(f" โœ“ Found {len(procs)} Python processes") else: print(f" โœ— Error: {result.error}") # Test 9: Format code (check only) print("\n9. Testing format_code (check mode)...") result = await tools.format_code(config_file, formatter="black", check_only=True) test_results.append(("format_code", True)) # Success even if formatting needed if result.success: print(f" โœ“ Format check completed") else: print(f" โš  Format issues found (expected): {result.message}") # Test 10: Execute allowed command print("\n10. Testing execute_command...") result = await tools.execute_command("python --version") test_results.append(("execute_command", result.success)) if result.success: version = result.data.get("stdout", "").strip() print(f" โœ“ {version}") else: print(f" โœ— Error: {result.error}") # Summary print("\n" + "="*60) print("๐Ÿ“Š TEST SUMMARY") print("="*60) passed = sum(1 for _, success in test_results if success) total = len(test_results) for name, success in test_results: status = "โœ“ PASS" if success else "โœ— FAIL" print(f" {status}: {name}") print(f"\n Total: {passed}/{total} tests passed") if passed == total: print("\n๐ŸŽ‰ All tests passed! Server is ready to use.") return 0 else: print(f"\nโš  {total - passed} test(s) failed. Check configuration.") return 1 async def test_tool_call_handler(): """Test the tool call handler directly.""" print("\n๐Ÿ”ง Testing tool call handler...\n") class MockServer: def list_tools(self): def decorator(func): return func return decorator def call_tool(self): def decorator(func): return func return decorator tools = PythonProjectTools(MockServer()) # Test a simple tool call result = await tools.handle_tool_call( "get_python_env", {} ) if result and len(result) > 0: response = json.loads(result[0].text) if response.get("success"): print("โœ“ Tool call handler working correctly") return True else: print(f"โœ— Tool call failed: {response.get('error')}") return False else: print("โœ— No response from tool call handler") return False async def main(): """Main test runner.""" print(f"๐Ÿ MCP Python Project Manager - Test Suite") print(f" Workspace: {config.workspace_root}") print(f" Debug Mode: {config.debug_mode}") print(f" Python: {sys.version.split()[0]}\n") # Run tool tests tool_test_result = await test_tools() # Run handler test handler_result = await test_tool_call_handler() # Final result print("\n" + "="*60) if tool_test_result == 0 and handler_result: print("โœ… ALL TESTS PASSED - Server is ready!") return 0 else: print("โŒ SOME TESTS FAILED - Please check configuration") return 1 if __name__ == "__main__": exit_code = asyncio.run(main()) sys.exit(exit_code)