Bug description
I have an example project with 3 separate MCP Servers, but I am focusing on the pets-service
MCP Server example:
https://github.com/murphye/mcp-agentgateway-spring-ai-demo
To get Tools to list for an MCP Client, I have to add some extra code per the Spring MCP Server documentation, where PetsService
contains my @Tool
s:
@Bean
fun petsTools(petsService: PetsService): ToolCallbackProvider {
return MethodToolCallbackProvider.builder().toolObjects(petsService).build()
}
When adding the ToolCallbackProvider
code as specified, and if I have a ChatClient
used for my @Tool
s, it create a circular dependency error for toolCallbackResolver
.
@Service
class PetsService(private val chatClientBuilder: ChatClient.Builder) {
//...
private val chatClient: ChatClient by lazy {
chatClientBuilder.build()
}
//...
@Tool(description = "Search for available dogs for adoption")
fun searchDogs(criteria: String): String {
//...
val response = chatClient.prompt()
.user("Based on the search criteria '$criteria', recommend dogs from this list:\n$dogsInfo")
.call()
.content()
return response ?: "No dogs found matching your criteria."
}
Error:
The dependencies of some of the beans in the application context form a cycle:
petsApplication (field private com.demo.pets.PetsService com.demo.pets.PetsApplication.petsService)
┌─────┐
| petsService defined in file [/Users/insite/Documents/GitHub/mcp-agentgateway-spring-ai-demo/pets-service/target/classes/com/demo/pets/PetsService.class]
↑ ↓
| chatClientBuilder defined in class path resource [org/springframework/ai/model/chat/client/autoconfigure/ChatClientAutoConfiguration.class]
↑ ↓
| anthropicChatModel defined in class path resource [org/springframework/ai/model/anthropic/autoconfigure/AnthropicChatAutoConfiguration.class]
↑ ↓
| toolCallingManager defined in class path resource [org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfiguration.class]
↑ ↓
| toolCallbackResolver defined in class path resource [org/springframework/ai/model/tool/autoconfigure/ToolCallingAutoConfiguration.class]
↑ ↓
| petsTools defined in class path resource [com/demo/pets/PetsMcpConfig.class]
└─────┘
Environment
I am currently using Spring AI 1.1.0-SNAPSHOT.
Steps to reproduce
- Open
PetsMcpConfig.kt
. - Uncomment
fun petsTools(petsService: PetsService): ToolCallbackProvider
mvn compile spring-boot:test -pl pets-service
(Docker must be running)- Note that a circular reference error happens for
toolCallbackResolver
Expected behavior
No circular references error if must configure ToolCallbackProvider
Minimal Complete Reproducible example
See steps to reproduce for the example.
Comment From: murphye
I found a workaround using @Lazy
to avoid the error, but this is not ideal:
@Configuration
class PetsMcpConfig(@Lazy val petsService: PetsService) {
//...
@Bean
fun petsTools(): ToolCallbackProvider {
return MethodToolCallbackProvider.builder().toolObjects(petsService).build()
}