
Db
提供安全的数据库连接,用于执行针对 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
安装
-
克隆仓库:
bashgit clone <repository-url> cd mcp-db
-
安装依赖项(建议使用 Devbox 以确保一致性):
bashdevbox install # 或者如果不使用 Devbox,则直接使用 npm # npm install
-
复制
.env.example
到.env
并填写您的环境变量。bashcp .env.example .env # 使用您的详细信息编辑 .env
-
构建项目:
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
: 传输类型 (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):
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
。要添加新工具或资源:
-
创建类:
- 在
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
):typescriptimport { 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; // 确保默认导出
- 在
-
自动发现:
mcp-framework
会自动发现并注册从src/tools
和src/resources
目录中的文件默认导出的工具/资源类。- 确保您的新类是其文件的
默认导出
。
-
测试:
- 启动服务器(
make dev
)。 - 检查启动日志以确保列出您的新工具/资源。
- 使用 MCP 客户端(如
mcp-cli
或 MCP Inspector)调用工具或读取资源并验证其功能。
- 启动服务器(
最佳实践
- 使用 Zod 为工具定义明确的输入模式。
- 在
execute
/read
中优雅地处理错误,并返回格式化的错误响应(或抛出错误)。 - 在需要的地方通过
getConfig()
使用集中化的配置(src/config.ts
)。 - 利用
src/services/
中的服务初始化器来获取依赖项,例如数据库连接。 - 添加日志记录(
console.error
)以提高可见性。