AI AGENT 智能體開發之MCP擴展加載 (Spring AI 1.0.0-M6)
·
背景
因為2025年初使用Spring AI 1.0.0-M6構建智能體項目,所以版本有Bug也得踩。項目本來使用模型工具來實現“動作”,為了使得工具定義更快,先決定引入MCP的方式加速模塊化開發。官方文檔翻來覆去看了幾十遍,百度、谷歌了幾十篇文檔,甚至Gemini、ChatGPT查詢好久。僅僅找找一篇構建MCP Server的有價值的文檔。現將全部實踐做記錄。
追加多MCP動態接入擴展。
代碼
一、MCP Server 構建
①引入依賴(不要問為什麼引入這麼多,因為這是踩過坑的) Spring AI 1.0.0-M6
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp</artifactId>
</dependency>
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>0.32.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
②配置文件
spring.ai.mcp.server.enabled=true
spring.ai.mcp.server.name= webmvc-mcp-server
spring.ai.mcp.server.version= 1.0.0
spring.ai.mcp.server.type= SYNC
#spring.ai.mcp.server.type= ASYNC
spring.ai.mcp.server.sse-message-endpoint=/mcp/messages
# 暴露健康检查端点
management.endpoints.web.exposure.include=health
③配置類
@Configuration
@EnableWebMvc
public class McpServerConfig implements WebMvcConfigurer {
@Bean
public ToolCallbackProvider openLibraryTools(ToolServer toolServer) {
return MethodToolCallbackProvider.builder().toolObjects(toolServer).build();
}
}
④模型工具
@Service
public class WeatherService {
@Tool(description = "Get weather information by city name")
public String getWeather(String cityName) {
return cityName+":"+simulateTempAtTime(2.0,25.0,10.0);
}
public static BigDecimal simulateTempAtTime(double time, double baseTemp, double tempRange) {
double amplitude = tempRange / 2.0; // 振幅
// 1. 基礎趨勢:使用 Cos 函數模擬日溫變化
// 這裡使用 double time 計算,曲線會更平滑,支援非整點時刻
double trend = -Math.cos((time - 2) * Math.PI / 12);
// 2. 隨機噪音:模擬雲層或風導致的微小波動 (-0.5 ~ 0.5 度)
double noise = ThreadLocalRandom.current().nextDouble(-0.5, 0.5);
// 3. 計算最終溫度並格式化
return BigDecimal.valueOf(baseTemp + (trend * amplitude) + noise)
.setScale(1, RoundingMode.HALF_UP);
}
}
二、MCP Client 構建
①引入依賴 Spring AI 1.0.0-SNAPSHOT
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
②配置文件(注意從第二個Server開始需要增加配置,sse-endpoint)
spring.ai.mcp.client.enabled=true
spring.ai.mcp.client.name=my-mcp-client
spring.ai.mcp.client.request-timeout=60s
spring.ai.mcp.client.type=SYNC
spring.ai.mcp.client.sse.connections.server1.url= http://127.0.0.1:8888
spring.ai.mcp.client.sse.connections.server2.url= http://127.0.0.1:7777
spring.ai.mcp.client.sse.connections.server2.sse-endpoint=/server2-sse
③(可選)有些模型調用需要代理
@Configuration
public class McpClientWebClientConfig {
@Bean
@Primary
public WebClient.Builder mcpWebClientBuilder(
@Qualifier("mcpHttpClient") HttpClient mcpHttpClient) {
return WebClient.builder()
.clientConnector(
new ReactorClientHttpConnector(mcpHttpClient)
);
}
@Bean
@Qualifier("mcpHttpClient")
public HttpClient mcpHttpClient() {
return HttpClient.create()
.noProxy();
}
}
④MCP Client 調用 MCP Server
@Autowired
private List<McpSyncClient> mcpSyncClients;
@Autowired
private SyncMcpToolCallbackProvider toolCallbackProvider;
@PostMapping("/a/chat")
public String chat(/* @RequestBody SearchText searchRequest */) {
ToolCallback[] toolCallbacks = toolCallbackProvider.getToolCallbacks();
System.out.println(mcpSyncClients.toString());
System.out.println(toolCallbacks.toString());
return chatClient
.prompt("查詢重慶天氣信息")
.tools(toolCallbacks)
.call()
.content();
}
三、智能體(或者MCP Client)如何動態接入多個MCP Server?
1.分析源碼,根據源碼新增配置類
@Configuration
public class DbMcpClientConfiguration {
@Bean
public List<NamedClientMcpTransport> dbMcpClientTransports(
ObjectMapper objectMapper) {
List<McpClientConfig> cfgs = new ArrayList<>();
// cfgs = repository.findEnabled();
McpClientConfig cfg1=new McpClientConfig();
cfg1.setBaseUrl("http://127.0.0.1:8888");
cfg1.setName("my-mcp-client");
cfg1.setCode("mcp001");
cfg1.setEnabled(true);
cfg1.setTimeout(Duration.ofSeconds(30));
cfg1.setVersion("1.0.1");
cfgs.add(cfg1);
List<NamedClientMcpTransport> transports = new ArrayList<>();
for (McpClientConfig cfg : cfgs) {
var transport = new HttpClientSseClientTransport(
HttpClient.newBuilder(),
cfg.getBaseUrl(),
objectMapper
);
transports.add(
new NamedClientMcpTransport(cfg.getCode(), transport)
);
}
return transports;
}
}
更多推荐
所有评论(0)