Anki MCP
官方一个 MCP 服务器,使 AI 助手能够与 Anki(基于间隔重复的闪卡应用)交互。
你可以用 Anki MCP 做什么?
- 交互式复习到期卡片 — 让您的助手使用
get_due_cards获取到期卡片,通过present_card展示它们,并使用rate_card记录您的评分。 - 创建并自定义笔记类型样式 — 使用
createModel、updateModelStyling和updateModelTemplates构建具有特定字段、卡片模板和 CSS 的新笔记类型。 - 从列表批量添加闪卡 — 提供一组笔记,让助手使用
addNotes一次性创建它们,共享相同的牌组和模型。 - 搜索并更新现有笔记 — 使用
findNotes按牌组、标签或到期状态查找笔记,然后使用updateNoteFields、addTags或removeTags修改其字段或标签。 - 管理收藏中的媒体文件 — 使用
storeMediaFile从本地文件路径上传图片或音频,通过getMediaFilesNames列出已存储的文件,或删除未使用的媒体。 - 打开 Anki 的图形界面进行手动编辑 — 使用
guiBrowse打开卡片浏览器,使用guiAddCards预填充添加卡片对话框,或使用guiEditNote编辑特定笔记。
文档
Anki MCP 服务器
测试版 - 此项目正在积极开发中。API 和功能可能会发生变化。
一个模型上下文协议 (MCP) 服务器,使 AI 助手能够与间隔重复抽认卡应用程序 Anki 进行交互。
通过自然语言交互改变您的 Anki 体验——就像拥有一个私人导师。AI 助手不仅仅是呈现问题和答案;它还可以解释概念,使学习过程更具吸引力和人性化,提供上下文,并适应您的学习风格。它可以即时创建和编辑笔记,将您的学习过程转变为动态对话。更多功能即将推出!
示例和教程
有关在 Claude Desktop 中使用此 MCP 服务器的综合指南、真实示例和分步教程,请访问:
ankimcp.ai - 包含实用示例和用例的完整文档
请参阅 docs/ 获取补充文档,包括复习器设置指南和示例 Anki 牌组。
示例用例
三个代表性提示展示了此服务器启用的工具流程:
-
"帮我复习我的西班牙语牌组。" — 助手与 AnkiWeb 同步 (
sync),获取到期卡片 (get_due_cards带牌组过滤器),呈现每张卡片 (present_card),并记录您的评分 (rate_card)。为您量身定制的自然学习对话和解释。 -
"创建 10 张带有 RTL 样式的阿拉伯语词汇卡片。" — 助手列出笔记类型 (
modelNames),如果需要则创建自定义 RTL 模型 (createModel+updateModelStyling用于从右到左的 CSS),然后批量创建卡片 (addNotes)。 -
"将此图像从我的下载文件夹导入到所选笔记的正面。" — 助手上传本地文件 (
storeMediaFile带文件路径),从浏览器读取当前选定的笔记 (guiSelectedNotes+notesInfo),并使用<img>标签更新正面字段 (updateNoteFields)。
可用工具
服务器公开了 42 个 MCP 工具 — 31 个用于日常 Anki 操作的基本工具和 11 个用于笔记编辑/创建工作流程的驱动 Anki 桌面界面的 GUI 工具。
基本工具
复习与学习
sync- 与 AnkiWeb 同步以拉取最新数据并推送更改get_due_cards- 获取到期复习的卡片,可选择按牌组过滤get_cards- 通过状态(到期、新、学习中、暂停、隐藏)和牌组灵活过滤获取卡片present_card- 显示一张卡片以供复习,包括其问题/正面rate_card- 对卡片表现进行评分(重来、困难、良好、简单)并安排下次复习
注意: 卡片
front/back内容是根据其自己的模板按卡片呈现的(如 Anki 所示),因此翻转和完形填空卡片会显示正确的方向。卡片模板添加的静态文本也会出现在输出中。
牌组管理
listDecks- 列出所有牌组,可选择包含每个牌组的卡片计数统计信息deckStats- 获取单个牌组的综合统计信息(计数、轻松度/间隔分布)createDeck- 创建一个新的空牌组(支持Parent::Child,最多 2 级)changeDeck- 将卡片移动到不同的牌组(如果不存在则创建)
笔记管理
addNote- 创建具有指定字段和标签的单个笔记addNotes- 批量创建最多 100 个共享牌组和模型的笔记(支持部分成功)findNotes- 使用 Anki 查询语法搜索笔记(deck:、tag:、is:due等)notesInfo- 获取笔记的详细信息(字段、标签、CSS 样式)updateNoteFields- 更新现有笔记字段(支持 CSS,支持 HTML 内容)deleteNotes- 删除笔记和所有关联的卡片(破坏性操作,需要确认)
标签管理
getTags- 获取集合中的所有标签(首先使用以避免重复)addTags- 向指定笔记添加空格分隔的标签removeTags- 从指定笔记中移除空格分隔的标签replaceTags- 在指定笔记中重命名标签clearUnusedTags- 移除未被任何笔记使用的孤立标签(破坏性操作)
媒体管理
getMediaFilesNames- 列出collection.media中的媒体文件,可选择按模式过滤retrieveMediaFile- 以 base64 内容形式下载媒体文件storeMediaFile- 从 base64 数据、绝对文件路径或 URL 上传媒体deleteMediaFile- 从collection.media中移除媒体文件(破坏性操作)
💡 图像最佳实践:
- ✅ 使用文件路径(例如
/Users/you/image.png) - 快速高效 - ✅ 使用 URL(例如
https://example.com/image.jpg) - 直接下载 - ❌ 避免使用 base64 - 极慢且令牌效率低
只需告诉 Claude 图像在哪里,它将使用最有效的方法自动处理上传。
模型/模板管理
modelNames- 列出所有可用的笔记类型/模型modelFieldNames- 获取特定笔记类型的字段名称modelStyling- 获取笔记类型的 CSS 样式信息modelTemplates- 获取笔记类型的卡片模板(正面和背面 HTML)createModel- 使用自定义字段、卡片模板和 CSS 创建新的笔记类型(例如 RTL 模型)updateModelStyling- 更新现有笔记类型的 CSS 样式(应用于其所有卡片)updateModelTemplates- 更新现有笔记类型的卡片模板(正面和背面 HTML)(应用于其所有卡片)addModelField- 向现有笔记类型添加新字段(追加到末尾或插入到特定位置)removeModelField- 从现有笔记类型中移除字段(从所有笔记中删除其内容;需要明确确认)renameModelField- 重命名现有笔记类型中的字段(引用旧名称的卡片模板必须单独更新)repositionModelField- 更改现有笔记类型中字段的位置
统计信息
collection_stats- 所有牌组的聚合统计信息,包含每个牌组的细分review_stats- 复习历史分析(时间模式、记忆保留指标、学习连续记录)
GUI 工具
驱动 Anki 桌面界面的工具。用于笔记编辑/创建和牌组管理工作流程,不用于复习会话。
guiBrowse- 打开卡片浏览器并搜索卡片guiSelectCard- 在卡片浏览器中选择特定卡片guiSelectedNotes- 获取卡片浏览器中当前选定笔记的 IDguiAddCards- 打开添加卡片对话框,预设笔记详细信息guiEditNote- 打开特定笔记的笔记编辑器guiDeckOverview- 打开特定牌组的牌组概览对话框guiDeckBrowser- 打开牌组浏览器对话框guiCurrentCard- 获取复习模式下当前卡片的信息guiShowQuestion- 显示当前卡片的问题面guiShowAnswer- 显示当前卡片的答案面guiUndo- 撤销 Anki 中的上一个操作
先决条件
- 安装了 AnkiConnect 插件的 Anki
- Node.js 22.12.0+
安装
有几种方法可以将服务器安装到您的机器上。安装完成后,请前往连接 AI 客户端将其连接到您的 AI 助手——本地或远程。
npm(全局或 npx)
安装服务器的通用方法,适用于直接启动它的任何 MCP 客户端。
为运行 ankimcp 命令的客户端全局安装:
npm install -g @ankimcp/anki-mcp-server
或按需运行,无需安装:
npx @ankimcp/anki-mcp-server
MCPB 捆绑包(推荐用于 Claude Desktop)
为 Claude Desktop 安装此 MCP 服务器的最简单方法:
- 从 Releases 页面下载最新的
.mcpb捆绑包 - 在 Claude Desktop 中安装扩展:
- 方法 1:前往设置 → 扩展,然后拖放
.mcpb文件 - 方法 2:前往设置 → 开发者 → 扩展 → 安装扩展,然后选择
.mcpb文件
- 方法 1:前往设置 → 扩展,然后拖放
- 如果需要,配置 AnkiConnect URL(默认为
http://localhost:8765) - 重启 Claude Desktop
就是这样!该捆绑包包含了在本地运行服务器所需的一切。
对于 Anthropic MCP 目录审阅者: 一个从零到集成的演练,包含预填充的示例牌组,位于
docs/reviewer-setup.md。
从源代码安装(用于开发)
用于开发或高级用法:
npm install
npm run build
连接 AI 客户端
AI 助手可以通过两种方式访问此服务器,具体取决于助手运行的位置:
- 本地 — 服务器与 AI 客户端(Claude Desktop、Cursor、Cline、Zed 或本地浏览器会话)在同一台机器上运行。桌面 MCP 客户端使用 STDIO,本地基于 Web 的工具使用 HTTP。
- 远程 — 托管/远程 AI(例如云中的 ChatGPT 或 Claude.ai)需要访问在您本地机器上运行的 Anki。使用托管的 隧道(✅ 推荐 — 已认证),或者作为更轻量级的未认证替代方案,使用 ngrok。
本地
服务器与您的 AI 客户端在同一台计算机上运行,并与 localhost 上的 AnkiConnect 通信。
STDIO(主要本地集成)
STDIO 是本地桌面 MCP 客户端(Claude Desktop、Cursor IDE、Cline、Zed Editor 等)的标准传输方式。客户端将服务器作为子进程启动,并通过标准输入/输出进行通信。
支持的客户端:
- Claude Desktop
- Cursor IDE - AI 驱动的代码编辑器
- Cline - 用于 AI 辅助的 VS Code 扩展
- Zed Editor - 快速、现代的代码编辑器
- 其他支持 STDIO 传输的 MCP 客户端
对于 Claude Desktop,MCPB 捆绑包是最简单的途径。对于其他客户端,使用 --stdio 标志配置 npm 包。
配置 - 选择一种方法:
方法 1:使用 npx(推荐 - 无需安装)
{
"mcpServers": {
"anki-mcp": {
"command": "npx",
"args": ["-y", "@ankimcp/anki-mcp-server", "--stdio"],
"env": {
"ANKI_CONNECT_URL": "http://localhost:8765"
}
}
}
}
方法 2:使用全局安装
首先,全局安装:
npm install -g @ankimcp/anki-mcp-server
然后配置:
{
"mcpServers": {
"anki-mcp": {
"command": "ankimcp",
"args": ["--stdio"],
"env": {
"ANKI_CONNECT_URL": "http://localhost:8765"
}
}
}
}
配置文件位置:
- Cursor IDE:
~/.cursor/mcp.json(macOS/Linux) 或%USERPROFILE%\.cursor\mcp.json(Windows) - Cline:可通过 VS Code 中的设置 UI 访问
- Zed Editor:通过扩展市场安装为 MCP 扩展
有关客户端特定功能和故障排除,请查阅您的 MCP 客户端文档。另请参阅连接到 Claude Desktop 以获取直接指向已构建的 dist/main-stdio.js 的配置。
HTTP(本地基于 Web 的 AI)
HTTP 模式将服务器作为本地 Web 服务器运行,使用 MCP 可流式传输 HTTP 协议。这是基于 Web 的 AI 工具在指向您的机器时与之通信的传输方式,也是远程选项向外界公开的内容。单独使用时,HTTP 模式仅绑定到 localhost。
绑定到 localhost 之外? 如果您传递
--host 0.0.0.0(或在反向代理/公共域后运行),服务器默认仅接受环回Host标头以进行 DNS 重新绑定保护 — 将ALLOWED_HOSTS设置为客户端使用的主机名。请参阅 HTTP 模式配置。
设置 - 选择一种方法:
方法 1:使用 npx(推荐 - 无需安装)
# Quick start
npx @ankimcp/anki-mcp-server
# With custom options
npx @ankimcp/anki-mcp-server --port 8080 --host 0.0.0.0
npx @ankimcp/anki-mcp-server --anki-connect http://localhost:8765
方法 2:使用全局安装
# Install once
npm install -g @ankimcp/anki-mcp-server
# Run the server
ankimcp
# With custom options
ankimcp --port 8080 --host 0.0.0.0
ankimcp --anki-connect http://localhost:8765
方法 3:从源码安装(用于开发)
npm install
npm run build
npm run start:prod:http
要使本地 HTTP 服务器能被云端托管的 AI 访问,请使用下面的远程选项之一。
远程
托管/远程 AI(例如在云端运行的 ChatGPT 或 Claude.ai)无法直接访问 localhost。这些选项可将您的本地 Anki 暴露到互联网,以便远程助手与之通信。
隧道(✅ 推荐)
推荐的远程路径 — 经过身份验证且安全。 与原始公共端口不同,隧道模式要求您登录(OAuth 2.0 设备流程),因此端点不会对任何猜到 URL 的人开放。
隧道模式允许基于 Web 的 AI 助手访问您的本地 Anki,而无需您自己运行隧道。服务器通过 WebSocket 连接到托管的 AnkiMCP 隧道服务(wss://tunnel.ankimcp.ai),并分配到一个公共 URL。身份验证是内置的 — 无需 ngrok 账户或单独的隧道进程,您只需登录一次。
登录(OAuth 设备流程):
隧道模式使用 OAuth 2.0 设备授权许可。登录时会自动在浏览器中打开一个批准页面,代码已嵌入 URL — 无需输入任何内容,只需批准即可。(如果无法打开浏览器,终端会打印验证 URL 和代码作为后备方案,供手动输入。)成功后,凭据将保存到 ~/.ankimcp/credentials.json(文件权限 0600)。
# Pre-authenticate (optional — --tunnel will trigger this automatically if needed)
ankimcp --login
npx @ankimcp/anki-mcp-server --login
# Clear saved credentials
ankimcp --logout
启动隧道:
# Connect to the managed tunnel service (wss://tunnel.ankimcp.ai)
ankimcp --tunnel
npx @ankimcp/anki-mcp-server --tunnel
# Override the tunnel server URL (must be ws:// or wss://) — e.g. for self-hosting
ankimcp --tunnel wss://my-tunnel.example.com
如果不存在凭据,--tunnel 会自动首先启动登录流程,然后继续连接到隧道。此自动登录需要交互式终端 — 当 stdout 不是 TTY 时(systemd、无头 Docker、CI),服务器会快速失败并要求您先运行 ankimcp --login。连接后,将打印公共隧道 URL;按 Ctrl+C 断开连接。将该 URL 分享给您的 AI 助手。
隧道模式环境变量:
| 变量 | 描述 | 默认值 |
|---|---|---|
TUNNEL_SERVER_URL | 隧道服务器 WebSocket URL(--tunnel/--login 标志值会覆盖此项) | wss://tunnel.ankimcp.ai |
TUNNEL_AUTH_CLIENT_ID | 设备流程的 OAuth 客户端 ID。高级选项 — 仅在指向自托管隧道/身份验证服务时需要。 | (内置) |
设备流程身份验证端点(/auth/device、/auth/token)派生自 TUNNEL_SERVER_URL,因此将 --tunnel(或 TUNNEL_SERVER_URL)指向其他主机也会将身份验证移至该主机。
工作原理: 隧道模式在内存传输后运行进程内 MCP 服务器(McpModule 启动时不带内置传输)。TunnelMcpService 将该内存传输连接到 MCP 服务器,TunnelClient 通过 WebSocket 将其桥接到远程隧道服务 — 中继传入的 MCP 请求和传出的响应。AnkiConnect 仍然只能在您的本地机器上访问。
ngrok(未经身份验证的替代方案)
如果您希望在没有托管隧道账户的情况下公开本地 HTTP 模式,内置的 --ngrok 标志会启动一个 ngrok 子进程(src/services/ngrok.service.ts),并在启动横幅中打印公共 URL:
# One-time ngrok setup, then:
ankimcp --ngrok
此路由未经身份验证 — 任何知道 URL 的人都可以访问您的 Anki,因此安全性低于隧道。除非您有特定理由管理自己的 ngrok 端点,否则请优先选择隧道。(需要全局安装 ngrok 和 authtoken。)
--ngrok 标志使用 --host-header=rewrite 启动 ngrok,因此 ngrok 在转发前会将上游 Host 重写为 localhost。这样可以使请求保持在环回主机允许列表内(参见 DNS 重新绑定保护),而无需将公共 *.ngrok 域添加到 ALLOWED_HOSTS。如果您改为手动运行 ngrok,请使用相同的标志 — ngrok http --host-header=rewrite 3000 — 否则 ngrok 会将公共 ngrok 主机名作为 Host 转发,服务器会以 403 拒绝它。
CLI 选项(所有模式)
ankimcp [options]
Options:
--stdio Run in STDIO mode (for MCP clients)
--tunnel [url] Connect via the managed tunnel (authenticated)
--login Authenticate for tunnel mode (OAuth device flow)
--logout Clear saved tunnel credentials
-p, --port <port> Port to listen on (HTTP mode, default: 3000)
-h, --host <host> Host to bind to (HTTP mode, default: 127.0.0.1)
-a, --anki-connect <url> AnkiConnect URL (default: http://localhost:8765)
--ngrok Start ngrok tunnel (requires global ngrok installation)
--read-only Run in read-only mode (blocks all write operations)
--help Show help message
Usage with npx (no installation needed):
npx @ankimcp/anki-mcp-server # HTTP mode
npx @ankimcp/anki-mcp-server --port 8080 # Custom port
npx @ankimcp/anki-mcp-server --stdio # STDIO mode
npx @ankimcp/anki-mcp-server --tunnel # Managed tunnel mode
npx @ankimcp/anki-mcp-server --ngrok # HTTP mode with ngrok tunnel
npx @ankimcp/anki-mcp-server --read-only # Read-only mode
Usage with global installation:
npm install -g @ankimcp/anki-mcp-server # Install once
ankimcp # HTTP mode
ankimcp --port 8080 # Custom port
ankimcp --stdio # STDIO mode
ankimcp --tunnel # Managed tunnel mode
ankimcp --ngrok # HTTP mode with ngrok tunnel
ankimcp --read-only # Read-only mode
只读模式(所有模式)
--read-only 标志可防止对您的 Anki 集合进行任何修改。启用后:
- 所有读取操作正常工作(浏览牌组、查看卡片、搜索笔记)
- 允许复习操作(同步、answerCards、暂停/取消暂停)
- 阻止内容修改(addNote、deleteNotes、createDeck、updateNoteFields 等)
- 适用于安全探索 Anki 数据,无意外更改的风险
# HTTP mode with read-only
ankimcp --read-only
# STDIO mode with read-only
ankimcp --stdio --read-only
# Can combine with other flags
ankimcp --ngrok --read-only
您也可以通过环境变量启用只读模式:
READ_ONLY=true ankimcp
或在 MCP 客户端配置中:
{
"mcpServers": {
"anki-mcp": {
"command": "npx",
"args": ["-y", "@ankimcp/anki-mcp-server", "--stdio", "--read-only"],
"env": {
"ANKI_CONNECT_URL": "http://localhost:8765"
}
}
}
}
连接到 Claude Desktop(本地模式)
您可以通过以下任一方式在 Claude Desktop 中配置服务器:
- 前往:设置 → 开发者 → 编辑配置
- 或手动编辑配置文件
配置
将以下内容添加到您的 Claude Desktop 配置中:
{
"mcpServers": {
"anki-mcp": {
"command": "node",
"args": ["/path/to/anki-mcp-server/dist/main-stdio.js"],
"env": {
"ANKI_CONNECT_URL": "http://localhost:8765"
}
}
}
}
将 /path/to/anki-mcp-server 替换为您的实际项目路径。
配置文件位置
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
更多详情,请参阅官方 MCP 文档。
环境变量(可选)
| 变量 | 描述 | 默认值 |
|---|---|---|
ANKI_CONNECT_URL | AnkiConnect URL | http://localhost:8765 |
ANKI_CONNECT_API_VERSION | API 版本 | 6 |
ANKI_CONNECT_API_KEY | 如果在 AnkiConnect 中配置了 API 密钥 | - |
ANKI_CONNECT_TIMEOUT | 请求超时时间(毫秒) | 5000 |
READ_ONLY | 启用只读模式(true 或 1) | false |
ALLOWED_HOSTS | HTTP 模式:除环回地址外要接受的额外 Host 标头值(逗号分隔的主机名)。绑定到 LAN/公共地址或在反向代理后运行时必需。请参阅 HTTP 模式配置。 | 仅限环回 |
ALLOWED_ORIGINS | HTTP 模式:浏览器 Origin/Referer 模式的逗号分隔允许列表(支持通配符,例如 https://*.ngrok.io)。 | http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:* |
TUNNEL_SERVER_URL | 隧道服务器 WebSocket URL(仅限隧道模式) | wss://tunnel.ankimcp.ai |
MEDIA_ALLOWED_TYPES | 允许文件路径导入的额外 MIME 类型(逗号分隔,例如 application/pdf) | - |
MEDIA_IMPORT_DIR | 将文件路径导入限制在此目录 | - |
MEDIA_ALLOWED_HOSTS | 允许 URL 导入的特定私有网络主机(逗号分隔,例如 192.168.1.50,my-nas) | - |
使用示例
搜索和更新笔记
# Search for notes in a specific deck
findNotes(query: "deck:Spanish")
# Get detailed information about notes
notesInfo(notes: [1234567890, 1234567891])
# Update a note's fields (HTML content supported)
updateNoteFields(note: {
id: 1234567890,
fields: {
"Front": "<b>¿Cómo estás?</b>",
"Back": "How are you?"
}
})
# Delete notes (requires confirmation)
deleteNotes(notes: [1234567890], confirmDeletion: true)
Anki 查询语法示例
findNotes 工具支持 Anki 强大的查询语法:
"deck:DeckName"- 特定牌组中的所有笔记"tag:important"- 带有 "important" 标签的笔记"is:due"- 到期待复习的卡片"is:new"- 尚未学习的新卡片"added:7"- 最近 7 天添加的笔记"front:hello"- 正面字段中包含 "hello" 的笔记"flag:1"- 带有红旗标记的笔记"prop:due<=2"- 2 天内到期的卡片"deck:Spanish tag:verb"- 西班牙语牌组中带有动词标签的笔记(AND)"deck:Spanish OR deck:French"- 来自任一牌组的笔记
重要说明
CSS 和 HTML 处理
notesInfo工具返回 CSS 样式信息,以便正确感知渲染updateNoteFields工具支持字段中的 HTML 内容并保留 CSS 样式- 每个笔记模型都有自己的 CSS 样式 - 使用
modelStyling获取特定于模型的 CSS
更新警告
⚠️ 重要:使用 updateNoteFields 时,请勿在 Anki 的浏览器中查看笔记,否则字段将无法正确更新。更新前请关闭浏览器或切换到其他笔记。更多详情请参阅已知问题。
删除安全
deleteNotes 工具需要明确确认(confirmDeletion: true)以防止意外删除。删除笔记会永久移除所有关联的卡片。
安全性
媒体文件路径和 URL 验证
媒体工具(storeMediaFile、retrieveMediaFile、deleteMediaFile)和 updateNoteFields 音频/图片字段包含安全验证,以防止通过提示注入滥用:
- 文件路径导入仅限于媒体文件类型(图像、音频、视频)。非媒体文件(例如 SSH 密钥、凭据、shell 配置)会根据 MIME 类型被拒绝。配置
MEDIA_ALLOWED_TYPES以允许其他文件类型,或配置MEDIA_IMPORT_DIR将导入限制在特定目录。 - URL 导入经过 SSRF 攻击验证。对私有网络(10.x、172.16.x、192.168.x)、环回(127.x)、链路本地(169.254.x)和非 HTTP(S) 方案的请求将被阻止。配置
MEDIA_ALLOWED_HOSTS以允许特定的私有网络主机。 - 文件名经过清理以防止路径遍历(例如,
../../序列会被剥离)。
这些保护适用于 storeMediaFile、retrieveMediaFile、deleteMediaFile 和 updateNoteFields 音频/图片字段。
路径遍历漏洞由 Hideaki Takahashi 报告。
DNS 重新绑定保护(HTTP 传输)
在 HTTP 模式下运行时,服务器会验证每个请求上的 Host 标头。默认情况下,无论端口如何,仅接受环回主机(localhost、127.0.0.1、::1)。Host 是浏览器禁止的标头,因此恶意网页无法伪造它 — 这关闭了 DNS 重新绑定路径,即重新绑定的页面使用伪造的 Host 且没有 Origin 访问本地服务器,并访问 MCP 工具。不允许的 Host 会被拒绝,并返回 403。
如果您绑定到 0.0.0.0、在反向代理后运行或公开公共隧道域,请设置 ALLOWED_HOSTS(逗号分隔的主机名)以允许这些主机。使用 ngrok 建立隧道时,服务器使用 --host-header=rewrite,因此上游仍然看到环回 Host。有关选项的完整列表,请参阅 HTTP 模式配置。
DNS 重新绑定漏洞由 avishaigo-commits 和 yotampe-pluto 报告。
隐私政策
此 MCP 服务器在您的机器上本地运行,不收集任何遥测、分析或使用数据。
完整政策:https://ankimcp.ai/privacy/
- 数据收集:服务器不收集任何内容。它在您的 AI 助手和本地 AnkiConnect 插件之间代理请求。
- 使用/存储:无服务器端存储。所有闪卡数据都保存在您自己设备上的 Anki 安装中。
- 第三方共享:无。服务器仅与您配置的 AnkiConnect URL(默认:localhost)通信。如果您启用 Anki 内置的 AnkiWeb 同步,那是在您的 Anki 安装和 AnkiWeb 之间直接进行的 — 不在此服务器的范围内。
- 保留:不适用 — 服务器端不保留任何数据。
- 联系方式:support@ankimcp.ai
已知问题
有关已知问题和限制的完整列表,请访问我们的文档:
关键限制
在浏览器中查看时笔记更新失败
⚠️ 重要:使用 updateNoteFields 更新笔记时,如果该笔记当前正在 Anki 的浏览器窗口中查看,更新将静默失败。这是上游 AnkiConnect 的限制。
解决方法:更新前务必关闭浏览器或导航到其他笔记。
有关更多详细信息和其他已知问题,请参阅完整文档。
故障排除
ERR_REQUIRE_ESM 错误
如果您看到类似以下的错误:
Error [ERR_REQUIRE_ESM]: require() of ES Module not supported
这意味着您的 Node.js 版本不受支持。服务器需要 Node.js 22.12.0+。
注意: 最低支持的运行时环境为 Node.js 22.12.0。Node.js 20 (Iron) 已于 2026-04-30 终止生命周期,不再受支持。
检查您的版本:
node --version
解决方案: 将 Node.js 更新至 22.12.0 或更高版本。您可以从 nodejs.org 下载,或使用版本管理器,如 nvm。
开发
传输模式
此服务器通过独立的入口点支持三种 MCP 传输模式:
STDIO 模式(默认)
- 适用于 Claude Desktop 等本地 MCP 客户端
- 使用标准输入/输出进行通信
- 入口点:
dist/main-stdio.js - 运行:
npm run start:prod:stdio或node dist/main-stdio.js - MCPB 捆绑包:使用 STDIO 模式
HTTP 模式(可流式 HTTP)
- 适用于远程 MCP 客户端和基于 Web 的集成
- 使用 MCP 可流式 HTTP 协议
- 入口点:
dist/main-http.js - 运行:
npm run start:prod:http或node dist/main-http.js - 默认端口:3000(可通过
PORT环境变量配置) - 默认主机:
127.0.0.1(可通过HOST环境变量配置) - MCP 端点:
http://127.0.0.1:3000/(根路径)
隧道模式(托管 WebSocket 隧道)
- 适用于通过托管 AnkiMCP 隧道服务的基于 Web 的 AI 助手,内置身份验证
- MCP 服务器在内存传输层之后于进程内运行;
TunnelMcpService将其连接到 MCP 服务器,TunnelClient则通过 WebSocket 将其桥接到隧道服务 - 入口点:
dist/main-tunnel.js - 运行:
node dist/main-tunnel.js --tunnel(或ankimcp --tunnel) - 认证:
ankimcp --login/ankimcp --logout;凭据存储在~/.ankimcp/credentials.json(0600) - 开发:
npm run start:dev:tunnel(监视模式,运行--tunnel --debug)
构建
npm run build # Builds once, creates dist/ with all three entry points
main-stdio.js、main-http.js 和 main-tunnel.js 均构建到同一个 dist/ 目录中。根据您的需求选择运行哪个。
HTTP 模式配置
环境变量:
PORT- HTTP 服务器端口(默认:3000)HOST- 绑定地址(默认:127.0.0.1,仅限本地主机)ALLOWED_HOSTS- 逗号分隔的额外Host头值,用于在内置回环地址集(localhost、127.0.0.1、::1)之外接受。仅主机名,与端口无关。默认:仅限回环地址。ALLOWED_ORIGINS- 逗号分隔的浏览器Origin/Referer模式允许列表;支持通配符(例如https://*.ngrok.io)。默认:http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:*。LOG_LEVEL- 日志记录级别(默认:info)
安全性:
- 主机头验证(DNS 重新绑定保护) — 每个 HTTP 请求都必须携带一个与允许列表匹配的
Host头。默认情况下,无论端口如何,仅接受回环主机(localhost、127.0.0.1、::1)。Host是浏览器禁止的头,因此恶意网页无法伪造它——这堵住了 DNS 重新绑定 路径,即重新绑定的页面使用伪造的Host且没有Origin到达服务器。不允许的Host将被拒绝,并返回403。 - Origin 头验证 — 存在但不被允许的
Origin/Referer的浏览器请求将被拒绝。没有Origin的请求(curl、Postman、MCP-over-HTTP 客户端)则被允许;主机验证是抵御重新绑定的防线。 - 默认绑定到本地主机(127.0.0.1)。
- 当前版本无身份验证(计划支持 OAuth)。
将 HTTP 模式暴露到本地主机之外 — 如果您绑定到局域网/公共地址,或将服务器置于反向代理或公共域之后,您必须将 ALLOWED_HOSTS 设置为客户端将使用的主机名,否则所有非回环请求都将被拒绝,并返回 403:
# Bind to all interfaces and accept the machine's LAN name + a public domain
ALLOWED_HOSTS=my-nas.local,anki.example.com PORT=8080 HOST=0.0.0.0 node dist/main-http.js
当您在没有 ALLOWED_HOSTS 的情况下绑定到 0.0.0.0/:: 时,服务器会在启动时记录一条警告,指出仅接受回环 Host 头。
Docker / 反向代理 / 公共域: 同样的规则适用。在 Docker 中,请求通常携带容器的发布主机名或代理的
Host,因此请相应地设置ALLOWED_HOSTS。反向代理(nginx、Caddy、Traefik)应转发原始Host并将该主机名列入ALLOWED_HOSTS,或将上游Host重写为localhost。内置的--ngrok集成会自动处理此问题(见下文)。
示例:运行模式
# Development - STDIO mode (watch mode with auto-rebuild)
npm run start:dev:stdio
# Development - HTTP mode (watch mode with auto-rebuild)
npm run start:dev:http
# Production - STDIO mode
npm run start:prod:stdio
# or
node dist/main-stdio.js
# Production - HTTP mode
npm run start:prod:http
# or
PORT=8080 HOST=0.0.0.0 node dist/main-http.js
构建 MCPB 捆绑包
要创建可分发的 MCPB 捆绑包:
npm run mcpb:bundle
此命令将:
- 将版本从
package.json同步到manifest.json - 删除旧的
.mcpb文件 - 构建 TypeScript 项目
- 将
dist/和node_modules/打包到一个.mcpb文件中 - 运行
mcpb clean以移除 devDependencies(将捆绑包从约 47MB 优化至约 10MB)
输出文件将命名为 anki-mcp-server-X.X.X.mcpb,可分发给用户进行一键安装。
捆绑内容
MCPB 捆绑包包含:
- 编译后的 JavaScript(
dist/目录 - 包含所有三个入口点) - 仅生产依赖项(
node_modules/- devDependencies 已由mcpb clean移除) - 包元数据(
package.json) - 清单配置(
manifest.json- 配置为使用main-stdio.js) - 图标(
icon.png)
源文件、测试和开发配置通过 .mcpbignore 自动排除。
Claude Desktop 中的日志记录
在 Claude Desktop 中作为 MCPB 扩展运行时,日志将写入:
日志位置:~/Library/Logs/Claude/(macOS)
日志分散在多个文件中:
- main.log - Claude Desktop 应用程序常规日志
- mcp-server-Anki MCP Server.log - 此扩展的 MCP 协议消息
- mcp.log - 来自所有服务器的组合 MCP 日志
注意:pino 日志记录器输出(来自服务器代码的 INFO、ERROR、WARN 消息)会发送到 stderr,并出现在 MCP 特定的日志文件中。Claude Desktop 决定哪个日志文件接收哪些消息,但通常:
- 应用程序启动和 MCP 协议通信 → MCP 特定日志
- 服务器内部日志记录(pino) → MCP 特定日志,有时也出现在 main.log 中
要实时查看日志:
tail -f ~/Library/Logs/Claude/mcp-server-Anki\ MCP\ Server.log
调试 MCP 服务器
您可以使用 MCP Inspector 并从您的 IDE(WebStorm、VS Code 等)附加调试器来调试 MCP 服务器。
HTTP 模式注意: 使用 MCP Inspector 测试 HTTP 模式(可流式 HTTP)时,请使用“连接类型:通过代理”以避免 CORS 错误。
步骤 1:在 MCP Inspector 中配置调试服务器
mcp-inspector-config.json 已包含调试服务器配置:
{
"mcpServers": {
"stdio-server-debug": {
"type": "stdio",
"command": "node",
"args": ["--inspect-brk=9229", "dist/main-stdio.js"],
"env": {
"MCP_SERVER_NAME": "anki-mcp-stdio-debug",
"MCP_SERVER_VERSION": "1.0.0",
"LOG_LEVEL": "debug"
},
"note": "Anki MCP server with debugging enabled on port 9229"
}
}
}
步骤 2:启动调试服务器
使用调试服务器运行 MCP Inspector:
npm run inspector:debug
这将启动服务器,并在端口 9229 上启用 Node.js 调试,并在第一行暂停执行。
步骤 3:从您的 IDE 附加调试器
WebStorm
- 转到 运行 → 编辑配置
- 添加一个新的 附加到 Node.js/Chrome 配置
- 将端口设置为
9229 - 点击 调试 以附加
VS Code
- 打开调试面板(Ctrl+Shift+D / Cmd+Shift+D)
- 选择 调试 MCP 服务器(附加) 配置
- 按 F5 附加
步骤 4:设置断点并调试
附加后,您可以:
- 在 TypeScript 源文件中设置断点
- 逐步执行代码
- 检查变量和调用堆栈
- 使用调试控制台评估表达式
调试器将使用源映射,允许您调试原始 TypeScript 代码,而不是编译后的 JavaScript。
使用 Claude Desktop 进行调试
您还可以在 MCP 服务器于 Claude Desktop 内部运行时,通过启用 Node.js 调试器并附加您的 IDE 来进行调试。
步骤 1:配置 Claude Desktop 以进行调试
更新您的 Claude Desktop 配置以启用调试:
macOS:~/Library/Application Support/Claude/claude_desktop_config.json
Windows:%APPDATA%\Claude\claude_desktop_config.json
Linux:~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"anki-mcp": {
"command": "node",
"args": [
"--inspect=9229",
"<path_to_project>/anki-mcp-server/dist/main-stdio.js"
],
"env": {
"ANKI_CONNECT_URL": "http://localhost:8765"
}
}
}
}
关键更改:在 dist/main-stdio.js 的路径前添加 --inspect=9229
调试选项:
--inspect=9229- 立即启动调试器,不阻塞(推荐)--inspect-brk=9229- 暂停执行,直到调试器附加(用于调试启动问题)
步骤 2:重启 Claude Desktop
保存配置后,重启 Claude Desktop。MCP 服务器现在将在端口 9229 上启用调试运行。
步骤 3:从您的 IDE 附加调试器
WebStorm
- 转到 运行 → 编辑配置
- 点击 + 按钮,选择 附加到 Node.js/Chrome
- 配置:
- 名称:
Attach to Anki MCP (Claude Desktop) - 主机:
localhost - 端口:
9229 - 附加到:
Node.js < 8或Chrome or Node.js > 6.3(取决于 WebStorm 版本)
- 名称:
- 点击 确定
- 点击 调试(Shift+F9)以附加
VS Code
- 添加到
.vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach to Anki MCP (Claude Desktop)",
"port": 9229,
"skipFiles": ["<node_internals>/**"],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]
}
- 打开调试面板(Ctrl+Shift+D / Cmd+Shift+D)
- 选择 附加到 Anki MCP(Claude Desktop)
- 按 F5 附加
步骤 4:实时调试
附加后,您可以:
- 在 TypeScript 源文件(例如
src/mcp/primitives/essential/tools/create-model.tool.ts)中设置断点 - 正常使用 Claude Desktop - 调用工具时断点将被命中
- 逐步执行代码
- 检查变量和调用堆栈
- 使用调试控制台
示例:在 create-model.tool.ts 的第 119 行设置断点,然后让 Claude 创建一个新模型。调试器将在您的断点处暂停!
注意:只要 Claude Desktop 正在运行,调试器就会保持附加状态。您可以随时分离/重新附加,无需重启 Claude Desktop。
构建命令
npm run build # Build the project (compile TypeScript to JavaScript)
npm run start:dev:stdio # STDIO mode with watch (auto-rebuild)
npm run start:dev:http # HTTP mode with watch (auto-rebuild)
npm run type-check # Run TypeScript type checking
npm run lint # Run ESLint
npm run mcpb:bundle # Sync version, clean, build, and create MCPB bundle
NPM 包测试(本地)
在发布前本地测试 npm 包:
# 1. Create local package
npm run pack:local # Builds and creates @ankimcp/anki-mcp-server-*.tgz
# 2. Install globally from local package
npm run install:local # Installs from ./@ankimcp/anki-mcp-server-*.tgz
# 3. Test the command
ankimcp # Runs HTTP server on port 3000
# 4. Uninstall when done testing
npm run uninstall:local # Removes global installation
工作原理:
npm pack创建一个与 npm publish 将创建的完全相同的.tgz文件- 从
.tgz安装模拟了用户从npm install -g ankimcp获取的内容 - 这使您可以在发布到 npm 之前测试完整的用户体验
测试命令
npm test # Run all tests
npm run test:unit # Run unit tests only
npm run test:tools # Run tool-specific tests
npm run test:workflows # Run workflow integration tests
npm run test:e2e # Run end-to-end tests
npm run test:cov # Run tests with coverage report
npm run test:watch # Run tests in watch mode
npm run test:debug # Run tests with debugger
npm run test:ci # Run tests for CI (silent, with coverage)
测试覆盖率
该项目对以下方面保持 70% 的最低覆盖率阈值:
- 分支
- 函数
- 行
- 语句
覆盖率报告生成在 coverage/ 目录中。
版本控制
本项目遵循 语义化版本控制,采用 1.0 版之前的开发方法:
-
0.x.x - Beta/开发版本(当前阶段)
- 0.1.x - Bug 修复和补丁
- 0.2.0+ - 新功能或次要改进
- 破坏性更改 在 0.x 版本中是可接受的
-
1.0.0 - 第一个稳定版本
- 将在 API 稳定且经过测试后发布
- 破坏性更改将需要主版本号升级(2.0.0 等)
当前状态:0.22.0 - 活跃的 Beta 开发。近期功能包括集合范围的复习分析(当省略 deck 时,review_stats 现在会跨所有牌组聚合)、模型字段管理(addModelField、removeModelField、renameModelField、repositionModelField)、批量笔记创建(addNotes)、集成 ngrok 隧道(--ngrok 标志)、媒体文件管理、模型/模板管理以及全面的牌组统计。API 可能会根据反馈和测试进行更改。
MCPB 规范演进
本项目针对 Anthropic 的 MCPB 捆绑包规范,该规范仍在演进中。我们在 https://github.com/modelcontextprotocol/mcpb 跟踪该规范,并可能引入破坏性更改以保持合规。在 0.x.x 版本控制方案下,允许进行破坏性更改。
类似项目
如果您正在探索 Anki MCP 集成,以下是该领域的其他项目:
scorzeth/anki-mcp-server
- 状态:似乎已废弃(近期无更新)
- Anki MCP 集成的早期实现### nailuoGG/anki-mcp-server
- 实现方式:轻量级、单文件实现
- 架构:过程式代码结构,所有工具集中在一个文件中
- 适用场景:简单用例,最小化依赖
本项目与之不同的原因:
- 企业级架构:基于 NestJS 构建,采用依赖注入
- 模块化设计:每个工具都是独立的类,职责分离清晰
- 可维护性:无需修改现有代码即可轻松扩展新功能
- 测试:全面的测试套件,要求 70% 的覆盖率
- 类型安全:严格的 TypeScript 与 Zod 验证
- 错误处理:健壮的错误处理,提供有用的用户反馈
- 生产就绪:完善的日志记录、进度报告和 MCPB 包支持
- 可扩展性:能够轻松从基础工具扩展到复杂工作流
用例:如果您需要一个坚实的基础来构建高级 Anki 集成,或计划大幅扩展功能,本项目的架构方法使其更易于长期维护和扩展。
实用链接
许可证与归属
本项目基于 MIT 许可证授权 — 查看 LICENSE 获取全文。
版权所有 © 2026 Anatoly Tarnavsky。
第三方归属
-
Anki® 是 Ankitects Pty Ltd 的注册商标。本项目是一个非官方的第三方工具,与 Ankitects Pty Ltd 无关联、未受其认可或赞助。Anki 标志的使用遵循引用 Anki 并附带链接至 https://apps.ankiweb.net 的替代许可。如需访问官方 Anki 应用程序,请访问 https://apps.ankiweb.net。
-
模型上下文协议 (MCP) 是 Anthropic 制定的开放标准。MCP 标志来自官方 MCP 文档仓库,并根据 MIT 许可证使用。有关 MCP 的更多信息,请访问 https://modelcontextprotocol.io。
-
这是一个连接 Anki 和 MCP 技术的独立项目。所有商标、服务标志、商号、产品名称和标志均为其各自所有者的财产。