fix(tools): dereference draft-07 definitions in MCP tool schemas#5941
fix(tools): dereference draft-07 definitions in MCP tool schemas#5941gaoflow wants to merge 1 commit into
definitions in MCP tool schemas#5941Conversation
`_dereference_schema` only resolved `$ref`s against `$defs` (JSON Schema draft 2019-09+/2020-12) and only stripped the `$defs` block afterwards. A tool whose `inputSchema` uses JSON Schema draft-07 — `definitions` plus `$ref: "#/definitions/..."`, which the MCP specification explicitly permits — was therefore left with its refs unresolved and the `definitions` block intact, so `_to_gemini_schema` raised `KeyError: 'definitions'` while building the Gemini schema. Resolve refs against both `definitions` and `$defs` (the latter wins on a key collision) and strip both blocks once resolved. Fixes google#5940.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Response from ADK Triaging Agent Hello @gaoflow, thank you for submitting this pull request! It looks like the Contributor License Agreement (CLA) check has failed for this PR. According to our Contribution Guidelines, all contributions to this project must be accompanied by a signed CLA before they can be reviewed and accepted. Could you please visit https://cla.developers.google.com/ to sign the agreement? Signing the CLA is necessary to give us permission to use and redistribute your contributions as part of the project. Thank you! |
Summary
McpToolsetcrashes withKeyError: 'definitions'when an MCP server returns a toolinputSchemawritten in JSON Schema draft-07 — i.e. usingdefinitionsand$ref: "#/definitions/..."instead of the draft 2019-09+/2020-12$defs. The MCP specification (2025-11-25) explicitly permits draft-07 schemas, so ADK should accept them.Fixes #5940 (the same crash was previously reported in #3685 and closed as stale).
Root cause
_dereference_schemainsrc/google/adk/tools/_gemini_schema_util.pyonly looked up$refs in the$defsblock and only stripped$defsafter resolving:For a draft-07 schema there is no
$defs, sodefsis empty, every$ref: "#/definitions/..."is left unresolved, and thedefinitionsblock survives untouched._to_gemini_schemathen passes that leftoverdefinitionskeyword intoSchema.from_json_schema(...), which raisesKeyError: 'definitions'.Fix
Resolve refs against both
definitions(draft-07) and$defs(draft 2019-09+), and strip both blocks once resolved.$defswins on the (pathological) key collision. Draft 2019+ schemas are unaffected becausedefinitionsis simply absent.The
$reflookup itself already keys on the final path segment (ref_uri.split("/")[-1]), so#/definitions/Petand#/$defs/Petboth resolve toPetwithout further changes.Testing
Added
test_to_gemini_schema_draft_07_definitions_and_ref, mirroring the existing$defstest but using draft-07definitions+$ref: "#/definitions/...". It fails onmainwithKeyError: 'definitions'and passes with this change. The fulltests/unittests/tools/test_gemini_schema_util.pysuite (now 69 tests) passes, confirming no regression for the$defs/ circular-ref / reused-ref cases.Thanks to @rrazvd for the reproduction and
definitions→$defsworkaround in the issue thread.