spring-projects/spring-ai · warning
No tool methods found in the provided tool objects: <toolObj
Error message
No tool methods found in the provided tool objects: <toolObjects>
What it means
AsyncStatelessMcpToolProvider.getToolSpecifications logs this warning when annotation scanning of the configured tool objects produces zero tool specifications. The stateless async server will register no tools; the warning exists to catch providers wired with objects that contain no @McpTool methods.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/tool/AsyncStatelessMcpToolProvider.java:166
: ReturnMode.TEXT;
BiFunction<McpTransportContext, CallToolRequest, Mono<CallToolResult>> methodCallback = new AsyncStatelessMcpToolMethodCallback(
returnMode, mcpToolMethod, toolObject);
AsyncToolSpecification toolSpec = AsyncToolSpecification.builder()
.tool(tool)
.callHandler(methodCallback)
.build();
return toolSpec;
})
.toList())
.flatMap(List::stream)
.toList();
if (toolSpecs.isEmpty()) {
if (logger.isWarnEnabled()) {
logger.warn("No tool methods found in the provided tool objects: " + this.toolObjects);
}
}
return toolSpecs;
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Add/repair @McpTool annotations on public methods within the registered tool objects.
- Verify the tool object list given to AsyncStatelessMcpToolProvider is correct and non-empty.
- Check method visibility and parameter annotations (@McpToolParam) expected by the scanner.
- Drop the provider registration if it intentionally exposes no tools.
Example fix
// before new AsyncStatelessMcpToolProvider(List.of(new ServiceWithNoTools())); // after new AsyncStatelessMcpToolProvider(List.of(new RealTools())); // class with @McpTool-annotated public methods
Defensive patterns
Strategy: validation
Validate before calling
// Guard against empty stateless tool providers:
List<Object> validTools = toolObjects.stream()
.filter(o -> Arrays.stream(o.getClass().getDeclaredMethods())
.anyMatch(m -> m.isAnnotationPresent(McpTool.class)))
.toList();
if (validTools.isEmpty()) throw new IllegalArgumentException("No tool objects with @McpTool methods supplied"); Prevention
- Verify @McpTool annotations after any package or version upgrade.
- Pass concrete tool-bearing beans to AsyncStatelessMcpToolProvider, never empty or placeholder lists.
- Keep annotated tool methods public with scanner-compatible signatures.
- Monitor server startup logs and treat this warning as a build failure in CI.
When it happens
Trigger: Objects supplied to AsyncStatelessMcpToolProvider lack public @McpTool methods, the annotated methods are invisible/incompatible to the scanner, or toolObjects is empty — empty toolSpecs triggers the warn at AsyncStatelessMcpToolProvider.java:166.
Common situations: Forgetting to annotate tool methods; passing the wrong service bean to the provider; methods private after a refactor; duplicate tool providers where one ends up empty.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- No tool methods found in the provided tool objects: <toolObj
- No resource methods found in the provided resource objects:
- No resource methods found in the provided resource objects:
- No sampling methods found
- No sampling methods found
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/7667289d54637598.
Report an issue: GitHub.