news 2026/9/26 12:10:30

Dify 基于 MCP 接入 SQLBot:config.toml 骨架与连通性验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dify 基于 MCP 接入 SQLBot:config.toml 骨架与连通性验证

1. 为什么要在 Dify 里用 MCP 接 SQLBot

如果你正在做「让业务同事用自然语言查数据库」这件事,大概率绕不开两个东西:一个是 Dify 的工作流编排,另一个是能把自然语言稳定翻译成 SQL 的引擎。Dify 自带的 Database 插件确实能跑 text2sql,但它本质是「把表结构塞给 LLM,让模型直接写 SQL」,表一多、字段一杂,模型幻觉就上来了,生成的 SQL 经常字段名对不上、JOIN 写错,甚至编出不存在的表。

SQLBot 这类专门做 text-to-SQL 的服务,走的是 LLM + RAG 检索增强的路线:先把库表结构、字段注释、样例数据做成向量索引,用户提问时先检索相关 schema,再让模型基于检索结果生成 SQL,准确率比纯 LLM 硬写高一个档次。更关键的是它原生支持 MCP 协议,可以被 Dify 通过 MCP 工具节点直接调用,不用你自己写 HTTP 适配层。

这篇要解决的就是落地环节最卡人的一步:Dify 通过 MCP 接入 SQLBot 时,config.toml骨架到底怎么写、TaoToken 的统一 Key/API 通道放在哪个位置、以及怎么用一次连通性验证确认接入真的生效了。适合已经在 Dify 里搭过工作流、想把手写 SQL 节点换成 SQLBot 的开发者。下面所有配置我都按可复制的方式给,你改掉 IP 和端口就能用。

2. 前置准备:SQLBot 服务与 TaoToken 通道

2.1 SQLBot 侧要暴露 MCP 端点

SQLBot 用容器方式起最省事,关键是它要同时暴露 Web 端口和 MCP 端口。我实测下来,MCP 服务默认挂在8001端口的/mcp路径上,走 SSE 传输。启动命令大致是这样:

docker run -d \ --name sqlbot \ --restart unless-stopped \ -p 8000:8000 \ -p 8001:8001 \ -e SERVER_IMAGE_HOST=http://<你的宿主机IP>:8001/images/ \ -v ./data/sqlbot/excel:/opt/sqlbot/data/excel \ -v ./data/sqlbot/file:/opt/sqlbot/data/file \ -v ./data/sqlbot/images:/opt/sqlbot/images \ -v ./data/sqlbot/logs:/opt/sqlbot/logs \ -v ./data/postgresql:/var/lib/postgresql/data \ --privileged=true \ dataease/sqlbot

起来之后进http://<宿主机IP>:8000完成初始化,配好要查询的 MySQL/PostgreSQL 数据源,再在「AI 模型」里挂一个可用的对话模型。SQLBot 自己需要模型来生成 SQL,这一步别跳过,否则 MCP 调过去也是空转。

2.2 TaoToken 统一 Key 放在哪一层

这里有个容易搞混的点:TaoToken 的统一 Key/API 通道,是给「需要调用大模型」的环节用的,不是给 MCP 传输层用的。也就是说,SQLBot 内部生成 SQL 时如果走的是 OpenAI 兼容接口,那它的模型配置里填的 Base URL 和 Key 就应该指向 TaoToken 的通道;而 Dify 调 SQLBot 的 MCP 端点,走的是内网 HTTP,跟 TaoToken 无关。

TaoToken 的 API 入口是https://taotoken.net/api,兼容 OpenAI 的/v1/chat/completions格式。你在 SQLBot 的模型配置里,把 Base URL 填成这个地址,Key 填你在控制台生成的令牌即可。这样 SQLBot 生成 SQL 用的模型就走统一通道,换模型、看用量都在一个地方管。

如果你还没建 Key,去控制台建一个:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,建完在 API Keys 页面复制:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。想先确认模型通不通,可以直接在模型对话页试一句:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 。

2.3 Dify 侧要装的 MCP 插件

Dify 调 MCP 靠的是 marketplace 里的mcp_sse插件,插件 ID 形如junjiem/mcp_sse。装完之后,工作流里会多出一个「调用 MCP 工具」的节点,它的参数里有一个servers_config字段,这就是我们要写config.toml骨架的地方——准确说,Dify 的 MCP 节点用的是 JSON 形式的 servers 配置,但很多团队会把它抽成一个config.toml统一管理,下面我给两种写法。

3. 可复制的 config.toml 骨架

3.1 独立 config.toml 写法

如果你是在 Dify 之外先用命令行工具(比如 mcp 客户端)验证 SQLBot,config.toml可以这样写。注意transport必须是sse,URL 指向 SQLBot 的 MCP 端点:

# config.toml —— SQLBot MCP 接入骨架 [mcp_servers.sqlbot_mcp] url = "http://host.docker.internal:8001/mcp" transport = "sse" timeout = 50 sse_read_timeout = 50 # 如果 SQLBot 需要鉴权头,在这里加 [mcp_servers.sqlbot_mcp.headers] # Authorization = "Bearer <your-token>"

几个参数的含义对照一下:

参数作用建议值
urlSQLBot MCP 端点地址http://host.docker.internal:8001/mcp
transport传输协议固定sse
timeout单次调用超时(秒)50
sse_read_timeoutSSE 长连接读超时(秒)50
headers自定义请求头按需,无鉴权可留空

注意:host.docker.internal是容器访问宿主机的别名。如果你的 Dify 和 SQLBot 都在同一台宿主机上跑容器,用这个最稳;如果 SQLBot 在另一台机器,直接换成那台机器的内网 IP。

3.2 Dify MCP 节点里的 JSON 等价写法

Dify 的 MCP 工具节点不直接读 toml,它要的是 JSON 字符串。把上面的骨架翻译过去就是:

{ "sqlbot_mcp": { "url": "http://host.docker.internal:8001/mcp", "transport": "sse", "headers": {}, "timeout": 50, "sse_read_timeout": 50 } }

这个 JSON 填在 MCP 节点的servers_config参数里。我建议你把它存成一个环境变量或者工作流变量,别硬编码在节点里,后面换环境只改一处。

3.3 两个 MCP 工具节点的参数差异

SQLBot 的 MCP 暴露了两个关键工具:mcp_start和mcp_question。前者用来拿access_token和chat_id,后者用来真正提问。它们的arguments参数结构不一样,这是最容易配错的地方。

mcp_start的 arguments:

{ "username": "admin", "password": "SQLBot@123456" }

mcp_question的 arguments:

{ "chat_id": "{{#conversation.chat_id#}}", "question": "{{#sys.query#}}", "token": "{{#conversation.access_token#}}" }

看到区别了吗?mcp_start只要账号密码,mcp_question要的是上一轮拿到的chat_id和token。所以工作流里必须先调mcp_start,用代码节点把返回的data.chat_id和data.access_token解析出来,赋值给会话变量,再传给mcp_question。

4. 工作流串接与连通性验证

4.1 完整节点链路

一个能跑通的最小链路是这样的:

开始节点(收 username/password)→ 条件分支(判断 access_token 是否为空)→ MCP 工具mcp_start→ 代码节点(解析 token 和 chat_id)→ 变量赋值节点(写入会话变量)→ MCP 工具mcp_question→ 直接回复。

条件分支的作用是:第一次进来access_token为空,走mcp_start拿 token;后续对话 token 已存在,直接跳到mcp_question,省一次登录。

代码节点解析返回的 Python 逻辑:

import json def main(arg1: str) -> dict: json_obj = json.loads(arg1) return { "chat_id": json_obj["data"]["chat_id"], "access_token": json_obj["data"]["access_token"] }

变量赋值节点把chat_id和access_token分别写进conversation.chat_id和conversation.access_token,这样下一轮对话还能复用。

4.2 一次连通性验证动作

配完之后别急着接业务,先做一次最小验证。在 Dify 工作流里手动触发,username 填admin,password 填你 SQLBot 的密码,query 填一句最简单的:

查一下 smart_vision 库里有多少张表

预期返回分两段。第一段是mcp_start的返回,结构大致是:

{ "data": { "chat_id": 0, "access_token": "eyJhbGciOi..." } }

第二段是mcp_question的返回,里面会带 SQLBot 生成的 SQL 和查询结果,形如:

{ "data": { "sql": "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='smart_vision'", "result": [{"count": 12}] } }

只要你能看到access_token是一串非空的 JWT,并且mcp_question返回里带sql字段,就说明 MCP 链路通了。如果mcp_question返回空或者报错,八成是chat_id/token没传对,回去检查变量赋值节点。

4.3 用 curl 单独验证 MCP 端点

不想在 Dify 里反复点,也可以先用 curl 确认 SQLBot 的 MCP 端点活着:

curl -N -H "Accept: text/event-stream" \ http://<宿主机IP>:8001/mcp

正常的话会挂住并持续输出 SSE 事件流,能看到event: endpoint之类的行。如果直接 connection refused,说明 SQLBot 的 8001 端口没起来或者被防火墙挡了,先解决这个再谈 Dify 接入。

5. 本篇常见错排查

5.1 host.docker.internal 解析失败

这是最高频的坑。Dify 容器里访问host.docker.internal报Name or service not known,说明你的容器运行时没给这个别名。两个解法:一是启动 Dify 容器时加--add-host=host.docker.internal:host-gateway;二是干脆把 URL 换成宿主机的真实内网 IP,比如http://192.168.27.161:8001/mcp。后者更省事,我一般直接用 IP。

5.2 MCP 节点报 transport 不支持

如果你把transport写成了http或者streamable-http,Dify 的 mcp_sse 插件会直接拒绝。SQLBot 这个版本走的是 SSE,transport必须是小写sse。另外 URL 结尾的/mcp不能少,少了会 404。

5.3 mcp_question 返回 token 无效

多半是mcp_start和mcp_question用了不同的servers_config,导致两次调用连到了不同的 SQLBot 实例,token 自然对不上。检查两个 MCP 节点的servers_config是否完全一致。还有一种情况是会话变量没写进去,{{#conversation.access_token#}}取到空字符串,回去看变量赋值节点的write_mode是不是over-write。

5.4 SQLBot 生成 SQL 但执行报错

这通常不是 MCP 的问题,而是 SQLBot 侧的数据源配置或模型能力问题。先确认 SQLBot 里配的数据源能正常连通,再确认挂的模型能稳定输出 SQL。如果模型走的是 TaoToken 通道,去模型对话页发一句「写一条查询 users 表前 10 行的 SQL」看返回质量:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 。模型本身写 SQL 就不稳,换更强的模型比调 MCP 参数有用。

5.5 超时设置太短导致长查询中断

复杂查询 SQLBot 要检索 schema 再生成 SQL,耗时可能超过 30 秒。timeout和sse_read_timeout都建议给到 50 秒以上。如果还是断,看 SQLBot 容器日志里有没有模型调用超时,那就要从模型通道侧找原因。

6. 接入之后怎么继续往下走

链路通了只是第一步。真正上生产,你还要考虑几件事:SQLBot 的账号密码别硬编码在工作流里,用 Dify 的环境变量或者密钥管理;chat_id和access_token的会话变量要设过期策略,避免长期复用失效 token;MCP 调用失败要有兜底分支,别让整个对话直接崩掉。

如果你打算把 SQLBot 接进更复杂的 Agent 流程,或者需要长期跑编码类任务,可以看看 Coding Plan 的额度方案:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。接入细节和参数说明都在文档里:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。Claude Code 相关的接入配置参考:https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite 。

最后留一个我踩过的坑:Dify 工作流调试时,MCP 节点的输出经常是一大坨 JSON,直接看很痛苦。建议在代码节点里加一行print或者把关键字段单独输出,调试效率能高不少。

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

Windows 0xc0000142错误全解析:DLL初始化失败的原因与修复方法

1. 0xc0000142错误到底是什么&#xff1a;从现象到本质的完整拆解 1.1 一个让无数人抓狂的弹窗 如果你在Windows上双击某个程序&#xff0c;屏幕一黑&#xff0c;弹出一个对话框写着“应用程序无法正常启动(0xc0000142)。请单击‘确定’关闭应用程序”&#xff0c;然后程序就没…

作者头像 李华
网站建设 2026/9/26 12:09:03

Win11下ASP+Access库存系统部署与避坑实战

简介&#xff1a;这是一套基于ASPAccess开发的库存管理系统完整源码&#xff0c;面向Web开发初学者及具备基础数据库操作能力的开发者&#xff0c;适用于中小型企业或教学实训场景中的进销存业务管理需求。资源包为ZIP格式&#xff0c;大小4.85MB&#xff0c;包含全部可运行代码…

作者头像 李华
网站建设 2026/9/26 12:08:47

百考通AI实战:毕业设计从选题到答辩的全流程智能辅助方案

每年三四月&#xff0c;我朋友圈的画风就会突然统一起来——全是论文截图&#xff0c;配文不是“刚刚改完第7版”&#xff0c;就是“今晚要把绪论肝完”。这种痛我太熟了&#xff0c;带过几届毕业生&#xff0c;见过太多人被文献综述、数据分析、导师意见来回拉扯&#xff0c;最…

作者头像 李华
网站建设 2026/9/26 12:07:52

表单验证完整指南:从原生原理到工程化落地

表单验证完整实现&#xff1a;从原生原理拆解到工程化落地表单验证这事&#xff0c;说简单是真简单——一个required属性、一段正则、一个if判断就完事。但说复杂也真复杂&#xff0c;我接手过的项目里&#xff0c;因为表单验证没做好导致线上出事故的案例一只手数不过来。有的…

作者头像 李华