小贴士:按下Ctrl+D 或 ⌘+D,一键收藏本站,方便下次快速访问!
2
最近更新:6天前

提供安全的数据库连接,用于执行针对 PostgreSQL 数据库的 SQL 查询和使用 DuckDB 分析 Parquet 文件,并支持 Google Cloud Storage 集成。

MCP 数据库服务器

一个使用 mcp-framework 构建的 Model Context Protocol (MCP) 服务器,提供与数据库(通过 DuckDB 使用 PostgreSQL)和 Google Cloud Storage (GCS) 交互的工具和资源。

先决条件

  • Node.js 22 或更高版本
  • TypeScript
  • PostgreSQL(数据库功能所需)
  • Google Cloud 凭据(可选,用于 GCS 功能)
  • Devbox(用于通过 make 命令进行本地开发)

项目结构

plaintext 复制代码
.
├── docs
│   ├── assets
│   │   └── etl.png
│   ├── etl-workflow.md
│   └── setup-with-claude-desktop.md
├── migrations
│   ├── 1743322886782_initial-schema.cjs
│   └── 1743323460433_continuous-aggregates.cjs
├── scripts
│   └── setup-continuous-aggregates.sql
├── src
│   ├── resources       # MCP 资源定义
│   │   ├── gcs_objects.ts
│   │   └── sql_tables.ts
│   ├── services        # 服务初始化器(数据库连接、GCS 客户端)
│   │   ├── duckdb.ts
│   │   ├── gcs.ts
│   │   └── postgres.ts
│   ├── tools           # MCP 工具定义
│   │   ├── duckdb_insert.ts
│   │   ├── duckdb_query.ts
│   │   ├── duckdb_read_parquet.ts
│   │   └── gcs_directory_tree.ts
│   ├── utils           # 实用函数(日志记录、格式化)
│   │   ├── index.ts
│   │   └── logger.ts
│   ├── config.ts       # 配置加载和验证
│   ├── index.ts        # 主服务器入口点
│   └── utils.ts        # 已弃用的工具?(如果未使用则考虑移除)
├── .env.example        # 示例环境变量
├── .gitignore
├── CLAUDE.md
├── Dockerfile
├── MIGRATION.md
├── Makefile            # 开发命令
├── README.md
├── database.json       # 迁移配置
├── devbox.json         # Devbox 配置
├── devbox.lock
├── docker-compose.yml  # 数据库的 Docker 设置
├── fly.toml            # Fly.io 部署配置
├── package-lock.json
├── package.json
└── tsconfig.json

安装

  1. 克隆仓库:

    bash 复制代码
    git clone <repository-url>
    cd mcp-db
  2. 安装依赖项(建议使用 Devbox 以确保一致性):

    bash 复制代码
    devbox install
    # 或者如果不使用 Devbox,则直接使用 npm
    # npm install
  3. 复制 .env.example.env 并填写您的环境变量。

    bash 复制代码
    cp .env.example .env
    # 使用您的详细信息编辑 .env
  4. 构建项目:

    bash 复制代码
    # 使用 make(需要 Devbox)
    make build
    # 或者直接使用 npm
    # npm run build

配置

环境变量

使用以下环境变量(或命令行参数)配置服务器:

  • DATABASE_URL: PostgreSQL 连接字符串(除非使用 supergateway,否则必需)。
  • DATABASE_URLS: 逗号分隔的 alias=url 对列表,用于多个数据库连接(DATABASE_URL 的替代方案)。
  • LOG_LEVEL: 日志级别 (debug, info, error)。默认值:info
  • GCS_BUCKET: 默认 Google Cloud Storage 存储桶名称(可选)。
  • GCP_SERVICE_ACCOUNT: Base64 编码的 Google Cloud 服务账户密钥 JSON(可选,用于 GCS 认证)。
  • GCS_KEY_ID / GCS_SECRET: 特定于 DuckDB 的 httpfs 扩展的 GCS 凭据(可选)。
  • TRANSPORT: 传输类型 (stdiosse)。默认值:stdio
  • PORT: SSE 传输的端口号。默认值:3001
  • HOST: SSE 传输的主机名。默认值:localhost
  • API_KEY: 可选的 API 密钥,用于保护服务器(如果设置,则客户端必须在 Authorization: Bearer <key> 标头中提供它)。

命令行参数(例如,--port 8080, --gcs-bucket my-bucket)会覆盖环境变量。详情请参阅 src/config.ts

数据库迁移

该项目使用 node-pg-migrate 来管理 PostgreSQL 模式更改。有关运行和创建迁移的详细信息,请参阅上面原始 README 内容中的“数据库迁移”部分。

注意: 提到的 npm run setup:db 命令可能需要根据当前设置进行审查或更新。

运行服务器

使用 Makefile 获取方便的开发命令(需要 Devbox):

bash 复制代码
# 以开发模式运行(构建并使用 nodemon 启动以实现自动重启)
# 默认使用 SSE 传输,端口为 3001
make dev

# 运行测试(如果已配置)
# make test

# 构建用于生产
# make build

不使用 make 运行(在 npm run build 之后):

bash 复制代码
# 使用 stdio 传输运行
node dist/index.js --transport stdio

# 使用 SSE 传输在默认端口 3001 上运行
node dist/index.js --transport sse

# 在不同端口上使用 SSE 运行
node dist/index.js --transport sse --port 8080

客户端配置

要将您的 MCP 客户端(例如,mcp-cli,Claude Desktop)连接到本地服务器:

对于 SSE 传输(例如,在端口 3001 上):

json 复制代码
{
  "mcpServers": {
    "mcp-db-local": {
      "command": "node",
      "args": [
        "/path/to/mcp-db/dist/index.js", // 如果需要,请调整路径
        "--transport", "sse",
        "--port", "3001" // 匹配服务器运行的端口
      ],
      // 如果设置了 API_KEY,请添加 "env"
      // "env": { "API_KEY": "your-secret-key" }
    }
  }
}

(注意:之前的 README 中的 Docker/supergateway 示例可能已过时或特定于不同的部署设置。)

对于 Stdio 传输:

json 复制代码
{
  "mcpServers": {
    "mcp-db-local": {
      "command": "node",
      "args": [
        "/path/to/mcp-db/dist/index.js", // 如果需要,请调整路径
        "--transport", "stdio"
      ],
      // 如果设置了 API_KEY,请添加 "env"
      // "env": { "API_KEY": "your-secret-key" }
    }
  }
}

使用 npx 从 GitHub 运行

您可以直接使用 npx 运行服务器(需要包中的构建步骤):

bash 复制代码
# 确保设置了所需的环境变量
export DATABASE_URL="postgresql://user:password@localhost:5432/db"
export GCS_BUCKET="my-bucket"

npx github:dwarvesf/mcp-db --transport sse --port 3001

可用工具

  • duckdb_insert: 在通过 DuckDB 连接的 PostgreSQL 数据库上执行 INSERT 语句。仅允许 INSERT 查询。
  • duckdb_query: 使用 DuckDB 的 postgres_query 函数在附加的 PostgreSQL 数据库(postgres_db)上直接执行只读 SQL 查询。自动为未限定的表名添加前缀(例如,my_table 变为 postgres_db.public.my_table)。
  • duckdb_read_parquet: 使用 DuckDB 查询 Parquet 文件(如果已配置,通常来自 GCS)。
  • duckdb_update: 在通过 DuckDB 连接的 PostgreSQL 数据库上执行 UPDATE 语句。
  • gcs_directory_tree: 从 GCS 存储桶获取目录树结构,并支持分页。

可用资源

  • mcp://gcs/objects: 列出配置的 GCS 存储桶中的对象。
  • mcp://db/tables: 列出配置的 PostgreSQL 数据库中的所有表及其列。

开发:集成新工具/资源

此项目使用 mcp-framework。要添加新工具或资源:

  1. 创建类:

    • src/tools/src/resources/ 中创建新的 .ts 文件。
    • 定义一个扩展 MCPToolMCPResource 的类。
    • 实现所需属性(工具的 name, description, schema)和方法(工具的 execute,资源的 read)。
    • schema 属性中使用 Zod 进行输入验证(适用于工具)。
    • 在类内初始化任何依赖项(如数据库连接或 GCS 客户端),通常在构造函数中,可能使用 src/services/src/config.ts 中的服务。

    示例工具(src/tools/my_tool.ts):

    typescript 复制代码
    import { MCPTool } from "mcp-framework";
    import { z } from "zod";
    import { formatSuccessResponse } from "../utils.js";
    import { getDuckDBConnection } from "../services/duckdb.js"; // 示例依赖
    
    const MyToolInputSchema = z.object({
      param1: z.string().describe("参数 1 的描述"),
    });
    type MyToolInput = z.infer<typeof MyToolInputSchema>;
    
    export class MyTool extends MCPTool<MyToolInput> {
      name = "my_tool";
      description = "我的工具的功能描述。";
      schema = { // 匹配 Zod schema 结构
        param1: { type: z.string(), description: "参数 1 的描述" },
      };
    
      async execute(args: MyToolInput): Promise<any> {
        console.error(`处理工具请求: ${this.name}`);
        const duckDBConn = getDuckDBConnection(); // 获取依赖
        // ... 使用 args 和 duckDBConn 实现逻辑 ...
        const result = { message: `已处理 ${args.param1}` };
        return formatSuccessResponse(result);
      }
    }
    export default MyTool; // 确保默认导出
  2. 自动发现:

    • mcp-framework 会自动发现并注册从 src/toolssrc/resources 目录中的文件默认导出的工具/资源类。
    • 确保您的新类是其文件的 默认导出
  3. 测试:

    • 启动服务器(make dev)。
    • 检查启动日志以确保列出您的新工具/资源。
    • 使用 MCP 客户端(如 mcp-cli 或 MCP Inspector)调用工具或读取资源并验证其功能。

最佳实践

  • 使用 Zod 为工具定义明确的输入模式。
  • execute/read 中优雅地处理错误,并返回格式化的错误响应(或抛出错误)。
  • 在需要的地方通过 getConfig() 使用集中化的配置(src/config.ts)。
  • 利用 src/services/ 中的服务初始化器来获取依赖项,例如数据库连接。
  • 添加日志记录(console.error)以提高可见性。