Publish curated ITWorx_MCP_Hub source from 9ec6419178e8ddc76a698e84bde72d5ff4472411
This commit is contained in:
1 parent
5ff5c807d3
commit
f26354e16c
20 files changed
+1639
-84
No files matched your search
@@ -18,7 +18,7 @@ ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_appops_tool_catalog_is_bijective_and_server_namespaced() -> None:
|
||||
assert len(UPSTREAM_TO_PUBLIC) == len(PUBLIC_TO_UPSTREAM) == 25
|
||||
assert len(UPSTREAM_TO_PUBLIC) == len(PUBLIC_TO_UPSTREAM) == 29
|
||||
assert all(name.startswith("server.") for name in PUBLIC_TO_UPSTREAM)
|
||||
assert PUBLIC_TO_UPSTREAM["server.summary.get"] == "get_system_summary"
|
||||
assert PUBLIC_TO_UPSTREAM["server.operation.execute"] == "server.operation.execute"
|
||||
@@ -28,6 +28,19 @@ def test_appops_tool_catalog_is_bijective_and_server_namespaced() -> None:
|
||||
assert PUBLIC_TO_UPSTREAM["server.deployment.rollback"] == "deployment.rollback"
|
||||
assert PUBLIC_TO_UPSTREAM["server.deployment.target.enroll"] == "target.enroll"
|
||||
assert PUBLIC_TO_UPSTREAM["server.ci.runners.status"] == "gitea.actions.runners.status"
|
||||
assert PUBLIC_TO_UPSTREAM["server.appops.deployment.status"] == "appops.deployment.status"
|
||||
assert (
|
||||
PUBLIC_TO_UPSTREAM["server.appops.self_upgrade.preflight"]
|
||||
== "appops.self_upgrade.preflight"
|
||||
)
|
||||
assert (
|
||||
PUBLIC_TO_UPSTREAM["server.appops.self_upgrade.apply"]
|
||||
== "appops.self_upgrade.apply"
|
||||
)
|
||||
assert (
|
||||
PUBLIC_TO_UPSTREAM["server.appops.self_upgrade.status"]
|
||||
== "appops.self_upgrade.status"
|
||||
)
|
||||
|
||||
|
||||
def test_every_public_appops_tool_has_governance_metadata() -> None:
|
||||
@@ -42,6 +55,50 @@ def test_every_public_appops_tool_has_governance_metadata() -> None:
|
||||
assert set(PUBLIC_TO_UPSTREAM) <= canonical_names
|
||||
|
||||
|
||||
def test_appops_self_upgrade_manifests_are_fixed_target_and_fingerprint_bound() -> None:
|
||||
specs = {}
|
||||
for path in (ROOT / "catalog" / "tools").glob("*.yaml"):
|
||||
document = yaml.safe_load(path.read_text(encoding="utf-8"))
|
||||
spec = document.get("spec") if isinstance(document, dict) else None
|
||||
if isinstance(spec, dict) and spec.get("canonicalName", "").startswith(
|
||||
"server.appops."
|
||||
):
|
||||
specs[spec["canonicalName"]] = spec
|
||||
|
||||
assert set(specs) == {
|
||||
"server.appops.deployment.status",
|
||||
"server.appops.self_upgrade.preflight",
|
||||
"server.appops.self_upgrade.apply",
|
||||
"server.appops.self_upgrade.status",
|
||||
}
|
||||
for name in (
|
||||
"server.appops.self_upgrade.preflight",
|
||||
"server.appops.self_upgrade.apply",
|
||||
):
|
||||
schema = specs[name]["inputSchema"]
|
||||
assert schema["properties"]["repository"]["const"] == "jens/unraid-appops-gateway"
|
||||
assert schema["properties"]["revision"]["pattern"] == "^[0-9a-f]{40}$"
|
||||
assert schema["properties"]["reason"]["minLength"] == 8
|
||||
assert schema["properties"]["reason"]["maxLength"] == 500
|
||||
assert schema["properties"]["expected_current_revision"]["pattern"] == "^[0-9a-f]{40}$"
|
||||
apply = specs["server.appops.self_upgrade.apply"]
|
||||
assert apply["riskClass"] == "R3"
|
||||
assert apply["readOnly"] is False
|
||||
assert apply["inputSchema"]["properties"]["expected_preflight_fingerprint"][
|
||||
"pattern"
|
||||
] == "^[0-9a-f]{64}$"
|
||||
assert {
|
||||
"expected_preflight_fingerprint",
|
||||
"idempotency_key",
|
||||
} <= set(apply["inputSchema"]["required"])
|
||||
policy = yaml.safe_load(
|
||||
(ROOT / "catalog" / "policies" / "041-appops-governed-operations.yaml").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
)
|
||||
assert "server.appops.self_upgrade.apply" in policy["spec"]["match"]["toolPatterns"]
|
||||
|
||||
|
||||
def test_appops_proxy_rewrites_only_registered_tool_calls() -> None:
|
||||
request = {
|
||||
"jsonrpc": "2.0",
|
||||
@@ -73,6 +130,35 @@ def test_appops_proxy_rewrites_only_registered_tool_calls() -> None:
|
||||
with pytest.raises(ValueError, match="not registered"):
|
||||
rewrite_request({"method": "tools/call", "params": {"name": "shell.execute"}})
|
||||
|
||||
upgrade_request = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 10,
|
||||
"method": "tools/call",
|
||||
"params": {
|
||||
"name": "server.appops.self_upgrade.apply",
|
||||
"arguments": {
|
||||
"repository": "jens/unraid-appops-gateway",
|
||||
"revision": "a" * 40,
|
||||
"reason": "approved release",
|
||||
"expected_preflight_fingerprint": "b" * 64,
|
||||
"idempotency_key": "upgrade-2026-09-30",
|
||||
"expected_current_revision": "c" * 40,
|
||||
},
|
||||
},
|
||||
}
|
||||
upgrade_rewritten = rewrite_request(upgrade_request)
|
||||
assert upgrade_rewritten["params"]["name"] == "appops.self_upgrade.apply"
|
||||
assert upgrade_rewritten["params"]["arguments"] == upgrade_request["params"]["arguments"]
|
||||
|
||||
for upstream_name in (
|
||||
"appops.deployment.status",
|
||||
"appops.self_upgrade.preflight",
|
||||
"appops.self_upgrade.apply",
|
||||
"appops.self_upgrade.status",
|
||||
):
|
||||
with pytest.raises(ValueError, match="not registered"):
|
||||
rewrite_request({"method": "tools/call", "params": {"name": upstream_name}})
|
||||
|
||||
|
||||
def test_appops_proxy_rewrites_discovery_and_drops_unknown_tools() -> None:
|
||||
response = {
|
||||
@@ -84,6 +170,10 @@ def test_appops_proxy_rewrites_discovery_and_drops_unknown_tools() -> None:
|
||||
{"name": "gitea.projects.catalog", "description": "projects"},
|
||||
{"name": "deployment.preflight", "description": "deployment preflight"},
|
||||
{"name": "deployment.apply", "description": "typed deployment"},
|
||||
{"name": "appops.deployment.status", "description": "AppOps revision"},
|
||||
{"name": "appops.self_upgrade.preflight", "description": "upgrade preflight"},
|
||||
{"name": "appops.self_upgrade.apply", "description": "upgrade apply"},
|
||||
{"name": "appops.self_upgrade.status", "description": "upgrade status"},
|
||||
{"name": "future_unsafe_tool", "description": "unknown"},
|
||||
]
|
||||
},
|
||||
@@ -93,6 +183,10 @@ def test_appops_proxy_rewrites_discovery_and_drops_unknown_tools() -> None:
|
||||
{"name": "server.project.list", "description": "projects"},
|
||||
{"name": "server.deployment.preflight", "description": "deployment preflight"},
|
||||
{"name": "server.deployment.apply", "description": "typed deployment"},
|
||||
{"name": "server.appops.deployment.status", "description": "AppOps revision"},
|
||||
{"name": "server.appops.self_upgrade.preflight", "description": "upgrade preflight"},
|
||||
{"name": "server.appops.self_upgrade.apply", "description": "upgrade apply"},
|
||||
{"name": "server.appops.self_upgrade.status", "description": "upgrade status"},
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user