MCP

下载客户端

Cherry Studio https://pan.quark.cn/s/14657423f0c9

构建mcp-server

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.easyai</groupId>
<artifactId>easyai</artifactId>
<version>1.0.0</version>
</parent>

<groupId>com.easyai</groupId>
<artifactId>mcp-server-sse</artifactId>
<name>mcp-server-sse</name>
<version>1.0.0</version>

<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.easyai.McpSseServerApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

WeatherService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class WeatherService {

@Tool(description = "通过城市名称获取天气")
public String getWeather(@ToolParam(description = "城市名称") String cityName) {
return String.format("城市 %s 的天气:晴,温度 25 摄氏度。今天是 %s", cityName, new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
}
}

McpSseServerApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class McpSseServerApplication {

private static final Logger logger = LoggerFactory.getLogger(McpSseServerApplication.class);

public static void main(String[] args) {
SpringApplication.run(McpSseServerApplication.class, args);
}

@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
logger.info("注册天气工具到 MCP 服务器");
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}
}

application.yml(sse)

1
2
3
4
5
6
7
8
9
10
server:
port: 8083
spring:
ai:
mcp:
server:
sse:
enabled: true # 启用SSE模式
name: weather-server # 服务器名称
version: 1.0.0

application.yml(sdtio)

1
2
3
4
5
6
7
8
9
spring:
main:
web-application-type: none //不以web服务启动
banner-mode: off //关闭启动时候的spring logo
ai:
mcp:
server:
name: weather-server # 服务器名称
version: 1.0.0

application.yml(streamable http)

1
2
3
4
5
6
7
8
9
10
11
12
server:
port: 8084
spring:
ai:
mcp:
server:
protocol: STREAMABLE # STREAMABLE STATELESS
name: weather-server # 服务器名称
version: 1.0.0
streamable-http:
mcp-endpoint: /mcp #默认是mcp
keep-alive-interval: 30s

Cherry Studio 调用mcp-server

SSE调用

Stdio调用

streamable http调用

springai 调用mcp server

McpController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/mcp")
public class McpController {

@Resource
private ChatClient ollamaChatChatClient;

@Resource
private ToolCallbackProvider toolCallbackProvider;

@RequestMapping(value = "/chat1", produces = "text/stream;charset=utf8")
public Flux<String> chatOllama() {
Flux<String> flux = ollamaChatChatClient.prompt()
.toolCallbacks(toolCallbackProvider)
.user("武汉今天的天气如何,还有天气报道的时间")
.stream().content();
return flux;
}
}

application-dev.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
spring:
datasource:
url: jdbc:mysql://localhost:3306/easyai?allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2B8&characterEncoding=utf8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
config:
activate:
on-profile: dev
ai:
mcp:
client:
enabled: true
name: my-mcp-client
version: 1.0.0
request-timeout: 30s
type: SYNC # or ASYNC for reactive applications
stdio:
servers-configuration: classpath:/mcp/mcp-server-config.json
#sse:
# connections:
# weather-server: # 连接标识符,可自定义
# url: http://localhost:8083 # 天气服务器的SSE端点
# 开发环境特定配置
debug: true

mcp-server-config.json

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"mcpServers": {
"mcp-server-weather": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dlogging.pattern.console=",
"-jar",
"E:\\workspace21\\easyai\\mcp-server-stdio\\target\\mcp-server-stdio-1.0.0.jar"
]
}
}
}

代码分析