Skip to main content
Glama
README.md
# WHU MCP Server

武汉大学校园服务 MCP 服务器。一个文件 (`server.py`) 搞定全部——图书馆座位、课表、成绩、考试、天气,14 个工具,零外部存储依赖。

## 快速开始

### 本地 stdio(推荐个人使用)

```bash
git clone https://github.com/daoxiang0520/LuojiaAgent.git
cd LuojiaAgent/mcp_http
pip install -r requirements.txt
playwright install chromium
```

`~/.mcp.json`:

```json
{
  "mcpServers": {
    "whu-lib": {
      "command": "python",
      "args": ["-X", "utf8", "/绝对路径/mcp_http/server.py", "--transport", "stdio"]
    }
  }
}
```

### 远程 SSE(零安装,直接连)

已部署服务器,在 `~/.mcp.json` 中加入以下配置即可使用:

```json
{
  "mcpServers": {
    "whu-lib": {
      "type": "sse",
      "url": "https://whu-mcp.daoxiang.xyz/sse"
    }
  }
}
```

> 当前服务器状态:可通过 `curl https://whu-mcp.daoxiang.xyz/health` 检查。

### 远程 SSE(自部署)

服务器上启动:

```bash
cd /www/wwwroot/luojiaagent/mcp_http
pip install -r requirements.txt
playwright install chromium && playwright install-deps chromium
python server.py --transport sse --host 127.0.0.1 --port 8000
```

`~/.mcp.json`:

```json
{
  "mcpServers": {
    "whu-lib": {
      "type": "sse",
      "url": "https://你的域名/sse"
    }
  }
}
```

### 安装 Skill(可选)

```bash
mkdir -p ~/.claude/skills/whu-lib
cp skill/SKILL.md ~/.claude/skills/whu-lib/SKILL.md
```

重启 Claude Code 后生效。

## 三种登录方式

| 方式 | 工具 | 说明 |
|---|---|---|
| 扫码登录 | `login_qr` → `login_qr_poll` | ASCII 二维码显示在对话中,手机扫码 |
| 密码登录 | `login_password` | 对话中直接输入学号密码 |
| 会话复用 | — | session_id 有效期内无需重新登录 |

## 使用

```
第一次:
  你: "帮我登录武大"
  Claude: [显示 ASCII QR 码]
  [手机扫码]
  你: "扫好了"
  Claude: "✅ session_id: abc123"

之后(4 小时内无需重新登录):
  你: "工学分馆明天有座位吗"
  你: "我这学期 GPA 多少"
  你: "帮我预约 305 区 120 号,下午 2 点到 6 点"
  你: "明天带伞吗"
```

## 工具列表(14 个)

| 工具 | 登录 | 说明 |
|---|---|---|
| `login_password` | — | 学号+密码登录 |
| `login_qr` | — | ASCII 终端二维码,手机扫码 |
| `login_qr_poll` | — | 轮询扫码结果完成登录 |
| `get_seats` | ✅ | 分馆座位大盘 |
| `get_seat_map` | ✅ | 区域座位排布 |
| `reserve_seat` | ✅ | 预约座位(自动破解验证码) |
| `get_current_usage` | ✅ | 当前在坐座位 |
| `get_reservations` | ✅ | 预约记录 |
| `cancel_reservation` | ✅ | 取消预约 |
| `stop_usage` | ✅ | 签退释放 |
| `query_schedule` | ✅ | 课表 |
| `query_exam_schedule` | ✅ | 考试安排 |
| `query_grades` | ✅ | 成绩 + GPA |
| `get_weather` | ❌ | 珞珈山天气(免登) |

## 架构

```
用户
  │
Claude Code
  ├── Skill (whu-lib) ── 武大领域知识,按需注入
  └── MCP Client ─────── SSE/stdio 协议
  │
  ▼
MCP Server (server.py) ── 14 个工具,单文件
  │
  ├── lib/library_api.py   ──▶ 图书馆 (HMAC 签名 + API)
  ├── lib/courses_tool.py  ──▶ 教务 (课表)
  ├── lib/exam_tool.py     ──▶ 教务 (考试)
  ├── lib/grades_tool.py   ──▶ 教务 (成绩)
  ├── lib/weather_tool.py  ──▶ Open-Meteo (天气)
  ├── lib/cas_login.py     ──▶ CAS (认证)
  ├── lib/login_helper.py  ──▶ Playwright (凭证收割)
  ├── lib/captcha_solver.py──▶ 验证码破解
  └── lib/cas_encrypt.py   ──▶ AES 密码加密
```

### 存储

| 模式 | 存储方式 | 重启后 |
|---|---|---|
| SSE (远程) | 内存字典 `MemStore` | 丢失 |
| stdio (本地) | 文件 `.whu_session.json` | 保留 |

零外部依赖——不需要 Redis、数据库。

### 两级 Session

```
MCP Session                     Whu Session
(协议层,自动管理)                (业务层,login 后创建)
SSE 连接时分配                   12 位短 ID
仅用于消息路由                    存 CASTGC + token + educational
MCP Server 内存                  MemStore / FileStore
```

### 扫码登录流程

```
login_qr:
  CAS QR 图片 → OpenCV 解码 → qrcode 生成 ASCII → 终端显示
  用户 APP 扫码

login_qr_poll:
  轮询 CAS → CASTGC → Playwright harvest → token + educational
  → 存入 MemStore/FileStore → 返回 session_id
```

## 项目结构

```
mcp_http/
├── server.py              # 入口 (--transport stdio|sse)
├── requirements.txt
├── README.md
├── skill/
│   └── SKILL.md           # Claude Code Skill
└── lib/                   # 自包含依赖模块
    ├── library_api.py
    ├── cas_login.py
    ├── cas_encrypt.py
    ├── login_helper.py
    ├── captcha_solver.py
    ├── captcha_refs.npz   # 验证码参考库 (865KB)
    ├── courses_tool.py
    ├── exam_tool.py
    ├── grades_tool.py
    └── weather_tool.py
```

## 部署

### 服务器

```bash
cd /www/wwwroot/luojiaagent/mcp_http
pip install -r requirements.txt
playwright install chromium && playwright install-deps chromium
python server.py --transport sse --host 127.0.0.1 --port 8000
```

### 宝塔保活

Supervisor → 添加守护进程:

| 字段 | 值 |
|---|---|
| 名称 | whu-mcp |
| 目录 | /www/wwwroot/luojiaagent/mcp_http |
| 命令 | `python server.py --transport sse --host 127.0.0.1 --port 8000` |

### Nginx 反代

```nginx
location /sse {
    proxy_pass http://127.0.0.1:8000/sse;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_buffering off;
    proxy_read_timeout 3600s;
}
location /messages { proxy_pass http://127.0.0.1:8000/messages; }
location /health   { proxy_pass http://127.0.0.1:8000/health; }
```

## FAQ

**Q: 密码安全吗?**  
A: HTTPS 传输。不存盘、不进日志、不落存储。对话中短暂出现后即被覆盖。

**Q: 二维码不显示?**  
A: 按 Ctrl+O 展开工具输出。ASCII QR 码在折叠区里。

**Q: stdio 和 SSE 怎么选?**  
A: 自己用 → stdio(零运维)。给同学用 → SSE(部署一次,大家共享)。

**Q: 为什么去掉 Redis?**  
A: 不需要。MCP Server 单进程,内存字典就够了。登录也在 MCP 里完成,没有跨进程通信需求。