fix(mcp): normalize local schema refs

This commit is contained in:
amplifierplus
2026-07-27 01:14:41 +08:00
committed by Xubin Ren
parent 2e2f15dd0c
commit 9aae7485d6
2 changed files with 162 additions and 15 deletions
+73
View File
@@ -236,6 +236,79 @@ def test_wrapper_normalizes_nullable_property_anyof() -> None:
}
def test_wrapper_hoists_recursive_local_refs_into_defs() -> None:
recursive_items_ref = "#/properties/filter/properties/items"
tool_def = SimpleNamespace(
name="search_dataset",
description="search tool",
inputSchema={
"type": "object",
"properties": {
"filter": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {"$ref": recursive_items_ref},
}
},
"required": ["items"],
}
},
},
)
wrapper = MCPToolWrapper(SimpleNamespace(call_tool=None), "test", tool_def)
generated_ref = wrapper.parameters["properties"]["filter"]["properties"]["items"][
"items"
]["$ref"]
assert generated_ref.startswith("#/$defs/ref_")
generated_name = generated_ref.removeprefix("#/$defs/")
generated_schema = wrapper.parameters["$defs"][generated_name]
assert generated_schema["type"] == "array"
assert generated_schema["items"]["$ref"] == generated_ref
def test_wrapper_hoists_root_self_ref_into_defs() -> None:
tool_def = SimpleNamespace(
name="tree",
description="tree tool",
inputSchema={
"type": "object",
"properties": {
"children": {"type": "array", "items": {"$ref": "#"}},
},
},
)
wrapper = MCPToolWrapper(SimpleNamespace(call_tool=None), "test", tool_def)
generated_ref = wrapper.parameters["properties"]["children"]["items"]["$ref"]
assert generated_ref.startswith("#/$defs/ref_")
generated_name = generated_ref.removeprefix("#/$defs/")
assert wrapper.parameters["$defs"][generated_name]["properties"]["children"]["items"] == {
"$ref": generated_ref
}
def test_wrapper_preserves_existing_defs_refs() -> None:
tool_def = SimpleNamespace(
name="demo",
description="demo tool",
inputSchema={
"type": "object",
"$defs": {"value": {"type": "string"}},
"properties": {"value": {"$ref": "#/$defs/value"}},
},
)
wrapper = MCPToolWrapper(SimpleNamespace(call_tool=None), "test", tool_def)
assert wrapper.parameters["properties"]["value"]["$ref"] == "#/$defs/value"
assert wrapper.parameters["$defs"]["value"]["type"] == "string"
def test_normalize_windows_stdio_command_is_noop_off_windows(
monkeypatch: pytest.MonkeyPatch,
) -> None: