跳到主要内容

在Dify中使用universal-db-mcp实现智能问数

·1879 字·4 分钟

在Dify中使用universal-db-mcp实现智能问数 #

在Dify中配置universal-db-mcp的过程中,我发现Dify在MCP方面不仅仅支持通过自定义工具(REST API方式)进行配置,还支持SSE(Server-Sent Events)和Streamable HTTP的MCP传输模式。

所以我在universal-db-mcp的v2.6.0版本中做了升级,不仅支持了原有的stdio模式和REST API模式,也支持了SSE(Server-Sent Events)和Streamable HTTP模式。

简单说一下这三种MCP的传输模式:

1. stdio (Standard Input/Output)

这是最常见、最基础的模式。如果你是在本地运行 MCP 服务器(比如在你的电脑上运行一个连接本地数据库的工具),通常用的就是这个。

  • 工作原理: 客户端(如 Claude Desktop)通过标准输入输出与服务器通信。
  • 适用场景: 本地开发、个人自动化脚本、运行在本地容器中的服务。
  • 优点: 简单、延迟极低、不需要配置网络端口。
  • 缺点: 只能本地使用,客户端必须能启动服务进程。

2. SSE (Server-Sent Events)

当你需要把 MCP 服务器部署在远程服务器或云端时,SSE 就派上用场了。

  • 工作原理: 客户端向服务器发起 HTTP 请求,服务器保持连接开启,并以“流”的形式单向向客户端推送更新。
  • 适用场景: 远程托管的服务、跨网络的工具调用。
  • 优点: 能够穿透大多数防火墙,比传统的 WebSockets 更轻量,专门为流式传输设计。
  • 缺点: 需要网络配置,稍高延迟。

3. Streamable HTTP

这其实是针对现代 Web 开发环境(特别是基于边缘计算的场景,如 Vercel 或 Cloudflare Workers)的一种特殊实现。

  • 工作原理: 它利用了 HTTP/1.1 或 HTTP/2 的分块传输编码(Chunked Transfer Encoding),允许在标准的 HTTP 请求/响应周期中进行持续的数据交换。
  • 适用场景: 无服务器架构(Serverless)、对延迟极其敏感的 Web 环境。
  • 优点: 比SSE更灵活,支持更复杂的交互模式。

前面说了,在使用Dify配置universal-db-mcp的过程中发现,Dify支持REST API、SSE、Streamable HTTP,所以下面将对这三种模式分别进行配置。

当然,不管用那种传输方式,你都需要先启动universal-db-mcp,这部分内容可以直接参考部署启动指南

1. Streamable HTTP配置(推荐) #

1.1 配置MCP服务 #

按照图中内容填写信息

1.2 配置Agent #

按照图中内容,创建Agent。

  1. 添加刚才创建的MCP服务的工具;
  2. 设置模型
  3. 调试
  4. 发布

2. SSE配置 #

2.1 配置MCP服务 #

按照图中内容填写信息

服务端点URL示例

http://host.docker.internal:3000/sse?type=xxx&host=xxx.xxx.xxx.xxx&port=xxxx&user=xxxx&password=xxxx&database=xxxx

2.2 配置Agent #

按照图中内容,创建Agent。

  1. 添加刚才创建的MCP服务的工具;
  2. 设置模型
  3. 调试
  4. 发布

3. REST API配置 #

3.1 创建自定义工具 #

  1. 点击工具
  2. 点击自定义
  3. 创建自定义工具

3.2 填写自定义工具信息 #

填写必要信息

Schema示例

openapi: 3.0.0
info:
  title: Universal DB MCP
  description: 数据库查询工具
  version: 1.0.0
servers:
  - url: http://host.docker.internal:3000/api

paths:
  /connect:
    post:
      operationId: connectDatabase
      summary: 连接到数据库
      description: 建立数据库连接并返回会话ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  description: "数据库类型,支持: mysql, postgres, polardb, sqlite, mongodb, redis, elasticsearch"
                  example: "polardb"
                host:
                  type: string
                  description: 数据库主机地址
                  example: "xxx.xxx.xxx.xxx"
                port:
                  type: integer
                  description: 数据库端口
                  example: 3306
                user:
                  type: string
                  description: 数据库用户名
                  example: "test"
                password:
                  type: string
                  description: 数据库密码
                database:
                  type: string
                  description: 数据库名称
                  example: "test"
              required:
                - type
                - host
                - port
                - user
                - password
                - database
      responses:
        '200':
          description: 连接成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  sessionId:
                    type: string
                    description: 会话ID,用于后续查询

  /disconnect:
    post:
      operationId: disconnectDatabase
      summary: 断开数据库连接
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                sessionId:
                  type: string
                  description: 要断开的会话ID
              required:
                - sessionId
      responses:
        '200':
          description: 断开成功

  /query:
    post:
      operationId: executeQuery
      summary: 执行SQL查询
      description: 在已连接的数据库上执行SQL查询
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                sessionId:
                  type: string
                  description: 数据库会话ID
                query:
                  type: string
                  description: 要执行的SQL语句
                  example: "SELECT * FROM users LIMIT 10"
              required:
                - sessionId
                - query
      responses:
        '200':
          description: 查询成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  rows:
                    type: array
                    items:
                      type: object
                  rowCount:
                    type: integer

  /tables:
    get:
      operationId: listTables
      summary: 列出所有表
      description: 获取数据库中的所有表名
      parameters:
        - name: sessionId
          in: query
          required: true
          schema:
            type: string
          description: 数据库会话ID
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  tables:
                    type: array
                    items:
                      type: string

  /schema/{tableName}:
    get:
      operationId: getTableSchema
      summary: 获取表结构
      description: 获取指定表的字段信息
      parameters:
        - name: tableName
          in: path
          required: true
          schema:
            type: string
          description: 表名
        - name: sessionId
          in: query
          required: true
          schema:
            type: string
          description: 数据库会话ID
      responses:
        '200':
          description: 成功
          content:
            application/json:
              schema:
                type: object
                properties:
                  columns:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        type:
                          type: string
                        nullable:
                          type: boolean

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

security:
  - ApiKeyAuth: []

鉴权方法选择请求头 –> Custom

填入下图的X-API-Key和自己设置的value

3.3 配置Agent #

  1. 填写提示词

    提示词示例

    你是一个数据库查询助手。
    
    使用工具的步骤:
    1. 先用 connectDatabase 连接数据库,记住返回的 sessionId
    2. 用 listTables 查看有哪些表
    3. 用 getTableSchema 查看表结构
    4. 用 executeQuery 执行 SQL 查询
    5. 完成后用 disconnectDatabase 断开连接
    
    数据库连接信息:
    - type: 你的数据库类型
    - host: 你的host
    - port: 你的端口
    - user: 你的用户
    - password: 你的密码
    - database: 你的database
    
    注意:查询时添加 LIMIT 限制返回数量。
    
  2. 选择刚才自定义的工具

  3. 选择模型

  4. 调试

  5. 发布

注意

如果 Dify 的 SSRF 安全代理 阻止了对 host.docker.internal 的访问,可以修改一下 修改 Dify 的 SSRF 白名单:.env中

# 允许访问的内网地址
SSRF_PROXY_HTTP_URL=
SSRF_PROXY_HTTPS_URL=

然后重启dify就行了