MCP 数据库工具
一种模型上下文协议服务器,提供与数据库交互的工具,包括PostgreSQL、DuckDB和Google Cloud Storage Parquet文件。
服务介绍
MCP 数据库服务器
使用 mcp-framework 构建的模型上下文协议 (MCP) 服务器,提供了与数据库(通过 DuckDB 访问 PostgreSQL)和 Google Cloud Storage (GCS) 交互的工具和资源。
先决条件
- Node.js 22 或更高版本
- TypeScript
- PostgreSQL(数据库功能所需)
- Google Cloud 凭证(可选,用于 GCS 功能)
- Devbox(使用
make命令进行本地开发)
项目结构
.
├── 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 Resource definitions
│ │ ├── gcs_objects.ts
│ │ └── sql_tables.ts
│ ├── services # Service initializers (DB connections, GCS client)
│ │ ├── duckdb.ts
│ │ ├── gcs.ts
│ │ └── postgres.ts
│ ├── tools # MCP Tool definitions
│ │ ├── duckdb_insert.ts
│ │ ├── duckdb_query.ts
│ │ ├── duckdb_read_parquet.ts
│ │ └── gcs_directory_tree.ts
│ ├── utils # Utility functions (logging, formatting)
│ │ ├── index.ts
│ │ └── logger.ts
│ ├── config.ts # Configuration loading and validation
│ ├── index.ts # Main server entry point
│ └── utils.ts # Deprecated utils? (Consider removing if unused)
├── .env.example # Example environment variables
├── .gitignore
├── CLAUDE.md
├── Dockerfile
├── MIGRATION.md
├── Makefile # Development commands
├── README.md
├── database.json # Migration configuration
├── devbox.json # Devbox configuration
├── devbox.lock
├── docker-compose.yml # Docker setup for DBs
├── fly.toml # Fly.io deployment config
├── package-lock.json
├── package.json
└── tsconfig.json
安装
-
克隆仓库:
git clone <repository-url> cd mcp-db -
安装依赖(推荐使用 Devbox 以保持一致性):
devbox install # 如果不使用 Devbox,则直接使用 npm # npm install -
将
.env.example复制为.env并填写您的环境变量。cp .env.example .env # 根据您的详细信息编辑 .env -
构建项目:
# 使用 make(需要 Devbox) make build # 或者直接使用 npm # npm run build
配置
环境变量
使用这些环境变量(或命令行参数)配置服务器:
DATABASE_URL: PostgreSQL 连接字符串(除非使用超级网关运行,否则必需)。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: 传输类型(stdio或sse)。默认: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):
# Run in development mode (builds and starts with nodemon for auto-restarts)
# Uses SSE transport by default on port 3001
make dev
# Run tests (if configured)
# make test
# Build for production
# make build
如果不使用 make(在 npm run build 之后):
# Run with stdio transport
node dist/index.js --transport stdio
# Run with SSE transport on default port 3001
node dist/index.js --transport sse
# Run with SSE on a different port
node dist/index.js --transport sse --port 8080
客户端配置
要将您的 MCP 客户端(例如 mcp-cli、Claude Desktop)连接到本地服务器:
对于 SSE 传输(例如端口 3001):
{
"mcpServers": {
"mcp-db-local": {
"command": "node",
"args": [
"/path/to/mcp-db/dist/index.js", // Adjust path if needed
"--transport", "sse",
"--port", "3001" // Match the port the server is running on
],
// Add "env" if API_KEY is set
// "env": { "API_KEY": "your-secret-key" }
}
}
}
(注意:之前的README中的Docker/supergateway示例可能已经过时,或者适用于不同的部署设置。)
对于Stdio传输:
{
"mcpServers": {
"mcp-db-local": {
"command": "node",
"args": [
"/path/to/mcp-db/dist/index.js", // Adjust path if needed
"--transport", "stdio"
],
// Add "env" if API_KEY is set
// "env": { "API_KEY": "your-secret-key" }
}
}
}
通过npx从GitHub运行
您可以直接使用npx运行服务器(需要在包中进行构建步骤):
# Ensure required env vars are set
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)。gcs_directory_tree: 从GCS存储桶中获取目录树结构,并支持分页。
可用资源
mcp://gcs/objects(gcs_objects):列出配置的GCS存储桶中的对象。mcp://db/tables(sql_tables):列出配置的PostgreSQL数据库中的所有表及其列。
开发:集成新工具/资源
此项目使用mcp-framework。要添加新工具或资源:
-
创建类:
- 在
src/tools/或src/resources/中创建一个新的.ts文件。 - 定义一个继承自
MCPTool或MCPResource的类。 - 实现必需的属性(工具的
name、description和schema)和方法(工具的execute,资源的read)。 - 在
schema属性中使用 Zod 进行输入验证(工具)。 - 在类中初始化任何依赖项(如数据库连接或 GCS 客户端),通常在构造函数中进行,可能需要使用
src/services/中的服务或src/config.ts中的配置。
示例工具 (
src/tools/my_tool.ts):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 模式结构 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; // 确保默认导出 - 在
-
自动发现:
mcp-framework会自动发现并注册从src/tools和src/resources目录中的文件默认导出的工具/资源类。- 确保你的新类是其文件中的
默认导出。
-
测试:
- 运行服务器 (
make dev)。 - 检查启动日志以确保你的新工具/资源被列出。
- 使用 MCP 客户端(如
mcp-cli或 MCP Inspector)调用工具或读取资源,并验证其功能。
- 运行服务器 (
最佳实践
- 使用 Zod 为工具定义清晰的输入模式。
- 在
execute/read中优雅地处理错误,并使用formatErrorResponse返回格式化的错误响应(或抛出错误)。 - 在需要的地方通过
getConfig()使用集中配置 (src/config.ts)。 - 利用
src/services/中的服务初始化程序来处理依赖项,如数据库连接。 - 添加日志记录 (
console.error) 以便于查看。