内容
# 学习镜像
**本地学习镜像。** 将您的 [慕尼黑大学 Learnweb](https://www.uni-muenster.de/LearnWeb/learnweb2/) (Moodle)课程镜像到本地文件夹 - 这样您和任何 AI 编程代理(Claude Code、Codex等)都可以读取课程资料为纯文本文件 **而无需代理触及您的大学凭证**。
```
█████████████████░░░░░░░ 143/199 · 294.3 MB/335.9 MB · 练习表 03.pdf
```
## 为什么
AI 代理在“总结本周的幻灯片”或“与我一起完成练习表 3”方面非常出色 - 但将大学密码交给 AI 工具链是一个糟糕的主意。lernspiegel 分裂了这个问题:
```
Learnweb(大学)
▲ macOS 钥匙串中的令牌
│
learnweb CLI ──写入──► ~/Learnweb/ ◄──读取── 您的 AI 代理
(纯文本文件) │
sync_now(子进程) ◄── MCP 服务器 ◄──┘
(无令牌)
```
- 您的密码仅在本地输入一次到 `learnweb login` 中 - 仅发送到大学服务器,绝不存储。
- 生成的 API 令牌(官方 Moodle 应用程序使用的相同机制)存储在 **macOS 钥匙串** 中,绝不存储在文件或环境变量中。
- 捆绑的 **MCP 服务器故意设计为无令牌** :它只列出和搜索本地镜像。代理获取课程数据;凭证通过设计保持在可及范围之外。
## 需求
- macOS(令牌通过系统钥匙串存储)
- Node.js ≥ 20
- Learnweb 账户 - 或任何启用了移动网络服务的 Moodle 实例(参见下文)
## 安装
通过 Homebrew:
```sh
brew tap theitger/tap
brew install lernspiegel
```
这提供了 `learnweb`(CLI)和 `learnweb-mcp`(无令牌 MCP 服务器),并自动拉取 `node`。
或手动从此仓库:
```sh
git clone https://github.com/theitger/lernspiegel
cd lernspiegel
npm install && npm run build && npm link # 提供 `learnweb` 和 `learnweb-mcp`
```
需求:
```text
macos
node >= 20
```
## 快速开始
```sh
learnweb login # 用户名 + 密码 → 钥匙串中的令牌
learnweb sync --dry-run # 查看将下载的内容(总大小)
learnweb sync # 将当前学期的课程镜像到 ~/Learnweb
```
重新运行 `sync` 是增量式的:仅下载新的或更改的文件。已中断的下载永远不会留下半成品文件(`.part` + 原子重命名)。
## 命令
| 命令 | 用途 |
| --- | --- |
| `learnweb login [--token <t>] [--mirror <dir>] [--url <moodle>]` | 获取 + 存储 API 令牌(或重用现有令牌) |
| `learnweb courses [--json]` | 列出已注册的课程,附带当前/旧/排除状态 |
| `learnweb sync [courses…] [--all] [--dry-run] [--max-size <mb>]` | 增量镜像 - 默认当前学期课程,`--all` 获取所有课程(大小上限 200 MB) |
| `learnweb exclude <courses…>` / `include <courses…>` | 永久跳过课程 / 始终同步它们 |
| `learnweb status [--json]` | 镜像状态(最后同步,文件数量) |
| `learnweb logout` | 从钥匙串中删除令牌 |
课程可以通过 ID、shortname 或任何唯一的名称片段来指定:`learnweb sync statistik`。模糊片段会报错并显示候选项,而不是猜测。
## 如何检测“当前学期”
Learnweb 很少维护课程结束日期,因此 lernspiegel 使用两个可靠的信号:
1. **类别路径** - Learnweb 将课程文件归档到“Archiv …”类别;任何归档的都是旧的。
2. **开始日期** - 学期课程在学期开始前不久创建(SoSe:4月,WiSe:10月)。常设课程(协调、学生委员会等)带有旧的开始日期,默认跳过。
`learnweb courses` 显示每个课程的判决结果;`include`/`exclude` 永久覆盖它。
## AI 代理集成
**Claude Code:**
```sh
claude mcp add --scope user learnweb -- node /path/to/lernspiegel/dist/mcp.js
```
**Codex** (`~/.codex/config.toml`):
```toml
[mcp_servers.learnweb]
command = "node"
args = ["/path/to/lernspiegel/dist/mcp.js"]
```
MCP 工具:`list_courses`,`list_materials`,`search_materials`,`sync_status`,`sync_now`。所有工具返回绝对本地路径 - 代理使用其普通文件工具读取文件。`sync_now` 通过运行 CLI 作为子进程刷新镜像(CLI 持有凭证;MCP 服务器从不持有)。
可以运行 shell 命令的代理甚至不需要 MCP - 镜像只是文件。
## 其他 Moodle 实例
默认目标是慕尼黑大学,但整个堆栈都是标准 Moodle 网络服务:
```sh
learnweb login --url https://moodle.example.edu
```
如果实例启用了移动网络服务(即官方 Moodle 应用程序与其配合使用),则此功能有效。“Archiv”学期检测是 Learnweb 特有的;在其他实例上使用显式课程选择或 `--all`。
## 限制和路线图
- 镜像文件、文件夹和课程页面的外部链接。作业、论坛、公告和截止日期正在计划中 - API 客户端已经支持扩展。
- 上游删除的文件在本地保留(无修剪 - 旧幻灯片不会从您手中消失)。
- 目前仅限 macOS(钥匙串);跨平台秘密存储将提升。
## 合规使用
本工具使用与官方 Moodle 应用程序相同的 API,用于您自己的课程。请做个好公民:下载受到限制(3个并发),并且没有理由比每天几次同步更多。 与慕尼黑大学无关。
## 许可证
[MIT](LICENSE)