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
AsyncMcpToolProvider.getToolSpecifications logs this warning when scanning the configured tool objects yields zero @McpTool-annotated methods, producing an empty tool specification list. The MCP server will expose no tools from this provider; the library flags it because a registered tool provider with no tools is almost always a wiring mistake.
Source
Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/tool/AsyncMcpToolProvider.java:161
: ReturnMode.TEXT;
BiFunction<McpAsyncServerExchange, CallToolRequest, Mono<CallToolResult>> methodCallback = new AsyncMcpToolMethodCallback(
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
- Verify each tool object has at least one public method annotated with @McpTool.
- Confirm the tool object list passed to AsyncMcpToolProvider is non-empty and contains the intended beans.
- Check method visibility and signatures match the scanner's requirements.
- Remove the tool provider if no tools are intended.
Example fix
// before
class Tools { public String weather(String city) { ... } } // no @McpTool
// after
class Tools { @McpTool(description = "Get weather") public String weather(@McpToolParam String city) { ... } } Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight check for tool methods before creating AsyncMcpToolProvider:
long tools = Arrays.stream(toolObject.getClass().getDeclaredMethods())
.filter(m -> m.isAnnotationPresent(McpTool.class) && Modifier.isPublic(m.getModifiers()))
.count();
if (tools == 0) throw new IllegalStateException(toolObject + " exposes no @McpTool methods"); Prevention
- Annotate tool methods with @McpTool and parameters with @McpToolParam.
- Register the class that actually contains the tool methods.
- Keep tool methods public; the scanner skips non-public ones.
- Add a test asserting toolSpecifications() is non-empty for each provider.
When it happens
Trigger: Passing objects without any public @McpTool methods to AsyncMcpToolProvider, annotated methods filtered out (visibility/signature), or an empty toolObjects list — empty toolSpecs triggers the warn at AsyncMcpToolProvider.java:161.
Common situations: Tool class not registered with the provider; @McpTool annotation missing or wrong import; tool methods private; upgrade renamed annotation attributes causing scan mismatch.
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/9a95e284a3a1ea4c.
Report an issue: GitHub.