news 2026/9/28 18:10:02

Spring AI + MCP + SQLite 实战:用 TaoToken 统一 Key 打通本地工具链

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI + MCP + SQLite 实战:用 TaoToken 统一 Key 打通本地工具链

1. 为什么 Spring AI 接 SQLite 总是卡在 Key 和配置上

如果你正在用 Spring AI 做本地 AI 工具链,大概率会遇到这样一个场景:想让大模型直接查本地 SQLite 数据库,用自然语言问「帮我看看 products 表里价格最高的三个商品」,模型就能自动生成 SQL、执行、再把结果翻译成人话返回。这个链路听起来很顺,但真正动手时,问题往往不在 Spring AI 本身,而在两个地方:一是 MCP 服务端怎么配、怎么启动;二是模型调用的 Key 从哪来、怎么统一管理。

我见过太多项目,文件系统 MCP 用一个 Key,SQLite MCP 又换一个 Key,Brave Search 再来一个,最后环境变量里躺了五六个OPENAI_API_KEY的变体,改一个忘一个,调试半小时发现是 Key 写错了。更麻烦的是,有些工具链需要不同的 base-url,有的走官方,有的走兼容端点,配置一多就容易乱。

这篇要解决的就是这个问题:用 TaoToken 统一 Key,把 Spring AI + MCP + SQLite 这条本地工具链一次性跑通。TaoToken 是一个模型调用聚合入口,你可以在一个地方拿到 Key,然后统一给 Spring AI 里的 OpenAI 兼容客户端用,不用每个 MCP 服务单独配一套凭证。官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api ,后面配置里会直接用到。

适合谁看:已经会用 Spring Boot、想快速把本地 SQLite 接进 AI 工具链的 Java 开发者;或者你已经在用 Spring AI,但被多工具 Key 分散搞得很烦,想统一收口。整篇按「能跟着做」来写,配置骨架可以直接复制,SQLite 读写验证也有完整命令和预期结果。

2. TaoToken 前置:统一 Key 到底省了什么

先说清楚 TaoToken 在这个链路里的位置。Spring AI 的 OpenAI starter 本质上是一个 OpenAI 兼容客户端,它需要两个东西:api-key和base-url。传统做法是每个项目、每个 MCP 工具都去申请一套 Key,然后分别配。TaoToken 的做法是给你一个统一的 Key 和一个统一的 base-url,所有走 OpenAI 兼容协议的调用都从这里走。

这意味着什么?你的 Spring AI 项目里只需要维护一份凭证。SQLite MCP 服务本身不直接调模型,它是被 Spring AI 的 MCP 客户端通过 stdio 启动的本地进程,真正调模型的是 Spring AI 里的 ChatClient。所以统一 Key 的关键点在于:ChatClient 的 OpenAI 配置指向 TaoToken,而不是每个 MCP 服务各自配。

操作上分两步。第一步,去 TaoToken 控制台拿 Key。打开 https://taotoken.net/api-keys ,登录后创建一个 API Key,复制出来。这个 Key 后面会写进环境变量,不要硬编码到代码里。第二步,确认你的调用入口。模型对话调试可以用 https://taotoken.net/models ,长期编码或 Agent 场景可以看 https://taotoken.net/coding-plan ,接入文档在 https://taotoken.net/doc 。这些入口后面 CTA 会分流,这里先记住 Key 和 base-url 两个值。

注意:TaoToken 的 API 地址是https://taotoken.net/api,配置 base-url 时不要多加/v1之外的路径,Spring AI 的 OpenAI starter 会自动拼接/chat/completions。如果你用的是其他兼容客户端,按文档里的 base-url 写就行。

环境变量建议这样设,Linux/macOS 用 export,Windows 用 set 或系统环境变量:

export TAOTOKEN_API_KEY="sk-你的TaoTokenKey" export TAOTOKEN_BASE_URL="https://taotoken.net/api"

设完之后,Spring AI 的配置文件里直接引用这两个变量,后面第三节会给完整配置。

3. 可复制配置:MCP 服务端骨架 + Spring AI 接入

这一节是核心,直接给能跑的配置。先确认环境:JDK 17、Maven 3.8+、Node.js(npx 可用)、uv(uvx 可用)、SQLite3。这些是 MCP SQLite 服务端启动的前提,缺一个都会在启动时报错。

先建一个 SQLite 测试库,用来验证读写。命令行执行:

sqlite3 test.db

进入 SQLite 交互界面后,建表并插数据:

CREATE TABLE products ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, price REAL NOT NULL, stock INTEGER DEFAULT 0 ); INSERT INTO products (name, price, stock) VALUES ('机械键盘', 399.0, 12), ('人体工学椅', 1299.0, 5), ('4K显示器', 2199.0, 8), ('降噪耳机', 899.0, 20); .quit

这样test.db里就有数据了。接下来是 Maven 依赖,pom.xml里加 Spring AI 的 BOM 和两个 starter:

<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-openai</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-client</artifactId> </dependency> </dependencies>

spring-ai-starter-model-openai负责模型调用,spring-ai-starter-mcp-client负责 MCP 客户端和 stdio 传输。版本由 BOM 统一管理,不用每个依赖写版本号。

然后是application.properties,这里把 TaoToken 的 Key 和 base-url 接进来:

spring.application.name=spring-ai-mcp-sqlite spring.main.web-application-type=none spring.ai.openai.api-key=${TAOTOKEN_API_KEY} spring.ai.openai.base-url=${TAOTOKEN_BASE_URL} spring.ai.openai.chat.options.model=gpt-4o-mini

web-application-type=none是因为这个 demo 不需要 Web 容器,跑完预设问题就退出。模型名按 TaoToken 文档里支持的写,这里用gpt-4o-mini做示例,实际以你控制台可用的模型为准。

接下来是 MCP 客户端配置,也就是 SQLite 服务端的启动骨架。核心是ServerParameters和StdioClientTransport:

@Bean(destroyMethod = "close") public McpSyncClient mcpClient() { var stdioParams = ServerParameters.builder("uvx") .args("mcp-server-sqlite", "--db-path", getDbPath()) .build(); var mcpClient = McpClient.sync(new StdioClientTransport(stdioParams)) .requestTimeout(Duration.ofSeconds(30)) .build(); var init = mcpClient.initialize(); System.out.println("MCP Initialized: " + init); return mcpClient; } private static String getDbPath() { return System.getProperty("user.dir") + "/test.db"; }

这里uvx mcp-server-sqlite --db-path就是 MCP SQLite 服务端的启动命令,Spring AI 会以子进程方式拉起它,通过标准输入输出通信。requestTimeout设 30 秒,因为模型生成 SQL 加执行可能比纯文件操作慢。getDbPath()用当前工作目录拼test.db,避免硬编码绝对路径在不同机器上跑不起来。

最后是 ChatClient 的构建,把 MCP 工具注册进去:

@Bean public CommandLineRunner predefinedQuestions( ChatClient.Builder chatClientBuilder, List<McpSyncClient> mcpClients, ConfigurableApplicationContext context) { return args -> { var chatClient = chatClientBuilder .defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpClients)) .build(); String question = "帮我查一下 products 表里价格最高的三个商品,列出名称和价格"; System.out.println("问题: " + question); System.out.println("助手: " + chatClient.prompt(question).call().content()); context.close(); }; }

SyncMcpToolCallbackProvider会把 MCP 服务端暴露的工具自动注册给 ChatClient,模型在需要时会自己决定调用query或list_tables这类工具。你不需要手动写工具映射。

4. 验证请求:从自然语言到 SQLite 读写结果

配置写完,跑起来验证。先确认 MCP SQLite 服务端能单独启动,命令行执行:

uvx mcp-server-sqlite --db-path ./test.db

如果没报错、进程挂起等待输入,说明服务端本身没问题。按 Ctrl+C 退出,然后跑 Spring Boot 应用:

mvn clean package java -jar target/spring-ai-mcp-sqlite-0.0.1-SNAPSHOT.jar

预期输出会分几段。第一段是 MCP 初始化信息,类似:

MCP Initialized: InitializeResult[protocolVersion=2024-11-05, capabilities=...]

这说明 Spring AI 成功通过 stdio 连上了 SQLite MCP 服务端。第二段是模型回答,针对「价格最高的三个商品」这个问题,模型会先调用工具查表,然后返回类似:

根据查询结果,products 表中价格最高的三个商品是: 1. 4K显示器 - 2199.0 2. 人体工学椅 - 1299.0 3. 降噪耳机 - 899.0

如果你看到这个结果,说明整条链路通了:自然语言 → 模型判断需要调工具 → MCP 客户端转发 → SQLite 服务端执行 SQL → 结果回传 → 模型生成自然语言回答。

再验证一次写操作。把问题改成:

String question = "往 products 表里插入一条新记录:名称 '无线鼠标',价格 199.0,库存 30,然后告诉我现在表里有多少条记录";

重新跑应用。模型会调用插入工具,再调用查询工具,最后返回类似「已插入,当前共 5 条记录」。你可以再用 sqlite3 命令行确认:

sqlite3 test.db "SELECT COUNT(*) FROM products;"

输出5就说明写操作真的落库了。这一步很关键,因为很多 MCP 配置问题表现为「读能读、写报错」,通常是服务端权限或路径问题。

5. 本篇常见错排查

错误一:uvx: command not found。这是 uv 没装或没进 PATH。用pip install uv装完后,确认uv --version能输出。如果还不行,检查 Python 的 Scripts 目录有没有加到 PATH。

错误二:MCP Initialized一直不打印,卡在启动。大概率是mcp-server-sqlite这个包没下载下来,uvx 首次运行会去拉包。可以手动执行uvx mcp-server-sqlite --help看能不能拉下来。如果网络慢,多等一会,或者检查 uv 的缓存目录。

错误三:模型返回「我没有访问数据库的工具」。说明工具没注册上。检查SyncMcpToolCallbackProvider有没有正确注入List<McpSyncClient>,以及mcpClient()这个 Bean 有没有被 Spring 扫描到。常见原因是@Bean方法所在的类没加@Configuration或没被主启动类扫描到。

错误四:401 或 403,模型调用失败。这是 TaoToken Key 的问题。确认TAOTOKEN_API_KEY环境变量在当前 shell 里生效,echo $TAOTOKEN_API_KEY能输出值。另外确认 base-url 是https://taotoken.net/api,不要写成带/v1的完整路径,Spring AI 会自己拼。如果 Key 没问题还报错,去 https://taotoken.net/api-keys 确认 Key 状态和额度。

错误五:SQLite 报unable to open database file。路径问题。getDbPath()用的是user.dir,如果你在 IDE 里跑,工作目录可能是项目根目录,也可能是模块目录。最稳的办法是先打印一下System.getProperty("user.dir"),确认test.db确实在那个目录下。或者直接写绝对路径调试,跑通后再改成相对路径。

错误六:模型生成的 SQL 语法不对。这通常不是配置问题,是模型能力问题。换一个更强的模型,或者在 prompt 里明确说「使用标准 SQLite 语法」。TaoToken 控制台里可以切换模型,去 https://taotoken.net/models 看看当前可用的模型列表。

6. 统一 Key 之后,工具链怎么继续扩

跑通 SQLite 这条链路后,你会发现统一 Key 的价值不只是省事。当你再加一个文件系统 MCP、或者一个搜索 MCP 时,Spring AI 这边只需要多注册一个McpSyncClient,模型调用侧完全不用动,因为 Key 和 base-url 还是那一套。这就是把凭证收口到 TaoToken 的好处:工具链在扩,配置不膨胀。

如果你后面要做长期编码或 Agent 场景,比如让模型持续读写本地数据库、自动生成报表,可以看 https://taotoken.net/coding-plan ,那里有针对长任务的方案。接入过程中遇到 Key 或 base-url 的问题,直接翻 https://taotoken.net/doc ,文档里有各语言的配置示例。模型对话调试用 https://taotoken.net/models ,控制台管理 Key 在 https://taotoken.net/console ,API Key 创建在 https://taotoken.net/api-keys 。

最后留一个实用技巧:把test.db的路径做成配置项,而不是写死在getDbPath()里。这样你可以在application.properties里加一行mcp.sqlite.db-path=./test.db,然后用@Value注入。换库的时候只改配置,不用重新编译。这个改动很小,但在多环境切换时能省不少事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 18:10:02

ESP32-S3 + LVGL9 + FreeType动态渲染中文字体完整实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 18:09:55

Jetson Orin NX部署YOLOv8实战:从环境踩坑到32FPS稳定推理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 18:09:11

阿里Qwen3.5-122B-A10B实测:MoE开源多模态模型配TaoToken的config.toml骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 18:09:07

Linux下用Python操作MySQL:TaoToken统一Key接入与config.toml配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华