Skip to main content
Glama
adlkt

db-connector

by adlkt
README.md
# db-connector · MCP 落地服务 Demo(TypeScript + DeepSeek/OpenRouter)

> 让 AI 直接查询你的业务数据库,全程只读、安全可控。
> MCP 落地服务的**敲门砖作品**:TypeScript 实现 + AI 驱动,真实可跑。

## 技术栈

- **MCP 协议**:官方 `@modelcontextprotocol/sdk`(server + client,标准协议)
- **数据库**:`better-sqlite3`(演示)↔ PostgreSQL(生产,改适配层即可)
- **AI**:默认 DeepSeek,也支持 OpenRouter(含免费模型)——任意 OpenAI 兼容模型只需改 `.env`

## 快速开始

```bash
npm install
cp .env.example .env      # 填入 API key(DeepSeek 或 OpenRouter,见下)
npm run seed              # 生成演示库 demo.db(电商订单系统)
npm run smoke             # 冒烟测试(不依赖 key,验证协议与只读防护)
npm run e2e               # 端到端测试(3 个自然语言问题,需 key)
npm run chat              # 命令行直接问数据库(AI 自动查库回答)
```

```bash
> 哪个城市销售额最高?
🤖 销售额最高的城市是南京,约 ¥8.7 万(59 单)……

> 最近 30 天卖得最好的商品是?
> 买得最多的 3 个客户?
```

### 配置模型(三选一)

```bash
# ① DeepSeek 官方(推荐:便宜、快、国内可用)
DEEPSEEK_API_KEY=sk-xxx
DEEPSEEK_BASE_URL=https://api.deepseek.com
DEEPSEEK_MODEL=deepseek-chat

# ② OpenRouter 免费模型(demo 零成本,但每天限 50 次请求,充值 $10 解锁 1000 次)
DEEPSEEK_API_KEY=sk-or-v1-xxx
DEEPSEEK_BASE_URL=https://openrouter.ai/api/v1
DEEPSEEK_MODEL=nvidia/nemotron-3-super-120b-a12b:free   # 实测工具调用较稳

# ③ 本地 ollama(零成本、数据不出本机,需先装 ollama 并 pull qwen3:8b)
DEEPSEEK_API_KEY=
DEEPSEEK_BASE_URL=http://localhost:11434/v1
DEEPSEEK_MODEL=qwen3:8b

# ④ 任意 OpenAI 兼容服务(通义/豆包/GPT 等)
DEEPSEEK_BASE_URL=<你的服务地址>
DEEPSEEK_MODEL=<模型名>
```

> 本地模型演示建议:qwen3:8b(`ollama pull qwen3:8b`)经实测能稳定答对「哪个城市销售额最高」「哪个商品卖得最多」,但涉及日期函数/复杂多表的问题会不稳(8B 能力边界)。演示脚本请用稳定问题集。

## 两种演示方式(给客户看)

### 方式一:CLI 直接问(推荐,最快出效果)

`npm run chat` → 输入问题 → AI 自动完成「找表 → 看结构 → 写 SQL → 查库 → 分析回答」。全程肉眼可见地调用工具。

### 方式二:接入 Claude Desktop(展示 MCP 通用性)

编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "db-connector": {
      "command": "/Users/wjy/.workbuddy/binaries/node/versions/22.22.2/bin/node",
      "args": ["--import", "tsx", "/Users/wjy/Documents/code/apps/mcp-demo-server/src/server.ts"]
    }
  }
}
```

重启后直接问:「帮我分析订单数据,哪个城市销售额最高?」(推荐先用 `npm run build` 编译成 dist 再用 node 跑,避免依赖 tsx)

## 演示问题清单

- 「按城市统计销售额排名,哪个城市卖得最好?」
- 「最近 30 天销售额和订单量是多少?环比上月增长多少?」
- 「哪个商品是爆款?哪个商品卖不动?」
- 「帮我查出买得最多的 3 个客户」

## 架构

```
AI 客户端 (DeepSeek Agent / Claude Desktop / Cursor)
        │  MCP 标准协议
        ▼
  db-connector (本仓库)
  ├── list_tables      → 自动发现数据结构
  ├── describe_table   → 查看表结构
  └── query            → 只读 SQL 查询(安全拦截非 SELECT)
        │
        ▼
  SQLite (demo.db) / PostgreSQL (生产)
```

**to B 安全卖点(客户最关心):**

| 能力 | 实现 |
|---|---|
| 只读防护 | 非 `SELECT/EXPLAIN/WITH` 语句一律拦截(`src/db.ts`) |
| 结果限额 | 默认 20 行、最多 100 行,防拖库 |
| 模型自由 | DeepSeek / 任意 OpenAI 兼容模型,不绑定 Claude 订阅 |
| 协议标准 | MCP 官方协议,所有 AI 客户端通用 |

## 生产扩展(接单后按客户需求加)

- **认证与权限**:按客户/角色限制可访问的表(白名单)
- **操作日志**:记录 AI 执行的每条 SQL(审计)
- **只读账号**:接数据库只读副本,从源头杜绝写操作
- **更多工具**:除数据库外可接 ERP/CRM API、内部知识库、审批流

## 目录结构

```
src/
├── db.ts        # 数据库适配 + 只读防护
├── server.ts    # MCP Server(stdio 模式 + setupServer 复用)
├── agent.ts     # DeepSeek Agent(自然语言 → MCP 工具 → 回答)
├── cli.ts       # 命令行问答入口
├── seed.ts      # 生成演示数据库
└── smoke.ts     # 冒烟测试(不依赖 API key)
```

## 常见问题

**Q: AI 会不会乱改数据?** 不会。服务端强制只读:非查询类 SQL 直接拦截报错;生产再加只读账号双保险。

**Q: 必须用 DeepSeek 吗?** 不用。改 `.env` 里的 `DEEPSEEK_BASE_URL` / `DEEPSEEK_MODEL` 就能换任意 OpenAI 兼容模型(通义/豆包/GPT 等)。