Skip to main content
Glama
Vanity-1

edu-db-readonly-mcp

by Vanity-1
README.md
# Edu DB Readonly MCP — 教育教务只读数据库网关

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)]() [![MCP](https://img.shields.io/badge/Protocol-MCP-green.svg)]() [![FastMCP](https://img.shields.io/badge/FastMCP-3.x-orange.svg)]()

一个面向**教育教务业务数据库**的安全**只读查询网关 MCP**。用官方
FastMCP SDK 把"教务库(学生 / 课程 / 成绩 / 选课)"暴露成一组 MCP 工具,
让 LLM Agent 能安全查询业务数据,但**从协议层到数据库层都禁止一切写操作**。

> 与 ChatGPT 套壳、通用 MCP Server、纯 RAG demo 不同,本项目专注
> **"把业务库安全地开放给 Agent 读"**这条工程链路,是数据安全 + MCP 落地的硬核案例。

---

## 核心卖点(面试可讲)

| 安全维度 | 实现方式 |
|---|---|
| **写防护** | SQL 词法静态校验:仅允许 `SELECT/WITH`,拦截 `INSERT/UPDATE/DELETE/DROP/PRAGMA`;禁止分号多语句注入 |
| **只读兜底** | SQLite 以 `mode=ro` 打开,即使 SQL 漏判,数据库层面也无法落盘 |
| **防爆库** | 未写 `LIMIT` 自动强制追加上限(默认 100 行),防止 Agent 全表拖库 |
| **防注入** | 网关层全部走参数绑定,业务工具用固定查询白名单函数,天然免疫拼接注入 |
| **超时保护** | 慢查询超过阈值(默认 3s)自动终止,避免聪明 Agent 卡死 |
| **鉴权** | 可选 `READONLY_GATEWAY_TOKEN`,token 不匹配直接拒绝 |
| **审计** | 每次查询落盘 `audit.log`(时间/工具/SQL/行数/耗时),调用可追溯 |

---

## 工具清单(MCP)

| 工具 | 说明 |
|---|---|
| `list_tables` | 列出全部业务表及行数 |
| `describe_table` | 返回指定表字段 / 类型 / 主键 |
| `query` | 原始只读 SQL 网关(安全校验 + LIMIT + 超时) |
| `get_student_profile` | 学生画像(基本信息 + 平均分 + 选课成绩明细) |
| `get_course_stats` | 课程人数 / 均分 / 最高最低 / 及格率 |
| `get_enrollment_summary` | 选课成绩汇总报表,可按年份 / 学季过滤 |

`query` 展示"原始 SQL 网关"能力,其余是面向教务的**行业化安全封装函数**
(固定参数化查询,比裸 SQL 更安全、更贴合业务)。

---

## 快速开始

```bash
# 1. 安装依赖
pip install -r requirements.txt

# 2. 初始化教务演示库
python scripts/init_db.py

# 3. 运行命令行演示(连 stdio MCP,展示 6 个工具 + 写操作被拦截)
python scripts/demo_client.py

# 4. 启动为 MCP Server(供 Claude / Cursor / 任意 MCP 客户端接入)
python -m src.server
# 开启鉴权:
#   READONLY_GATEWAY_TOKEN=your_secret python -m src.server
```

示例查询:学生画像、CS205 课程统计、按学季汇总……

---

## 测试

```bash
pytest tests/            # 22 个用例:写防护/注入/多语句/截断/工具行为/审计
```

---

## 目录结构

```
edu-db-readonly-mcp/
├── README.md
├── pyproject.toml
├── requirements.txt
├── data/edu.db                 # 生成的教务演示库(只读打开)
├── scripts/
│   ├── init_db.py              # 建表 + 造种子数据(10学生/10课/32选课)
│   └── demo_client.py          # 命令行 MCP 演示
├── src/
│   ├── server.py               # FastMCP 入口,注册 6 个工具
│   ├── gateway/
│   │   ├── readonly_gateway.py # 核心:SQL 只读校验 + LIMIT + 超时
│   │   ├── auth.py             # token 鉴权
│   │   └── audit.py            # 审计日志
│   ├── db/connection.py        # mode=ro 连接 + 元数据读取
│   └── tools/
│       ├── query_tool.py       # 原始 SQL 网关
│       ├── schema_tools.py     # list_tables / describe_table
│       └── edu_workflows.py    # 教务业务封装工具
└── tests/
    ├── test_gateway_security.py   # 安全用例
    └── test_tools.py              # 工具行为用例
```

设计文档 → [`docs/DESIGN.md`](docs/DESIGN.md)

---

## 简历描述(可粘贴)

> **教育教务只读数据库网关 MCP(FastMCP)**
> 独立开发一个面向教育教务库的安全只读 MCP Server。设计轻量
> SQL 只读网关:仅放行 `SELECT/WITH` 的静态校验拦截 DML/DDL 与分号
> 多语句注入、未带 `LIMIT` 自动强制限行、参数化查询防注入、线程超时
> 保护、SQLite `mode=ro` 只读兜底;提供表自省与教务业务封装工具并
> 支持 Token 鉴权与 `audit.log` 审计。22 个单元测试覆盖写防护、注入、
> 多语句、截断等安全场景,端到端 demo 验证写操作被协议层拦截。