Skip to main content
Glama

Errorbook MCP

CI Python 3.11+ License: MIT

Local-first error notebook infrastructure for MCP agents, with FSRS scheduling and printable math PDFs.

Errorbook MCP 是一个可直接接入支持 Model Context Protocol (MCP) 的 agent 的错题管理服务。图片识别由 agent 自己的视觉能力完成;MCP 负责接收结构化题干、稳定编号、去重、复习调度、优先级维护,以及生成带数学公式的打印版 PDF。

核心设计

  • 题目使用不可变编号(例如 EB-2026-000001),编辑不会换号。

  • 复习间隔由版本锁定的 FSRS 算法维护;重复答错会缩短间隔并增加错题权重。

  • 用户手动提高优先级会记录为独立事件,并随时间衰减,不会让旧题永久占据队首。

  • 所有关键写操作支持幂等键;agent 重试不会重复录题或重复记一次作答。

  • 每份 PDF 使用题目快照。之后修改题目不会改变已经生成的试卷。

  • SQLite 默认启用 WAL、外键和写事务,适合本地单用户 agent 并发调用。

Related MCP server: Paper Memory MCP Lite

MCP 能力

类型

名称

用途

Prompt

record_from_image

约束宿主视觉模型忠实转写图片,模糊内容先确认,公式输出为 Markdown + LaTeX

Tool

create_problem

校验、去重、记录单题并分配固定编号

Tool

get_problem

按编号读取题目,可选完整复习和优先级历史

Tool

search_problems

按文本、编号、学科、标签、题型、状态和到期时间组合查询

Tool

update_problem

使用 expected_version 乐观锁修正 OCR 或题目内容

Tool

record_review

追加真实作答结果并更新 FSRS

Tool

adjust_priority

记录用户明确提出的临时优先级调整

Tool

set_problem_status

在 active、mastered、archived 之间切换,不硬删除历史

Tool

create_review_sheet

冻结题目快照并生成仅含题目的 A4 错题复习卷

Tool

get_export_status

查询导出状态、路径、资源 URI、大小和 SHA-256

Tool

list_exports

列出历史 PDF 文件及其存在状态

Tool

delete_export

删除指定 PDF 导出,不影响题目调度

Tool

get_library_stats

查看题库、到期积压和学科分布

Resource

errorbook://exports/{export_id}/questions

读取 questions PDF 二进制内容

所有有副作用的操作都接收 idempotency_key。建议 agent 使用“用户会话/动作类型/随机 UUID”组成的 8-128 字符键,并在网络重试时保持不变。

记忆与选卷算法

系统明确分开两个问题:FSRS 决定“下一次何时复习”,队列评分决定“本周容量有限时先打印哪些题”。人工优先级不会篡改 FSRS 状态。

复习结果映射如下:

实际结果

FSRS rating

行为

做错、空白、放弃

Again

缩短间隔,错误压力增加 1

部分正确、提示后正确

Hard

较短间隔,错误压力增加 0.5

独立正确

Good

正常增长稳定度,错误压力减半

明确轻松且无提示

Easy

更长间隔,错误压力降为四分之一

跳过

不评分

只留审计事件,不改变卡片状态

默认 desired_retention=0.90,使用依赖锁定的 FSRS 6.x 官方实现。普通“答对”必须记为 Good,不能由 agent 擅自升级为 Easy。mastered 题再次做错或部分正确会自动恢复为 active。

近期错误压力按 42 天半衰期衰减并在 6 封顶;人工 boost 按 14 天半衰期衰减并在正负 5 封顶。两者进入评分前都经过 1 - exp(-mass) 饱和,历史错误次数不会线性累加并永久霸榜。

周卷基础分为:

score = 42% 到期紧迫度
      + 22% 近期错误压力
      + 12% FSRS 难度
      + 10% 人工 boost
      +  8% 用户长期 importance

到期紧迫度在到期点为 0.5,随逾期连续上升并趋近 1;未来到期则连续下降。默认候选仅包含 active 且在未来七天内到期的题,或仍有有效人工 boost 的题。已到期且创建超过 28 天的题进入 fairness_must_include 必选桶,防止大题库中长期饥饿。PDF 导出是只读查阅操作,不会改变 FSRS、队列优先级或题目数据。返回结果会报告 backlog、必选溢出和按当前卷容量估算的清空周数。

题库过载时算法不能凭空消除工作量:如果每周新增/到期数量长期高于 max_questions,agent 应把返回的 backlog 明确告诉用户,而不是悄悄丢题。

安装

需要 Python 3.11+、uv 和 Chromium 系浏览器。Windows 会自动寻找 Microsoft Edge。

git clone https://github.com/stardustlil/errorbook-mcp.git
Set-Location errorbook-mcp
uv sync --locked
uv run errorbook-mcp

环境变量不会自动读取 .env;请在 MCP 客户端配置中直接设置。最小配置示例:

{
  "mcpServers": {
    "errorbook": {
      "command": "uv",
      "args": ["--directory", "C:\\path\\to\\errorbook", "run", "errorbook-mcp"],
      "env": {
        "ERRORBOOK_DATA_DIR": "C:\\path\\to\\errorbook-data",
        "ERRORBOOK_TIMEZONE": "Asia/Tokyo"
      }
    }
  }
}

Hermes Agent

Hermes Agent v0.18+ 可以通过 stdio 直接加载全部工具。先完成上面的 uv sync --locked,再执行:

hermes mcp add errorbook `
  --command ".venv\Scripts\python.exe" `
  --connect-timeout 30 `
  --env "ERRORBOOK_DATA_DIR=$env:LOCALAPPDATA\errorbook-data" "ERRORBOOK_TIMEZONE=Asia/Tokyo" `
  --args -m errorbook_mcp

当 Hermes 询问是否启用全部工具时直接回车,然后验证:

hermes mcp test errorbook
hermes mcp list

请启动一个新的 Hermes 会话使配置生效。图片 OCR 由 Hermes 当前选择的视觉模型完成,因此该模型必须支持图片输入。

也可以直接运行模块:

uv run python -m errorbook_mcp

Agent 录题流程

  1. 用户把错题图片上传给具备视觉能力的 agent。

  2. agent 使用 MCP prompt record_from_image 的规则,将图片忠实转写成 Markdown;数学公式使用 $...$ 或 $$...$$ LaTeX。

  3. agent 调用 create_problem。OCR 不清楚的内容不能猜,应先向用户确认。

  4. MCP 校验题型和选项,检查重复内容,并分配固定编号。

一个题目只保存规范化后的文本;原始图片仍由宿主应用管理。这样不需要在 MCP 中配置第二套视觉模型或上传凭据。

复习与出卷

  • 做错后调用 record_review(outcome="incorrect");这既保留历史,也会通过 FSRS 自动提前下次复习。

  • 用户明确说“提高 EB-2026-000123 的优先级”时调用 adjust_priority。不要用优先级工具伪造一次作答。

  • 每周调用 create_review_sheet,默认选择已经到期和未来七天内到期的题目,并生成仅含题目的错题复习卷。

  • 工具返回本地绝对路径、SHA-256 和 errorbook://exports/... MCP resource URI。

PDF 将原始 Markdown 转为静态 MathML,再由本机 Edge/Chrome/Chromium 打印,不执行 JavaScript 或 TeX 程序。原始 HTML、外部图片、链接和危险 LaTeX 命令会被拒绝。资源读取时会重新核对 SHA-256;文件被替换或损坏时不会静默返回。

导出使用数据库租约。进程在渲染中退出时,原幂等键会先保持 generating;租约最多五分钟后,同一请求和同一幂等键可从已冻结的题目快照恢复,不会重新选题。导出成功只会保存 PDF 文件和导出记录,不会写回题目或调度状态。

数据与备份

默认数据目录是当前目录下的 data/:

data/
  errorbook.sqlite3
  exports/
  tmp/

停止 MCP 服务后,备份整个数据目录即可。不要只复制 SQLite 主文件而遗漏仍在使用中的 WAL 文件。

开发验证

uv sync --extra dev
uv run pytest

测试覆盖数据库事务、并发稳定编号、幂等与崩溃恢复、FSRS 状态更新、优先级衰减、公平选卷、MCP stdio 往返、公式安全、PDF 文件完整性和真实浏览器渲染。

构建可分发 wheel:

uv build

安全边界

  • MCP 不读取任意图片路径,也不向外部 OCR 服务发送题目。

  • 题干按纯 Markdown 处理,原始 HTML 被转义;LaTeX 只转换为 MathML,不执行 TeX 命令。

  • stdio 模式的日志只写入 stderr,避免破坏 MCP 协议帧。

  • 远程 streamable HTTP 部署需要由反向代理提供 TLS、认证和单用户隔离;默认配置面向本地 stdio。

  • streamable HTTP 模式本身不提供多租户隔离。不要把默认服务直接暴露到公网。

参与项目

开发流程见 CONTRIBUTING.md,架构与一致性边界见 docs/architecture.md。安全问题请按 SECURITY.md 私下报告,不要在公开 issue 中附带真实题目、数据库或访问凭据。

Available Tools

12 tools
adjust_priority调整错题优先级A

仅在用户明确要求提高或降低某编号优先级时调用。delta 为 -5..-1 或 1..5;影响按 14 天半衰期衰减,不会篡改 FSRS 或伪造复习。若用户说又做错了,应调用 record_review。

Inputs: delta (required), number (required), reason (required), idempotency_key (required). Returns: object

create_problem记录错题A

保存宿主视觉模型已转写并确认的单道题,分配不可变编号并初始化 FSRS。不要把未确认的 OCR 猜测写入题库。幂等键用于安全重试。

Inputs: draft (required), idempotency_key (required), duplicate_policy. Returns: object

create_review_sheet生成复习 PDFA

冻结所选题目的当前版本并生成仅含题目的 A4 错题复习卷。scheduled 模式选择已到期、未来 horizon_days 内到期或有人工提升的题;生成试卷本身不会更新 FSRS。

Inputs: request (required), idempotency_key (required). Returns: object

delete_export删除复习 PDFA

删除指定导出及其 PDF 文件,但不会修改题目、FSRS 或优先级。

Inputs: export_id (required). Returns: object

get_export_status查看 PDF 导出A

按 export_id 获取导出状态、文件路径、资源 URI、大小和 SHA-256。

Inputs: export_id (required). Returns: object

get_library_stats错题本统计A

返回活动、已掌握、已归档、当前到期和七天内到期数量及学科分布。

Inputs: no named parameters. Returns: object

get_problem查看错题A

按固定编号精确读取错题;需要分析学习轨迹时可包含完整复习历史。

Inputs: number (required), include_history. Returns: object

list_exports管理复习 PDFB

列出历史导出文件及其是否仍存在,不会改变题目调度状态。

Inputs: limit, offset. Returns: object

record_review记录复习结果A

追加一次真实复习结果并更新 FSRS。incorrect=做错/空白,partial=部分正确或提示后正确,correct=独立正确,easy=明确轻松,skipped=只记录跳过且不改调度。普通答对应使用 correct,不要自动判为 easy。

Inputs: number (required), outcome (required), idempotency_key (required), notes, +3 more. Returns: object

search_problems查询错题A

按文本、编号、学科、标签、题型、状态或到期时间查询。默认按当前周卷优先级排序,返回各评分分量和原因。

Inputs: filters (required). Returns: object

set_problem_status设置错题状态A

将题目标为 active、mastered 或 archived。归档不会删除题目、编号、修订或复习历史。

Inputs: number (required), status (required), idempotency_key (required). Returns: object

update_problem修正错题A

修正 OCR 文本、标签等内容。必须传入读取时获得的 expected_version,冲突时重新读取,编号不会改变。

Inputs: patch (required), number (required), reason (required), idempotency_key (required), +1 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 12 tools

    Disambiguation5/5

    Each tool targets a distinct operation: problem CRUD, review recording, priority adjustment, status changes, export management, and statistics. No two tools have overlapping purposes; even get_problem vs search_problems are clearly differentiated by fixed ID vs. criteria-based search.

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern in snake_case, such as create_problem, record_review, list_exports. There are no mixed conventions or vague verbs, making the API highly predictable.

    Tool Count5/5

    12 tools is well within the ideal range for a domain-specific MCP server. Each tool serves a clear purpose in the error book workflow, from problem creation to review sheets and export management, without unnecessary bloat.

    Completeness5/5

    The tool surface covers the full lifecycle: create, read, update, search, review, priority, status, exports, and statistics. Archiving via set_problem_status addresses the absence of deletion, and get_problem can include review history, so there are no critical gaps.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers