This commit is contained in:
louis-xiv 2025-04-24 14:22:37 +08:00
parent 3c73dee8f3
commit d762a1fde5
11 changed files with 137 additions and 56 deletions

2
.gitignore vendored
View File

@ -31,3 +31,5 @@ build/
### VS Code ###
.vscode/
*.log

View File

@ -33,7 +33,7 @@
<!-- spring ai -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<!-- <dependency>-->
@ -41,12 +41,6 @@
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>-->
<!-- </dependency>-->
<!--actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>

View File

@ -1,7 +0,0 @@
package cn.louisxiv.mcp.dbconnect;
import org.springframework.stereotype.Component;
@Component
public class DbConnectTool {
}

View File

@ -1,14 +1,7 @@
package cn.louisxiv.mcp.dbconnect;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.function.FunctionToolCallback;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
@SpringBootApplication
public class McpDbConnectApplication {
@ -16,26 +9,4 @@ public class McpDbConnectApplication {
public static void main(String[] args) {
SpringApplication.run(McpDbConnectApplication.class, args);
}
// @Bean
// public ToolCallbackProvider dbConnectTool() {
// List<ToolCallback> tools = ...
// return ToolCallbackProvider.from(tools);
// }
@Bean
public ToolCallback getTime() {
return FunctionToolCallback.builder("getNowTime", this::getNowTime)
.inputType(String.class)
.description("Get now time, input: timeZone")
.build();
}
private String getNowTime(String timeZone) {
ZonedDateTime zonedDateTime = ZonedDateTime.now();
LocalTime localTime = zonedDateTime.withZoneSameInstant(ZoneId.of(timeZone)).toLocalTime();
return localTime.toString();
}
}

View File

@ -0,0 +1,19 @@
package cn.louisxiv.mcp.dbconnect.config;
import cn.louisxiv.mcp.dbconnect.tool.DbConnectTool;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfiguration {
/**
* 声明ToolCallbackProvider
*/
@Bean
public ToolCallbackProvider toolCallbackProvider(DbConnectTool dbConnectTool) {
return MethodToolCallbackProvider.builder().toolObjects(dbConnectTool).build();
}
}

View File

@ -0,0 +1,16 @@
package cn.louisxiv.mcp.dbconnect.tool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class DbConnectTool {
@Tool(description = "获取表结构定义,参数是表名")
public String getTableDefinition(String tableName) {
log.info("get table definition: {}", tableName);
return "create " + tableName;
}
}

View File

@ -4,21 +4,14 @@ spring:
mcp:
server:
name: mcp-db-connect
version: 1.0.0
type: SYNC
sse-message-endpoint: /mcp/messages
version: 0.0.1
type: ASYNC
sse-message-endpoint: /mcp/sse
# 退化为STDIO模式需要关闭banner
main:
banner-mode: off
management:
endpoints:
web:
exposure:
include: health,info,metrics,env,beans,mappings
endpoint:
health:
show-details: always
# 退化为STDIO模式需要关闭控制台日志
logging:
file:
name: ./model-context-protocol/weather/starter-webmvc-server/target/starter-webmvc-server.log
name: ./log/mcp-server.log

View File

@ -0,0 +1,28 @@
package cn.louisxiv.mcp.dbconnect.tool;
import io.modelcontextprotocol.client.McpAsyncClient;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.transport.StdioClientTransport;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
@SpringBootTest
@ActiveProfiles("stdio")
public class DbConnectToolStdioTest {
McpAsyncClient mcpAsyncClient;
@BeforeEach
public void init() {
//mcpAsyncClient = McpClient.async(new StdioClientTransport());
}
@Test
public void testStdio() {
}
}

View File

@ -0,0 +1,50 @@
package cn.louisxiv.mcp.dbconnect.tool;
import io.modelcontextprotocol.client.McpAsyncClient;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.transport.WebFluxSseClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.web.reactive.function.client.WebClient;
import java.util.Map;
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ActiveProfiles("webflux")
public class DbConnectToolWebFluxTest {
McpAsyncClient mcpAsyncClient;
@Value(value = "${app.base-url}")
String baseUrl;
@Value(value = "/sse")
String sseEndpoint;
@BeforeEach
public void init() {
log.info("baseUrl: {}", baseUrl);
log.info("sseEndpoint: {}", sseEndpoint);
var webClient = WebClient.builder().baseUrl(baseUrl);
var client = WebFluxSseClientTransport.builder(webClient)
.sseEndpoint(sseEndpoint)
.build();
mcpAsyncClient = McpClient.async(client).build();
}
@Test
public void testWebFlux() {
log.info("test webflux start");
Map<String, Object> map = Map.of("tableName", "t_test");
McpSchema.CallToolRequest request = new McpSchema.CallToolRequest("getTableDefinition", map);
var result = mcpAsyncClient.callTool(request);
var a = result.contextCapture().subscribe();
log.info("test end: {}", a);
}
}

View File

@ -0,0 +1,9 @@
spring:
ai:
mcp:
server:
stdio: true
logging:
file:
name: ./log/stdio/test.log

View File

@ -0,0 +1,6 @@
app:
base-url: http://localhost:8080
logging:
file:
name: ./log/webflux/test.log