Rename source directory kicad_mcp/ → mckicad/, update all imports, pyproject.toml metadata, documentation references, Makefile targets, and .gitignore paths. All 195 tests pass.
268 lines
9.8 KiB
Python
268 lines
9.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test MCP tools through the server interface.
|
|
This validates that our MCP server exposes all tools correctly.
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
from pathlib import Path
|
|
|
|
# Add the mckicad module to path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
# Import our server and tools
|
|
from mckicad.server import create_server
|
|
|
|
def test_server_initialization():
|
|
"""Test MCP server initialization and tool registration."""
|
|
print("🔧 Testing MCP Server Initialization")
|
|
print("-" * 40)
|
|
|
|
try:
|
|
# Create server instance
|
|
server = create_server()
|
|
print(f"✅ MCP server created: {server}")
|
|
|
|
# Check that server has the required components
|
|
print(f"✅ Server type: {type(server).__name__}")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Server initialization failed: {e}")
|
|
return False
|
|
|
|
def test_tool_registration():
|
|
"""Test that all tools are properly registered."""
|
|
print("\n📋 Testing Tool Registration")
|
|
print("-" * 40)
|
|
|
|
try:
|
|
# Import and test tool registration functions
|
|
from mckicad.tools.analysis_tools import register_analysis_tools
|
|
from mckicad.tools.project_tools import register_project_tools
|
|
from mckicad.tools.drc_tools import register_drc_tools
|
|
from mckicad.tools.bom_tools import register_bom_tools
|
|
from mckicad.tools.netlist_tools import register_netlist_tools
|
|
from mckicad.tools.pattern_tools import register_pattern_tools
|
|
from mckicad.tools.export_tools import register_export_tools
|
|
|
|
# Test that registration functions exist
|
|
registration_functions = [
|
|
("analysis_tools", register_analysis_tools),
|
|
("project_tools", register_project_tools),
|
|
("drc_tools", register_drc_tools),
|
|
("bom_tools", register_bom_tools),
|
|
("netlist_tools", register_netlist_tools),
|
|
("pattern_tools", register_pattern_tools),
|
|
("export_tools", register_export_tools),
|
|
]
|
|
|
|
print(f"📊 Tool Categories Available:")
|
|
for name, func in registration_functions:
|
|
print(f" ✅ {name}: {func.__name__}()")
|
|
|
|
print(f"✅ All tool registration functions available!")
|
|
return True
|
|
|
|
except ImportError as e:
|
|
print(f"❌ Tool import failed: {e}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Tool registration test failed: {e}")
|
|
return False
|
|
|
|
def test_resource_registration():
|
|
"""Test that all resources are properly registered."""
|
|
print("\n📄 Testing Resource Registration")
|
|
print("-" * 40)
|
|
|
|
try:
|
|
# Import resource registration functions
|
|
from mckicad.resources.projects import register_project_resources
|
|
from mckicad.resources.files import register_file_resources
|
|
from mckicad.resources.drc_resources import register_drc_resources
|
|
from mckicad.resources.bom_resources import register_bom_resources
|
|
from mckicad.resources.netlist_resources import register_netlist_resources
|
|
|
|
resource_functions = [
|
|
("project_resources", register_project_resources),
|
|
("file_resources", register_file_resources),
|
|
("drc_resources", register_drc_resources),
|
|
("bom_resources", register_bom_resources),
|
|
("netlist_resources", register_netlist_resources),
|
|
]
|
|
|
|
print(f"📊 Resource Categories Available:")
|
|
for name, func in resource_functions:
|
|
print(f" ✅ {name}: {func.__name__}()")
|
|
|
|
print(f"✅ All resource registration functions available!")
|
|
return True
|
|
|
|
except ImportError as e:
|
|
print(f"❌ Resource import failed: {e}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Resource registration test failed: {e}")
|
|
return False
|
|
|
|
def test_prompt_registration():
|
|
"""Test that all prompts are properly registered."""
|
|
print("\n💬 Testing Prompt Registration")
|
|
print("-" * 40)
|
|
|
|
try:
|
|
# Import prompt registration functions
|
|
from mckicad.prompts.templates import register_prompts
|
|
from mckicad.prompts.drc_prompt import register_drc_prompts
|
|
from mckicad.prompts.bom_prompts import register_bom_prompts
|
|
from mckicad.prompts.pattern_prompts import register_pattern_prompts
|
|
|
|
prompt_functions = [
|
|
("templates", register_prompts),
|
|
("drc_prompts", register_drc_prompts),
|
|
("bom_prompts", register_bom_prompts),
|
|
("pattern_prompts", register_pattern_prompts),
|
|
]
|
|
|
|
print(f"📊 Prompt Categories Available:")
|
|
for name, func in prompt_functions:
|
|
print(f" ✅ {name}: {func.__name__}()")
|
|
|
|
print(f"✅ All prompt registration functions available!")
|
|
return True
|
|
|
|
except ImportError as e:
|
|
print(f"❌ Prompt import failed: {e}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"❌ Prompt registration test failed: {e}")
|
|
return False
|
|
|
|
def test_core_functionality():
|
|
"""Test core functionality imports and basic operations."""
|
|
print("\n⚙️ Testing Core Functionality")
|
|
print("-" * 40)
|
|
|
|
try:
|
|
# Test key utility imports
|
|
from mckicad.utils.file_utils import get_project_files
|
|
from mckicad.utils.ipc_client import KiCadIPCClient, check_kicad_availability
|
|
from mckicad.utils.freerouting_engine import check_routing_prerequisites
|
|
from mckicad.utils.netlist_parser import extract_netlist
|
|
|
|
print(f"📦 Core Utilities Available:")
|
|
print(f" ✅ file_utils: Project file management")
|
|
print(f" ✅ ipc_client: Real-time KiCad integration")
|
|
print(f" ✅ freerouting_engine: Automated routing")
|
|
print(f" ✅ netlist_parser: Circuit analysis")
|
|
|
|
# Test basic functionality
|
|
project_path = "/home/rpm/claude/MLX90640-Thermal-Camera/PCB/Thermal_Camera.kicad_pro"
|
|
|
|
if Path(project_path).exists():
|
|
files = get_project_files(project_path)
|
|
print(f" ✅ File analysis: {len(files)} project files detected")
|
|
|
|
# Test IPC availability (quick check)
|
|
ipc_status = check_kicad_availability()
|
|
print(f" ✅ IPC status: {'Available' if ipc_status.get('available') else 'Unavailable'}")
|
|
|
|
# Test routing prerequisites
|
|
routing_status = check_routing_prerequisites()
|
|
routing_ready = routing_status.get('overall_ready', False)
|
|
print(f" ✅ Routing status: {'Ready' if routing_ready else 'Partial'}")
|
|
|
|
print(f"✅ Core functionality operational!")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Core functionality test failed: {e}")
|
|
return False
|
|
|
|
def test_server_completeness():
|
|
"""Test that server has all expected components."""
|
|
print("\n🎯 Testing Server Completeness")
|
|
print("-" * 40)
|
|
|
|
try:
|
|
# Check that the main server creation works
|
|
from mckicad.server import create_server
|
|
from mckicad.config import KICAD_CLI_TIMEOUT
|
|
from mckicad.context import KiCadAppContext
|
|
|
|
print(f"📊 Server Components:")
|
|
print(f" ✅ create_server(): Main entry point")
|
|
print(f" ✅ Configuration: Timeout settings ({KICAD_CLI_TIMEOUT}s)")
|
|
print(f" ✅ Context management: {KiCadAppContext.__name__}")
|
|
|
|
# Verify key constants and configurations
|
|
from mckicad import config
|
|
|
|
config_items = [
|
|
'KICAD_CLI_TIMEOUT', 'DEFAULT_KICAD_PATHS',
|
|
'COMPONENT_LIBRARY_MAP', 'DEFAULT_FOOTPRINTS'
|
|
]
|
|
|
|
available_config = []
|
|
for item in config_items:
|
|
if hasattr(config, item):
|
|
available_config.append(item)
|
|
|
|
print(f" ✅ Configuration items: {len(available_config)}/{len(config_items)}")
|
|
|
|
print(f"✅ Server completeness confirmed!")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Server completeness test failed: {e}")
|
|
return False
|
|
|
|
def main():
|
|
"""Test complete MCP server interface."""
|
|
print("🖥️ MCP SERVER INTERFACE TESTING")
|
|
print("=" * 45)
|
|
print("Testing complete MCP server tool exposure...")
|
|
|
|
results = {
|
|
"server_init": test_server_initialization(),
|
|
"tool_registration": test_tool_registration(),
|
|
"resource_registration": test_resource_registration(),
|
|
"prompt_registration": test_prompt_registration(),
|
|
"core_functionality": test_core_functionality(),
|
|
"server_completeness": test_server_completeness()
|
|
}
|
|
|
|
print("\n" + "=" * 45)
|
|
print("🎯 MCP SERVER INTERFACE TEST RESULTS")
|
|
print("=" * 45)
|
|
|
|
passed = 0
|
|
for test_name, result in results.items():
|
|
status = "✅ PASS" if result else "❌ FAIL"
|
|
test_display = test_name.replace('_', ' ').title()
|
|
print(f"{status} {test_display}")
|
|
if result:
|
|
passed += 1
|
|
|
|
print(f"\n📊 Results: {passed}/{len(results)} tests passed")
|
|
|
|
if passed == len(results):
|
|
print("🎉 PERFECTION! MCP server interface FULLY OPERATIONAL!")
|
|
print("🖥️ Complete tool/resource/prompt exposure confirmed!")
|
|
print("⚡ Ready for Claude Code integration!")
|
|
elif passed >= 5:
|
|
print("🚀 EXCELLENT! MCP server core functionality working!")
|
|
print("🖥️ Advanced EDA automation interface ready!")
|
|
elif passed >= 4:
|
|
print("✅ GOOD! Essential MCP components operational!")
|
|
else:
|
|
print("🔧 PARTIAL! MCP interface needs refinement!")
|
|
|
|
return passed >= 4
|
|
|
|
if __name__ == "__main__":
|
|
success = main()
|
|
sys.exit(0 if success else 1) |