npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sql-agent-bridge

v0.2.2

Published

A lightweight, portable, security-hardened MCP server for multi-dialect database access

Readme

sql-agent-bridge

一个轻量级、可移植、安全加固的 MCP(Model Context Protocol)服务器,为 AI 编程助手提供多方言数据库、默认只读且可选受控写模式的访问能力(MySQL / SQLite / Oracle / SQLServer)。当前版本 v0.2.0

特性

| 方面 | 能力 | |------|------| | 🔗 多方言 + 多数据源 | 单一配置文件管理多个数据库实例,支持 MySQL / SQLite / Oracle / SQLServer | | 🔒 企业级安全 | 默认只读(可选受控写模式)、参数化查询防注入、危险操作拦截、行数/超时限制、审计日志 | | 🖥️ 跨平台运行 | 纯 Node.js 实现,支持 Windows / macOS / Linux | | 🤖 Agent 无关 | 严格遵循 MCP 标准(STDIO / SSE),兼容 Reasonix、Cursor、Claude Desktop 等任意客户端 | | 🐳 容器化友好 | 提供 Dockerfile,支持一键部署 | | 📦 可选驱动安装 | 仅需 Node.js(v18+) 运行时;方言驱动按需安装(better-sqlite3 / oracledb / mssql) | | 📋 配置精简 | Template 继承减少重复,MCP_ALLOWED_CONNECTIONS 白名单精细化暴露 |

快速开始

安装

npm install -g sql-agent-bridge

首次启动会自动在 ~/.sql-agent-bridge/ 创建配置文件模板。

配置

编辑 ~/.sql-agent-bridge/mcp-config.json,填入你的数据库信息:

{
  "connections": [
    {
      "name": "my-db",
      "description": "我的 MySQL 数据库",
      "url": "mysql://readonly_user:${DB_PASSWORD}@127.0.0.1:3306/my_database"
    },
    {
      "name": "local-sqlite",
      "description": "本地 SQLite 文件",
      "url": "sqlite:///path/to/data.db"
    }
  ]
}

密码用 ${DB_PASSWORD} 占位符,运行时从环境变量读取。URL 格式为 dialect://[user[:pass]@]host[:port][/db][?opts]

启动

# 设置密码环境变量
# Linux/macOS: export DB_PASSWORD="your-password"
# Windows: $env:DB_PASSWORD="your-password"

sql-agent-bridge    # STDIO 模式(默认)

# SSE 模式
MCP_TRANSPORT=sse MCP_PORT=3000 sql-agent-bridge

配置详解

连接配置字段 (connections[])

| 字段 | 类型 | 必需 | 说明 | |------|------|------|------| | name | string | ✅ | 连接别名,AI 通过此名称引用数据库 | | description | string | ✅ | 连接描述,对 AI 可见,建议写明用途和环境 | | url | string | ✅ | 数据库连接 URL,格式:dialect://[user[:pass]@]host[:port][/db][?opts],支持 ${ENV_VAR} 注入 | | mode | string | | "readonly"(默认)或 "readwrite"(需配合全局开关) | | poolSize | number | | 连接池大小,默认 10(SQLite 忽略此字段) | | charset | string | | 字符集,默认继承全局 defaults.charset(utf8mb4) | | timezone | string | | 时区,默认继承全局 defaults.timezone"Z" 即 UTC) | | extends | string | | 指向 templates 中的一个 key,该 template 的字段作为默认值(单层继承) | | healthCheck | boolean | | 连接级覆盖 defaults.healthCheck |

URL 方言参考

| 方言 | URL 示例 | |------|---------| | MySQL | mysql://user:pass@localhost:3306/mydb?ssl=true | | SQLite | sqlite:///absolute/path/to/db.sqlitesqlite:relative.db | | Oracle | oracle://scott:tiger@dbhost:1521/XEPDB1 | | SQLServer | sqlserver://sa:pass@dbhost:1433/mydb?encrypt=true |

Template 继承 (templates)

{
  "templates": {
    "base": {
      "mode": "readonly",
      "poolSize": 5,
      "charset": "utf8mb4"
    }
  },
  "connections": [
    {
      "name": "prod-db",
      "description": "生产数据库(只读)",
      "url": "mysql://reader:${PROD_PASS}@prod-host:3306/mydb",
      "extends": "base"
    }
  ]
}

全局默认配置 (defaults)

| 字段 | 类型 | 默认值 | 说明 | |------|------|--------|------| | maxRows | number | 1000 | 绝对最大返回行数,查询 LIMIT 不会超过此值 | | queryTimeout | number | 30000 | 查询超时时间(毫秒),超时返回 E003 | | defaultLimit | number | 100 | 未指定 limit 参数时自动追加的 LIMIT 值 | | charset | string | "utf8mb4" | 全局默认字符集 | | timezone | string | "Z" | 全局默认时区 | | healthCheck | boolean | false | 启动时是否对每个连接执行 SELECT 1 预检 | | enableKeepAlive | boolean | true | 是否启用 TCP keep-alive | | keepAliveInitialDelay | number | 10000 | keep-alive 初始延迟(毫秒) |

环境变量

| 变量名 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | MCP_CONFIG_PATH | string | ~/.sql-agent-bridge/mcp-config.json | 配置文件路径(默认在用户全局目录) | | MCP_TRANSPORT | stdio | sse | stdio | 传输模式 | | MCP_PORT | number | 3000 | SSE 模式监听端口 | | MCP_ALLOW_WRITE | true | false | false | 全局写操作开关 | | MCP_ALLOWED_CONNECTIONS | string | — | 逗号分隔的连接白名单;设置后只暴露列表中指定的数据库 | | MCP_LOG_LEVEL | string | info | 日志级别:debug / info / warn / error | | MCP_LOG_FILE | string | — | 日志文件路径,不设置则输出到 stderr | | MCP_FEEDBACK | true | false | false | 是否启用反馈收集工具 submit_feedback | | MCP_FEEDBACK_DIR | string | ~/.sql-agent-bridge/ | 反馈文件存储目录 |

提供的工具

| 工具 | 描述 | 参数 | |------|------|------| | list_connections | 列出所有可用数据库别名 | 无 | | query | 执行 SQL 查询(默认只读) | connectionName, sql, limit?, confirm? | | get_schema | 获取指定表结构,包括表注释(tableComment)和每列的列注释(comment)、类型、主键、默认值、是否可空等 | connectionName, table | | explain_query | 获取 SELECT 执行计划 | connectionName, sql |

get_schema 输出示例

{
  "tableName": "users",
  "tableComment": "用户表",
  "columns": [
    {
      "name": "id",
      "type": "int",
      "key": "PRI",
      "nullable": "NO",
      "default": "",
      "extra": "auto_increment",
      "comment": "主键ID",
      "position": 1,
      "table_comment": "用户表"
    },
    {
      "name": "email",
      "type": "varchar(255)",
      "key": "",
      "nullable": "NO",
      "default": "",
      "extra": "",
      "comment": "邮箱地址",
      "position": 2,
      "table_comment": "用户表"
    }
  ],
  "columnCount": 2
}

MySQL/Oracle/SQLServer 返回真实注释;SQLite 返回空串但字段始终存在。

默认情况下所有工具均为只读。写操作需同时满足 MCP_ALLOW_WRITE=true、连接 mode="readwrite" 以及 confirm="I understand the risk"

AI 客户端接入

全局安装后(npm install -g sql-agent-bridge),所有客户端只需一行 "command": "sql-agent-bridge"

Reasonix

{
  "mcpServers": {
    "sql-agent-bridge": {
      "type": "stdio",
      "command": "sql-agent-bridge",
      "enabled": true
    }
  }
}

Cursor

{
  "mcpServers": {
    "sql-agent-bridge": {
      "command": "sql-agent-bridge"
    }
  }
}

Claude Desktop

{
  "mcpServers": {
    "sql-agent-bridge": {
      "command": "sql-agent-bridge"
    }
  }
}

OpenCode

{
  "mcp": {
    "sql-agent-bridge": {
      "type": "local",
      "command": ["npx", "-y", "sql-agent-bridge"]
    }
  }
}

密码通过系统环境变量传入(如 export DB_PASSWORD=xxx),不出现任何配置文件中。首次运行自动创建 ~/.sql-agent-bridge/mcp-config.json

Docker 部署

docker build -t sql-agent-bridge .
docker run -e DB_PASSWORD="xxx" sql-agent-bridge

SSE 模式:docker run -e DB_PASSWORD=xxx -e MCP_TRANSPORT=sse -p 3000:3000 sql-agent-bridge

v0.1 → v0.2 迁移指南

v0.2.0 将连接配置从扁平字段(host/port/user/password/database)改为单一 url 字段。提供自动迁移脚本:

npx tsx scripts/migrate-config-v0.2.ts ~/.sql-agent-bridge/mcp-config.json

脚本会输出新版配置到 stdout,不覆盖原文件。检查无误后手动替换。

手动迁移对照

{
  "connections": [
    {
      "name": "my-db",
-     "host": "127.0.0.1",
-     "port": 3306,
-     "user": "root",
-     "password": "${DB_PASS}",
-     "database": "mydb",
+     "url": "mysql://root:${DB_PASS}@127.0.0.1:3306/mydb"
    }
  ]
}

安全设计

纵深防御体系

配置层   → 凭证不硬编码,通过 ${ENV_VAR} 注入,缺失即退出
连接层   → 建议使用只读数据库账户 + 强制 SSL/TLS
工具层   → 默认只暴露只读工具,全局 + 连接级双重写开关
SQL 层   → node-sql-parser 解析校验 + 参数化查询防注入
审计层   → 结构化日志记录所有操作,SQL 脱敏后输出

写操作授权(可选)

若需允许写操作,须同时满足三个条件:

  1. 启动时设置 MCP_ALLOW_WRITE=true
  2. 配置文件中对应连接的 mode 设为 "readwrite"
  3. 调用 query 时传入 confirm: "I understand the risk"

SQL 注入防护

  • 所有动态值通过参数化查询(Prepared Statement)的 ? 占位符传递,绝不拼接用户输入
  • 启动时强制 SET NAMES utf8mb4,防止编码攻击
  • SQL 解析失败 → 直接拒绝(E007),不以原始 SQL 透传

日志脱敏

查询日志中 SQL 的字面量(字符串、数字)被替换为 ?

原始 SQL:  SELECT * FROM users WHERE id = 123 AND name = 'Alice'
脱敏后:    SELECT * FROM users WHERE id = ? AND name = ?

密码等敏感字段绝不出现在任何日志中。

错误码参考

| 错误码 | 含义 | |--------|------| | E001 | 连接别名不存在 | | E002 | SQL 语句不合法或非只读操作(INSERT/UPDATE/DELETE/DROP 等) | | E003 | 查询超时(超过 queryTimeout 毫秒) | | E004 | 结果集超过最大行数限制(保留) | | E005 | 数据库连接失败 | | E006 | 参数化查询执行失败 | | E007 | SQL 解析失败(不支持的语法或方言) | | E008 | 表不存在或无列(get_schema 专用) |

v0.2.2 已知修复

  • SHOW ... LIKE/WHERE 误判为写操作:根因是 query.ts 不区分 E007/E002 错误码导致解析失败被错误路由到写授权检测,加上 node-sql-parser 不支持 SHOW 后缀子句。修复方案:query.ts 按 error.code 分流(E007 直接返回、E002 多语句直接拒绝),sql-parser.ts 加 SIMPLE_SHOW_RE 正则白名单兜底。

已知限制

  • node-sql-parser 仍不支持 SHOW 后跟复杂 WHERE/LIKE 子句——超出 SIMPLE_SHOW_RE 白名单范围的会返回 E007。建议使用 list_tables 工具替代 SHOW TABLES LIKE
  • SHOW TABLES LIKE 'x';(带尾部分号的 LIKE 查询)会被 regex 拒绝 → 回落 parser → E007。LIKE 后缀不支持尾部分号。
  • list_tables pattern 不做 LIKE 转义(_% 保持原义传递)。

开发指南

项目结构

src/
├── index.ts              # 入口:启动流程、STDIO/SSE 传输、优雅关闭
├── server.ts             # MCP Server 初始化 + 工具注册
├── logger.ts             # pino 日志实例(全部输出到 stderr)
├── errors.ts             # BridgeError 统一错误类型
├── config/
│   ├── types.ts          # 类型定义(AppConfig / EnvConfig / ErrorCode)
│   ├── loader.ts         # 配置加载 + ${ENV_VAR} 解析 + template 继承 + 白名单过滤 + fail-fast
│   └── url-parser.ts     # URL 解析器(四方言:mysql/oracle/sqlserver/sqlite)
├── db/
│   ├── dialect.ts        # Dialect / ConnectionConfig / ParsedUrl 类型
│   ├── pool-manager.ts   # 多连接池管理器(driver-agnostic)
│   ├── client.ts         # [遗留] mysql2 查询封装
│   └── dialects/
│       ├── driver.ts     # DialectDriver 接口定义
│       ├── mysql.ts      # MySQL 驱动实现
│       ├── sqlite.ts     # SQLite 驱动实现(better-sqlite3)
│       ├── oracle.ts     # Oracle 驱动实现(oracledb thin)
│       └── sqlserver.ts  # SQLServer 驱动实现(mssql)
├── security/
│   ├── sql-parser.ts     # SQL 只读校验(多方言)
│   ├── sanitizer.ts      # SQL 日志脱敏
│   └── guard.ts          # 写权限双层校验
├── tools/
│   ├── list-connections.ts
│   ├── query.ts
│   ├── get-schema.ts
│   ├── explain-query.ts
│   ├── list-tables.ts
│   └── submit-feedback.ts
├── transport/
│   └── sse.ts            # SSE HTTP 服务器(多客户端)
└── types/
    └── optional-deps.d.ts # 可选依赖类型声明

命令

| 命令 | 说明 | |------|------| | npm run build | 编译 TypeScript → dist/ | | npm start | 运行编译产物(STDIO 模式) | | npm run dev | 开发模式(tsx 直接运行) | | npm run lint | 类型检查(不生成文件) | | npm test | 运行单元测试(vitest) |

开发约束(硬性要求)

  1. 日志全部走 pino + stderr:stdout 仅供 MCP 协议通信,严禁 console.log
  2. Fail-fast:启动时检测所有 ${ENV_VAR},未定义 → process.exit(1)
  3. SQL 安全:先解析校验只读 → 再执行,解析失败直接拒绝(E007)
  4. 参数化查询:所有动态值通过 ? 占位符传递
  5. 工具描述:每个工具必须包含详尽的 AI 可见 description 字段

发布前检查清单

  • [x] npm run build 零错误
  • [x] npm run lint 零错误
  • [x] npm test 全部通过(79 passed / 7 skipped)
  • [x] 通过 MCP 手工测试:SELECT / JOIN / GROUP BY / INSERT 拦截
  • [x] .gitignore 排除敏感文件

路线图

| 阶段 | 内容 | 状态 | |------|------|------| | 第1-5阶段 | 项目骨架 / 安全加固 / 功能补全 / SSE / Docker | ✅ 完成 | | v0.1.0 | 写模式落地、多语句护栏、统一错误对象、测试补全 | ✅ 完成 | | v0.2.0 | 多方言支持(MySQL/SQLite/Oracle/SQLServer)、URL 配置、template 继承、连接白名单 | ✅ 完成 | | v0.2.2 | SHOW…LIKE/WHERE 误判修复、list_tables 跨方言工具、MCP_FEEDBACK 可选反馈 | ✅ 完成 |

技术栈

| 组件 | 选型 | 说明 | |------|------|------| | 运行时 | Node.js 18+ | 轻量、跨平台 | | MCP SDK | @modelcontextprotocol/sdk v1.29 | 官方标准实现 | | MySQL 驱动 | mysql2 v3.14 | 支持预处理语句、连接池、SSL | | SQLite 驱动 | better-sqlite3 v11 | 同步 API,单文件零配置(可选安装) | | Oracle 驱动 | oracledb v6 | Thin 模式,无需 Oracle Instant Client(可选安装) | | SQLServer 驱动 | mssql v11 | 支持 Windows Auth + SQL Auth(可选安装) | | SQL 解析 | node-sql-parser v5.3 | AST 解析 + 类型识别 | | 日志 | pino v9.5 | 结构化 JSON 日志 | | 参数校验 | zod v3.24 | 工具输入 Schema 校验 | | 单元测试 | vitest v2.1 | 快速 ESM 原生测试框架 | | 集成测试 | vitest + vi.mock | 纯 mock 方案;真环境集成测试见 test-data/setup-pg.cjs(本地 PG 初始化) |

License

MIT