chore: pre-migration snapshot
Layer0, MCP servers, Terraform consolidation
This commit is contained in:
140
ci_check_tool_names.py
Executable file
140
ci_check_tool_names.py
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
CI Tool Name Parity Check
|
||||
|
||||
Validates that MCP server tool names match the capability registry.
|
||||
Fails CI if:
|
||||
- A tool exists but isn't registered
|
||||
- A registered tool no longer exists
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def get_registry_tools():
|
||||
"""Load tool names from capability registry."""
|
||||
with open("capability_registry_v2.json", "r") as f:
|
||||
registry = json.load(f)
|
||||
|
||||
registry_tools = {}
|
||||
for server_name, server_info in registry["mcp_servers"].items():
|
||||
# Extract base tool names (remove operation type)
|
||||
tools = []
|
||||
for tool_desc in server_info["tools"]:
|
||||
tool_name = tool_desc.split(" (")[0] # Remove "(operation_type)"
|
||||
tools.append(tool_name)
|
||||
registry_tools[server_name] = set(tools)
|
||||
|
||||
return registry_tools
|
||||
|
||||
|
||||
def get_actual_tools():
|
||||
"""Get actual tool names from MCP servers by examining source code."""
|
||||
actual_tools = {}
|
||||
|
||||
# Extract tools from Cloudflare Safe server source
|
||||
try:
|
||||
with open("mcp/cloudflare_safe/server.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Look for tool function definitions
|
||||
import re
|
||||
|
||||
tool_pattern = r"def (cf_\w+)\("
|
||||
tools_found = set(re.findall(tool_pattern, content))
|
||||
|
||||
# Filter out internal functions
|
||||
valid_tools = {tool for tool in tools_found if not tool.startswith("_")}
|
||||
actual_tools["cloudflare_safe"] = valid_tools
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not extract tools from cloudflare_safe: {e}")
|
||||
|
||||
# Extract tools from WAF Intelligence server source
|
||||
try:
|
||||
with open("mcp/waf_intelligence/mcp_server.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
tool_pattern = r"def (waf_\w+)\("
|
||||
tools_found = set(re.findall(tool_pattern, content))
|
||||
|
||||
valid_tools = {tool for tool in tools_found if not tool.startswith("_")}
|
||||
actual_tools["waf_intelligence"] = valid_tools
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not extract tools from waf_intelligence: {e}")
|
||||
|
||||
# Extract tools from Oracle Answer server source
|
||||
try:
|
||||
with open("mcp/oracle_answer/server.py", "r") as f:
|
||||
content = f.read()
|
||||
|
||||
tool_pattern = r"def (\w+)\("
|
||||
tools_found = set(re.findall(tool_pattern, content))
|
||||
|
||||
# Look for oracle_answer specifically
|
||||
oracle_tools = {tool for tool in tools_found if "oracle" in tool.lower()}
|
||||
actual_tools["oracle_answer"] = oracle_tools
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not extract tools from oracle_answer: {e}")
|
||||
|
||||
return actual_tools
|
||||
|
||||
|
||||
def check_tool_parity():
|
||||
"""Compare registry tools with actual tools."""
|
||||
registry_tools = get_registry_tools()
|
||||
actual_tools = get_actual_tools()
|
||||
|
||||
errors = []
|
||||
|
||||
for server_name in set(registry_tools.keys()) | set(actual_tools.keys()):
|
||||
reg_tools = registry_tools.get(server_name, set())
|
||||
act_tools = actual_tools.get(server_name, set())
|
||||
|
||||
# Check for tools in registry but not in actual
|
||||
missing_in_actual = reg_tools - act_tools
|
||||
if missing_in_actual:
|
||||
errors.append(
|
||||
f"❌ {server_name}: Tools registered but not found: {missing_in_actual}"
|
||||
)
|
||||
|
||||
# Check for tools in actual but not in registry
|
||||
missing_in_registry = act_tools - reg_tools
|
||||
if missing_in_registry:
|
||||
errors.append(
|
||||
f"❌ {server_name}: Tools found but not registered: {missing_in_registry}"
|
||||
)
|
||||
|
||||
# Report parity
|
||||
if not missing_in_actual and not missing_in_registry:
|
||||
print(f"✅ {server_name}: Tool parity verified ({len(reg_tools)} tools)")
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def main():
|
||||
"""Main CI check function."""
|
||||
print("🔍 CI Tool Name Parity Check")
|
||||
print("=" * 50)
|
||||
|
||||
errors = check_tool_parity()
|
||||
|
||||
if errors:
|
||||
print("\n❌ Registry drift detected:")
|
||||
for error in errors:
|
||||
print(error)
|
||||
print(
|
||||
"\n💡 Fix: Update capability_registry_v2.json to match actual MCP server tools"
|
||||
)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("\n✅ All MCP server tools match capability registry")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user