|
@@ -161,6 +161,36 @@ def test_mcp_garden_cycle_list_detailed_has_strain_info():
|
|
|
assert any_strain_desc or any_siblings, "Expected strainDesc and/or cloneSiblings to be present"
|
|
assert any_strain_desc or any_siblings, "Expected strainDesc and/or cloneSiblings to be present"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def test_mcp_input_schema_announced_for_garden_tools():
|
|
|
|
|
+ """OpenClaw MCP compliance: garden_* tools should expose inputSchema via tools/list."""
|
|
|
|
|
+ response = requests.post(
|
|
|
|
|
+ MCP_URL,
|
|
|
|
|
+ json={"jsonrpc": "2.0", "id": 999, "method": "tools/list", "params": {}},
|
|
|
|
|
+ timeout=10,
|
|
|
|
|
+ )
|
|
|
|
|
+ response.raise_for_status()
|
|
|
|
|
+ body = response.json()
|
|
|
|
|
+ assert body.get("result"), f"Expected tools/list result, got: {body}"
|
|
|
|
|
+
|
|
|
|
|
+ tools = body["result"].get("tools") or []
|
|
|
|
|
+ tool_by_name = {t.get("name"): t for t in tools if isinstance(t, dict)}
|
|
|
|
|
+
|
|
|
|
|
+ # At least validate a couple of the “new” tools.
|
|
|
|
|
+ for name in [
|
|
|
|
|
+ "garden_clone_to",
|
|
|
|
|
+ "garden_cycle_plants",
|
|
|
|
|
+ "garden_cycle_list_detailed",
|
|
|
|
|
+ ]:
|
|
|
|
|
+ assert name in tool_by_name, f"Missing tool {name} in tools/list"
|
|
|
|
|
+ input_schema = tool_by_name[name].get("inputSchema")
|
|
|
|
|
+ assert isinstance(input_schema, dict), f"{name}.inputSchema missing/invalid"
|
|
|
|
|
+
|
|
|
|
|
+ # Specifically: garden_cycle_plants should allow missing cycle_uri.
|
|
|
|
|
+ cycle_plants_schema = tool_by_name["garden_cycle_plants"].get("inputSchema", {})
|
|
|
|
|
+ props = cycle_plants_schema.get("properties", {})
|
|
|
|
|
+ assert "cycle_uri" in props, "garden_cycle_plants inputSchema must define cycle_uri"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def test_load_examples_fixture(garden_layer):
|
|
def test_load_examples_fixture(garden_layer):
|
|
|
if os.getenv("MCP_ALLOW_EXAMPLE_LOAD", "false").lower() != "true":
|
|
if os.getenv("MCP_ALLOW_EXAMPLE_LOAD", "false").lower() != "true":
|
|
|
pytest.skip("MCP_ALLOW_EXAMPLE_LOAD must be true to load example fixtures")
|
|
pytest.skip("MCP_ALLOW_EXAMPLE_LOAD must be true to load example fixtures")
|