Tool.validate_params / Schema.validate_json_schema_value (nanobot/agent/tools/base.py) never resolve local $ref fragments and never evaluate anyOf/oneOf branches. Those are exactly the shapes MCP servers emit for model-typed and union parameters (e.g. a FastMCP tool built from def book(addr: Address, count: int | str)), so for such parameters local validation is a no-op:
addrgiven as{"zip": "98101"}(missing requiredcity,zipnot an integer) →validate_paramsreturns[]addrgiven as the string"Seattle"instead of an object →[]countgiven as a dict matching neither the integer nor the string branch →[]
The invalid arguments are forwarded to the MCP server unchecked, instead of producing the recoverable "invalid parameters" error other parameter shapes get.
Separately, an array parameter whose items is a list (draft-07 tuple form; prefixItems positions have the same problem) crashes both cast_params and validate_params with AttributeError: 'list' object has no attribute 'get'. That happens inside ToolRegistry.prepare_call, outside the tool-execution error handling, so one such tool schema turns every call into an unhandled exception rather than a tool error the model can react to.
Root cause: the validator reads schema.get("type"), which is absent for $ref/anyOf/oneOf fragments, and returns without checking anything; the array branch passes schema["items"] into the recursion assuming it is always a dict. The existing validation tests only use flat, native-type schemas, so none of these shapes are covered.
I have a fix with regression tests ready (validation resolves $defs/definitions refs and evaluates the composition branches; tuple/prefixItems elements are validated and cast positionally) and would like to open a PR.
Activity
0No activity yet.