随着 MCP(Model Context Protocol)协议逐步成为大模型与外部工具交互的标准,Spring AI 也快速跟进,推出了 spring-ai-starter-mcp-client 模块,使得 Java 应用能够以轻量级、标准化的方式接入各类 MCP Server,从而扩展大模型的能力边界。本文将以百度地图 MCP Server 为例,演示如何使用 Spring AI MCP Client 通过标准输入输出(stdio)与 Node.js 子进程通信,让通义千问大模型能够实时查询天气、IP 归属地、路线规划等地图服务,并梳理其底层运行原理。
前言
MCP(Model Context Protocol)模型上下文协议,是一套大模型外部工具调用标准协议。
核心特点:
1. Client‑Server架构,进程间通过stdio标准输入输出通信;
2. 底层传输报文基于JSON‑RPC 2.0;
3. 语言无关:MCP‑Server 可以是 Node、Python、Java 任意语言编写;
4. 大模型不需要直接对接各个第三方API,统一通过MCP协议调用能力。
百度地图推出国内首个地图MCP服务,我们可以通过Spring‑AI MCP‑Client直接接入,让大模型原生具备地址解析、IP归属地查询、路线规划等地图能力,无需手写复杂工具调用逻辑。
整体架构图:
MCP‑Client(Java SpringAI进程) ↔ stdio+JSON‑RPC2.0 ↔ MCP‑Server(npx启动的Node百度地图服务) ↔ 百度地图开放平台API。
MCP‑Client会启动子进程运行百度地图的MCP‑Server,通过标准输入输出完成JSON‑RPC通信,Server内部封装百度地图API,把地图能力包装成MCP工具提供给大模型。
一、环境依赖Maven
引入Spring‑AI openai兼容模型starter + mcp‑client客户端starter。
这里使用阿里云通义千问DashScope(兼容OpenAI接口协议)作为大模型。
<!-- 兼容OpenAI协议大模型,对接阿里云通义千问 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<!-- MCP Client核心依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
二、application.yml 配置文件
server:
port: 6016
servlet:
encoding:
enabled: true
force: true
charset: UTF-8
spring:
application:
name: springAI-16chat-mcpclient-call-baidumcp
# LLM 配置:阿里云通义千问 dashscope 兼容openai接口
ai:
openai:
api-key: ${aliQwen-api}
base-url: https://dashscope.aliyuncs.com/compatible-mode
chat:
options:
model: qwen-plus
# MCP‑Client配置
mcp:
client:
toolcallback:
enabled: true
# 指定MCP服务配置json文件,放在resources类路径下
stdio:
servers-configuration: classpath:/mcp-server.json
三、mcp‑server.json MCP服务定义文件
在src/main/resources下新建mcp-server.json,定义百度地图MCP Server启动参数。
Windows环境说明:
-command: cmd:调用windows命令解释器
-/c:执行完命令后关闭cmd窗口
-npx:Node.js工具,直接执行npm包,不需要全局安装
--y:自动确认所有交互提示
-@baidumap/mcp-server-baidu‑map:百度地图官方MCP服务npm包
-env环境变量注入百度地图开放平台AK密钥
{
"mcpServers": {
"baidu-map": {
"command": "cmd",
"args": ["/c", "npx", "-y", "@baidumap/mcp-server-baidu‑map"],
"env": {
"BAIDU_MAP_API_KEY": "你的百度地图开放平台AK"
}
}
}
}
⚠️注意:运行本机必须安装Node.js环境,npx命令依赖Node;Linux/Mac环境command改为npx,args去掉cmd相关参数。
参数释义:
- cmd:Windows命令行解释器;
- /c:执行后续命令,执行完毕关闭进程;
- npx:npm execute package,执行npm包内可执行程序;
- -y:自动yes确认,跳过交互输入;
- @baidumap/mcp‑server‑baidu‑map:百度地图MCP服务包;
- BAIDU_MAP_API_KEY:百度地图开放平台申请访问密钥AK。
四、Spring配置类 SaaLLMConfig
把MCP提供的ToolCallbackProvider注入ChatClient,只有经过defaultToolCallbacks装配后,ChatClient才具备MCP工具调用能力。
关键点:Spring‑AI会自动读取mcp‑server.json配置,启动子进程创建MCP连接,自动收集MCP‑Server暴露的全部工具,封装为ToolCallback。
package com.atguigu.study.config;
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;
/**
* @auther zzyybs@126.com
* @create 2025-07-31 20:47
* @Description MCP‑Client装配ChatClient,注入MCP工具回调
*/
@Configuration
public class SaaLLMConfig
{
@Bean
public ChatClient chatClient(ChatModel chatModel, ToolCallbackProvider tools)
{
return ChatClient.builder(chatModel)
// 将MCP服务提供的全部工具回调赋能给ChatClient对象
.defaultToolCallbacks(tools.getToolCallbacks())
.build();
}
}
五、Controller接口,对比有无MCP能力效果
提供两组接口做对照实验:
/mcp/chat:使用装配MCP工具的ChatClient对象,大模型可以自动调用百度地图MCP工具;/mcp/chat2:直接使用原生ChatModel,没有MCP工具能力,只会纯文本回答,无法调用地图API。
package com.zzyy.study.controller;
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;
/**
* @auther zzyy
* @create 2025-07-19 18:55
*/
@RestController
public class McpClientCallBaiDuMcpController
{
@Resource
private ChatClient chatClient; //✅已经注入MCP工具调用能力
@Resource
private ChatModel chatModel; //❌原生对象,没有MCP工具
/**
* 具备MCP调用能力,大模型会自动调用百度地图MCP工具
* http://localhost:6016/mcp/chat?msg=查询昌平到天安门路线规划
* http://localhost:6016/mcp/chat?msg=查询61.149.121.66归属地
*/
@GetMapping("/mcp/chat")
public Flux<String> chat(String msg)
{
return chatClient.prompt(msg).stream().content();
}
/**
* 无MCP能力,仅大模型幻觉回答,不会调用地图API
* http://localhost:6016/mcp/chat2?msg=查询北京天气
*/
@RequestMapping("/mcp/chat2")
public Flux<String> chat2(String msg)
{
return chatModel.stream(msg);
}
}
六、调用测试
测试1:带MCP能力接口
访问:
http://localhost:6016/mcp/chat?msg=查询昌平到天安门路线规划
现象:
SpringAI内部会通过stdio唤起npx启动百度地图MCP‑Server,JSON‑RPC交互,大模型识别意图自动调用MCP工具,拿到百度地图真实路线数据,整理成自然语言返回。
支持能力:IP地址解析、地址转坐标、路线规划、地点检索等百度地图开放API能力。
测试2:不带MCP能力接口
http://localhost:6016/mcp/chat2?msg=查询昌平到天安门路线规划
现象:大模型只能依靠训练数据做推测,没有真实地图数据,属于幻觉输出。
七、底层原理梳理
- MCP‑Client(Java SpringAI)读取
mcp‑server.json配置,通过ProcessBuilder启动子进程执行cmd/npx命令; - Java进程与MCP‑Server(Node子进程)之间使用标准输入输出stdio做进程间通信;
- 通信报文格式遵循
JSON‑RPC 2.0协议; - MCP‑Server内部封装百度地图API,把地图能力对外暴露为MCP工具列表;
- Spring‑AI自动把MCP工具转换为Spring‑AI的
ToolCallback,注册到ChatClient; - 用户提问,大模型判断需要地图能力,自动下发工具调用指令,MCP Client转发JSON‑RPC请求给子进程Server,拿到结果返回大模型整理输出。
八、踩坑与注意事项
- 本机必须安装Node.js:npx命令依赖Node环境,否则无法拉起百度地图MCP‑Server子进程;
- 操作系统差异:Windows用
cmd /c,Linux/Mac直接command写npx; - AK密钥保护:不要硬编码密钥,建议环境变量注入;
ToolCallbackProvider必须装配进ChatClient,直接用ChatModel不会生效MCP工具;- MCP是子进程通信,程序关闭MCP‑Server子进程会随之销毁。
总结
MCP协议统一了大模型调用外部工具的标准,业务代码几乎不用手写工具定义、参数解析、http请求,第三方服务商只需要提供MCP‑Server,Spring‑AI MCP‑Client就可以开箱即用接入各种外部能力。
百度地图作为国内首家支持MCP协议地图服务商,借助Spring‑AI可以快速给大应用增加地理信息能力。
扩展思考:除了百度地图,还可以对接文件操作、数据库查询等各类MCP‑Server,一套MCP Client复用所有外部能力。

142

被折叠的 条评论
为什么被折叠?



