内容
# anki-mcp
与你的Anki卡片对话。在复习时,直接在卡片上写下编辑指令——*“提示似乎无用”*、*“在背面显示一个自然的对话示例”*——LLM(大语言模型)会在稍后批量应用它:首先备份牌组,然后显示每个建议的更改为旧 → 新的差异,如果没有你的批准,集合中不会有任何更改。每次应用的编辑都会在卡片本身上记录。
底层:一个独立的MCP服务器,通过原生Claude工具公开完整的Anki——Claude直接调用工具,而不是构造JSON字符串和调用bash——以及Claude Code技能,协调反馈循环。
[Diotima](https://diotima.garden)的一部分,一个用于AI辅助学习的开放生态系统。
---
## 反馈循环在行动
一句指令——`process user feedback on spanish`——足以触发整个循环。无需指定grove路径、牌组名称或管道调用:
```
> process user feedback on spanish
```
这句指令通过`/pipe:tackle-feedback-on-grove`解析:读取grove的`context.md`以找到其牌组规格,编译它,同步Anki,模糊匹配牌组名称(`Español`),备份它,然后提取每个带有待处理`user_feedback`的卡片:

此次运行找到了两张卡片。`confirm.py` 在任何更改应用到集合之前,会在每张卡片旁边打印其指令以及更改前后的差异:一个名为“无用”的提示字段被替换为一个更相关的提示,而一个翻译获得了自然的、上下文相关的示例句子:
```
1. " a raise, fewer hours, AND more vacation..." (笔记 1778617822309)
反馈: "hint seems useless" → 提示:"sea" → "chancha"
2. "You'll feel with me" (1782161468245)
反馈: "show a natural conversation example on" → 背面增加了一个示例:…
```
确认关口并不需要一个字面上的“yes”——普通的对话确认也同样有效:

两次编辑都被应用,管道重新同步,运行报告了更改的确切位置和备份的位置:

结果,在 Anki 中实时渲染——“You'll feel like laughing with me”卡片,现在带有请求的示例,标记已清除:
![在 Anki 浏览器中预览编辑后的卡片,背面字段的示例句子/feedback-04-rendered.png)
`/pipe:tackle-feedback-on-grove`包装器(grove文、牌组解析、备份)位于父ima 项目中。在 anki-mcp 时,您 `anki-mcp:process-user-feedback-on-deck`技能(参见下面的技能)。
---
## 反的工作原理——托管笔记在项目配置中笔记类型(启动时使用 `--managed-config <path参见设置)会自动携带两个额外的字段,由 `managed/bootstrap.py` 在首次工具使用时注入(延迟、幂等、安全每次启动):
- `user_feedback 用户直接在 Anki 的卡片上写的编辑指令。仅用户创作只会清除它不会设置它。
log` —— 更改的 JSON 历史记录。
配置形状(monorepo 中的 `groves/managed-models.json`):
```json
{
"managed_note_types": [
{" "Production", "fields": ["Front", "Back", "Hint", "Interesting Facts"], "is_cloze": false}
]
}
```
**循环:** 用户在 `user_feedback` 中写入指令 → `extract.py`它,将卡片标记为红色,写入静态文件的绪记录 → LLM转换为字段编辑 → `` 差异写入到 `log` `user_feedback`,从红色变为绿色 `process-user-feedback-on-deck` 技能协调下面的技能)。
工具 | 功能 |
|---|---|
| `update(note_id, new_fields)`覆盖托管笔记的:与当前值进行差异写入和记录更改,清除 `user_feedback`,并将 RED 标志翻转为 GREEN。对于非托管笔记,行为保持不变。 |
---
## 设置
**先决条件:**
- 带有 [AnkiConnect](https://git.sr.ht/~foosoft/anki-connect) 插件的 [Anhttps://apps..net/)
- [ Code](https://cl/claude-code)另一个 MCP 客户端 Python 3
**创建并安装 MCP SDK(一次性```bash
python3 -m venv anki-mcp 目录>/.venv
<ki-mcp 目录>/.venv/bin/pip install mcp
```
虚拟 gitignore 忽略隆后或在新机器上运行。
**在项目的 `.mcp.json` 中**,调整路径仓库的检出位置(此处为 `anki-mcp`):json
{
cpServers": {
anki": {
"type": "stdio",
": "plugins/cp/.venv/bin",
"args":/anki-mcp", "--managed-configgroves/managed"]
}
}
--managed-config` 是可选的 - 它托管笔记类型/(上面的配置格式)。它,您将获得表面。
**在 `.mcp.json` 或服务器的任何更改后重启 Claude - 它在启动实例化。
---
工具
公开了 AnkiConnect 接口 -,笔记/卡,标签,标志,牌组,调度,媒体,统计数据 -工具,而不是 bash 字符串。这一部分是基本要求;每个类别一个文件,下面列出时细节(签名是化的,请参见源增值部分是建立在其上的内容:**分析**(折叠多步骤往返)和笔记类型**(上述反馈管道)。
### 基础表面(1:1 AnkiConnect)
| 类别 | 文件 | 工具 |
|---|---|---|
| 搜索 | `cards.py` | `find_cards`, `find_flagged_cards`, `find_notes` |
| 卡片和笔记元数据 |.py`, `` | `cards_info`,_info`,_to_notes` |
| 笔记变更 | `notes.py` | `add_notes`, `can_add_notesupdate_note`,_note_model`, ``, `remove_empty |
| 标签 |.py` |_tags`, `add_tags`, `remove_tags`, `update_note_tags`, `clear_unused_tags`, `replace_tags_in_all_notes` |
| 标志 | `cards.py` | `set_card_flag` |
| 牌组 | `decks.py` | `deck_names`, `deck_stats`, `get_decks`, `create_deck`, `get_deck_config`, `save_deck_config`, `change_deck`, `delete_decks`, `export_deck`, `import_package`, `sync` |
| 调度 | `scheduling.py` | `are_suspended`, `are_due`, `get_intervals`, `suspend_cards`, `unsuspend_cards`, `forget_cards`, `relearn_cards`, `answer_cards` |
| 模型 | `` | `model_names`, `model_field_names`, ``, `model_st `rename_model_field`, `add_model_field`, `remove_model_field`, `change_note_type`, `update_model_templates`, `update_model_styling`, `create_model` |
| 媒体 | `media.py` | `store_media_file`, `retrieve_media_file`, `get_media_files_names`, `get_media_dir_path`, `delete_media_file` |
| 统计数据 | `stats.py` | `get_collection_statscard_reviews`, `get_reviews_of_cards`, `get_latest_review_id` |
同时提供一种资源:`template-reference`(模板语法和CSS 在调用 `update_model `update_model 之前阅读)。ListMcpResources / `ReadMcpResourceTool` 访问。
###合与分析 - 折叠多步骤往返
| 工具 | 功能 |
|| `get_all_notes(deck, include_scheduling?)` | 牌组中的所有笔记展平。批量AI。 |
| `ged_notes(deck, flag)` | 标记的笔记合并并准备编辑 - card 展平字段调用。 |
|_snapshot(deck 成熟度分析 + 加估计 + 示例单词。 |
| `learning_velocity(deck, days?)` | 学习率 + 30 天和 365 天预测。## 技能
作为 Claude Code 插件claude-plugin/plugin)提供 - 当 `plugins/cp` 时,其技能anki-mcp:< 加载命名空间。
| 技能 | 调用 | 功能 |
|---|---|---|
| `process-user-feedback-on-deck` | 用户可调用 | 协调反馈循环从头到尾:`extract.py` → `edit.py`(驱动 `claude -p` 编辑)→ `confirm.py` → `apply.py`。由 monorepo 的 `/pipe:tackle-feedback-on-grove` 管道使用。 |
---
## 提示
提示是用户触发的模板,会将实时的 Anki到对话中作为上下文。通过 Claude Code 中的斜杠菜单调用它们,格式为cp__anki__<。
| 提示 | 参数 | 功能 |
|---|---|---|
| `deck_briefing` | `deck` | 词汇分析、牌组中处理标志。 |
---
## 内部
### 包布局
```
plugins/anki-mcp/
├── .claude-plugin/
│ └── plugin 插件清单 — 将技能公开为 anki:<name>
├── skills/
│ └── process-user-feedback-on-deck/ 用户可调用 — 协调反馈循环
│ ├── extract.py CLI查找待处理反馈,写入编辑输入文件
│ ├── edit.py CLI — 驱动 claude 编辑,写入编辑输出文件
│ ├── confirm.py — 打印差异供用户确认
│ └── apply — 应用确认,清除 user_feedback
├── server.py 入口点 — 设置 sys.path, 工具,cp
├── launcherki 进程生命周期_anki_running)
共享状态:mcp 实例,_call(),FLAGS,_log
├── managed_note_types/
│ ├── bootstrap.py 启动:确保配置的笔记类型存在 + 带有托管字段
│ ├── feedback.py_feedback_records —待处理 user_feedback 标志
└── tools/
│ └── edits.py update(_batch) — 差异感知,追加日志的覆盖
tools/
├── __init__.py 导入所有子模块 → 触发 @mcp.tool() 注册
├── cards.py 卡片搜索,元数据,标志操作
├── notes.py 笔记创建/更新/删除
├── tags 标签操作(笔记级别)
├── decks.py牌组管理 + 同步 ├── scheduling.py 暂停,遗重新学习,回答
├── models 笔记类型
├── media 媒体存储/检索/删除
├── 审查历史统计
.py 高级聚合(get_all_notes, get_flagged_notes)
└── analytics.py 计算指标(vocabulary_snapshot, learning```
**添加工具 在相应的 `tools` 文件中添加cp.tool()` `core` cp` 和 `_。服务器更改后 Code。
**非:** `extract_feedback 和 `update_note_fields_batch` 不是 MCP 工具 — 每个函数只有一个(技能的 CLI 脚本),因此它们是普通的函数,保留在不总是加载的工具列表中。`update_note_fields` 仍然是一个工具,因为它在管道外直接使用很有用。
### 标准输出规范
标准输出是 JSON 协议通道。
- 永远不要在 SDK 外使用 `print()` — 它会静默破坏流。
- 所有调试/日志输出通过 `core._log` 进入 `anki-mcp.log`。
### AnkiConnect 参考
https://git.sr.ht/~foosoft/anki-connect