Bug description
Similar to https://github.com/spring-projects/spring-ai/issues/4392. Only @McpTool functions that return Mono, etc, are used in ASYNC mode. This should also include Kotlin suspend functions (as well as ideally Flow returning functions).
I've categorized it as a bug, but if Kotlin isn't officially supported (i.e. https://github.com/spring-projects/spring-ai/issues/3718) it may fit better as a feature request.
Environment Java 24, Kotlin 2.2.10, Spring AI 1.1.0-M2
Steps to reproduce
Have a @McpTool method that returns Mono that works with an async server.
Change it to not return Mono but be suspend.
Expected behavior The function is still detected.
Minimal Complete Reproducible example
@SpringBootApplication
class Application {
companion object {
@JvmStatic
fun main(args: Array<String>) {
runApplication<Application>(*args)
}
}
@McpTool
fun testTool(): Mono<String> {
return Mono.just("test")
}
@McpTool
suspend fun testTool2(): String {
return "test"
}
}
testTool is registered, testTool2 is not. Config:
spring:
ai:
mcp:
server:
type: ASYNC
annotation-scanner:
enabled: true
capabilities:
tool: true
resource: true
prompt: true
completion: true
stdio: false
Comment From: jmirc
I had the same issue.
🔍 What's happening in the code?
The line you're pointing to is part of a stream pipeline that processes a list of tool objects to extract method specifications annotated with @McpTool. Here's a simplified breakdown:
List<AsyncToolSpecification> toolSpecs = this.toolObjects.stream()
.map(toolObject -> Stream.of(this.doGetClassMethods(toolObject))
.filter(method -> method.isAnnotationPresent(McpTool.class))
.filter(McpProviderUtils.isReactiveReturnType)
....