teacher-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| RUOYI_BASE_URL | No | Base URL of the RuoYi platform backend. | http://localhost:8080 |
| RUOYI_PASSWORD | Yes | Password for RuoYi platform login. | |
| RUOYI_USERNAME | Yes | Username for RuoYi platform login. | |
| TEACHER_MCP_ROLE | No | Role for tool grouping: all, prep, ingest, or lecture. | all |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| loginA | 以真实 teacher 账号登录平台,拿双头 token 注入本会话身份(后续所有工具隐式带该身份、落 RuoYi 权限审计)。 参数: username/password: teacher 账号。留空则用 .env 兜底(RUOYI_USERNAME/RUOYI_PASSWORD)。 返回: {ok, teacher_id, username} —— token 仅驻留 server 侧会话态,不回吐明文给调用方。 |
| login_asA | 飞书机器人免密切身份(PRD-007):凭服务密钥用 open_id 换该 teacher 的 token,替换本会话身份。 用途:bot 后端按飞书消息发送者的 open_id 逐消息切身份,让写操作(录题/组卷等)归属各自 teacher。 鉴权:服务密钥走 env BOT_SECRET(只在机器人后端持有、不入 git);调用方不需密码。 401 自动重签:切身份后,后续工具遇 token 失效会按当前 open_id 自动重调 botLogin 重签(不走密码重登)。 参数: openid: 飞书 open_id(如 ou_xxx)。 返回: 成功 → {ok:true, user_id, openid}。 失败 → {ok:false, hint}:openid 未绑定 teacher → hint 含「未绑定」(bot 按此路由拒绝话术); BOT_SECRET 未配置 / 密钥错 / 账号停用等各有对应提示。 |
| list_kg_treeA | 查平台知识点树(组卷的知识点白名单源)。返回顶层节点 + children 嵌套。 编排层(Claude Code)据此选要考查的知识点叶子 id,喂给 compose_paper 的 outline.subjectId。 返回: {ok, nodes:[{id,name,children?}, ...]};空树 → {ok:true, nodes:[]} 不报错。 |
| resolve_kgA | KG 锚定查表(确定性只读,数学+科学一套通吃):按名称/节号/父节点在某教材根下查节点,供选锚定叶子。 🔴 叶子=无子节点(is_leaf),别按 level 判——科学 901 树 5 层、902-906 树 4 层,叶深不一(H2 实测)。 用法:先 query 模糊(如「乘方」)看候选 → 挑 is_leaf=true 的最贴切者作 ingest_items 的 kp_id; 同步练习类卷名带节号可 section_num 精确命中(如 "2.5" → 「2.5 有理数的乘方」节点)。 参数: subject_root: 教材根 id(数学七上="100";科学="901".."906")——锚定范围的唯一开关 query : 名称模糊词(LIKE %query%) section_num : 节号精确匹配(如 "2.5",命中名称以「2.5 」开头的节点) parent_id : 只列某节点的直接子节点(浏览下钻用;给了它则忽略 subject_root 前缀过滤) leaves_only : 只返回叶子 返回: {ok, count, nodes:[{id,name,level,parent_id,is_leaf}]};无命中 → count=0 不报错。 |
| search_questionsA | 从题库分页检索题目(备课圈题核心)→ POST /teacher/question/page。返回 {ok, total, items}。 🔴 快速找回路径(PRD-O-005 溯源增强):给 batch_id 或 since 任一 → 改走 backends/db 只读检索 (按 import_batch_id / create_time / create_user 查,不依赖 stem LIKE,故不漏 stem_text=NULL 的变式题),可与 mine/subject_id/question_type/difficult 组合。返回 items 附 import_source/batch_id/create_time。
🔴 subject_id 语义 = 前缀子树匹配:传章节/课时的 biz_subject 节点 id → 召回该节点下 整棵子树所有知识点的题(likeRight 前缀);传叶子 id → 只该叶子的题。非数字 id → BE 静默返空集。 🔴 私有 vs 公共两套口径:
|
| my_recent_uploadsA | 一键找回当前登录老师在最近时间窗内录的东西(题 / 卷 / 讲义片段)——DB 只读,不依赖 stem 关键词。 用途:老师刚用 MCP 录完一批题/组完卷/存完讲义,想快速核对「我刚才录进去了啥」。 参数: hours 时间窗(默认 24 小时;<1 视为 1)。 返回: {ok, hours, questions: {total, batches:[{batch_id, import_source, count, items:[{id, stem_head(30字/占位), import_source, batch_id, create_time}]}]} # 按录入批次分组,倒序 papers: [{id, name, question_count, create_time}] # biz_paper 同窗口本人建的卷 lecture_frags: [{id, title, create_time}] # biz_kg_lecture_frag 同窗口本人 owner 的片段 view_url} # 题库页深链,供浏览器核对 🔴 双管道语义:import_source 带 "mcp-" 前缀 = MCP 机录;'举一反三'=引擎落库;其余=手工/其他管道。 |
| get_questionA | 按 id 批量拉题目详情(🔴 装段前人工核对题面/答案/解析,避免盲装误人子弟)→ GET /teacher/question/list?ids=。返回 {ok, items}。 参数: ids : 题 id 列表(字符串雪花号,单次 ≤100);软删题 BE 自动过滤,返回按入参保序。 返回: {ok, items:[{id, stem_text, answer, analyze, question_type, difficult, subject_id, block_json/answer_block_json/analyze_block_json(三端结构化渲染源), stem_img, free_tags, patterns, question_knowledges(U 轨 kp), status, label_status}]}。 🔴 选项内容在 block_json 里(选择题),无独立 options 字段。 |
| get_role_manualA | 取角色说明书全文(协议内自带;另有 MCP resource teacher://manual/)。 role 分角色返回(缺省跟随本连接的 TEACHER_MCP_ROLE):
|
| health_checkA | 探活三依赖(ruoyi BE / toolkit / MySQL),任何异常算 down 不抛。返回 {ruoyi, toolkit, db}。
|
| convert_docA | Word(.docx / docx伪装的.doc)→ 结构化文本 + 题图清单。确定性 XML 解析(OMML→$LaTeX$),非 OCR。 产出文本里:数学公式=$LaTeX$;图=〖图:rId〗占位(与 images 的 rid 对应)。 下一步:文本喂 parse_paper_text 确定性拆题;images[].local_path 喂 upload_image 传 OSS。 参数: doc_path 卷子绝对路径;batch 批次名(图文件名前缀+文本落盘名,空=文件名主干)。 返回: {ok, text, paras, text_path, images:[{rid, local_path}]};真 OLE .doc → {ok:false, reason:"另存为 docx"}。 |
| convert_pdfA | PDF → 文字层检测 + 按页转图(多模态拆题的原料)。确定性 pymupdf,非 OCR。 🔴 拆题一律以页图多模态直读为准(H1a:文字层公式不可信);text_layer 仅辅助(题号定位/纯文字题)。 参数: pdf_path 绝对路径;batch 页图文件名前缀(空=文件名主干);dpi 渲染精度(170 实测够);max_pages 限页(0=全部)。 返回: {ok, page_count, has_text_layer, pages:[页图路径...], text_layer_path?}。 |
| parse_paper_textA | 规整卷面文本 → 题列表 JSON(确定性规则拆题,零 LLM)。适合 convert_doc 产物 / 规整粘贴文本。 拆题规则:题号「N、/N./N.」+ 章节头判题型 + 【来源】/【答案】/【解析】+ 多小问状态机 + 卷尾参考答案回填。 产出每题含 〖图:rId〗 占位(如有)。🔴 agent 拿到后须核对题数/补漏,再构造 IngestItem[] 喂 ingest_items; 位置序号(数组下标+1)= 入库 sort,别用 num(原卷题号遇杂散「N.」会错位——七上教训)。 参数: text 卷面文本(与 text_path 二选一,text 优先)。 返回: {ok, count, questions:[{num,type,stem,options,answer,analyze,has_fig,source,score}], digest}。 |
| format_questionA | 把自然 markdown 题干 + 选项数组确定性转成 blockJson(三端统一渲染格式)。底座永不抛、识别不了降级 markdown 块。 Claude 只产最小内容:markdown 题干(可含小问(1)(2)、图标记 |
| upload_imageA | 把本地磁盘图片直传 OSS + 去重,返回可塞进 blockJson 图块 / ingest_question.images 的 ossUrl。 参数: local_path 本地绝对路径;asset_kind 资产类型(figure 等)。 返回: {ok, asset_id, oss_url, dedup}。 |
| ingest_questionA | 录一道题入库(事务多表),归属当前登录 teacher。返回 {ok, question_id, created, import_source, batch_id}。 free_tags: 自由标签 → biz_free_tag 字典 + biz_question_free_tag 关联(三件套之一,检索锚)。 参数(NOT NULL=必填): subject_id : 科目锚 level1(年级根,如 数学七上 的根 id),NOT NULL question_type: 字典 biz_question_type 1选择/2判断/3应用/4填空/5解答/6作图/7计算/8证明,NOT NULL difficult : 1基础/2提升/3压轴,NOT NULL stem_text : 纯文本题干(全文检索 + 去重 hash),NOT NULL block_json : 来自 format_question 的 blockJson(三端渲染);空则只存 stem_text answer_text / analyze_text: 答案 / 解析文本 knowledge_ids: 锚知识点叶子 [{kpId, isPrimary, source, confidence}](KG 关联,供组卷/举一反三召回) images : 题图 [{ossUrl, assetId, role, ...}](来自 upload_image) external_key: 幂等键(book+节+课时+题号),去重;空则按 stem_text hash 去重 status : '0'草稿 / '1'发布(默认发布) import_source: 双管道来源标记;空则自动打 "mcp-<角色>"(MCP 机录,与手工/其他管道可区分) import_batch_id: 录入批次号;空则自动生成 mcp-YYYYMMDD-HHMMSS-4位随机 🔴 双管道语义:不带 "mcp-" 前缀的 import_source(main/手工导入/'举一反三'引擎…)= 其他/手工管道。 异常: 底座报错 → {ok:false, reason}(不假成功)。 |
| ingest_itemsA | 🔴 统一入库口(七类来源殊途同归):一次调用完成 题+图+知识点关系+打标字段+可选成卷,无需事后手补。 每题依次:图代传 OSS(local_path→ossUrl 并替换题面占位)→ blockJson 格式化 → 录题落库 (kp_id 走 knowledgeIds → 底座自动写 biz_question_knowledge + dim1_kp_id)→ 打标字段 (err/scenario/free_tags → biz_question_ai;why → difficulty_reason;models/new_models → 模型链,批尾串行)。 参数: items: IngestItem[](契约见 get_role_manual;未知字段拒绝,缺 stem 单条 fail 不中断批) subject_root: KG 教材根(数学七上="100";科学="901".."906")——无 kp_id 的题 subject_id 落此根 paper: 可选建卷 {name, category_id, total_score, suggest_time};null=散题不成卷 前置信息原样落库不被覆盖(AC3);同题干重复录入自动去重复用(AC4)。 🔴 双管道来源标记(PRD-O-005 溯源增强):本调用自动生成一个批次号,每题打 import_source="mcp-<角色>"(MCP 机录)+ import_batch_id=该批次号。录完记住返回的 batch_id, 日后 search_questions(batch_id=…) 或 my_recent_uploads() 一键找回。 不带 "mcp-" 前缀的 import_source(main/手工导入/'举一反三'引擎…)= 其他/手工管道。 返回: {ok, batch_id, results:[{num, question_id, created, reason?, warnings?}], paper_id?, stats:{ok,reused,fail,img}, view_url?}。 |
| verify_ingestA | 🔴 灌库后铁律验证:检查题干开头来源前缀残留(如「(真题·杭州滨江)」「(2025 浙江期末)」)。 ingest_items 已内置预防端自动剥前缀;本工具是验证端——每次灌完卷/批必须跑一次,residue_count 必须=0。 参数: paper_id(查整卷题)或 question_ids(查指定题),二选一。 返回: {ok, residue_count, residues:[{id, head}]};residue_count>0 = 清洗未过,逐题人工处置。 |
| label_questionA | 给一道已入库的题写 DNA 打标(难度 + 知识点锚 + 解法骨架 + 变式底料),归当前登录 teacher。 前置:题已 ingest_question 入库(有题干/答案/解析/配图)。Claude 先读题(多模态)+本章 KG 上下文判好,再调本工具落库。 参数(必填 = question_id, difficult;其余按题打满 / 基础题留空): question_id : biz_question.id difficult : ★难度 1基础/2中等/3较难/4压轴(按「难度评级」rubric 判档,非 LLM 自评) dim1_kp_id : 知识点锚叶子 id(同版本精确锚,如浙教七上根 100 下的叶子;不跨版本近似,对不上就留空+need_anchor_review=1) anchor_confidence: 锚定置信 0-1 need_anchor_review: 锚存疑待人审 1/0 dim5_structure: 图形/情境结构指纹 solution_skeleton: 解法骨架(步骤序列,【】标最难步)—— 撑变式①数值②结构算子 assessment_type: 考察类型 hard_points : 难点[](受控词表 biz_anno_ERROR:概念混淆/计算失误/审题偏差/隐含遗漏/分类不全/表达不规范/思路缺失) breakthrough_points: 突破点[](★1/★2 送分/常规题可空) tags : 检索标签 3-6(召回用) scenario : 场景(仅应用题;受控词表 biz_anno_SCENE:纯数学/现实生活/科学跨学科/数学文化) dna_type : DNA 类型 parametric_slots / modeling_frame / conditions / variation_profile: 变式底料(母题打满,普通题可简,应用题才有 modeling_frame) 返回: {ok, question_id, ai_id, difficult, dim1_kp_id};异常 → {ok:false, reason}。 |
| delete_questionsA | 🔴 安全删题(只能删散题)。confirm=False(默认)=dry_run 预览:返回 deletable/blocked 清单不动库; confirm=True 才真删——删前自动备份主行+正文 JSON(返回 backup_path),随删全部附属表行并写审计。 阻删闸(命中即拒删该 id):试卷/导入卷/书架书/教辅书/解题模型母题/活血缘母题/讲义引用。 单次上限 500;id 一律字符串传(雪花号截尾)。删除不可逆——真删前先 dry_run 给用户过目。 |
| convert_lecture_docxA | 讲义 docx → 忠实 Tiptap 内容 + KG 知识点靶子 + 图清单(确定性,零 login,零落库)。理解式映射的原料台。 🔴 崔崔版式实测=模块(H3)>分组(H3)>知识点(H4),纯确定性 H3 切片对不上 KG 知识点 → 默认 mode='assist': 工具只做忠实转换 + 按顶层 H3 分段 + 给出该课时 KG 知识点靶子,切成知识点由 agent 理解式映射 (读 raw_path 全文,按 kg_targets 重组讲解成片段 IR,习题模块的题走 ingest_items 拿 qid 后挂 kgExample)。 mode='auto':仅当来源 H3 已== KG 知识点名(已清洗源)才用——跑确定性 split_frags + 对齐闸,直接产 IR。 🔴 图不在此上传:content 里 image.src=〖图:rId〗占位 + rid;images[].local_path 喂 upload_image 拿 ossUrl, save_lecture_frag(image_map={rid:ossUrl}) 回填。忠实转换细节:heading/paragraph 留 bold/italic/color、 表 w:shd→背景色、单元格内图、图 EMU→px 内容区 clamp、EMF/WMF 矢量图无 local_path(浏览器不支持)。 参数: docx_path : 讲义 docx 绝对路径 course_subject_id : 课时 L4 subject_id(如 901001002001)——KG 知识点靶子来源 book_id : 教辅套 id(崔崔=CC7S) batch : 产物落盘名前缀(空=docx 文件名主干) mode : 'assist'(默认,理解式原料) | 'auto'(确定性 H3 切片,仅清洗源可用) | 'cuicui'(崔崔适配器) 返回(assist): {ok, mode, course, kg_targets:[{id,name}], sections:[{h3,node_count,preview,start,end}], images:[{rid,local_path}], raw_path, stats, deterministic_hint:{toc,unmatched_h3,frags}} ← 后者是 H3 切片试探,崔崔版必 FAIL 仅供参考。 返回(auto): {ok, mode, course, frag_count, frags, toc, unmatched_h3, images, ir_path, stats} |
| save_lecture_fragA | 片段 IR → :9090 upsert 入库(唯一入库口,UK=subjectId+bookId+owner 幂等覆盖)。需先 login。 图回填:image_map={rid:ossUrl} 把 content 里 〖图:rId〗占位换成 OSS 地址;无 ossUrl 的 image 节点会被剔除 并在 unresolved_images 里报告(不静默丢)。对齐闸:任何 UNMATCHED 片段默认拒绝入库(除非 allow_toc_fail)。 参数: ir_path : convert_lecture_docx 产出的 IR 文件路径(与 frags 二选一,优先) frags : 片段 IR 列表 [{subjectId,title,contentJson,status?}](与 ir_path 二选一) book_id : 教辅套 id(ir_path 里带则以其为准) image_map : {rId: ossUrl}(upload_image 的产物) owner : 归属 uid;省略=登录者(admin 登录省略即官方库覆盖) allow_toc_fail : True 才允许含未匹配 KG 的片段入库(BE 仍会因 subjectId 不存在而单条失败) 返回: BE saveFrags 响应 {ok, owner, results:[{subjectId,action}], stats} + {unresolved_images, view_url?}。 |
| remove_lecture_fragA | 删除某 owner 在某 subjectId 前缀下的讲义片段(覆盖录入的「先删」步;打 :9090)。需先 login。 🔴 前缀 LIKE 删除: |
| list_lecture_docsA | 查讲义目录(哪些课时/知识点有讲义片段,定位「据讲义出题」的锚点)→ :9090 GET /teacher/kg/lecture-catalog。返回 {ok, volume_id, lessons}。 参数: book_id : 教材/书 id(空=服务端默认书 DEFAULT_BOOK)。 返回: {ok, volume_id, lessons:[...]}(lessons 为课时×来源聚合,含各课时 subjectId/标题/ 有无片段/owner 等;结构随 BE getCatalog 演进)。库里无讲义资产时 lessons=[](空态非报错)。 |
| get_lecture_contentA | 读某知识点/课次的讲义正文(🔴 据讲义出题的原料入口)→ :9090 GET /teacher/kg/lecture?subjectId=。返回 {ok, subject_id, text, example_qids, ...}。 🔴 text = docJson(Tiptap)递归抽出的纯讲解正文;例题只是 kgExample(qid) 引用——正文里以 【例题 qid=...】 占位、真题面不在讲义片段里。要看例题题面 → 用返回的 example_qids 调 get_question(qids)。据 text 理解知识点讲法后,agent 自己出同源题。 参数: subject_id : 知识点/课次的 biz_subject id(get_plan_detail.kgNodeIds / resolve_kg 来)。 🔴 讲义按前缀树序汇聚:传课时节点会拿到其下片段拼成的整篇。 book_id : 教材/书 id(空=默认书)。 owner : 指定讲义作者 owner(字符串 userId);空=默认视图(我的>本部门管理员>官方兜底)。 返回: {ok, subject_id, node, book_id, owner, has_content, text, example_qids:[qid str]}。 🔴 has_content=False / text="" = 该知识点无讲义资产(空态,agent 应降级为凭 KG + 题库出题)。 |
| compose_paperA | 按大纲从真题库确定性组卷并真落库 biz_paper,归属当前登录 teacher。 参数: outline: [{subjectId, subjectName?, questionType, difficult, count}, ...] subjectId 取自 list_kg_tree 的叶子 id;编排层负责选点,本工具不二次解析意图。 title: 卷名(可选,默认"MCP组卷")。 lesson_id / slot_seq: 🔴 PRD-B-101 备课卷位绑定(可选,二者必须同现)——给了则本卷落 【备课卷】(paper_kind='2') 并绑到该课次卷位;只给一个 → 本地报错不发请求; 都省 = 普通卷(一切照旧)。🔴 备课卷私有,绝不 set-public。 返回: {ok, paper_id, item_count, paper, notes};底座不在/无匹配题 → {ok:false, reason}(不假成功)。 |
| create_paperA | 按指定题目 id 列表(顺序即试卷内题号顺序)组装成一套试卷入卷库,归属当前登录 teacher。 用于整卷录入:题目已 ingest_question 入库后,把它们按原卷题号顺序串成 biz_paper(建 section + biz_paper_question 关联)。 参数: name: 试卷名(如原卷标题),1-200 字符。 question_ids: 题目 id 列表,顺序 = 试卷内题号顺序,至少 1 题。 paper_category_id: 试卷分类 id(可选,卷库目录树;空=根级)。 lesson_id / slot_seq: 🔴 PRD-B-101 备课卷位绑定(可选,二者必须同现)——给了则本卷落 【备课卷】(paper_kind='2') 并绑到该课次卷位;只给一个 → 本地报错不发请求; 都省 = 普通卷。🔴 备课卷私有,绝不 set-public。 返回: {ok, paper_id, ...};异常 → {ok:false, reason}。 |
| update_paperA | 给试卷按**年级标准分(通值)**算每题分值 + 设建议时长,走 /update 落库。 分值规则(不抠原卷,按常规给):选择/判断=3分、填空=3分,大题类(应用/解答/作图/计算/证明)把剩余分铺满到 total_score(余数加在靠后的难题)。 参数: paper_id;total_score 总分(初中数学期末常规 120);suggest_time 建议时长(分钟,常规 120)。 返回: {ok, paper_id, total, per_question:[...]};异常 → {ok:false, reason}。 |
| bind_paper_slotA | 🔴 PRD-B-101 备课卷位绑定管理(绑既有卷 / 解绑 / 标记已备好)→ 备课线。返回 {ok, paper_slots, prep_state}。 备课主路 = 组卷时直接带 lesson_id+slot_seq 建卷即自动绑(create_paper/compose_paper); 本工具是事后管理:把已有卷挂到卷位(D7 兜底)、解绑、或手动标记整课次已备好。 🔴 备课卷私有,本工具不含任何公开化能力(绝不 set-public)。 参数: lesson_id : 课次 id(字符串雪花号)——必填。 slot_seq : 卷位序号(≥1)——action=bind/unbind 必填;action=manual_ready 忽略(课次级)。 action : 动作枚举—— 'bind' 绑既有卷到卷位(传 paper_id,必须真实存在且归我;BE 自动置该卷 paper_kind='2') 'unbind' 解绑卷位(卷留库不删;🔴 解绑会自动清该课次 manual_ready=false) 'manual_ready' 手动标记整课次备课态(传 ready;0 卷位课次 → BE 400) paper_id : action=bind 时必填(要挂的既有卷 id,字符串雪花号)。 ready : action=manual_ready 时的目标态(True=已备好,默认 True)。 返回: {ok, paper_slots:[...], prep_state:'0未备/1备课中/2已备好'};异常 → {ok:false, error}。 |
| create_teach_targetA | 建教学对象档案(学生或班级)→ :9090。返回 {ok, id}(id 为字符串雪花号)。 对象即「教谁」:一个学生或一个班课,后续排课/备课/回收全挂在它身上。 🔴 R1a 建模口径:年级/教材不再传文本,改传 gradeNo+gradeYear+字典码。 暑期录「升四」= grade_no:4, grade_year:2026(gradeYear=该年级生效学年的起始年, 当前年级由服务端按 9/1 学年进位推导)。 参数: target_type : 'student'(学生一对一)| 'class'(班课)——必填 name : 对象名(学生姓名 / 班级名) grade_no : 年级 1-12(字典 biz_edu_grade;1-6 小学 / 7-9 初中 / 10-12 高中) grade_year : grade_no 生效学年起始年(如 2026 = 2026-09-01 起学年) textbook_edition : 教材版本字典码(biz_edu_edition:'1'浙教/'2'人教/'3'北师大/'4'苏教) subject : 学科字典码(biz_edu_subject:'1'数学/'2'科学/'3'语文/'4'英语) (edition/subject 服务端兼容中文标签归一化,但请按码传) parent_phone : 家长手机号 profile : 肖像 dict(学生画像)——UI 四格 = traits/level.desc/level.target_layer/error_signals, 结构见契约 profile_json:{traits:[str], level:{desc,target_layer}, env:str, history:[{topic,status:'吃透|讲过未吃透',src}], error_signals:[{tag,evidence,session_id,ts,by:'system|teacher',status:'pending|confirmed'}]} color : 色板色(空则服务端从色板轮转分配) |
| list_teach_targetsA | 查我名下的教学对象卡片墙(含实时聚合:排课数/绑定计划进度/下一课/班课学员数)→ :9090。 建对象前查重、选排课对象都走它。返回 {ok, items}。 参数: target_type : 'student' | 'class',省略=两类都查 keyword : 名称模糊过滤 include_archived: True 才含已归档对象(默认只看在用的) |
| update_teach_targetA | 改教学对象档案(学生/班级信息修改)→ :9090。返回 {ok, id, updated:['basic'/'profile']}。 create_teach_target 只能建、建完改不了——本工具补上「改」:改名/年级/教材/学科/家长手机/色,或整体覆写肖像。 🔴 只改传入的字段:不传的保持原值(BE updateById NOT_NULL 跳空);基本维不动肖像,肖像走独立整覆写。 🔴 target_type 必传(BE 靠它选学生表/班级表);改肖像务必先 get_student_profile 取全量再整体回传(传 {} 会清空)。 参数: target_id : 对象 id(字符串雪花号)——必填 target_type : 'student' | 'class'——必填(决定改哪张表) name : 新对象名(不传=不改) grade_no : 年级 1-12(字典 biz_edu_grade) grade_year : grade_no 生效学年起始年(如 2026) textbook_edition : 教材版本码(biz_edu_edition:1浙教/2人教/3北师大/4苏教,兼容中文标签) subject : 学科码(biz_edu_subject:1数学/2科学/3语文/4英语,兼容中文标签) parent_phone : 家长手机号(仅学生) color : 日历着色 profile : 肖像 dict(整体覆写,非增量!结构见 create_teach_target 的 profile 说明)—— 改肖像典型流程 = get_student_profile 读回 → 本地改 → 整体传回 |
| archive_targetA | 归档 / 取消归档教学对象(学生·班级的「软删除」)→ :9090。 返回 {ok, id, archived, cancelled_sessions?}。 🔴 归档 = 本系统的「删学生」:对象移出排课选择器、历史保留(非硬删)。 归档会联动取消该对象未来未上的场次,cancelled_sessions 返回联动取消的场次数。 取消归档(archived=False)只解归档标记、不恢复已取消场次(复课需重新排课)。 参数: target_id : 对象 id(字符串雪花号) archived : True=归档(软删,默认)| False=取消归档(复用) |
| upsert_course_planA | 建/改课程计划 + 批量 upsert 课次(一步到位)→ :9090。返回 {ok, plan_id, lesson_ids, view_url}。 计划 = 一段周期(如一个暑假)的课次编排蓝本;排课时按 lesson_seq 顺序自动绑到场次上。 🔴 R1a·S1:计划有归属——新建必传 target_type + target_id(BE 强校验对象存在且归我,缺传 400)。 🔴 PRD-B-101 契约平移:课次内容模型 = 专项卷位 paper_slots(替代旧 seg_template『段模板』)。 一课次 = N 张专项卷,每卷位可绑一张卷。旧字段 seg_template / default_seg_template 收到即报错拒绝 (不静默兼容,防两套字段并存漂移)。 参数: plan : {id?, name, target_type:'student|class', target_id:str(归属对象 id,🔴 新建必传), term_tag:'暑假|上学期|寒假|下学期', year:int, material_note?:str(素材说明,如「学而思 36 周书·挑题制」), default_paper_slots?:list(默认专项卷位模板,lesson 空则继承), status?:'0草稿|1启用|2归档'} —— 带 id = 改计划基本维,空 id = 新建。🔴 无 total_lessons(=课次数实时聚合)。 lessons : 课次列表,每个 dict:{id?(空=新增), lesson_seq:int, title, lesson_type:'0教学|1测试', tag?(自由标签,吃透课走这), source_ref?(素材源,如「学而思第10+11周」), thinking_action?(思维动作), layer_target?(层数目标,如 '2→3'), parent_copy?(家长版口语文案), kg_node_ids?:[str](课内同步锚的 biz_subject id), paper_slots?:list(本课次专项卷位模板,覆盖计划默认): [{slot_seq:int, name:str(必填非空), style:str, rules:str, note:str}] (🔴 绑定字段 paper_id/manual_ready 由服务端管,agent 写入通常只给 slot_seq/name/style/rules/note)} |
| schedule_sessionsA | 批量排课(给某对象铺一串场次)→ :9090。返回 {ok, created, conflicts}。 auto_bind=True 时按 lesson_seq 顺序把未排课次自动绑到这批场次上(items 里也可显式 plan_lesson_id)。 🔴 冲突处理(契约 D6):命中冲突且 force=False → 一条不落、只回 conflicts 明细; 前端弹警告后可 force=True 强存(重发同一批)。冲突口径:老师撞场(create_by 同人时间重叠)/学生撞场。 参数: target_type : 'student' | 'class' target_id : 对象 id(字符串) items : [{date:'YYYY-MM-DD', start:'HH:MM', end:'HH:MM', plan_lesson_id?:str, session_type?:'1正课|2测试|3外部占位', external_title?:str(外部占位标题), note?:str}] plan_id : 绑定的计划 id(auto_bind 用它取课次顺序) auto_bind : 按 lesson_seq 顺序自动绑未排课次(默认 True) force : True = 无视冲突强存(默认 False,先探冲突) |
| list_scheduleA | 查某时间窗的月历场次(对象名/色、时间、课次标题、类型、备课态)→ :9090。返回 {ok, sessions}。 参数: start : 起始日期 'YYYY-MM-DD'(含) end : 结束日期 'YYYY-MM-DD'(含) target_id : 只看某对象的场次(省略=我名下全部) |
| update_sessionA | 改单场次(改期/请假/取消/标已上/锁内容/改绑课次/改备注)→ :9090。返回 {ok, deferred?, overflow?}。 参数: session_id : 场次 id(字符串) action : 动作枚举—— 'reschedule' 改期(传 date/start/end;🔴 改期=只改时间不改状态、不触发顺延) 'leave' 请假 → 🔴 触发顺延:该对象该计划、日期在其后的「已排」场次,绑定课次整体前移补位; lesson_locked='1' 的场次保持原课次被跳过;末位课次悬空 → overflow 提示需补排 'cancel' 取消 → 软取消:置 status='3',行留库(同样触发顺延,口径同 leave) 'delete' 🔴 移除课程 → 物理删除整行、不可恢复(区别于 cancel 软取消);仅本人场次可删 'mark_done' 标记已上(session_status→已上) 'lock' 锁定本场绑定的课次内容(顺延时被跳过、不改绑) 'unlock' 解锁 'rebind' 改绑课次(传 plan_lesson_id;只改本场,不动别的场次) 'note' 改备注(传 note) date/start/end : reschedule 用;plan_lesson_id : rebind 用;note : note 用 返回:leave/cancel 会带 deferred(顺延明细 [{sessionId,newLessonId}])+ overflow(悬空课次提示)。 |
| build_prep_packA | 🔴 DEPRECATED(PRD-B-101 已退役):备课不再走「装备课包」,改为按卷位组卷。 备课材料模型已从「一包 N 段」升维为「一课次 N 张专项卷位」:逐卷位
|
| render_prep_packA | 🔴 DEPRECATED(PRD-B-101 已退役):MCP 不再出 PDF。 备课卷 PDF 一律走组卷前端链路(平台「我的卷库·备课卷」导出),服务端简化渲染(纯 Java PDF)退役。
备课改为逐卷位 |
| submit_reviewA | 课后回收(录逐题对错)→ 生成家长反馈 + 肖像增量 → :9090。返回 {ok, parent_msg, portrait_delta}。 提交即标该场次「已上」。parent_msg 服务端模板拼装「家长您好!…思维题:/同步:/拓展奥数:」—— 🔴 R1b S5:parent_msg 即时生成不落库(提交/查详情时都按当时上下文现算,override 也过内部词防线); 🔴 内部词(层/★/素材/挑题/薄弱)一律不进家长文案。portrait_delta = 错/卡题按 cause 聚合出的 error_signals(by=system,status=pending,带 session_id 溯源),自动 append 进对象肖像。重复提交=覆盖+上一版进 prev_json。 参数: session_id : 场次 id item_results : 逐题结果 [{question_id?:str, seg:'段名', seq:int, result:'对|错|卡', cause:'计算|概念辨析|策略|其他'}] teacher_note : 老师备注(可选) parent_msg_override: 传入则用它替换模板文案(LLM 润色位,可选) |
| get_student_profileA | 取对象详情 + 肖像(含 error_signals 易错库)→ :9090。返回 {ok, target, profile}。 备课前读画像、看回收后新增的 pending 易错信号都走它。 参数: target_id : 对象 id(字符串) target_type : 'student'(默认)| 'class' |
| get_plan_detailA | 读某课程计划的全部课次明细(🔴 备课前读「这节课的编排蓝本」)→ :9090 GET /teacher/schedule/plan/{id}。返回 {ok, plan, lessons}。 当前链条最硬的读缺口:现有 upsert_course_plan 只写、list_schedule 只给场次概览,读不到 某课次的分段蓝本 / 课内锚点 → 圈题无依据。本工具补上。 参数: plan_id : 课程计划 id(字符串雪花号;list_schedule 的场次里带 plan_lesson_id 可回溯到 plan)。 返回: plan : {id, name, targetType, targetId, termTag, year, materialNote, defaultPaperSlots(计划默认专项卷位模板), status, createTime, updateTime, lessonCount} lessons : [{id, planId, lessonSeq, title, lessonType('0'教学/'1'测试), tag, sourceRef, thinkingAction, layerTarget(层数目标如 '2→3'), parentCopy(家长版文案,🔴 家长可见、 无内部词), kgNodeIds:[str](🔴 课内锚点,直接喂 search_questions(subject_id=)), paperSlots:[{slot_seq,name,style,rules,note,paper_id,manual_ready}](🔴 PRD-B-101 专项卷位蓝本: 每卷位对应一张专项卷;空卷位=待组,逐卷位走 compose_paper/create_paper(lesson_id,slot_seq)), paperSlotsInherited(true=继承自计划 default_paper_slots), prepState(备课态,服务端按 paper_slots 推导:'0'未备/'1'备课中/'2'已备好)}] |
| list_feedback_sheetsA | 列出当前老师名下的课后反馈单(owner 硬隔离)→ {ok, rows, total}。 rows=[{id,targetId,targetName,batchKey,lessonSeq,title,lessonDate,...}](新→旧)。 🔴 改单前先用它找回目标单的 id,别新建重复单;🔴 接力新课次前先用它看该生 最新批次已到第几节(batchKey+lessonSeq),新单 lesson_seq = 最大值 + 1。 参数: target_id(可选)/ keyword(标题模糊)/ batch_key(只看某批次,PRD-010)。 |
| get_feedback_sheetC | 读一张反馈单详情(含五列 rows)→ {ok, sheet}。参数 sheet_id 字符串传。 |
| upsert_feedback_sheetA | 建/改课后反馈单(归属当前登录老师)→ {ok, sheet_id}。 🔴 PRD-010 批次模型(用户工作流=批次累积一次性全发):一个学生一段课程 = 一个批次 (batch_key 如「多多五上暑假数学」,独立概念不绑课程计划),批次内课次 lesson_seq 依次递增。接力建新课次单时必须带 batch_key + lesson_seq(先 list_feedback_sheets 看该生最新批次到第几节,新单 = 最大 lesson_seq + 1;title 缺省口径 「{batch_key}第{N}节课上课内容」)。老师说"新开批次/新学期"才换新 batch_key 从 1 重计。 参数: target_id : 学生对象 id(字符串;先用 list_teach_targets 映射,严禁编造) title : 标题(🔴 家长可见,禁内部词) lesson_date: 上课日期 yyyy-MM-dd(可选) rows : 五列行数组 [{seq,module,content,mastery,weakness,kp_id?}] sheet_id : 传了=改这张(PUT),不传=新建 batch_key : 批次键(接力单必带) lesson_seq : 批次内课次号(接力单必带,>0 生效) 🔴 掌握情况写「熟练/基本掌握/待巩固」等家长话术。 |
| export_feedback_batch_pngA | 批次全量导出(PRD-010,🔴 发家长用这个不用单张):该学生一个批次 1~N 节全部 反馈单按课次拼一张长图 → {ok, batch_key, sheet_count, local_path, file_marker}。 batch_key 缺省 = 该生最新批次(新建课次后直接调它即可拿到含最新一节的全量图)。 🔴 导出后把 file_marker([[FILE:/tmp/fb_batch_*.png]])原样写进回复, 机器人据此把长图内联发回会话。 |
| export_feedback_pngA | 把单张反馈单导成家长版 PNG 并下载到本机 → {ok, local_path, file_marker, ...}。 🔴 发家长的常规场景请用 export_feedback_batch_png(批次全量长图,用户实发形态); 本工具只在明确要"单独看某一节"时用。 🔴 导出后必须把返回的 file_marker(形如 [[FILE:/tmp/fb_export_123.png]])原样写进 给用户的回复里(方括号内一字不改),飞书机器人据此把这张图内联发回会话。 参数 sheet_id 字符串传。 |
| compose_specialA | 跨多本书选料,一单建成一个"专项"(book_type='special')并批量挑题入区块。 专项 = word/教辅式文档(非试卷):结构 = 区块(sec) → 难度档(tier) → 题。挑题必在 区块框架下(secHint 指定落点,缺则新建)。跨书 = picks 里的题可来自不同源书, 专项只引用题库题 id,不动源书与题库(源书 item 数、题库 stem 全程不变)。 参数: title: 专项名(卷面可见,🔴 只写干净知识点名,绝不含内部词 层/素材/薄弱/★)。 picks: [{questionId?|nodeId?, secHint?, overrideJson?}, ...],逐条挑题。 grade / subject_id: 可选元信息。 返回: {ok, special_id, picked, secs:[{secId,name}], skipped};未登录/空 picks → {ok:false, reason}。 |
| export_specialA | 把专项导出成题目卷 / 答案卷双 PDF(苏俊宇卷版式,HTML→无头 Chrome→PDF)。 导出即对专项内每道 item used_count+1(认证计数=拿去上课的信号,不可逆软计数)。 🔴 卷面纪律:★ 仅 with_stars=True 显示(默认隐藏);【解析】仅 with_analysis=True 附带; 卷面绝不出现内部词(层/素材/薄弱)。 参数: special_id: 专项 id(字符串)。 papers: ['question','answer'] 任子集,缺省两卷都出。 with_analysis: 答案卷是否含解析(默认 True)。 with_stars: 是否显示难度星标(默认 False=隐藏)。 返回: {ok, special_id, question_url?, answer_url?, marked_count};空专项(无题) → {ok:false, reason}。 |
| bind_special_to_lessonA | 把专项绑到课次材料位(D4 持久绑定),或解绑,或查本课已绑材料。 🔴 只 UPDATE biz_course_plan_lesson.special_ids 单列——绝不整行 upsert(历史事故: 整行重写把 paper_slots 已绑 paper_id 抹掉)。BE 端 partial updateById 只写 special_ids。 参数: lesson_id: 课次 id(字符串)。 special_id: 专项 id(action=materials 时忽略)。 action: 'bind'(默认)/ 'unbind' / 'materials'(查本课已绑专项概要)。 返回: bind/unbind → {ok, lesson_id, special_ids:[...]}; materials → {ok, lesson_id, special_ids:[...], specials:[{id,title,itemCount}]}。 |
| list_calc_typesA | 计算题出题器·类型全表(覆盖人教版小学 1-6 年级计算谱系,46 类)。 每类一条 {code, name, grade(1-6), term(1上/2下)}:一年级 5以内加减/10以内/20以内进退位/ 两位数±一位数…,二年级 100以内/表内乘除/有余数除法…,三年级 三位数/乘除一位数/同分母分数/ 一位小数…,四年级 三位数乘两位数/四则混合/简算/小数加减…,五年级 小数乘除/解方程/异分母 分数/公因数公倍数/约分…,六年级 分数乘除混合/百分数互化/化简比/解比例。 返回: {ok, types:[{code,name,grade,term}]}。 |
| generate_calc_paperA | 一键生成计算题卷(确定性程序生成非 LLM)→ 题目卷 PDF(口算主场景不出答案卷)。 按 groups 逐组生成(每组一个类型一个多栏区块),约束内置:进退位可控、除法整除/ 有余数分型、分数自动约分/假分数化带分数、全卷跨组去重;题目卷带「姓名/用时/做对」栏。 参数: groups: [{type, count, label?, level?}],type 从 list_calc_types 查(严禁编造)。 title: 卷名(卷面可见,如"口算训练③(10分钟)")。 seed: 随机种子(任意字符串,同串复现同一份卷;空=随机)。 with_group_label: False 时不印组标(整卷混排风格)。🔴 组标卷面只印「一、二」 序号标识、绝不印练习内容名(学生自明,规范 2026-07-19)。 with_answer: True 才附带教师答案卷(🔴 口算卷默认不出,高年级分数/方程需核对时才开)。 fill_rows: 缺省 True = 每组题数向上凑整到栏数倍数(网格每行凑满,故实际题数可能 多于 count);要「填几题出几题」传 False。 返回: {ok, question_url, answer_url?, total, seed};未登录/未知类型 → {ok:false, reason}。 |
| generate_calc_itemsA | 只出计算题数据、不渲染 PDF —— 拿 {q,a} 塞进自有版面(每日一练等)。 与 generate_calc_paper 同一套生成器(确定性、跨组去重、难度档、seed 复现), 区别 = 不出 PDF、直接返回题面与答案,排版归 agent。 🔴 题目由程序生成,答案由生成器同步算出——不需要再人工/LLM 验算。 参数: groups: [{type, count, label?, level?}],type 从 list_calc_types 查(严禁编造); level=basic/advanced 出基础版/提高版(同考点不同难度,两版一次做完)。 seed: 随机种子(任意字符串,同串复现同一批题;空=随机)。 fill_rows: 🔴 缺省 False = 要几题给几题(自排版场景不该被静默改数量); True 才向上凑整到栏数倍数。 返回: {ok, total, seed, groups:[{label, cols, mode, items:[{q,a}]}]}。 |
| render_shuzimi_figureA | 数字谜竖式图生成器:按结构化 puzzles 确定性画竖式 PNG('?'=待填□方框),可直传 OSS。 🔴 结构规范:puzzles=1~4 个竖式横向并排,每个 {label?, rows:[{op,cells}...]}; cells 一字符一格(数字/汉字均可),'?'=□;op=+ - × ÷ 或空;op="HR"=横线行。 例(6□37+3□□=7183):rows=[{"op":"","cells":"6?37"},{"op":"+","cells":"3??"}, {"op":"HR"},{"op":"","cells":"7183"}]。 参数: upload=True 则直传 OSS(需先 login),False 只落本地;out_name 自定义文件名(可空)。 返回: {ok, local_path, width, height, oss_url?, asset_id?}。 产物用法: oss_url 塞 blockJson 图块(biz_question_block)或 ingest_question.images; 答案版把 '?' 换成实际字符再调一次。 |
| upsert_punch_dayA | 把「第 N 天」整天内容灌进打卡书(幂等:同 book+day 重调 = 覆盖,不重复建节点)。 天节点名由 BE 按 day 生成,goals 落节点 meta_json.goals(今日目标条,简短口径, 🔴 学生/家长可见 → 禁内部词:层/★/素材/薄弱/挑题)。modules 原样透传给 BE。 参数: book_id : 打卡书 id(🔴 字符串;list_books(book_type='daily_punch') 查,严禁编造) day : 第几天(1 起正整数;同一 day 重灌 = 整天覆盖,agent 侧批量修正走这条路) goals : 今日目标 ["乘法连续进位","小数退位减","年、月、日"](简短短语,非整句) modules : 模块数组,按卷面顺序排;两类结构 —— ① 计算模块(出题器现产,题目不在题库 → 内容随书存 content_json): {"type":"oral|vertical|stepwise", "title":"口算题", "items":[{"q":"357+276=","a":"633"}, ...]} type 三型 = oral 口算 / vertical 竖式 / stepwise 脱式;q 题面、a 答案成对给全 (答案缺失 = 解析卷开天窗)。题目由 generate_calc_items 产,无需再人工验算。 ② 轮换位(教辅真题,题在题库 → 引用不复制): {"type":"rotating", "title":"解决问题", "qids":["2077057695340310530", ...]} 🔴 qids = 题目 id 的字符串数组(雪花号,search_questions / 生成器给的原样字符串); 🔴 绝不传题面文本——题面由 BE 按 biz_question_block.block_json 渲染, 改题库即改打卡书,零漂移(D5/D11)。传文本 = 制造第二个半源,必被打回。 返回: {ok, node_id(str), item_ids:[str]};未登录/参数不合法/BE 报错 → {ok:false, reason}。 |
| list_punch_daysA | 列一本打卡书的全部天(目录 + 审核态)→ {ok, days:[{day,node_id,item_count,review}]}。 review = {status:"pending|passed|issue", issueCount}(审核页目录角标 ○/✓/⚠N 的数据源)。 🔴 重灌某天前先用它看该天是否已存在、审核到哪一步(已 passed 的天重灌会把审核态打回)。 参数 book_id 字符串传。 |
| get_punch_dayA | 读回「第 N 天」完整内容 → {ok, goals, modules, review}(展示页/生成器回读共用)。 modules 结构与 upsert_punch_day 入参同构:计算模块带 items:[{q,a}]; 🔴 返回与 upsert 入参同构(round-trip 语义):轮换位返 {type:'rotating',title,qids}—— 不含题面(改字回读→upsert 直接可用);要渲染态题面走 BE /teacher/punch/preview (blocks 由 BE 现取 block_json 组装,agent 无需自行拉题)。 review = {status, issues:[{module,seq,kind,note,resolved}]}。 🔴 局部改一天内容 = 先 get 拿全量 → 改 → 整天 upsert_punch_day 回灌(覆盖语义)。 参数: book_id 字符串;day 第几天(1 起)。 |
| submit_punch_reviewA | 提交「第 N 天」人眼审核结论(审核流主闭环)→ {ok, review}。 action 三态: pass 本天通过(🔴 全书每一天都 pass 后,BE 自动置书级审定标记——书由此可挂 SKU 上架) issue 本天记问题(必带 issues;天角标转 ⚠N,进全书问题清单) reopen 销账后重开审核(问题已修复重灌 → 打回 pending 再审一遍) 参数: book_id: 打卡书 id(字符串) day : 第几天(1 起) action : "pass" | "issue" | "reopen"(其余值直接拒,不猜) issues : action=issue 时必带 —— [{module, seq, kind, note}] module = 模块 type(oral/vertical/stepwise/rotating) seq = 模块内题号(1 起) kind = "难度不符" | "题面有误" | "排版" | "其他" note = 问题描述(一句话说清改什么,供重产/重灌时对账) 🔴 大改(换题/调难度)= 记问题 → 重产 → upsert_punch_day 重灌 → reopen 重审; 打卡页对题库题只读,改题库题走题目详情页修改态(D10/D11),不在本工具面内。 |
| create_bookA | 新建一本空书(起步)。book_type 开放注册制(BE 不校验,任意 snake_case slug 可传): 已注册值 = lecture讲义 / workbook练习册 / textbook电子课本 / special备课挑题专项(不进书架列表) / variant_special举一反三专项(SOP-2 立项即建) / daily_punch每日打卡。 新资料形态(口算集训、错题重练…)自定新 slug 即可,🔴 但须先到 认知/服务与能力总目录.md「书类型注册表」挂号 + book-ui BOOK_TYPE_LABEL 补中文名,否则前端显示裸 slug。 返回 {ok, book_id(str)};随后用 add_book_node + add_book_item 建目录树与内容, 或整树一次建书走 import(B 线录入直出书交接面,本工具面不含 import)。 |
| list_booksA | 我的书列表(owner 归属自动过滤 + type/subject/status 可选筛选)。 返回 {ok, books:[{id,bookType,title,subjectId,grade,nodeCount,questionCount,itemCount,...}]}。 统计字段(nodeCount/questionCount/itemCount)供书架卡片 'N 节 · M 题' 展示。 |
| get_book_structureC | 书结构整树(目录树 + 各节点内容项,一次返回可渲染)。 返回 {ok, book, tree:[{id,name,nodeType,kpId?,items:[{id,kind,questionId?,override?,explain?}],children:[...]}]}。 override 优先于题库原题面渲染;kind=explain 走 explain.title/text。 |
| add_book_nodeA | 给书加一个目录节点。node_type 自由值(chapter章/lecture讲/qtype_group题型组/tier难度档/sec区块…)。 parent_id 省 = 根层节点;kp_id 可选(KG 锚,仅标签,与树结构解耦 D8)。 节点名 name 卷面可见——🔴 禁内部词(层/★/素材/薄弱),只写干净知识点名。 返回 {ok, node_id(str)}。 |
| add_book_itemA | 给节点加一个内容项。kind=question 题引用(传 question_id)/ explain 讲解块(传 explain_*)。 🔴 question_id 一律 str(雪花号 JSON number 会截尾)。讲解块内容书自持(D2,不引用 KG 讲义层)。 返回 {ok, item_id(str)}。 |
| bind_book_node_to_lessonA | 把书籍章节(书架书目录节点)绑到课次材料位,或解绑,或查本课已绑书章节。 备课态口径(2026-07-15 扩展):「有专项或有书章节=已备好」——绑上任一书章节, 课次即显已备好(与 bind_special_to_lesson 同为材料位,两者并集推导)。 🔴 只 UPDATE biz_course_plan_lesson.book_node_ids 单列——绝不整行 upsert(历史事故: 整行重写把 paper_slots 已绑 paper_id 抹掉)。BE 端 partial updateById 只写 book_node_ids。 参数: lesson_id: 课次 id(字符串)。 node_id: 书章节节点 id(biz_shelf_node.id,字符串;action=materials 时忽略)。 action: 'bind'(默认)/ 'unbind' / 'materials'(查本课已绑书章节概要)。 返回: bind/unbind → {ok, lesson_id, book_node_ids:[...]}; materials → {ok, lesson_id, book_node_ids:[...], materials:[{nodeId,nodeTitle,bookId,bookTitle,questionCount}]}。 |
| override_itemA | 书内改一道题的题面(D3 override 副本):只影响本书,题库原子题不动。 override.stem/options 写入 item.override_json;question_id 溯源保留(血缘不断)。 还原原题 = 传空 override({})即清。含数学 <> 不会被 XSS 剥。 返回 {ok}。 |
| make_variantsA | 举一反三·母题轮:读图解题打标 → 出母题卡(LLM 轮 ~60s)。图驱动 + D8 渲图旁路。 入参三选一(image_url > stem_text > question_id 优先级):
|
| confirm_variant_chapterA | 确认母题所属章节(need_confirm 分支续跑)→ 回填锚点重锚(~3s)。 参数: thread_id(make_variants 返回);chapter_id(从 kg_candidates 挑的真实章节 id,字符串)。 返回: {ok, thread_id, status:"ready", mother_card}。之后调 generate_variants。 |
| generate_variantsA | 触发变式生成(start_variants 续跑,LLM 轮 ~70s)→ 取题组。 参数: thread_id : make_variants/confirm 后的会话 id。 auto_verify: True=生成后每题自动 sympy 验算;False(默认,产品口径)=每题 tier=pending, 按需 verify_variant。透传 agent_config.auto_verify。 返回: {ok, thread_id, count, variants:[{item_id, seq, stem, answer, solution, qtype, difficulty, tier, verify_status, figure_spec, dna, question_id}]}。 🔴 生成偶发首轮空题组(opus 对压轴母题首轮不收尾)——本工具按 AC4「重试≤2」自动再触发一次 start_variants(实测第二次即出题);两次仍空 → ok:false + 引擎回文,交驱动 agent 处置。 |
| verify_variantA | 对某道变式独立验算(无状态 sympy 重算,~17s)→ 判决。persist 前须逐题过(说明书铁律)。 参数: thread_id;item_id(generate_variants 返回的变式 id,= seq,字符串)。 返回: {ok, item_id, verdict:"pass"|"fail"|"degrade", reason, computed}。 pass=标答自洽 / fail=标答错(computed=真算值) / degrade=sympy 吃不下转人工(非判错)。 |
| edit_variantA | 手动编辑某道变式(零 LLM,只 patch 传入字段)→ 标手动编辑态。 参数: thread_id;item_id(= seq,字符串); patch: {stem?, answer?, analyze?}(analyze 映射 toolkit 的 solution 字段;None 键不改)。 返回: {ok, item_id, item}(编辑后该题快照)。改后建议重跑 verify_variant。 |
| compose_variant_figureA | 为某道变式造图(~12s)→ 中性 JSXGraph DSL(bbox+objects),客户端 GeoEngine 渲活图。 参数: thread_id;item_id(= seq,字符串); dsl: 传入=覆盖重绘(把该 DSL 作修正依据令引擎照此重画;不传=从题面/figure_spec 现推)。 返回: {ok, item_id, needs_figure, figure_spec}(figure_spec=JSXGraph DSL:{bbox, objects[]}); 造图降级 → {ok:false, needs_figure:true, reason}。 |
| persist_variantsA | 把变式落库拿真实 qid(owner=登录老师)。🔴 落库前须逐题 verify_variant(说明书铁律)。 参数: thread_id;item_ids: 只落指定几题(item_id/seq 字符串列表);缺省=全部入库。 返回: {ok, results:[{item_id, question_id:str}], view_url}(题库页深链,老师视觉验收入口)。 |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| _manual_data | |
| _manual_prep | |
| _manual_variant | |
| _manual_all |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/RuntimeAll/teacher-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server