内容
# 💬 GitBook 聊天
> 查询 GitBook 文档并保存回答为 `.md` 的聊天界面。
> 无状态,固定 RAG 源,集成 MCP SSE 服务器。
<!-- 1.编程语言 | 2.包管理器 | 3.框架 | 4.库 | 5.测试 | 6.环境 | 7.管道 | 8.部署 -->
       
---
## 🎯 关于项目
无状态应用程序,查询固定 GitBook 文档(`GITBOOK_URL`)并保存回答为 `asks/` 目录下的 `.md` 文件。
每次提问都是独立的 - 没有前一次交互的记忆。RAG 源是固定的:每次查询都对同一 URL 执行 `?ask=` 操作。`welcome.md` 是原始 README 的本地副本,作为起点。它永远不会被重新获取。
通过 SSE 集成 MCP(模型上下文协议)服务器,允许诸如 opencode 之类的工具查询 GitBook,列出以前的搜索并浏览历史记录 - 所有这些都在同一个进程中,端口 8000。
> [!WARNING]
> 应用运行在 BUG/FAILURE 之上
> 作为 RAG 源的 GitBook AI API 是公开的,没有身份验证
> 它每 5 分钟仅有 20 个请求限制。
> 服务器不会累积队列 - 超出限制的请求会失败。
---
## 📦 先决条件
- Node.js 20+ — 使用 `node --version` 验证
- Docker 24+ — 使用 `docker --version` 验证
---
## 🚀 安装
### 安装依赖
```bash
cp .env.example .env
# 编辑 .env 中的 GITBOOK_URL
docker compose run --rm gitbook-chat npm install
```
### 运行应用程序
```bash
docker compose up -d --build
```
访问:`http://localhost:8000`
---
## 🔐 环境变量
| 变量 | 描述 |
|---------------|---------------------------------------|
| `GITBOOK_URL` | GitBook 文档 URL(固定 RAG 源) |
---
## 📁 项目结构
```
├── server.js # REST API + WebSocket + MCP SSE
├── package.json
├── docker-compose.yml
├── .env.example
├── public/
│ ├── index.html # Alpine.js + Tailwind UI
│ └── app.js # 聊天逻辑
├── tests/
│ └── api.test.js # API 测试
├── asks/ # 持久化回答
├── scripts/
│ └── seed-questions.js
└── welcome.md # 初始内容(本地副本)
```
---
## 🧪 测试
```bash
docker exec gitbook-chat npm test
```
---
## 🌐 API 端点
| 方法 | 路由 | 描述 |
|--------|------------------------------|----------------------------------------|
| GET | `/api/history` | 列出问题(分页) |
| GET | `/api/history/:file` | 已保存的回答内容 |
| GET | `/download/readme.md` | 下载 welcome.md |
| WS | `/` | WebSocket 聊天 |
| GET | `/sse` | SSE 端点(MCP — 启动会话) |
| POST | `/mcp?sessionId={id}` | MCP 的 JSON-RPC 消息 |
### MCP 工具
| 工具 | 描述 |
|------|-----------|
| `query_gitbook(question)` | 向 GitBook 文档(固定 RAG 源)提问 |
| `list_asks(page?, limit?, order?)` | 列出已保存的问题,分页 |
| `get_ask(filename)` | 获取完整回答内容 |
| `search_asks(term)` | 在已保存的回答中搜索术语 |
| `get_welcome()` | 返回 welcome.md |
---
## 🏗️ 架构
```mermaid
graph TB
Client[客户端<br/>Alpine.js] --> WS[WebSocket]
Client --> SSE[SSE MCP]
WS --> Server[服务器<br/>Express + ws]
SSE --> Server
Server --> GitBook[GitBook RAG<br/>GITBOOK_URL]
Server --> FS[(文件<br/>asks/)]
```