Skip to content

Conversation

@ilayaperumalg
Copy link
Member

@ilayaperumalg ilayaperumalg commented Nov 11, 2025

  • For both Sync/Async toolcallbacks, verify the inputSchema when setting the Spring AI ToolDefinition

    • This is needed for the cases where the MCP servers that provide Tools with incomplete inputSchema. In particular schemas that doesn't include JSON schema parameters such as "properties" when parameterless tool definition is used. This specific case is implicitly handled for Spring AI's FunctionToolCallback, MethodToolCallback (@tool) and @mcptool tools when creating MCP Servers. The fix is only needs for external (non SpringAI) MCP server that doesn't provide the required JSON fields.
  • Applied the fix specifically for Sync and Async ToolCallbacks

  • Added JsonSchemaUtils to ensure the schema is validated and fixed with the required parameters. Thanks to @liugddx for the fix from fix: ensure valid parameters schema for parameter-less functions in OpenAiApi #4832

  • Add integration tests in OpenAiChatModelIT to verify MCP tool callbacks with incorrect inputSchema is handled correctly

  • Add MCP integration test to validate the same

Fixes #4776

 - For both Sync/Async toolcallbacks, verify the inputSchema when setting the Spring AI ToolDefinition
    - This is needed for the cases where the inputSchema doesn't include required JSON schema parameters such as "properties" when parameterless tool definition is used. This specific case is implicitly handled for both Spring AI FunctionToolCallback and McpTool annotated Tools and needs to be fixed for the case where MCP tools don't have valid inputSchema set.

 - Applied the fix specifically for Sync and Async ToolCallbacks

 - Added JsonSchemaUtils to ensure the schema is validated and fixed with the required parameters. Thanks to @liugddx for the fix from spring-projects#4832

 - Add integration tests in OpenAiChatModelIT to verify MCP toolbacks with incorrect inputSchema is handled correctly

 - Add MCP integration test to validate the same

Fixes spring-projects#4776

Co-authored-by: liugddx <liugddx@gmail.com>
Signed-off-by: Ilayaperumal Gopinathan <ilayaperumal.gopinathan@broadcom.com>
@tzolov
Copy link
Contributor

tzolov commented Nov 11, 2025

LGTM, thanks @ilayaperumalg

@ilayaperumalg ilayaperumalg added this to the 1.1.0 milestone Nov 11, 2025
Copy link
Contributor

@liugddx liugddx left a comment

Choose a reason for hiding this comment

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

@ilayaperumalg I have some comments, just some suggestions. Generally LGTM

Map<String, Object> schemaMap = ModelOptionsUtils.jsonToMap(inputSchema);
assertThat(schemaMap).isNotNull();
assertThat(schemaMap).containsKey("type");
assertThat(schemaMap.get("type")).isEqualTo("object");
Copy link
Contributor

Choose a reason for hiding this comment

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

Add an assertion to preserve additionalProperties, ensuring that the field is retained after normalization.

McpServerFeatures.SyncToolSpecification toolSpec = new McpServerFeatures.SyncToolSpecification(
parameterlessTool, (exchange, arguments) -> {
McpSchema.TextContent content = new McpSchema.TextContent(
"Current time: 2025-11-11T12:00:00Z");
Copy link
Contributor

Choose a reason for hiding this comment

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

The McpToolCallbackParameterlessToolIT returns a fixed date string "2025-11-11T12:00:00Z". It can be changed to the current time to reduce the semantic misunderstanding caused by the "specific date string" (this does not affect correctness, only a readability suggestion).

Comment on lines 93 to 98
return DefaultToolDefinition.builder()
.name(this.prefixedToolName)
.description(this.tool.description())
.inputSchema(ModelOptionsUtils.toJsonString(this.tool.inputSchema()))
.inputSchema(
JsonSchemaUtils.ensureValidInputSchema(ModelOptionsUtils.toJsonString(this.tool.inputSchema())))
.build();
Copy link
Contributor

Choose a reason for hiding this comment

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

The logic for constructing ToolDefinition in both the synchronous and asynchronous sections is almost identical. It is recommended to extract a common helper method to facilitate future maintenance.

 - Move Sync/Async ToolDefinition creation into utils
 - Add assertion and updates to McpToolCallbackParameterlessToolIT

Signed-off-by: Ilayaperumal Gopinathan <ilayaperumal.gopinathan@broadcom.com>
@ilayaperumalg
Copy link
Member Author

@liugddx thank you for the quick response reviewing the PR! Much appreciated.

I have updated the PR addressing the review comments.

@liugddx
Copy link
Contributor

liugddx commented Nov 12, 2025

LGTM

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid schema for function 'xxx': In context=(), object schema missing properties. When tool doesn't have any paramters

3 participants