
1. 为什么要在 Dify 里接 ClickHouseMCP 协议到底解决了什么Dify 里做数据分析类应用绕不开一个尴尬LLM 本身不会查库。你可以在工作流里写 HTTP 节点拼 SQL但字段一多、表结构一变提示词就得跟着改维护成本高得离谱。MCPModel Context Protocol出现的意义就是把「LLM 调用外部能力」这件事标准化——数据库、文件系统、浏览器都通过统一的工具描述暴露给模型模型自己决定调哪个工具、传什么参数。ClickHouse 作为列式分析库天然适合做日志分析、埋点统计、实时报表这类场景。把 ClickHouse 通过 MCP 接进 Dify 之后你可以在对话应用里直接问「昨天各渠道的订单量是多少」模型会自动生成 SQL、调用工具、把结果整理成自然语言返回。整个过程不需要你手写一行查询代码。这套链路适合谁三类人最需要一是做企业内部数据助手的后端同学希望把已有 ClickHouse 集群快速接进 AI 应用二是做 SaaS 产品的团队想让客户用自然语言查自己的业务数据三是个人开发者手头有 ClickHouse 想试试 MCP 到底好不好用。链路本身分四层Dify 负责对话和工具编排MCP SSE 插件负责把工具调用转成 SSE 请求mcp-proxy 负责把 SSE 转成 stdiomcp-clickhouse 负责真正执行 SQL 并回传结果。中间任何一层配置错了表现都是「工具调不通」所以下面我会把每一层的参数和验证动作都写清楚。另外提一句凭据管理。Dify 里除了 MCP 工具往往还要配模型比如 Claude、GPT 系列。如果每个应用都单独填一遍 Key后期换 Key 会非常痛苦。我的做法是用 TaoToken 做统一通道模型调用走一个 Base URL 一个 KeyMCP 这边只关心数据库凭据两边解耦排查问题时不会互相干扰。2. 前置准备mcp-clickhouse 与 mcp-proxy 的安装和连通性检查动手之前先把两个 Python 包装上。mcp-clickhouse 是 ClickHouse 官方维护的 MCP Server 实现mcp-proxy 是社区里用得比较多的协议转换工具负责 SSE 和 stdio 之间的桥接。pip install mcp-clickhouse pip install mcp-proxy如果你用虚拟环境建议把这两个包装在同一个 venv 里后面 config.json 里的command直接指向 venv 的 python能避免「本机跑得通、换台机器就找不到模块」的问题。装完之后先别急着配 MCP第一步是确认 ClickHouse 本身能通。ClickHouse 默认的 HTTP 接口在 8123 端口用 curl 打一下curl http://192.168.101.150:8123返回Ok.就说明 HTTP 接口正常。如果返回连接拒绝先检查 ClickHouse 是否启动、防火墙是否放行 8123。这一步看着简单但我见过太多人跳过它最后在 Dify 里报 timeout回头查了半天才发现是数据库根本没通。接着验证 mcp-clickhouse 能不能独立启动。先 export 一组环境变量export CLICKHOUSE_HOST192.168.101.150 export CLICKHOUSE_PORT8123 export CLICKHOUSE_USERdefault export CLICKHOUSE_PASSWORDyour-password export CLICKHOUSE_SECUREfalse export CLICKHOUSE_VERIFYfalse export CLICKHOUSE_MCP_SERVER_TRANSPORTstdio然后运行python -m mcp_clickhouse.main如果看到Transport: STDIO和ClickHouse tools registered说明 Server 本身没问题。这时候按 CtrlC 退出因为 stdio 模式下它是等着被 mcp-proxy 拉起的不适合手动常驻。这里有个关键点mcp-clickhouse 默认走 HTTPS 8443。很多内网 ClickHouse 只开了 HTTP 8123如果不显式设置CLICKHOUSE_SECUREfalse启动时就会报 SSL 相关错误。这个坑后面第五节会专门讲。关于模型凭据如果你打算在 Dify 里同时用 Claude 或 GPT 做对话层可以提前在 TaoToken 控制台建好 Key。它的 API 地址是https://taotoken.net/api兼容 OpenAI 风格的调用方式Dify 的模型供应商里选 OpenAI 兼容就能填。这样 MCP 管数据库、TaoToken 管模型职责清晰。3. 可复制配置mcp-proxy 的 config.json 与 Dify MCP SSE 插件接入这一节是整篇的核心配置片段都可以直接复制改。先建一个工作目录比如/root/mcp-workspace/mcp-proxy在里面创建config.json{ mcpServers: { clickhouse: { command: /root/mcp-workspace/venv/bin/python, args: [-m, mcp_clickhouse.main], env: { CLICKHOUSE_HOST: 192.168.101.150, CLICKHOUSE_PORT: 8123, CLICKHOUSE_USER: default, CLICKHOUSE_PASSWORD: your-password, CLICKHOUSE_SECURE: false, CLICKHOUSE_VERIFY: false, CLICKHOUSE_MCP_SERVER_TRANSPORT: stdio } } } }几个容易写错的地方。command建议写绝对路径尤其是用 venv 的时候写python3可能指向系统 Python导致找不到 mcp_clickhouse 模块。args用-m模块方式启动比直接调可执行文件更稳。env里的变量会覆盖系统环境变量所以密码写在这里就行不用再 export 一遍。启动 mcp-proxy注意要监听 0.0.0.0否则 Dify 在另一台机器上访问不到mcp-proxy \ --named-server-config /root/mcp-workspace/mcp-proxy/config.json \ --host 0.0.0.0 \ --port 45195启动成功会看到Registered server: clickhouse和Proxy is now listening。这时候 SSE 端点是http://192.168.101.150:45195/servers/clickhouse/sse注意路径里的servers/clickhouse对应 config.json 里的 server 名字别写错。接下来进 Dify 后台。在「插件」里搜索并安装 MCP SSE 插件然后在工具配置里新增一个 MCP 服务填入{ clickhouse: { url: http://192.168.101.150:45195/servers/clickhouse/sse, headers: {}, timeout: 60, sse_read_timeout: 300 } }timeout是建立连接的超时sse_read_timeout是读取 SSE 流的超时。ClickHouse 查询如果比较慢sse_read_timeout建议给到 300 秒以上否则大查询会被掐断。保存后 Dify 会自动拉取工具列表。如果配置正确你能看到run_select_query、list_databases、list_tables这类工具。到这一步链路就通了。如果你还想在 Dify 里用 Claude 做对话模型可以在模型供应商里加 TaoToken 的通道Base URL 填https://taotoken.net/apiKey 填控制台生成的。这样模型和 MCP 工具各走各的互不影响。4. 验证请求从 Dify 对话到 ClickHouse 查询的完整链路配置完不验证等于没配。验证要分层做从下往上逐层确认。第一层确认 mcp-proxy 的 SSE 端点活着。用 curl 打一下curl -N http://192.168.101.150:45195/servers/clickhouse/sse-N是关闭缓冲你会看到 SSE 流持续输出event: endpoint之类的消息。如果卡住没输出说明 mcp-proxy 没起来或者端口不对。第二层确认 mcp-clickhouse 能被拉起。看 mcp-proxy 的日志正常会有Registered server: clickhouse。如果报command not found或者ModuleNotFoundError回去检查 config.json 里的command路径。第三层在 Dify 里做真实查询。新建一个对话应用把 MCP 工具挂上然后在调试窗口输入查询一下 system.tables 里有哪些表正常情况下你会看到模型先输出一段思考然后调用工具Tool: run_select_query SQL: SELECT * FROM system.tables LIMIT 10接着返回结果模型把表名整理成列表。如果这一步成功说明整条链路 Dify → MCP SSE → mcp-proxy → mcp-clickhouse → ClickHouse 全部打通。第四层验证模型通道。如果你在 Dify 里配了 TaoToken 的模型可以问一个不需要查库的问题比如「你好介绍一下你自己」确认模型调用正常。这样能把「模型问题」和「MCP 问题」区分开——如果模型能回但工具调不通问题一定在 MCP 链路如果模型都不回先查模型配置。实测下来最容易出问题的是第三层。常见表现是模型不调用工具或者调用了但返回空。前者通常是工具描述没被正确加载后者多半是 SQL 权限或表不存在。可以在 mcp-proxy 的日志里看实际发出的 SQL对照 ClickHouse 里手动执行一遍很快能定位。5. 常见报错排查SSL wrong version number、401 与 local proxy failed这一节把踩过的坑列出来对照报错直接查。报错一[SSL: WRONG_VERSION_NUMBER]这是最高频的错误。原因是 mcp-clickhouse 默认用 HTTPS 连 8443而你的 ClickHouse 只开了 HTTP 8123。解决就是在 config.json 的 env 里加CLICKHOUSE_SECURE: false, CLICKHOUSE_VERIFY: falseCLICKHOUSE_VERIFYfalse是跳过证书校验内网自签名证书场景必须加。改完重启 mcp-proxy 即可。报错二401 Unauthorized两种可能。一是 ClickHouse 用户名密码错了检查CLICKHOUSE_USER和CLICKHOUSE_PASSWORD。二是你在 Dify 里配了模型但 Key 无效这种 401 来自模型侧而不是数据库侧。区分方法看报错发生在工具调用前还是调用后。调用前是模型问题调用后是数据库问题。报错三local proxy failed或connection refusedmcp-proxy 没监听 0.0.0.0或者 Dify 和 mcp-proxy 不在同一网络。检查启动命令里有没有--host 0.0.0.0以及防火墙有没有放行 45195 端口。Docker 部署的话还要确认端口映射写对了。报错四Error reading choices或模型返回空这通常是模型通道的问题不是 MCP 的问题。如果你用 TaoToken 做统一通道检查 Base URL 是不是https://taotoken.net/apiKey 有没有过期。Dify 里模型供应商选 OpenAI 兼容模型名填你实际要用的。报错五工具列表为空Dify 连上了 SSE 但拉不到工具。多半是 config.json 里 server 名字和 URL 路径不匹配。URL 是/servers/clickhouse/sseconfig.json 里就必须是clickhouse大小写敏感。排查顺序建议从下往上先 curl ClickHouse 8123再 curl mcp-proxy 的 SSE 端点再看 mcp-proxy 日志最后看 Dify 的工具列表。每层都确认了问题一定跑不掉。6. 凭据统一管理用 TaoToken 收敛模型 KeyMCP 只管数据库链路跑通之后还有一个长期维护的问题Key 散落各处。Dify 里每个应用配一遍模型 KeyMCP 这边又配一遍数据库密码换一次密码要改一堆地方。我的做法是分层管理。数据库凭据留在 mcp-proxy 的 config.json 里因为它是 MCP Server 的启动参数本来就该跟着 Server 走。模型凭据统一收到 TaoTokenDify 里所有应用共用同一个 Base URL 和 Key。具体操作在 TaoToken 控制台生成一个 Key然后在 Dify 的模型供应商里配置Base URL: https://taotoken.net/api API Key: 你的 TaoToken Key Model: claude-sonnet-4-5 或其他你要用的模型这样做的直接好处是换模型或换 Key 只改一处所有应用自动生效。而且模型调用和 MCP 工具调用在日志上是分开的排查问题时能快速判断是模型侧还是数据库侧。如果你做的是长期编码或 Agent 类应用调用量比较大可以看看 TaoToken 的 Coding Plan按套餐走比按量计费更可控。接入文档在https://taotoken.net/doc里面有各语言的示例。最后说一个实用技巧mcp-proxy 的 config.json 里密码不要明文写死可以用环境变量引用。虽然 mcp-proxy 本身不直接支持${VAR}语法但你可以在启动脚本里先 source 一个 env 文件再启动 mcp-proxy这样密码就不在配置文件里了。生产环境建议这么做。整套配置跑下来Dify 里问一句「查一下最近一小时各接口的调用量」模型自动生成 SQL、调 ClickHouse、返回结果全程不用手写查询。MCP 的价值就在这里——把数据库能力标准化地暴露给模型剩下的交给 LLM 自己编排。