Spring AI Alibaba 【六】
MCP(模型上下文协议)是一种用于将 AI 应用程序连接到外部系统的开源标准。使用 MCP,Claude 或 ChatGPT 等人工智能应用程序可以连接到数据源(例如本地文件、数据库)、工具(例如搜索引擎、计算器)和工作流程(例如专门提示),使它们能够访问关键信息并执行任务。将 MCP 视为用于 AI 应用的 USB-C 端口。正如 USB-C 提供了连接电子设备的标准化方式一样,MCP 也提供了
1. Tool Calling工具调用
1.1 定义
工具调用(也称为函数调用)是 AI 应用程序中的一种常见模式,允许模型与一组 API 或_工具_交互,从而增强其能力。
工具主要用于:
- 信息检索:此类工具可用于从外部源(如数据库、Web 服务、文件系统或 Web 搜索引擎)检索信息。目标是增强模型的知识,使其能够回答原本无法回答的问题。例如,工具可用于检索给定位置的当前天气、检索最新新闻文章或查询数据库中的特定记录。
- 执行操作:此类工具可用于在软件系统中执行操作,如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。目标是自动化原本需要人工干预或显式编程的任务。例如,工具可用于为客户预订航班、填写网页表单或基于自动化测试(TDD)实现 Java 类。
尽管我们通常将_工具调用_称为模型能力,但实际上是由客户端应用程序提供工具调用逻辑。模型只能请求工具调用并提供输入参数,而应用程序负责从输入参数执行工具调用并返回结果。模型永远无法访问作为工具提供的任何 API,这是一个关键的安全考虑因素。
简单来说,Tool Calling 就是LLM的外部utils工具类。
需要注意的是:
- ToolCalling(也称为FunctionCalling)它允许大模型与一组API或工具进行交互,将 LLM 的智能与外部工具或 API无缝连接,从而增强大模型其功能。
- LLM本身并不执行函数,它只是指示应该调用哪个函数以及如何调用。
1.2 作用
- 访问实时数据
- 执行某种工具类/辅助类操作,例如触发并调用第三方函数,比如发邮件/查询微信/调用支付宝/查看顺丰快递单据号等等......
1.3 工作流程

1.4 编码实战(不使用 ToolCalling)
1.4.1 新建Module
可以命名为 ToolCalling
1.4.2 修改POM文件
在依赖配置节点修改为以下配置:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-ai-alibaba dashscope-->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
1.4.3 编写配置文件
在resources目录下新建application.properties配置文件,内容如下:
server.port=8013
# 设置全局编码格式
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.charset=UTF-8
spring.application.name=ToolCalling
# ====SpringAIAlibaba Config=============
spring.ai.dashscope.api-key=${DASHSCOPE_API_KEY}
1.4.4 编写主启动类
新建主启动类,并编写如下内容:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ToolCallingApplication {
public static void main(String[] args){
SpringApplication.run(ToolCallingApplication.class, args);
}
}
1.3.5 编写业务类
新建子包controller,并在其中新建业务类 NoToolCallingController
import com.alibaba.cloud.ai.dashscope.api.DashScopeApi;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
public class NoToolCallingController
{
@Resource
private ChatModel chatModel;
/**
* http://localhost:8013/notoolcall/chat
* @param msg
* @return
*/
@GetMapping("/notoolcall/chat")
public Flux<String> chat(@RequestParam(name = "msg",defaultValue = "你是谁现在几点") String msg)
{
return chatModel.stream(msg);
}
}
1.3.6 测试
启动主启动类后,在浏览器中请求如下地址:
http://localhost:8013/notoolcall/chat

不使用 ToolCalling,则大模型无法感知时间。
1.5 编码实战(通过ChatModel实现)
1.5.1 新建Tool工具类
新建子包utils,并在其中创建工具类DateTimeTools
import org.springframework.ai.tool.annotation.Tool;
import java.time.LocalDateTime;
public class DateTimeTools{
/**
* 1.定义 function call(tool call)
* 2. returnDirect
* true = tool直接返回不走大模型,直接给客户
* false = 默认值,拿到tool返回的结果,给大模型,最后由大模型回复
*/
@Tool(description = "获取当前时间", returnDirect = false)
public String getCurrentTime()
{
return LocalDateTime.now().toString();
}
}
工具调用直接返回

1.5.2 编写业务类
在controller子包新建业务类 ToolCallingController
import com.atguigu.study.utils.DateTimeTools;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.ai.support.ToolCallbacks;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
public class ToolCallingController
{
@Resource
private ChatModel chatModel;
@GetMapping("/toolcall/chat")
public String chat(@RequestParam(name = "msg",defaultValue = "你是谁现在几点") String msg)
{
// 1.工具注册到工具集合里
ToolCallback[] tools = ToolCallbacks.from(new DateTimeTools());
// 2.将工具集配置进ChatOptions对象
ChatOptions options = ToolCallingChatOptions.builder().toolCallbacks(tools).build();
// 3.构建提示词
Prompt prompt = new Prompt(msg, options);
// 4.调用大模型
return chatModel.call(prompt).getResult().getOutput().getText();
}
}
1.5.3 测试
启动主启动类后,在浏览器中请求如下地址:
http://localhost:8013/toolcall/chat

1.6 编码实战(通过ChatClient实现)
由于chat client本身不会自动装配,直接定义无法使用,所以需要通过ChatClient.builder(chatModel).build()来构建。
1.6.1 编写配置类
新建子包config,并在其中新建配置类SaaLLMConfig
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SaaLLMConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel){
return ChatClient.builder(chatModel).build();
}
}
1.6.2 修改业务类
将上文的业务类 ToolCallingController 进一步替换为如下
import com.atguigu.study.utils.DateTimeTools;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.ai.support.ToolCallbacks;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
public class ToolCallingController
{
@Resource
private ChatModel chatModel;
@GetMapping("/toolcall/chat")
public String chat(@RequestParam(name = "msg",defaultValue = "你是谁现在几点") String msg)
{
// 1.工具注册到工具集合里
ToolCallback[] tools = ToolCallbacks.from(new DateTimeTools());
// 2.将工具集配置进ChatOptions对象
ChatOptions options = ToolCallingChatOptions.builder().toolCallbacks(tools).build();
// 3.构建提示词
Prompt prompt = new Prompt(msg, options);
// 4.调用大模型
return chatModel.call(prompt).getResult().getOutput().getText();
}
@Resource
private ChatClient chatClient;
@GetMapping("/toolcall/chat2")
public Flux<String> chat2(@RequestParam(name = "msg",defaultValue = "你是谁现在几点") String msg)
{
return chatClient.prompt(msg)
.tools(new DateTimeTools())
.stream()
.content();
}
}
1.6.3 测试
启动主启动类后,在浏览器中请求如下地址:

将 DateTimeTools的 getCurrentTime方法上的@Tool注解修改为如下
@Tool(description = "获取当前时间", returnDirect = true)

将@Tool注解修改为以下,即returnDirect 设置为false
@Tool(description = "获取当前时间", returnDirect = false)
请求的结果和默认是一致的

1.7 注意事项
ToolCalling使用的前提是大模型支持function call才能正常调用。
2. MCP模型上下文协议(Model Context Protocol)
2.1 MCP 出现之前的局限性
之前每个大模型(如DeepSeek、ChatGPT)需要为每个工具单独开发接口(FunctionCalling),导致重复劳动。
2.2 MCP定义
MCP(模型上下文协议)是一种用于将 AI 应用程序连接到外部系统的开源标准。使用 MCP,Claude 或 ChatGPT 等人工智能应用程序可以连接到数据源(例如本地文件、数据库)、工具(例如搜索引擎、计算器)和工作流程(例如专门提示),使它们能够访问关键信息并执行任务。将 MCP 视为用于 AI 应用的 USB-C 端口。正如 USB-C 提供了连接电子设备的标准化方式一样,MCP 也提供了将 AI 应用程序连接到外部系统的标准化方式。

模型上下文协议(即 Model Context Protocol,MCP)是一个开放协议,它规范了应用程序如何向大型语言模型(LLM)提供上下文。MCP 提供了一种统一的方式将 AI 模型连接到不同的数据源和工具,它定义了统一的集成方式。在开发智能体(Agent)的过程中,我们经常需要将将智能体与数据和工具集成,MCP 以标准的方式规范了智能体与数据及工具的集成方式,可以帮助您在 LLM 之上构建智能体(Agent)和复杂的工作流。
简单地说,MCP协议就是Java界的SpringCloud Openfeign,只不过Openfeign是用于微服务通讯的,而MCP用于大模型通讯的,但它们都是为了通讯获取某项数据的一种机制。
2.3 作用
提供了一种标准化的方式来连接 LLMs 需要的上下文,MCP 就类似于一个 Agent 时代的 Type-C协议,希望能将不同来源的数据、工具、服务统一起来供大模型调用。
MCP 厉害的地方在于,不用重复造轮子。过去每个软件(比如微信、Excel)都要单独给 AI 做接口,现在 MCP 统一了标准,就像所有电器都用 USB-C 充电口,AI 一个接口就能连接所有工具。
形象化理解



官网地址: https://mcp.so/zh
2.4 MCP 架构知识
MCP遵循客户端-服务器架构,包含以下几个核心部分:

- MCP 主机(MCP Hosts):发起请求的 AI 应用程序,比如聊天机器人、AI 驱动的 IDE 等。
- MCP 客户端(MCP Clients):在主机程序内部,与 MCP 服务器保持 1:1 的连接。
- MCP 服务器(MCP Servers):为 MCP 客户端提供上下文、工具和提示信息。
- 本地资源(Local Resources):本地计算机中可供 MCP 服务器安全访问的资源,如文件、数据库。
- 远程资源(Remote Resources):MCP 服务器可以连接到的远程资源,如通过 API 提供的数据。
2.4.1 MCP的两种模式

2.4.1.1 STDIO(标准输入/输出)
支持标准输入和输出流进行通信,主要用于本地集成、命令行工具等场景。
2.4.1.2 SSE (Server-Sent Events)
支持使用 HTTP POST 请求进行服务器到客户端流式处理,以实现客户端到服务器的通信。
2.4.1.3 二者对比

2.5 小总结
- ToolCalling 工具类,为了让大模型使用Util工具。
- RAG 知识库,为了让大模型获取足够的上下文。
- MCP 协议,为了让大模型之间的相互调用。



2.5.1 MCP VS ToolCalling
之前每个大模型(如DeepSeek、ChatGPT)需要为每个工具单独开发接口(FunctionCalling),导致重复劳动(ToolCalling)
开发者只需写一次MCP服务端,所有兼容MCP协议的模型都能调用,MCP让大模型从"被动应答”变为”主动调用工具”(MCP)
调用一个MCP服务器就等价调用一个带有多个功能的Utils工具类,自己还不用受累携带(MCP)
2.6 编码实战(MCP-Server服务端实现)
2.6.1 新建Module
可以命名为LocalMcpServer
2.6.2 修改POM文件
在依赖配置节点修改为以下配置:
<dependencies>
<!--注意事项(重要)
spring-ai-starter-mcp-server-webflux不能和<artifactId>spring-boot-starter-web</artifactId>依赖并存,
否则会使用tomcat启动,而不是netty启动,从而导致mcpserver启动失败,但程序运行是正常的,mcp客户端连接不上。
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--mcp-server-webflux-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2.6.3 编写配置文件
在resources目录下新建application.properties配置文件,内容如下:
server.port=8014
# 设置全局编码格式
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.charset=UTF-8
spring.application.name=LocalMcpServer
# ====mcp-server Config=============
spring.ai.mcp.server.type=async
spring.ai.mcp.server.name=customer-define-mcp-server
spring.ai.mcp.server.version=1.0.0
2.6.4 编写主启动类
新建主启动类,并编写如下内容:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LocalMcpServerApplication {
public static void main(String[] args){
SpringApplication.run(LocalMcpServerApplication.class, args);
}
}
2.6.5 编写业务类
新建子包service,并在其中新建业务类 WeatherService
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class WeatherService {
@Tool(description = "根据城市名称获取天气预报")
public String getWeatherByCity(String city)
{
Map<String, String> map = Map.of(
"北京", "11111降雨频繁,其中今天和后天雨势较强,部分地区有暴雨并伴强对流天气,需注意",
"上海", "22222多云,15℃~27℃,南风3级,当前温度27℃。",
"深圳", "333333多云40天,阴16天,雨30天,晴3天"
);
return map.getOrDefault(city, "抱歉:未查询到对应城市!");
}
}
2.6.6 编写配置类
新建子包config,并在其中新建配置类 McpServerConfig
import com.atguigu.study.service.WeatherService;
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 McpServerConfig {
/**
* 将工具方法暴露给外部 mcp client 调用
* @param weatherService
* @return
*/
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider.builder()
.toolObjects(weatherService)
.build();
}
}
2.7 编码实战(MCP-Client客户端实现)
2.7.1 新建Module
可以命名为 LocalMcpClient
2.7.2 修改POM文件
在依赖配置节点修改为以下配置:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-ai-alibaba dashscope-->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<!-- 2.mcp-clent 依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2.7.3 编写配置文件
在resources目录下新建application.properties配置文件,内容如下:
server.port=8015
# 设置全局编码格式
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.charset=UTF-8
spring.application.name=LocalMcpClient
# ====SpringAIAlibaba Config=============
spring.ai.dashscope.api-key=${DASHSCOPE_API_KEY}
# ====mcp-client Config=============
spring.ai.mcp.client.type=async
spring.ai.mcp.client.request-timeout=60s
spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.sse.connections.mcp-server1.url=http://localhost:8014
2.7.4 编写主启动类
新建主启动类,并编写如下内容:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class LocalMcpClientApplication {
public static void main(String[] args){
SpringApplication.run(LocalMcpClientApplication.class, args);
}
}
2.7.5 编写业务类
新建子包controller,并在其中新建业务类 McpClientController
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
public class McpClientController
{
@Resource
private ChatClient chatClient;//使用mcp支持
@Resource
private ChatModel chatModel;//没有纳入tool支持,普通调用
// http://localhost:8015/mcpclient/chat?msg=上海
@GetMapping("/mcpclient/chat")
public Flux<String> chat(@RequestParam(name = "msg",defaultValue = "北京") String msg)
{
System.out.println("使用了mcp");
return chatClient.prompt(msg).stream().content();
}
@RequestMapping("/mcpclient/chat2")
public Flux<String> chat2(@RequestParam(name = "msg",defaultValue = "北京") String msg)
{
System.out.println("未使用mcp");
return chatModel.stream(msg);
}
}
2.7.6 编写配置类
新建子包config,并在其中新建配置类 SaaLLMConfig
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SaaLLMConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel, ToolCallbackProvider tools) {
return ChatClient.builder(chatModel)
.defaultToolCallbacks(tools.getToolCallbacks()) //mcp协议,配置见yml文件
.build();
}
}
2.7.7 测试
先启动MCP-Server端的主启动类,作为服务端等待调用

然后在浏览器输入如下地址
http://localhost:8015/mcpclient/chat?msg=上海

可以看到调用了MCP的大模型给出的回复。
http://localhost:8015/mcpclient/chat2?msg=上海

可以看到,本来我们是需要给定城市的天气信息,而大模型给我们返回的并不是我们想要的信息。
2.8 远程MCP增强案例-对接互联网通用MCP服务(百度地图)
对接互联网通用MCP服务(百度地图)

2.8.1 环境配置
下载最新版的NodeJS https://nodejs.org/zh-cn
注册百度地图账号+申请API-key https://lbsyun.baidu.com/

一定要注意此处全部勾选

可以设置为指定IP,Demo阶段建议简单设置为所有ip,生产环境请勿设置全开放。

2.8.2 编码实战
2.8.2.1 新建Module
可以命名为 ClientCallBaiduMcpServer
2.8.2.2 修改POM文件
在依赖配置节点修改为以下配置:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-ai-alibaba dashscope-->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<!-- 2.mcp-clent 依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
2.8.2.3 编写配置文件
在resources目录下新建application.properties配置文件,内容如下:
server.port=8016
# 设置全局编码格式
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.charset=UTF-8
spring.application.name=ClientCallBaiduMcpServer
# ====SpringAIAlibaba Config=============
spring.ai.dashscope.api-key=${DASHSCOPE_API_KEY}
# ====mcp-client Config=============
spring.ai.mcp.client.request-timeout=20s
spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-server.json5
2.8.2.4 编写主启动类
新建主启动类,并编写如下内容:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ClientCallBaiduMcpServerApplication {
public static void main(String[] args) {
SpringApplication.run(ClientCallBaiduMcpServerApplication.class, args);
}
}
2.8.2.5 编写配置类
新建子包config,并在其中新建配置类SaaLLMConfig
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SaaLLMConfig
{
@Bean
public ChatClient chatClient(ChatModel chatModel, ToolCallbackProvider tools)
{
return ChatClient.builder(chatModel)
//mcp协议,配置见yml文件,此处只赋能给ChatClient对象
.defaultToolCallbacks(tools.getToolCallbacks())
.build();
}
}
2.8.2.6 编写业务类
新建子包controller,并在其中新建业务类 McpClientCallBaiDuMcpController
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
public class McpClientCallBaiDuMcpController {
@Resource
private ChatClient chatClient; //添加了MCP调用能力
@Resource
private ChatModel chatModel; //没有添加MCP调用能力
/**
* 添加了MCP调用能力
* http://localhost:8016/mcp/chat?msg=查询北纬39.9042东经116.4074天气
* http://localhost:8016/mcp/chat?msg=查询61.149.121.66归属地
* http://localhost:8016/mcp/chat?msg=查询昌平到天安门路线规划
* @param msg
* @return
*/
@GetMapping("/mcp/chat")
public Flux<String> chat(String msg)
{
return chatClient.prompt(msg).stream().content();
}
/**
* 没有添加MCP调用能力
* http://localhost:8016/mcp/chat2?msg=查询北纬39.9042东经116.4074天气
* @param msg
* @return
*/
@RequestMapping("/mcp/chat2")
public Flux<String> chat2(String msg)
{
return chatModel.stream(msg);
}
}
2.8.2.7 nodejs配置编码-Typescript接入
在resources目录下新建mcp-server.json5
{
"mcpServers":
{
"baidu-map":
{
"command": "cmd",
"args": ["/c", "npx", "-y", "@baidumap/mcp-server-baidu-map"],
"env": {"BAIDU_MAP_API_KEY": "此处替换为你申请的应用的AK"}
}
}
}
// 构建McpTransport协议
//cmd:启动 Windows 命令行解释器。
///c:告诉 cmd 执行完后面的命令后关闭自身。
//npx:npx = npm execute package,Node.js 的一个工具,用于执行 npm 包中的可执行文件。
//-y 或 --yes:自动确认操作(类似于默认接受所有提示)。
//@baidumap/mcp-server-baidu-map:要通过 npx 执行的 npm 包名
//BAIDU_MAP_API_KEY 是访问百度地图开放平台API的AK
使用说明:Baidu Map MCP Server
2.8.2.8 测试
启动主启动类后,在后台可以看到以下输出:

在浏览器中输入以下地址:
http://localhost:8016/mcp/chat?msg=查询北纬39.9042东经116.4074天气

http://localhost:8016/mcp/chat?msg=查询昌平到天安门路线规划

没有使用MCP的结果
http://localhost:8016/mcp/chat2?msg=查询北纬39.9042东经116.4074天气

更多推荐

所有评论(0)