Bug description

A bean of type AsyncToolSpecification will not be added as a tool.

Environment Spring AI 1.1.0-M2, spring boot 3.5.6, using the async server starter

Steps to reproduce

  1. Use the async server starter (and configure an async server)
  2. Register AsyncToolSpecification bean

Expected behavior

The bean is used as a tool.

Minimal Complete Reproducible example

@SpringBootApplication
class Application {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            runApplication<Application>(*args)
        }

        val emptySchema = McpSchema.JsonSchema("object", emptyMap(), emptyList(), false, emptyMap(), emptyMap())
    }

    @Bean
    fun missingTool(): McpServerFeatures.AsyncToolSpecification = McpServerFeatures.AsyncToolSpecification
        .builder()
        .tool(McpSchema.Tool.builder().name("missing").inputSchema(emptySchema).build())
        .callHandler { _, _ -> error("Test!") }
        .build()

    @Bean
    fun presentTool(): List<McpServerFeatures.AsyncToolSpecification> = listOf(
        McpServerFeatures.AsyncToolSpecification
            .builder()
            .tool(McpSchema.Tool.builder().name("present").inputSchema(emptySchema).build())
            .callHandler { _, _ -> error("Test!") }
            .build()
    )

    @McpTool(name = "present2")
    fun presentTool2(): Mono<String> = mono { error("Test!") }
}
spring:
  ai:
    mcp:
      server:
        type: ASYNC  # Recommended for reactive applications
        annotation-scanner:
          enabled: true
        capabilities:
          tool: true
          resource: true
          prompt: true
          completion: true
        stdio: false

Additional information

The issue seems to be with McpServerAutoConfiguration. If I debug mcpAsyncServer, calling tools.getIfAvailable returns a list containing only my bean (and not ones derived from @McpTool annotated methods) while tools.stream().flatMap(List::stream).toList() returns only the @McpTool tools. I'm not familiar enough with the internals of Spring to know why.

Note that registering my tool as a List<AsyncToolSpecification> bean makes it work fine.