96 lines
2.6 KiB
Python
Executable File
96 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
CI Entrypoint Sanity Check
|
|
|
|
Validates that all MCP server entrypoints are runnable.
|
|
Fails CI if any entrypoint has import or startup errors.
|
|
"""
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import os
|
|
from pathlib import Path
|
|
|
|
|
|
def get_registry_entrypoints():
|
|
"""Load entrypoints from capability registry."""
|
|
with open("capability_registry_v2.json", "r") as f:
|
|
registry = json.load(f)
|
|
|
|
entrypoints = {}
|
|
for server_name, server_info in registry["mcp_servers"].items():
|
|
entrypoints[server_name] = server_info["entrypoint"]
|
|
|
|
return entrypoints
|
|
|
|
|
|
def check_entrypoint(server_name: str, entrypoint: str) -> tuple[bool, str]:
|
|
"""Check if an entrypoint is runnable."""
|
|
try:
|
|
# Test with --help flag or equivalent
|
|
env = os.environ.copy()
|
|
env["PYTHONPATH"] = "/Users/sovereign/work-core"
|
|
|
|
result = subprocess.run(
|
|
["python3", "-m", entrypoint, "--help"],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=10,
|
|
env=env,
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
return True, f"✅ {server_name}: Entrypoint '{entrypoint}' is runnable"
|
|
else:
|
|
return (
|
|
False,
|
|
f"❌ {server_name}: Entrypoint '{entrypoint}' failed with exit code {result.returncode}\n{result.stderr}",
|
|
)
|
|
|
|
except subprocess.TimeoutExpired:
|
|
return False, f"❌ {server_name}: Entrypoint '{entrypoint}' timed out"
|
|
except FileNotFoundError:
|
|
return False, f"❌ {server_name}: Entrypoint '{entrypoint}' not found"
|
|
except Exception as e:
|
|
return (
|
|
False,
|
|
f"❌ {server_name}: Entrypoint '{entrypoint}' failed with error: {e}",
|
|
)
|
|
|
|
|
|
def main():
|
|
"""Main CI check function."""
|
|
print("🔍 CI Entrypoint Sanity Check")
|
|
print("=" * 50)
|
|
|
|
entrypoints = get_registry_entrypoints()
|
|
errors = []
|
|
successes = []
|
|
|
|
for server_name, entrypoint in entrypoints.items():
|
|
success, message = check_entrypoint(server_name, entrypoint)
|
|
if success:
|
|
successes.append(message)
|
|
else:
|
|
errors.append(message)
|
|
|
|
# Print results
|
|
for success in successes:
|
|
print(success)
|
|
|
|
for error in errors:
|
|
print(error)
|
|
|
|
if errors:
|
|
print(f"\n❌ {len(errors)} entrypoint(s) failed")
|
|
print("💡 Fix: Update capability_registry_v2.json with correct entrypoints")
|
|
sys.exit(1)
|
|
else:
|
|
print(f"\n✅ All {len(successes)} entrypoints are runnable")
|
|
sys.exit(0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|