spring-projects/spring-ai · warning

No tool methods found in the provided tool objects: + this.t

Error message

No tool methods found in the provided tool objects: + this.toolObjects

What it means

This is a warning (not an exception) logged by SyncMcpToolProvider.getToolSpecifications when reflection over the supplied @McpTool-annotated tool objects yields zero tool specifications. The provider still returns an empty list, so downstream MCP clients will see a server/tool provider with no tools. It indicates the tool objects were provided but none of their methods matched the tool annotation scan.

Source

Thrown at mcp/mcp-annotations/src/main/java/org/springframework/ai/mcp/annotation/provider/tool/SyncMcpToolProvider.java:154

					ReturnMode returnMode = useStructuredOtput ? ReturnMode.STRUCTURED
							: (methodReturnType == Void.TYPE || methodReturnType == void.class ? ReturnMode.VOID
									: ReturnMode.TEXT);

					BiFunction<McpSyncServerExchange, CallToolRequest, CallToolResult> methodCallback = new SyncMcpToolMethodCallback(
							returnMode, mcpToolMethod, toolObject);

					var toolSpec = SyncToolSpecification.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

  1. Verify each object passed to the provider has at least one method annotated with @McpTool
  2. Check that methods are public (or otherwise visible to the annotation scanner) and the mcp-annotations dependency is on the classpath
  3. Log/inspect this.toolObjects at construction time to confirm the right beans are wired
  4. Upgrade/align the spring-ai mcp-annotations version so the annotation the scanner looks for matches the one used in your code

Example fix

// before
SyncMcpToolProvider provider = SyncMcpToolProvider.builder()
    .toolObjects(new MyService()) // MyService has no @McpTool methods
    .build();
// after
public class MyService {
    @McpTool(name = "getWeather", description = "Get weather")
    public String getWeather(String city) { ... }
}
SyncMcpToolProvider provider = SyncMcpToolProvider.builder()
    .toolObjects(new MyService())
    .build();
Defensive patterns

Strategy: validation

Validate before calling

// before building the provider
long toolCount = java.util.Arrays.stream(toolObjects)
    .flatMap(o -> Arrays.stream(o.getClass().getDeclaredMethods()))
    .filter(m -> m.isAnnotationPresent(org.springframework.ai.mcp.annotation.McpTool.class))
    .count();
if (toolCount == 0) throw new IllegalStateException("No @McpTool methods found in tool objects");

Prevention

When it happens

Trigger: Calling SyncMcpToolProvider with tool objects whose classes have no @McpTool-annotated methods; annotation metadata not on the classpath so scanning finds nothing; passing the wrong (unrelated) objects as toolObjects; methods annotated with a custom/incorrect annotation name instead of @McpTool.

Common situations: Renaming or removing @McpTool annotations during refactoring; building tools with a non-public method visibility the scanner skips; wiring an empty or wrong bean list into the provider constructor; mixing mcp-annotations versions where the annotation package changed.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/2ac24593c165bc55. Report an issue: GitHub.