内容
# 📚 study-mcp
> 一个将视频转录文本和学习材料转化为可搜索、由 AI 驱动的知识库的MCP(模型上下文协议)服务器,直接在Claude Desktop中。
[](https://github.com/italoo97/study-mcp/actions/workflows/ci.yml)
[](https://www.python.org)
[](#-development)
[](LICENSE)
---
## ✨ 功能介绍
粘贴视频转录文本或指向PDF、幻灯片、DOCX或图像文件,即可立即:
- 🎬 **导入视频转录文本** — 粘贴原始文本或加载`.srt`/`.vtt`字幕文件;时间戳被保留,以便您可以跳转到视频中的确切时刻
- 🔍 **语义搜索** — 用自然语言提问,涵盖所有材料,由本地嵌入(无API成本)提供支持
- 🎯 **生成测验** — 从任何材料中抽取代表性上下文,以便Claude可以为您测试
- 🧠 **总结和创建闪存卡** — 直接保存到Notion
- 📊 **跟踪您的图书馆** — 列出材料,检查概述,查看统计数据,删除您不再需要的材料
所有操作默认在本地运行(ChromaDB + HuggingFace嵌入)。设置一个环境变量即可切换到Supabase/Postgres上的pgvector。
---
## 🧰 技术栈
| 层 | 技术 |
|---|---|
| 语言 | Python 3.13 |
| MCP服务器 | [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) (FastMCP) |
| 嵌入 | [sentence-transformers](https://sbert.net) + HuggingFace模型(本地推理,PyTorch) |
| 向量存储 | [ChromaDB](https://www.trychroma.com)(本地)· [pgvector](https://github.com/pgvector/pgvector) 在Supabase/Postgres(云)上 |
| 文档解析 | [Docling](https://github.com/docling-project/docling)(PDF、DOCX、PPTX、HTML、图像)+ 原生SRT/VTT解析器 |
| 集成 | [Notion API](https://developers.notion.com) (`notion-client`) |
| 配置 | pydantic-settings(类型化,基于环境变量) |
| 工具 | Poetry · pytest (+coverage) · ruff · mypy `--strict` · pre-commit · commitizen |
| CI | GitHub Actions(每次推送/拉取请求时进行 lint、类型检查、测试) |
---
## 🏗️ 架构
```
study-mcp/
├── src/study_mcp/
│ ├── core/
│ │ ├── config.py # 通过环境变量设置(pydantic-settings)
│ │ ├── embeddings.py # sentence-transformers,本地推理,E5前缀
│ │ ├── chunker.py # 章节 → 段落 → 句子感知的分块
│ │ └── transcript.py # SRT/VTT解析器,保留时间戳
│ ├── db/
│ │ ├── __init__.py # VectorRepository协议 + 后端自动检测
│ │ ├── chroma.py # 本地向量存储(ChromaDB,零设置)
│ │ └── pgvector.py # 云向量存储(Supabase/Postgres,HNSW索引)
│ ├── tools/
│ │ ├── ingest.py # 文件和原始文本导入(Docling + 原生解析器)
│ │ ├── search.py # 语义搜索
│ │ ├── materials.py # 概述,测验上下文,统计,删除
│ │ ├── list_materials.py
│ │ └── notion.py # Notion集成(摘要和闪存卡)
│ └── server.py # FastMCP服务器:工具,资源,提示,生命周期
├── tests/ # 60个测试,约96%覆盖率,无需下载模型
└── docs/
└── claude_desktop_config.json
```
**设计亮点:**
- **仓库模式** — 两个向量后端都实现了相同的`VectorRepository`协议;后端在启动时根据`DATABASE_URL`选择,无需更改代码。
- **E5查询/段落前缀** — `intfloat/multilingual-e5-*`模型经过`query:` / `passage:`前缀训练;应用它们可以显著提高检索质量。在配置E5模型时自动应用。
- **句子感知分块** — 文本按章节、段落分组,然后按整个句子分组,句子间有重叠。块不会切分单词或句子。
- **幂等导入** — `material_id`是SHA-256内容哈希,因此重新导入相同材料是无操作的(`already_indexed`)而不是重复的。
- **时间戳感知转录** — SRT/VTT提示按语音暂停分组为段落;转录搜索结果带有`start_time`,以便您可以跳转回视频。
---
## 🛠️ 可用工具
| 工具 | 描述 |
|---|---|
| `ingest_text_tool` | 将原始文本导入向量存储 |
| `ingest_file_tool` | 转换和索引文件:PDF、DOCX、PPTX、HTML、图像、`.txt`、`.md`、`.srt`、`.vtt` |
| `search_tool` | 跨所有索引材料的语义搜索(可选范围到一个) |
| `list_materials_tool` | 列出所有索引材料 |
| `get_material_overview_tool` | 在总结或测验之前预览材料的第一个块 |
| `generate_quiz_context_tool` | 抽取材料的代表性上下文,以便Claude可以编写测验问题 |
| `study_stats_tool` | 总计:材料、块、每个材料的块 |
| `delete_material_tool` | 删除材料及其所有块 |
| `save_summary_tool` | 将摘要保存到Notion |
| `save_flashcards_tool` | 将问答闪存卡保存到Notion |
| `create_quiz_tool` | 在Notion中创建一个交互式测验页面(开放或多选题,在Notion中回答,然后粘贴回来检查) |
这三个Notion工具还接受`related_pages`(来自同一对话中早期保存的`notion_url`值的列表),以通过Notion的原生提及链接到相关材料 — 请参阅 [`docs/NOTION_SETUP.md`](docs/NOTION_SETUP.md).
服务器还公开了一个MCP **资源** (`study://materials`,当前库的JSON)和一个**提示** (`study_prompt`,适用于任何材料的即用型学习计划工作流)。
---
## 🚀 快速入门
### 1. 克隆并安装
```bash
git clone https://github.com/italoo97/study-mcp.git
cd study-mcp
poetry install
```
### 2. 配置环境
```bash
cp .env.example .env
```
所有变量都有合理的默认值 — 服务器使用ChromaDB和外部服务开箱即用。参见 [`.env.example`](.env.example) 获取每个选项。
### 3. 配置Claude Desktop
编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`(参见 [`docs/claude_desktop_config.json`](docs/claude_desktop_config.json) 获取完整示例):
```json
{
"mcpServers": {
"study-mcp": {
"command": "poetry",
"args": [
"--directory", "/绝对路径/to/study-mcp",
"run", "python", "-m", "study_mcp.server"
],
"env": {
"CHROMA_PATH": "/绝对路径/to/study-mcp/chroma_db"
}
}
}
}
```
> ⚠️ Claude Desktop从其自己的工作目录启动服务器,因此相对路径(例如`.env`文件或默认的`./chroma_db`)无法解析到项目文件夹。请将`CHROMA_PATH`设置为绝对路径,如上所示,并在`env`块中传递其他变量(`NOTION_TOKEN`、`DATABASE_URL`等) — 参见 [`docs/claude_desktop_config.json`](docs/claude_desktop_config.json) 获取完整示例。
> **向量后端自动检测:**
> - `DATABASE_URL`为空 → 本地ChromaDB(零设置)
> - `DATABASE_URL`已设置 → Supabase/Postgres上的pgvector(免费层有效;表和HNSW索引自动创建)
### 4. 重启Claude Desktop
工具将自动出现。
---
## 🎬 导入视频转录文本
为此服务器构建的主要工作流:
1. 打开视频(YouTube,录制的讲座,课程平台)并复制其转录文本 — 或下载字幕为`.srt`/`.vtt`。
2. 将其粘贴到Claude中: *"将此转录文本作为'线性代数 — 讲座3'导入:..."* → Claude调用 `ingest_text_tool`。
3. 询问任何问题: *"根据我的讲座,什么是特征向量?"* → `search_tool`返回最相关的段落,每个段落都有一个`start_time`,以便您可以跳转回视频中的那一刻。
4. 主动学习: *"用这个讲座测试我"* → `generate_quiz_context_tool`抽取材料的代表性上下文,Claude编写问题。
`.srt`/`.vtt`文件被原生解析:删除提示符和标记,将连续的提示符合并为自然语音暂停的段落,并将段落起始时间保留为元数据。
---
## 🧠 嵌入模型
设置 `EMBEDDING_MODEL` 为任何与 [sentence-transformers](https://sbert.net) 兼容的模型:
| 模型 | 语言 | 维度 |
|---|---|---|
| `intfloat/multilingual-e5-small` *(默认)* | PT + EN + 90种语言 | 384 |
| `intfloat/multilingual-e5-base` | PT + EN + 90种语言 | 768 |
| `BAAI/bge-small-en-v1.5` | 仅限英语 | 384 |
> 更新 `EMBEDDING_DIM` 以匹配 — 服务器在启动时验证维度,并在不匹配时快速失败。
---
## 📋 Notion 设置(可选)
仅 `save_summary_tool` 和 `save_flashcards_tool` 需要。完整
演练(包括为您创建数据库的脚本)
在 [`docs/NOTION_SETUP.md`](docs/NOTION_SETUP.md).
快速版本:
1. 在 [notion.so/my-integrations](https://www.notion.so/my-integrations) 创建集成
2. 创建数据库 — 运行
`poetry run python scripts/create_notion_database.py <parent_page_id>`
(使用正确的模式创建并自动共享),或
使用以下属性手动创建:`Name`(标题),`Type`
(选择),`Material`(富文本),`Tags`(多选)— 然后
手动将其与您的集成共享。
3. 在Claude Desktop配置的`env`块中设置 `NOTION_TOKEN` 和 `NOTION_DATABASE_ID` (**不是** `.env` — 参见
[`docs/claude_desktop_config.json`](docs/claude_desktop_config.json)).
---
## 💡 Claude中的示例用法
```
"将此转录文本作为'ML课程 — 梯度下降'导入:[粘贴的转录文本]"
"导入此文件:/Users/me/Downloads/algorithms_lecture.pdf"
"搜索我的材料:什么是动态规划?"
"给我一个材料a1b2c3d4的概述"
"用10个问题测试我关于梯度下降讲座的内容"
"总结它并保存到Notion,标签:ML,优化"
"显示我的学习统计数据"
```
---
## 🔧 开发
```bash
poetry install
poetry run task lint # ruff check
poetry run task format # ruff format
poetry run task type_check # mypy --strict
poetry run task test # pytest(60个测试,覆盖率门槛为80%)
```
测试套件在不下载任何嵌入模型的情况下运行 — 嵌入由确定性向量伪造,存储库层在内存双重存储库和临时目录中的真实ChromaDB实例中测试。
CI(GitHub Actions)在每次推送和拉取请求时运行lint、严格的类型检查和完整的测试套件。
---
## 📄 许可证
[MIT](LICENSE)