Skip to main content
Glama
README.md
<div align="center">

# MCP Gateway

**中文** | [English](./README.en.md)

**把零散的业务接口与数据库,变成 AI 可发现、可鉴权、可审计的统一能力入口**

[![Node](https://img.shields.io/badge/node-%3E%3D22.5-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![MCP](https://img.shields.io/badge/MCP-Streamable%20HTTP-6E56CF)](https://modelcontextprotocol.io/)
[![Tests](https://img.shields.io/badge/tests-150%20passed-brightgreen)](#-测试与自检)
[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)

[快速开始](#-快速开始) · [项目目标](#-项目目标) · [整体架构](#-整体架构) · [核心逻辑](#-核心逻辑一次调用发生了什么) · [文档索引](#-文档索引)

</div>

---

## 💡 为什么需要它

企业里 AI 要用数据,通常卡在三件事上:

| 痛点 | 现实表现 |
| --- | --- |
| **接口分散** | AI 每接入一个业务系统,就要在 Prompt/代码里硬编码一套接口与参数 |
| **权限失控** | 谁能访问什么系统、什么接口,散落在各系统里,没有统一入口可管 |
| **数据裸奔** | 让 AI 直连数据库 → SQL 注入、跨部门越权、无审计、结果撑爆上下文 |

MCP Gateway 的做法:**AI 只连一个 MCP 端点**,由网关统一完成身份识别、权限判定、请求转发或只读查询、结果裁剪与审计留痕。

---

## 🎯 项目目标

<div align="center">

```mermaid
flowchart TB
    subgraph PAIN["现状:AI 直连,能力散落"]
        direction LR
        A1["AI / Skill"] -->|"逐个适配"| B1["订单系统"]
        A1 -->|"明文凭证"| B2["用户系统"]
        A1 -->|"裸连数据库"| B3["分析库"]
        B1 & B2 & B3 -.-> X1["越权 · 注入 · 无审计 · 上下文溢出"]
    end

    subgraph GOAL["目标:统一网关,一次接入"]
        direction LR
        A2["AI / Skill"] -->|"一个 MCP 端点<br/>一把 API Key"| G["MCP Gateway"]
        G -->|"按权限转发"| C1["业务接口服务"]
        G -->|"只读 + 部门过滤"| C2["业务数据库"]
        G -.->|"全量留痕"| C3["审计日志"]
    end

    PAIN ==>|"收敛为单一入口"| GOAL
```

</div>

**一句话目标**:让 AI **天然知道自己能做什么**(权限内服务自动发现),并且**只能做被允许的事**(服务级 + 操作级双层管控),所有数据访问**可追溯、可隔离、不裸奔**。

---

## 🏗 整体架构

```mermaid
flowchart LR
    subgraph CONSUMER["消费方"]
        AI["AI / Skill / Agent"]
        ADMIN["管理后台<br/>React + Ant Design"]
    end

    subgraph GATEWAY["MCP Gateway"]
        direction TB
        AUTH["① 认证<br/>API Key → 用户身份<br/>(库中仅存 SHA-256 指纹)"]
        DISC["② 能力发现<br/>tools · resources · prompts<br/>只返回权限内清单"]
        PERM["③ 权限判定<br/>allow / deny + 操作级 scopes"]
        PROXY["④-a HTTP 代理<br/>call_service"]
        ENGINE["④-b 数据查询引擎<br/>参数化 · 部门过滤 · 脱敏 · 限流限行"]
        AUDIT["⑤ 审计与可观测<br/>行数/字节/耗时/状态 + 健康探针"]
    end

    subgraph BACKEND["业务后端"]
        SVC["业务接口服务<br/>REST API"]
        DB[("只读数据库<br/>SQLite / MySQL / PG")]
    end

    AI -->|"Bearer mcg_..."| AUTH
    AUTH --> DISC --> PERM
    PERM --> PROXY
    PERM --> ENGINE
    PROXY --> SVC
    ENGINE --> DB
    PROXY --> AUDIT
    ENGINE --> AUDIT
    ADMIN -->|"JWT"| GATEWAY
```

---

## ⚙️ 核心逻辑:一次调用发生了什么

```mermaid
flowchart TD
    START(["AI 发起 tools/call"]) --> A{"API Key 有效?<br/>用户为 active?"}
    A -->|否| E1["401 / 403 拒绝"]
    A -->|是| B{"对该服务有 allow 授权?<br/>scopes 包含该操作?"}
    B -->|否| E2["拒绝并回传「你可用哪些操作」"]
    B -->|是| C{"服务类型"}

    C -->|"api<br/>HTTP 接口"| D1["校验端点 method + path<br/>拒绝路径穿越"]
    D1 --> D2["转发上游<br/>超时控制 + 响应截断"]

    C -->|"database<br/>数据查询"| Q1["列白名单 + 标识符合法性校验"]
    Q1 --> Q2["强制注入部门过滤<br/>dept_id + 组织子树"]
    Q2 --> Q3["参数化执行<br/>只读连接 · 行数上限 · 超时"]
    Q3 --> Q4["敏感列脱敏 mask / hash"]
    Q4 --> R{"结果规模"}

    R -->|"≤1000 行 且 ≤1MB"| R1["直返 JSON<br/>total · returned · has_more"]
    R -->|"超阈值"| R2["落盘 data/query-results/<br/>返回 file_path"]
    R2 -.-> R3["read_query_result<br/>按审计归属校验后取回"]

    D2 --> AUD["写入审计<br/>用户 · 部门 · 服务 · 行数 · 耗时 · 状态"]
    R1 --> AUD
    R2 --> AUD
```

> 关键设计:**AI 永远不需要知道接口地址、SQL、部门 ID**。它只表达"我要什么",网关负责"能不能给、给多少、怎么给"。

---

## ✨ 核心能力

| 能力 | 说明 |
| --- | --- |
| **MCP 三件套** | Tools(服务发现/调用/查询)+ Resources(指南/清单/能力索引)+ Prompts(查数据/发布服务/排障) |
| **双层权限** | 服务级 `allow/deny`(deny 优先)+ 操作级 `scopes`(限定具体端点/查询工具) |
| **AI 友好发现** | `list_services` 天然只返回权限内服务;未授权操作会回传"你能用什么" |
| **HTTP 接口代理** | 维护 `base_url` + 端点,支持路径参数/query/body,路径穿越防护 |
| **只读数据查询** | 参数化 SQL · 列白名单 · 行数上限 · 超时 · 只读连接 · 组织树部门过滤 · 敏感列脱敏 |
| **结果智能分流** | 小结果直返 JSON,大结果落盘返回路径(防上下文溢出),可安全取回 |
| **审计与观测** | 每次查询留痕 + 导出;三级健康探针 `/health/live` `/health/ready` `/health` |
| **开箱即用** | `.env` 自动加载 · 配置启动校验 · 一键脚本 · Docker · `npm run doctor` · 150 项测试 |
| **可选数据中台** | ODS/DWD/DWS/ADS 四层 + 数据字典 + 质量规则;`npm run dp:demo` 一条命令落地,ADS 自动成为查询工具 |
| **数据源开箱即用** | MySQL / PostgreSQL / SQLite 驱动内置;填主机/端口/账号/库名即可接入,**无需手写连接串**;界面一键「测试连接」并给出分类错误提示 |
| **对外集成 API** | `/api/dp/*` 提供数据源与数据记录 CRUD,JWT 与 API Key 双认证,写操作需 `scopes` 显式授权 |

---

## 🚀 快速开始

```bash
# 1) 安装并构建(一键脚本会自动完成:检测 Node → 装依赖 → 构建 → 初始化 → 启动)
./start.sh          # Linux / macOS
.\start.ps1         # Windows PowerShell

# 2) 或手动执行
npm run setup       # 安装前后端依赖 + 构建
npm run db:demo     # 生成演示分析库(只读查询用)
npm run db:seed     # 初始化用户/服务/权限/API Key
npm run dp:demo     #(可选)落地数据中台:建库→采集→建视图→质量→注册查询工具
npm start           # 启动(内置 --experimental-sqlite)
```

启动后:

| 入口 | 地址 | 说明 |
| --- | --- | --- |
| 管理后台 | `http://localhost:3100/` | 默认 `admin / admin123`(生产务必修改) |
| MCP 端点 | `http://localhost:3100/mcp` | AI 用 `Authorization: Bearer mcg_...` 连接 |
| 健康诊断 | `http://localhost:3100/health` | 深度检查报告 |

### 接入 AI 客户端

```jsonc
{
  "mcpServers": {
    "mcp-gateway": {
      "url": "http://localhost:3100/mcp",
      "headers": { "Authorization": "Bearer mcg_你的APIKey" }
    }
  }
}
```

> 客户端需在 `Accept` 头同时允许 `application/json` 与 `text/event-stream`(MCP 协议要求,主流客户端自动处理)。

---

## 👥 两种角色,两条上手路径

| 角色 | 你要做的事 | 看这里 |
| --- | --- | --- |
| **业务人员**(想用 AI 查数据) | 装 AI 客户端 → 粘贴管理员给的连接配置 → 放入 `data-query` 技能 → 用日常语言提问 | [docs/SKILL-GUIDE.md](docs/SKILL-GUIDE.md) · 技能包 [skills/data-query](skills/data-query/SKILL.md) |
| **开发 / 运维**(要部署与授权) | 部署服务 → 配数据源与查询工具 → 建组织与用户 → 签发 API Key 并授权 → 把上述三样交付给业务 | [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) · [QUICKSTART.md](QUICKSTART.md) |

> 业务侧无需数据库账号;数据范围、脱敏、审计全部由网关强制执行。

---

## 🧪 测试与自检

```bash
npm test          # 150 项测试:权限模型 / 注入防护 / 部门过滤 / 分页 / 落盘 / 脱敏 / 限流
npm run doctor    # 环境自检:Node 版本 / 依赖 / 构建 / 数据库 / 端口,并给出修复建议
```

覆盖要点:只读语句白名单、SQL 注入不可绕过、跨部门数据不可见、API Key 指纹不可反向冒用、大结果落盘与归属校验、配置非法值阻断启动。

---

## 📚 文档索引

| 文档 | 内容 |
| --- | --- |
| [QUICKSTART.md](QUICKSTART.md) | 5 分钟上手:三种启动方式、拿 API Key、接 AI、常见问题 |
| [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) | **开发人员部署指南**:部署形态、数据中台对接、进程守护、Nginx/HTTPS、运维与安全检查清单 |
| [docs/SKILL-GUIDE.md](docs/SKILL-GUIDE.md) | **业务人员使用教程**:四步安装、能问什么、结果怎么读、合规注意、FAQ |
| [skills/data-query](skills/data-query/SKILL.md) | **可直接分发的技能包**:面向业务的数据查询技能(只读、部门隔离、脱敏) |
| [skills/README.md](skills/README.md) | 技能目录说明与自定义技能编写规范 |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | 架构设计、权限模型、数据查询安全链路、数据模型与目录结构 |
| [docs/API.md](docs/API.md) | 完整接口文档:MCP 协议、管理 API、知识库 API、健康探针、错误码 |
| [docs/CONFIG.md](docs/CONFIG.md) | 全部环境变量、默认值与调优建议 |
| [docs/DATA-PLATFORM.md](docs/DATA-PLATFORM.md) | **可选数据中台方案**:采集/存储/计算/服务/治理五能力轻量选型、模块协作、部署要求、对接方式、运维负担评估 |
| [docs/INTEGRATION-API.md](docs/INTEGRATION-API.md) | **对外集成 API 文档**:认证与权限、数据源 CRUD、连接测试错误码、数据记录增删改查、Python/Node 示例 |
| [docs/I18N.md](docs/I18N.md) | **中英双语编写规范**:文件配对、语言切换行、术语表、提交检查清单 |
| [README.en.md](README.en.md) | 本页英文版(其余文档均提供同名 `.en.md` 英文镜像) |
| [docs/COMPLETENESS.md](docs/COMPLETENESS.md) | 功能完整性审查与补齐记录(含缺陷修复清单) |
| [docs/AUDIT-REPORT.md](docs/AUDIT-REPORT.md) | 安全与正确性审计报告 |

> 以上文档均提供同名 `.en.md` 英文版,页面顶部可一键切换;双语规则见 [docs/I18N.md](docs/I18N.md)。
| [.env.example](.env.example) | 配置模板(复制为 `.env` 即生效) |
| [examples/order-skill](examples/order-skill/SKILL.md) | 示例 Skill:如何编写提示词调用本网关 |

---

## 🧱 技术栈

**后端**:TypeScript · Node.js ≥ 22.5(内置 `node:sqlite`,**零原生编译依赖**)· Express · `@modelcontextprotocol/sdk`
**前端**:React 18 · Ant Design 5 · Vite 6
**存储**:SQLite(网关元数据)· SQLite / MySQL / PostgreSQL(业务只读数据源)
**测试**:Node 内置 `node:test`(零额外依赖)

---

## 📄 许可

[MIT](LICENSE) © MCP Gateway Contributors