@@ -1126,7 +1126,8 @@ async def validate_tool_result(self, name: str, result: types.CallToolResult) ->
11261126 """Revalidate a `CallToolResult` against the tool's declared output schema.
11271127
11281128 Raises:
1129- RuntimeError: Structured content is missing or does not conform to the schema.
1129+ RuntimeError: Structured content is missing or does not conform to the schema, or the
1130+ schema is invalid or has a `$ref` that does not resolve within the schema document.
11301131 """
11311132 if name not in self ._tool_output_schemas :
11321133 # refresh output schema cache
@@ -1140,17 +1141,22 @@ async def validate_tool_result(self, name: str, result: types.CallToolResult) ->
11401141
11411142 if output_schema is not None :
11421143 from jsonschema import exceptions as jsonschema_exceptions
1144+ from referencing .exceptions import Unresolvable
11431145
11441146 if result .structured_content is None :
11451147 raise RuntimeError (f"Tool { name } has an output schema but did not return structured content" )
11461148 validator = self ._output_schema_validator (name , output_schema )
11471149 # `best_match` picks the same error the previous `jsonschema.validate()` call raised,
11481150 # so the message a caller sees is unchanged. It is untyped upstream.
11491151 errors = validator .iter_errors (result .structured_content )
1150- error = cast (
1151- "Exception | None" ,
1152- jsonschema_exceptions .best_match (errors ), # pyright: ignore[reportUnknownMemberType]
1153- )
1152+ try :
1153+ error = cast (
1154+ "Exception | None" ,
1155+ jsonschema_exceptions .best_match (errors ), # pyright: ignore[reportUnknownMemberType]
1156+ )
1157+ except Unresolvable as e :
1158+ # A `$ref` did not resolve within the schema document.
1159+ raise RuntimeError (f"Invalid schema for tool { name } : { e } " ) from e
11541160 if error is not None :
11551161 raise RuntimeError (f"Invalid structured content returned by tool { name } : { error } " ) from error
11561162
@@ -1168,6 +1174,7 @@ def _output_schema_validator(self, name: str, output_schema: dict[str, Any]) ->
11681174 """
11691175 from jsonschema import SchemaError
11701176 from jsonschema .validators import validator_for
1177+ from referencing import Registry
11711178
11721179 if (validator := self ._tool_output_validators .get (name )) is not None :
11731180 return validator
@@ -1177,9 +1184,8 @@ def _output_schema_validator(self, name: str, output_schema: dict[str, Any]) ->
11771184 validator_cls .check_schema (output_schema )
11781185 except SchemaError as e :
11791186 raise RuntimeError (f"Invalid schema for tool { name } : { e } " )
1180- # jsonschema ships no `py.typed`, so pyright reads typeshed's stub, which declares
1181- # `registry` as required (concrete validators default it); cast to a schema-only ctor.
1182- validator = cast ("Callable[[dict[str, Any]], Validator]" , validator_cls )(output_schema )
1187+ # An explicit empty registry: `$ref`s resolve within the schema document and the bundled metaschemas.
1188+ validator = validator_cls (output_schema , registry = Registry ())
11831189 self ._tool_output_validators [name ] = validator
11841190 return validator
11851191
0 commit comments