当前位置: 首页 > news >正文

Spring AI 接入 MCP:DeepSeek 连接 Filesystem Server 读取本地文件

Spring AI 接入 MCP:DeepSeek 连接 Filesystem Server 读取本地文件

做 Tool Calling Demo 时,我们通常会把工具直接写在 Java 应用里:

@Tool(description="查询订单")publicStringqueryOrder(StringorderId){returnorderService.query(orderId);}

这种写法很适合接入自己项目里的业务方法。

但如果工具来自外部系统,比如文件系统、GitHub、数据库、浏览器、运维平台,每个 AI 应用都重复写一套适配代码,就会很累。

MCP 要解决的就是这个问题:

外部工具怎么用统一协议接进 AI 应用。

它不是替代 Tool Calling,而是和 Tool Calling 配合:

Tool Calling:模型怎么请求调用工具 MCP:外部工具怎么标准化接进来

这次只跑一条最小链路:

Spring AI 作为 MCP Client,连接本地 Filesystem MCP Server,让模型读取一个测试文件。

先把这条链路跑通,再去接 GitHub、数据库、浏览器这些 MCP Server,就不会乱。

注意:这篇只演示本地测试目录。生产环境不要随便把真实目录暴露给模型。


一、先把范围缩小

Spring AI 里和 MCP 相关的写法不止一种:

Spring AI 做 MCP Client Spring AI 做 MCP Server stdio 连接本地 MCP Server SSE / Streamable HTTP 连接远程 MCP Server

入门时不要全塞在一起。我们先选最容易跑通的一条:

Spring AI 做 MCP Client,通过 stdio 连接本地 Filesystem MCP Server。

整体关系是这样:

Spring AI 应用 → 启动并连接 Filesystem MCP Server → 获取 Server 暴露的文件工具 → 把工具交给模型 → 模型通过 Tool Calling 请求调用 → MCP Server 真正读取文件

简单说:

MCP Client:你的 Spring AI 应用 MCP Server:外部工具服务

这篇用现成的 Filesystem Server,不从零写 Server。先把接入跑通。


二、准备一个测试目录

先准备几个前提:

  • 你已经有一个能正常调用ChatClient的 Spring Boot 项目;
  • 项目使用 Spring AI 1.1.7;
  • 本机已经安装 Node.js 和npx
  • 当前模型支持 Tool Calling。

这篇示例使用 DeepSeek,模型用deepseek-v4-flash。如果你走的是第三方兼容网关,要确认网关会不会完整透传tools参数和 tool call 响应。

先建一个测试目录:

mkdir-p/tmp/spring-ai-mcp-demoecho"Hello from Spring AI MCP Demo">/tmp/spring-ai-mcp-demo/test.txt

先手动验证 Filesystem MCP Server 能不能启动:

npx-y@modelcontextprotocol/server-filesystem /tmp/spring-ai-mcp-demo

如果看到类似输出,说明本地 Server 能跑:

Secure MCP Filesystem Server running on stdio

验证完可以停掉。真正接入 Spring AI 时,Spring AI 会根据配置自动启动它。


三、添加依赖

pom.xml至少需要这几个依赖:

<properties><java.version>17</java.version><spring-ai.version>1.1.7</spring-ai.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-deepseek</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client</artifactId></dependency></dependencies>

spring-ai-starter-mcp-client负责把 Spring AI 应用变成 MCP Client。这篇连接的是本地 stdio Server。

如果以后要接远程 MCP Server,再考虑spring-ai-starter-mcp-client-webflux


四、配置 DeepSeek 和 MCP

application.yaml这样写:

spring:application:name:spring-ai-mcp-demoai:model:chat:deepseekdeepseek:api-key:${DEEPSEEK_API_KEY}chat:options:model:deepseek-v4-flashtemperature:0.2mcp:client:type:SYNCstdio:connections:filesystem:command:npxargs:--y-"@modelcontextprotocol/server-filesystem"-/tmp/spring-ai-mcp-demo

启动前设置环境变量:

exportDEEPSEEK_API_KEY=你的 API Key

这段配置的关键点有三个:

  • 使用 DeepSeek 作为聊天模型;
  • 通过npx启动 Filesystem MCP Server;
  • 只暴露/tmp/spring-ai-mcp-demo测试目录。

如果用 IDEA 运行,在 Run/Debug Configurations 里给启动配置加环境变量:

DEEPSEEK_API_KEY=你的 API Key

Windows 上通常要用cmd.exe /c包一层:

command:cmd.exeargs:-/c-npx--y-"@modelcontextprotocol/server-filesystem"-C:\tmp\spring-ai-mcp-demo

macOS / Linux 按前面的写法即可。


五、写一个测试接口

新建McpController

packagecom.example.springaideepseekdemo.controller;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.tool.ToolCallbackProvider;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;@RestControllerpublicclassMcpController{privatefinalChatClientchatClient;privatefinalToolCallbackProvidermcpTools;publicMcpController(ChatClient.Builderbuilder,ToolCallbackProvidermcpTools){this.chatClient=builder.defaultSystem(""" 你是一个文件读取助手。 只能通过工具访问 /tmp/spring-ai-mcp-demo 目录。 当用户说 test.txt 或测试目录时,都指 /tmp/spring-ai-mcp-demo。 不要请求访问 /、用户主目录、项目源码目录或其他目录。 """).build();this.mcpTools=mcpTools;}@GetMapping("/ask")publicStringask(@RequestParamStringquestion){returnchatClient.prompt().user(question).toolCallbacks(mcpTools).call().content();}}

这里有个容易写错的点:不要想当然写成McpClient.getTools("filesystem")

在 Spring AI 1.1.7 里,MCP Client Starter 会把 MCP Server 暴露的工具转换成ToolCallbackProvider

ChatClient可以直接这样接:

.toolCallbacks(mcpTools)

如果项目里还有其他ToolCallbackProviderBean,构造方法注入时可能需要用@Qualifier指定。这个最小 Demo 只有一个 MCP Provider,可以直接注入。


六、启动测试

启动应用:

./mvnw spring-boot:run

读取test.txt

curl--get"http://localhost:8080/ask"\--data-urlencode"question=帮我读取 /tmp/spring-ai-mcp-demo/test.txt 的内容"

如果模型选择了文件读取工具,最终会返回类似:

test.txt 的内容是:Hello from Spring AI MCP Demo

也可以测试列目录:

curl--get"http://localhost:8080/ask"\--data-urlencode"question=列出 /tmp/spring-ai-mcp-demo 目录下有哪些文件"

如果日志里出现:

Access denied - path outside allowed directories

不用慌。

这说明模型请求了白名单之外的路径,比如/。Filesystem MCP Server 拒绝了这次访问,这是安全拦截,不是 MCP 没接上。

如果模型一直普通回答,没有请求工具,优先检查:

模型是否支持 Tool Calling DEEPSEEK_API_KEY 是否正确 中间网关是否透传 tools 参数

先跑编译:

./mvnw clean compile-DskipTests

然后启动应用,请求/ask,能读到:

Hello from Spring AI MCP Demo

七、背后发生了什么

业务代码看起来只有这一段:

chatClient.prompt().user(question).toolCallbacks(mcpTools).call().content();

背后其实分成两条链路。

应用启动时:

Spring AI 读取 application.yaml → 启动 Filesystem MCP Server → 建立 stdio 连接 → 获取 Server 的工具列表 → 转成 Spring AI 的 ToolCallback

用户提问时:

用户提问 → 模型看到可用工具 → 模型判断要调用文件工具 → Spring AI 执行 ToolCallback → ToolCallback 通过 MCP 调用 Filesystem Server → Server 读取文件并返回结果 → 模型基于工具结果组织回答

所以 MCP 和 Tool Calling 不是两套互斥方案:

MCP 负责把外部工具接进来 Tool Calling 负责让模型请求调用这些工具

八、什么时候用 MCP

如果只是当前项目里的几个业务方法,直接写@Tool更轻:

查订单 查物流 查库存

这些能力本来就在当前应用里,没必要为了 MCP 多绕一层。

MCP 更适合:

工具要被多个 AI 应用复用 工具需要独立部署和维护 要接入现成的外部 MCP Server 工具很多,不想每个应用都重复适配

可以这样记:

@Tool:把当前应用里的方法暴露给模型 MCP:把外部工具服务标准化接入应用

Spring AI 不需要知道 Filesystem Server 内部怎么读文件,只要按 MCP 协议连接它、拿到工具、执行工具调用就行。


九、别忽略安全边界

MCP 接入不难,但安全边界一定要提前想清楚。Filesystem Server 会真正读写文件。

入门 Demo 只暴露:

/tmp/spring-ai-mcp-demo

不要暴露:

/ /Users/你的用户名 项目源码目录 .ssh 配置和密钥目录

工具描述不是权限控制。真正的目录边界、权限校验、危险操作拦截,都要在应用侧或 MCP Server 侧做。

入门阶段建议只读文件、列目录。

如果要开放写入、创建目录、移动文件,至少要加:

用户权限校验 目录白名单 操作日志 二次确认 限流和超时

还有一个常见误区:MCP Server 能连上,不代表模型一定会调用工具。

模型会不会调用,还取决于模型能力、工具描述、用户问题,以及模型服务是否支持 Tool Calling。

排查时分两步看:

先确认 MCP Server 能启动 再确认模型真的返回 tool call

这两个问题不要混在一起。


写在最后

这篇文章跑通的是一条最小链路:

Filesystem MCP Server 暴露工具 → Spring AI MCP Client 连接 Server → MCP 工具转成 ToolCallbackProvider → ChatClient 把工具交给模型 → 模型通过 Tool Calling 请求调用 → Spring AI 通过 MCP 执行工具

如果说@Tool是把工具写在应用里,那 MCP 就是把工具从应用里拆出去,再用协议接回来。

它的价值不在于“更高级”,而在于:

  • 工具可以独立维护;
  • 多个 AI 应用可以复用;
  • 外部工具生态可以标准化接入。

但 MCP 只负责连接,不负责替你做权限、业务规则和风险兜底。

先用本地 Filesystem Server 跑通,再考虑 GitHub、数据库、浏览器或公司内部系统。

Agent 能力越多,安全边界越要清楚。


后续会继续更新 Spring AI、RAG、Memory、Tool Calling、MCP 等实战内容。

http://www.jsqmd.com/news/1069505/

相关文章:

  • 复杂流体系统实时控制:模型降阶与滚动时域优化实践
  • DINOv3+LoRA:基于视觉基础模型的图像篡改检测新范式
  • 当AI Agent开始写AI Agent:自进化系统在企业管理中的伦理与安全红线
  • MatRIS-MoE与Janus框架:突破百亿参数通用机器学习原子间势训练壁垒
  • 指纹浏览器指纹工厂(下):基于真实设备数据特征的马尔可夫链生成与校验
  • 广告物料行业实践指南:从制作到落地的全流程解析与未来趋势展望
  • 基于SRAM存内计算的Transformer Softmax硬件加速方案解析
  • 自适应信息流:让视觉语言模型学会动态聚焦的关键技术
  • 小旺 AI 截图:基于多模态大模型的桌面效率工具
  • 大语言模型对齐中的奖励破解问题与CARP框架解析
  • Shell脚本为何成为AI智能体视觉(TVA)的“反射弧”(6)
  • 专利代理师:2025年实务真题回忆版
  • 【趣解】压力测试:极限情况下的系统表现
  • 暗黑模式下的WCAG合规性:从颜色对比度到欺骗性设计的全面解析
  • 当AI吞噬肌肉记忆:我们该缴械投降,还是做冷酷的“混合智能体”?
  • Codex和cc Switch的安装以及使用DeepSeek大模型
  • 范畴论与多项式映射:从微分模态中提取N-过滤结构的原理与实践
  • Windows Codex + CC Switch+deepseek 完整闭坑配置指南
  • AI评估准则:从博弈论到机制设计的20条实战原则
  • Redis Cluster 的重试逻辑
  • AestheticNet:融合视觉认知与语义感知的图像美学质量评估新范式
  • 博弈论与机制设计:构建AI系统评估的20条核心原则与实践指南
  • CentOS初始服务器安全配置:firewalld、sudo与SSH密钥实战指南
  • P3T:3D视觉语言模型的原型点级提示调优方法解析
  • Mind‘s Eye视觉认知基准:从抽象推理到动态预测的AI能力评估
  • 《个人头像上传》一、photoAccessHelper_Functions使用指南
  • 云计算虚拟网络:VXLAN覆盖网络与SDN控制器架构
  • HYPERHEURIST框架:LLM与模拟退火算法协同优化RTL设计PPA
  • 从脆弱数据主体到脆弱化数据实践:AI伦理的工程化视角与加固方法
  • Tango框架:视频大语言模型的高效令牌剪枝技术