Skip to content

Commit f046a09

Browse files
liu-657667glmapper
authored andcommitted
添加 Nacos MCP 客户端和服务端模块 (#32)
* support nacos mcp guides
1 parent e50a71a commit f046a09

File tree

13 files changed

+356
-0
lines changed

13 files changed

+356
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Spring AI Nacos MCP Client
2+
3+
这是一个Spring AI Nacos MCP客户端模块,提供基于Nacos注册中心的MCP(Model Context Protocol)客户端实现。
4+
5+
## 功能特性
6+
- 基于Nacos的服务发现
7+
- 集成OpenAI兼容的聊天模型
8+
- 支持与MCP服务端通信
9+
- 提供REST API进行对话交互
10+
11+
## 客户端配置
12+
配置在`application.yml`中设置:
13+
```yaml
14+
spring:
15+
ai:
16+
openai:
17+
api-key: ${spring.ai.openai.api-key} # DashScope平台API密钥
18+
chat:
19+
base-url: https://dashscope.aliyuncs.com/compatible-mode # 兼容模式基础URL
20+
completions-path: /v1/chat/completions # 补全路径
21+
options:
22+
model: qwen-plus # 使用的模型类型
23+
mcp:
24+
client:
25+
name: mcp-nacos-client # 客户端名称(需全局唯一)
26+
version: 1.0.0 # 客户端版本(语义化版本号)
27+
request-timeout: 30s # 请求超时时间
28+
type: ASYNC # 通信类型(ASYNC适用于响应式应用)
29+
enabled: true # 启用MCP客户端
30+
alibaba:
31+
mcp:
32+
nacos:
33+
namespace: 07fa822a-269c-4b42-a4ab-d243351e57aa # Nacos命名空间ID
34+
server-addr: 127.0.0.1:8848 # Nacos服务器地址
35+
username: nacos # Nacos认证用户名
36+
password: nacos # Nacos认证密码
37+
client:
38+
enabled: true # 启用Nacos客户端
39+
sse:
40+
connections:
41+
server1:
42+
service-name: weather-mcp-server # 要连接的服务名称
43+
version: 1.0.0 # 服务版本
44+
```
45+
46+
## 启动客户端
47+
确保已启动Nacos服务器和MCP服务端,然后运行:
48+
```bash
49+
mvn spring-boot:run
50+
```
51+
52+
## 主要组件
53+
- `NacosClientApplication` - 应用主类
54+
- `ChatController` - 对话交互的REST控制器
55+
- `McpClientConfig` - MCP客户端配置类
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>com.glmapper</groupId>
8+
<artifactId>spring-ai-mcp</artifactId>
9+
<version>0.0.1</version>
10+
</parent>
11+
12+
<groupId>com.glmapper.ai.nacos.client</groupId>
13+
<artifactId>nacos-mcp-client</artifactId>
14+
15+
<dependencies>
16+
17+
<dependency>
18+
<groupId>com.alibaba.cloud.ai</groupId>
19+
<artifactId>spring-ai-alibaba-starter-nacos-mcp-client</artifactId>
20+
<version>1.0.0.3-SNAPSHOT</version>
21+
</dependency>
22+
23+
<dependency>
24+
<groupId>org.springframework.ai</groupId>
25+
<artifactId>spring-ai-autoconfigure-model-openai</artifactId>
26+
</dependency>
27+
28+
<dependency>
29+
<groupId>org.springframework.ai</groupId>
30+
<artifactId>spring-ai-autoconfigure-model-chat-client</artifactId>
31+
</dependency>
32+
33+
<dependency>
34+
<groupId>org.springframework.ai</groupId>
35+
<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
36+
</dependency>
37+
38+
</dependencies>
39+
40+
</project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.glmapper.ai.nacos.client;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class NacosClientApplication {
8+
public static void main(String[] args) {
9+
SpringApplication.run(NacosClientApplication.class, args);
10+
}
11+
12+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.glmapper.ai.nacos.client.config;
2+
3+
import org.springframework.ai.chat.client.ChatClient;
4+
import org.springframework.ai.openai.OpenAiChatModel;
5+
import org.springframework.ai.tool.ToolCallbackProvider;
6+
import org.springframework.beans.factory.annotation.Qualifier;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.context.annotation.Configuration;
9+
10+
@Configuration
11+
public class McpClientConfig {
12+
@Bean
13+
ChatClient chatClient(OpenAiChatModel chatModel, @Qualifier("loadbalancedMcpAsyncToolCallbacks") ToolCallbackProvider toolCallbackProvider) {
14+
return ChatClient.builder(chatModel).defaultToolCallbacks(toolCallbackProvider.getToolCallbacks()).build();
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.glmapper.ai.nacos.client.controller;
2+
3+
import jakarta.annotation.Resource;
4+
import lombok.RequiredArgsConstructor;
5+
import org.springframework.ai.chat.client.ChatClient;
6+
import org.springframework.web.bind.annotation.GetMapping;
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
@RestController
11+
@RequestMapping("/mcp/chat")
12+
@RequiredArgsConstructor
13+
public class ChatController {
14+
15+
@Resource
16+
private ChatClient chatClient;
17+
18+
@GetMapping("/ai")
19+
public String generation(String userInput) {
20+
return this.chatClient.prompt().user(userInput).call().content();
21+
}
22+
23+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
spring:
2+
ai:
3+
openai:
4+
api-key: ${spring.ai.openai.api-key} # DashScope平台API密钥
5+
chat:
6+
base-url: https://dashscope.aliyuncs.com/compatible-mode # 兼容模式基础URL
7+
completions-path: /v1/chat/completions # 补全路径
8+
options:
9+
model: qwen-plus # 使用的模型类型
10+
mcp:
11+
client:
12+
name: mcp-nacos-client # 客户端名称(需全局唯一)
13+
version: 1.0.0 # 客户端版本(语义化版本号)
14+
request-timeout: 30s # 请求超时时间
15+
type: ASYNC # 通信类型(ASYNC适用于响应式应用)
16+
enabled: true # 启用MCP客户端
17+
alibaba:
18+
mcp:
19+
nacos:
20+
namespace: 07fa822a-269c-4b42-a4ab-d243351e57aa # Nacos命名空间ID
21+
server-addr: 127.0.0.1:8848 # Nacos服务器地址
22+
username: nacos # Nacos认证用户名
23+
password: nacos # Nacos认证密码
24+
client:
25+
enabled: true # 启用Nacos客户端
26+
sse:
27+
connections:
28+
server1:
29+
service-name: weather-mcp-server # 要连接的服务名称
30+
version: 1.0.0 # 服务版本
31+
server:
32+
port: 8082
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Spring AI Nacos MCP Server
2+
3+
这是一个Spring AI Nacos MCP服务端模块,提供基于Nacos注册中心的MCP(Model Context Protocol)服务实现。
4+
5+
## 功能特性
6+
- 基于Nacos的服务注册与发现
7+
- 提供天气查询工具服务
8+
- 支持异步消息通信
9+
- 完整的MCP协议支持
10+
11+
## 服务配置
12+
配置在`application.yml`中设置:
13+
```yaml
14+
spring:
15+
ai:
16+
mcp:
17+
server:
18+
name: weather-mcp-server # MCP服务名称(需全局唯一)
19+
version: 1.0.0 # 服务版本(语义化版本号)
20+
type: ASYNC # 通信类型(ASYNC适用于响应式应用)
21+
sse-message-endpoint: /mcp/messages # SSE消息端点路径
22+
capabilities:
23+
tool: true # 启用工具调用能力
24+
resource: false # 禁用资源访问能力
25+
prompt: false # 禁用提示词功能
26+
completion: false # 禁用补全功能
27+
alibaba:
28+
mcp:
29+
nacos:
30+
namespace: 07fa822a-269c-4b42-a4ab-d243351e57aa # Nacos命名空间ID
31+
server-addr: 127.0.0.1:8848 # Nacos服务器地址
32+
username: nacos # Nacos认证用户名
33+
password: nacos # Nacos认证密码
34+
registry:
35+
enabled: true # 启用服务注册
36+
service-group: mcp-server # 服务分组
37+
service-name: weather-mcp-server # 服务名称(应与server.name一致)
38+
```
39+
40+
## Nacos初始化配置
41+
在启动服务前,请确保已正确初始化Nacos:
42+
1. 启动Nacos服务器(可使用Docker Compose)
43+
```bash
44+
docker-compose up -d
45+
```
46+
47+
2. 创建命名空间(如未使用默认public空间)
48+
- 登录Nacos控制台(http://localhost:8080)
49+
- 在"命名空间"页面创建新命名空间
50+
- 使用对应的namespace ID配置
51+
52+
3. 配置服务元数据(可选)
53+
- 可通过Nacos控制台设置服务的元数据信息
54+
- 这些信息可用于服务发现时的过滤条件
55+
56+
## 启动服务
57+
确保已启动Nacos服务器,然后运行:
58+
```bash
59+
mvn spring-boot:run
60+
```
61+
62+
## 主要组件
63+
- `NacosServerApplication` - 应用主类
64+
- `WeatherService` - 天气查询工具服务
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
services:
2+
nacos:
3+
image: nacos/nacos-server
4+
container_name: nacos-standalone-derby
5+
environment:
6+
- MODE=standalone
7+
- NACOS_AUTH_TOKEN=${your_nacos_auth_secret_token}
8+
- NACOS_AUTH_IDENTITY_KEY=${your_nacos_server_identity_key}
9+
- NACOS_AUTH_IDENTITY_VALUE=${your_nacos_server_identity_value}
10+
ports:
11+
- "8080:8080"
12+
- "8848:8848"
13+
- "9848:9848"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>com.glmapper</groupId>
8+
<artifactId>spring-ai-mcp</artifactId>
9+
<version>0.0.1</version>
10+
</parent>
11+
12+
<groupId>com.glmapper.ai.nacos.server</groupId>
13+
<artifactId>nacos-mcp-server</artifactId>
14+
15+
<dependencies>
16+
17+
<dependency>
18+
<groupId>org.springframework.ai</groupId>
19+
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
20+
</dependency>
21+
22+
<dependency>
23+
<groupId>com.alibaba.cloud.ai</groupId>
24+
<artifactId>spring-ai-alibaba-starter-nacos-mcp-server</artifactId>
25+
<version>1.0.0.3-SNAPSHOT</version>
26+
</dependency>
27+
28+
</dependencies>
29+
30+
</project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.glmapper.ai.nacos.server;
2+
3+
import com.glmapper.ai.nacos.server.service.WeatherService;
4+
import org.springframework.ai.tool.ToolCallbackProvider;
5+
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
6+
import org.springframework.boot.SpringApplication;
7+
import org.springframework.boot.autoconfigure.SpringBootApplication;
8+
import org.springframework.context.annotation.Bean;
9+
10+
@SpringBootApplication
11+
public class NacosServerApplication {
12+
public static void main(String[] args) {
13+
SpringApplication.run(NacosServerApplication.class, args);
14+
}
15+
16+
// 注册工具回调
17+
@Bean
18+
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
19+
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
20+
}
21+
22+
}

0 commit comments

Comments
 (0)