refactor: update MCP API usage to version 0.8.0

- Remove all book-library MCP examples (servlet, webflux, and webmvc implementations)
- Update weather example to use MCP version 0.8.0-SNAPSHOT
- Refactor transport handling to use transport providers instead of direct transport objects
- Update method calls from toSyncToolRegistration to toSyncToolSpecifications
- Add central-portal-snapshots repository to pom.xml for dependency resolution
- Align with the new MCP client class names

Add MCP Sampling capability with weather example

Adds MCP Sampling implementation that demonstrates how to delegate LLM requests to multiple providers.

- add a weather server that retrieves data and uses MCP Sampling to generate creative content
- add a client that routes requests to different LLM providers (OpenAI and Anthropic) based on model hints
- add README documentation explaining the MCP Sampling workflow and implementation details

The MCP Sampling capability enables applications to leverage multiple LLM providers within a single workflow,
allowing for creative content generation, model comparison, and specialized task delegation.

refactor: migrate to spring-ai-mcp-client-spring-boot-starter

- Replace spring-ai-mcp dependency with spring-ai-mcp-client-spring-boot-starter
- Update import statements from org.springframework.ai.mcp.* to io.modelcontextprotocol.client.*
- Replace McpFunctionCallback with SyncMcpToolCallbackProvider
- Update Spring AI version from 1.0.0-M5 to 1.0.0-SNAPSHOT in multiple projects
- Enable tool callback auto-configuration with spring.ai.mcp.client.toolcallback.enabled

refactor: update Spring AI artifact IDs to new naming convention

- Update all Spring AI dependencies to use the new naming convention:
spring-ai-*-spring-boot-starter → spring-ai-starter-*
spring-ai-openai-spring-boot-starter → spring-ai-starter-model-openai
spring-ai-mcp-client-spring-boot-starter → spring-ai-starter-mcp-client
- And similar patterns for other artifacts
- Enable debug mode in brave module's application.properties

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
Christian Tzolov
2025-03-18 12:26:20 +01:00
committed by Mark Pollack
parent 1ca981eba5
commit 41c921bc33
96 changed files with 1732 additions and 4340 deletions

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2025-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.mcp.samples.client;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import io.modelcontextprotocol.client.McpSyncClient;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpSchema.CreateMessageResult;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
import org.springframework.ai.mcp.customizer.McpSyncClientCustomizer;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class McpClientApplication {
public static void main(String[] args) {
SpringApplication.run(McpClientApplication.class, args);
}
@Bean
public CommandLineRunner predefinedQuestions(OpenAiChatModel openAiChatModel,
ConfigurableApplicationContext context, List<McpSyncClient> mcpClients) {
return args -> {
var mcpToolProvider = new SyncMcpToolCallbackProvider(mcpClients);
ChatClient chatClient = ChatClient.builder(openAiChatModel).defaultTools(mcpToolProvider).build();
String userQuestion = """
What is the weather in Amsterdam right now?
Please incorporate all createive responses from all LLM providers.
After the other providers add a poem that synthesizes the the poems from all the other providers.
""";
System.out.println("> USER: " + userQuestion);
System.out.println("> ASSISTANT: " + chatClient.prompt(userQuestion).call().content());
context.close();
};
}
@Bean
McpSyncClientCustomizer samplingCustomizer(Map<String, ChatClient> chatClients) {
return (name, mcpClientSpec) -> {
mcpClientSpec.sampling(llmRequest -> {
var userPrompt = ((McpSchema.TextContent) llmRequest.messages().get(0).content()).text();
String modelHint = llmRequest.modelPreferences().hints().get(0).name();
ChatClient hintedChatClient = chatClients.entrySet().stream()
.filter(e -> e.getKey().contains(modelHint)).findFirst()
.orElseThrow().getValue();
String response = hintedChatClient.prompt()
.system(llmRequest.systemPrompt())
.user(userPrompt)
.call()
.content();
return CreateMessageResult.builder().content(new McpSchema.TextContent(response)).build();
});
System.out.println("Customizing " + name);
};
}
@Bean
public Map<String, ChatClient> chatClients(List<ChatModel> chatModels) {
return chatModels.stream().collect(Collectors.toMap(model -> model.getClass().getSimpleName().toLowerCase(),
model -> ChatClient.builder(model).build()));
}
}

View File

@@ -0,0 +1,16 @@
spring.application.name=mcp
spring.main.web-application-type=none
# Disable the chat client auto-configuration because we are using multiple chat models
spring.ai.chat.client.enabled=false
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.anthropic.api-key=${ANTHROPIC_API_KEY}
spring.ai.mcp.client.sse.connections.server1.url=http://localhost:8080
logging.level.io.modelcontextprotocol.client=WARN
logging.level.io.modelcontextprotocol.spec=WARN
# spring.ai.mcp.client.toolcallback.enabled=false