Skip to content

fix(mcp): handle inline nested objects in McpToolSpec.create_model_from_json_schema#22143

Open
anishesg wants to merge 1 commit into
run-llama:mainfrom
proudhare:fix/ph-issue-22141
Open

fix(mcp): handle inline nested objects in McpToolSpec.create_model_from_json_schema#22143
anishesg wants to merge 1 commit into
run-llama:mainfrom
proudhare:fix/ph-issue-22141

Conversation

@anishesg

Copy link
Copy Markdown

The McpToolSpec.create_model_from_json_schema method in llama_index/tools/mcp/tool_spec_mixins.py was not handling inline nested objects correctly. When a property had type: "object" with its own properties and required fields (not via $ref), the method treated it as a bare Dict type, losing the nested schema structure.

The root cause was in the _resolve_basic_type method, which only checked for simple objects (those with additionalProperties) but not for inline nested objects (those with properties). This caused inline nested objects to fall through to the default type mapping, returning a bare Dict instead of recursively creating a nested Pydantic model.

The fix adds a new helper method _is_inline_nested_object to detect schemas with inline nested properties, and a new method _create_nested_model to recursively build Pydantic models for these nested objects. The logic is inserted before the default type mapping fallback in _resolve_basic_type, ensuring inline nested objects are properly handled. The fix also includes a regression test to verify that both inline nested objects and referenced nested objects (via $ref) work correctly.

Fixes #22141

…om_json_schema

The `McpToolSpec.create_model_from_json_schema` method in `llama_index/tools/mcp/tool_spec_mixins.py` was not handling inline nested objects correctly. When a property had `type: "object"` with its own `properties` and `required` fields (not via `$ref`), the method treated it as a bare `Dict` type, losing the nested schema structure.

Signed-off-by: anish <anishesg@users.noreply.github.com>
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jun 25, 2026

@gyx09212214-prog gyx09212214-prog left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix for inline object schemas. One more schema shape would be worth covering: two inline nested object properties with the same property key set but different field types/required sets. _create_nested_model derives the fallback model name only from sorted property names, so {value: string} and {value: integer} both become the same NestedModel_<hash>.

Pydantic's JSON schema generation may then reuse/collide $defs names and one nested schema can overwrite or alias the other. Could the hash include the full nested schema, e.g. canonical JSON with sorted keys, or the property path, plus a regression with two same-key inline objects?

@anishesg

Copy link
Copy Markdown
Author

good catch, yeah that's a real collision risk. updated the hash to include the full schema definition, not just the keys. added a test with two nested objects that have the same keys but different types to make sure they don't collide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: McpToolSpec.create_model_from_json_schema drops nested inline object properties

2 participants