Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
DATABASE_URLNoPostgres connection string. Optional — without it the server boots in inspection mode (LS_INSPECT): full handshake and tool listing, DB-backed calls return a clean structured error.

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

CapabilityDetails
tools
{}
prompts
{}
resources
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
create_pairA

建立一段新的 learner-agent 关系 (pair) —— 真入学的唯一正门 (get_context 报 No active pair 时走这里, 流程见 recipe://bootstrap 的"无 pair 分支": 先说明、知情同意对话、再建对)。⚠️ 名字主权红线: learner_display_name 必须与学习者本人在首跑页亲手登记的名字逐字一致——名字是学习者的主权动作, agent 代填代猜即越权; 学习者还没登记时本工具会拒绝, 此时引导她去首跑页亲手输入自己的名字, 不要替她填。agent 三件套 (provider/model/display_name) 由你自报——一千个不同的好老师, 系统不推断你的身份。守卫: 该学习者已有 active pair 时拒绝重复建对, 回执指路既有关系。成功后 pair 即为"当前关系" (真 pair 永远优先于 demo 样板间), 下一步读 recipe://learner-orientation 上开学第一课, 顺势谈第一份契约。

propose_contractA

立约前先读 skill intake/contract-establish(prompt _stack 可见全栈)——goal 一句话不足以立好约, 挖掘对话产出 timeline/baseline/cadence 后再填单. 立约对话谈完后, 把 TeachingContract 草案递交给 LS, 状态为等待学习者签字 (setup_status: proposed). 只写 Class A (goal 必答/time_range/success_criteria) + Class B (intensity/interaction_mode/content_modality/pace/weekly_capacity_hours/preferred_time_of_day) — Class C (提醒渠道偏好: push/ical/email 等) 不收, 那是学习者在签字台表单里自己定的. cadence(节奏条款, Contract 2.0)例外: 若立约对话里谈过"定时 or 碎片化学习", 在这里一并写下——它决定的是"存不存在固定节奏约定"这件事本身, 不是 Class C 的渠道细节, 谈过就该带着签字台走, 不用学习者自己再填一遍. source_material(自带教材条款)同理: 学习者带自己的书来学时, 把谈定的教材条款(书名+依赖档位+版本年份)一并记进合同, 见该参数的形状说明. 学习者点开 /contract 页看到草案卡片, 可以拧 Class B/cadence 旋钮再签, 也可以直接 Establish.

update_contract_cadenceA

只改一份已签合同的 cadence(节奏条款), 不动其他任何条款、不必重签. 节奏条款随时可改, 改约成本必须低于立约——这是它存在的意义. 形状同 propose_contract 的 cadence: {mode:"scheduled"|"fragmented", slots?:[{weekday:0-6(0=周日), time:"HH:MM"(24h), tz:string}], reminders:"native"|"none", auto_duty:boolean(涉及学习者额度消耗, 必须明示询问, 默认 false), weekly_review_nudge?:boolean, prep_rhythm?:"per_lesson"|"batch"(备课节奏——per_lesson 随学而备/推荐默认, batch 一次备齐; 见 skill intake/contract-establish 的语义说明)}. 完整替换, 不是逐字段合并——改 prep_rhythm 而漏带其他既有键(如 slots)会把它们清空, 调用前先读现有 cadence 再整体重写. teaching_contracts 没有 revision/history 表(version 列是历史遗留, 从未被真实写路径 bump 过)——留痕方式: 本工具自动在写入的 cadence 里盖一个 updated_at(ISO 时间戳, 不是调用者字段), 同时同步 bump 合同自身的 updated_at 列. 提醒本身仍不由 LS 发出——只是改了"存的约定"。

void_contractA

作废合约前,必须把作废理由原文展示给学习者,并取得学习者亲口的同意答复;learner_consent 填学习者的原话。未经同意调用属违纪。 作废不是删除——合约行原样保留,只是标记作废(active=false, voided_at=now(), void_reason=你传入的 reason)并从此退出"当前合约"选择(get_context/pickSkillStack/pair://contract/active 等一切现读, 见 lib/currentContract.ts)。幂等:对已作废的合约重复调用,原样返回其作废状态,不报错、不二次写入、不覆盖原 void_reason。

update_contract_coverageA

修改一份合约的 covered_course_ids 覆盖单(这份合约名下实际教过的课程清单, 不是许可范围声明) —— {add_course_ids?, remove_course_ids?} 至少传一个非空数组。去重(加了两遍/加了已存在的不报错), 并校验每个 course_id 存在且属于同一个 pair(不属于/不存在直接拒绝, 不静默忽略)。已结业的合约(completed_at 非空)拒改——结业是终态, 覆盖单在那一刻定格, 想续教开新合约。

complete_contractA

把一份合约收作结业 (State 2.0 文书三幕剧: 立约 → 履约 → 结业, 迁移 0030) —— completed_at/completion_note 是与 established(签约)/voided(作废)并列的第三种终态, 不是覆盖关系。completion_note 是结业词——给这段学习旅程的证词, 认真写, 不是流程按钮上敷衍一句"完成了"。前置校验, 任一条不满足即结构化拒绝并附差额: ① 合约现役(经 lib/currentContract 判定路径——未签/已作废/已过终态一律拒绝); ② covered_course_ids 非空(先 update_contract_coverage 或建课时带 contract_id 把教过的课挂上); ③ 覆盖单里每门课须 goal_completion_ready (见 get_context 的 contract_progress) —— 全部已发布课 learning 状态 ∈ {completed_declared, closed} (未发布的课不计入), 且课程定过 planned_lesson_count 并已发布节数够数——没定过计划节数的课不再放行。不满足则回执附结构化差额, 分两种: 缺 planned_lesson_count (missing_planned_count) 或已发布节数不足计划 (below_planned_count), 外加"哪门课还差几节未读完"的清单, 不是一句"没教完"。幂等: 已结业的合约重复调用原样返回既有结业词, 不报错、不二次写入。

create_courseA

新建一个 course. 零材料启动新主题时用——不需要挂靠已有 course. 可选 contract_id: 建课即履约——有现役合约时应携带, 建课成功后新课 id 会自动并入该合约的 covered_course_ids(等价紧接着调一次 update_contract_coverage, 这里省一刀)。contract_id 必须现役 (经 lib/currentContract 判定路径)且属于同一 pair, 否则拒绝建课(不留孤儿关联)。建课时问学习者的第一问——"一共几节"——落 planned_lesson_count(可选, 正整数)。定了它, complete_contract/get_context 的结业判定会多一道门槛: 已发布节数须够这个数才算课程完成; 留空(null)则 goal_completion_ready 恒为 false, 结业永不放行, 且事后无补录入口。

add_lessonA

为指定 course 添加一节 lesson. agent 备课时用. 脑图种子为可选教具, 默认不生成、例外才有 (2026-07-21 定): 仅当空间/因果/分支结构确实比文字更清楚时才配 (判断权归老师), 不为教具齐整而出图. 想留"为什么不配"的教学法笔记可写 modality_declarations.mindmap (纯可选, 不写不罚).

update_lessonA

修订已有 lesson (revision pass 回写). 旧版全文快照入 lesson_revisions 后应用 patch, revision += 1. 必须带 revision_reason; 没有理由的修订直接拒绝. modality_declarations.mindmap 同 add_lesson (纯可选笔记; 脑图默认不生成, 留空不罚). revision_kind (迁移 0033, 双轨修订): 问自己——这次改动是她教出来的, 还是机器逼出来的? 前者 teaching (会呈现给学习者并触发回看提醒), 后者 technical (留痕但对她隐身)。缺省 teaching——发布后的修订默认面向学习者, 宁可多呈现不可偷藏.

add_lesson_patchA

给一节课打老师注或勘误补丁 (§4 改课三律): 三律边界 — 未开始的课直接用 update_lesson 整改, 不要打补丁; 学习中的课 (学习者还没宣布已学完) 只许 kind=teacher_note (追加, 不抽换正文, 标注来源"基于你第X课的作业, 此处补一句"); 已学完的课 (学习者已宣布) 只许 kind=erratum (原文保留, 补丁并列, 永不重写课文本身)。判断学习中/已学完请先查这节课的 lesson_progress 状态 (GET /pairs/:pairId/lessons/:lessonId/progress)。

close_lesson_loopA

把一节课的教学闭环收口: 写回执 (§5, 逐条列出本轮动了哪里) + 把这节课的 lesson_progress 置为 closed (§6 "已回课"终态, 由批改完成+回执送达触发, 不可逆——已 closed 的课再调用本工具会报错)。一次判决原则: 关课不产生新判决——判决齐不齐由 closure_progress 核对。receipt 现在是可选的 (2026-07-26): 它曾是"给学习者的 changelog", 但学习者侧的回执渲染卡已于 2026-07-22 退役 (行项退役案 — 行项是记账动词, 对学习者零价值; 已回课由课页的 已回课 徽标传达), 这份 changelog 现在没有读者, 不再强制老师写。想留档就照旧传, 每条 description 指认"动了哪里", 不重新评讲、不复述判决内容; 传了就仍然按老规矩验 (ref_id 悬空照拒)。注意: 本课若有已完成的 Live 课, 闸门 ④ 仍然要求一条引用其 snapshot/场评 的回执 —— 那种课上不传 receipt 是关不掉的。receipt 的每条 kind 必须落在封闭枚举内 (七种, 没有第八种): exercise_feedback(指认某份提交已批改, ref_id 指 submission——评语和分数的判决本体在 grade_exercise 记录上, 此处不复述评语、不重新打分) / forward_revision(前方课修订) / teacher_note(学习中的课的老师注) / erratum(已学完的课的勘误补丁) / flashcard_change(闪卡增删) / hypothesis_update(假设修订) / journal_entry(journal条目)。枚举外的 kind 一律打回——这是"不许发明新黑箱"的机器化, 不要绕过。 空转防护: 关课服务端强制四检——① 本课有已提交未批改的作业则拒关(先 grade_exercise 还债); ② 关课须带认知更新(post_lesson_evaluation 或指向真实假设的 hypothesis_update 回执), 皆无则须传 no_cognitive_update_reason; ③ 每条 ref_id 必须指向真实记录(悬空 ref 拒关); ④ 本课有已完成 Live 课则 回执须有一条 kind=journal_entry 引用其 snapshot。回执自带闭环进度——不用另查状态机。

get_lesson_closure_stateA

关课前先调我——顺序、缺口、下一步和 id 都替你串好,不用脑内记账。只读, 复用 close_lesson_loop 同一份事实装配 (lib/lesson-closure-facts.ts), 不改动任何状态。返回 { lesson_id, state, completed[], missing[], next_required_action, incorrect_review_signal }。state 是"首个缺口的语义名"(graded/live_completed/live_evidence/live_evaluation/post_lesson_evaluation/reflection 之一), 或 ready_to_close(万事俱备只差调 close_lesson_loop), 或 closed(已关课, 终态)。读法警示: state 点名的是"当前卡在哪一项"——它指的是还欠着的待办, 不是已达成的成就, 所以 state=graded 时 missing[] 里同时出现 graded 是同一句话说了两遍, 不是矛盾; 已完成的项只看 completed[]。live_completed/live_evidence/live_evaluation 三项只在本课挂过 Live 时出现。next_required_action 是 {tool, pre_filled_refs} —— 能预填的 id (submission_id/session_id/live_session_id/lesson_id) 已经替你摘出来了, closed 时为 null。incorrect_review_signal (错题卡事实行) 是纯陈述, 不进 missing[], 不带 severity: {incorrect_submission_count, concepts_with_flashcard, concepts_total} —— 本课判错提交数, 以及这些判错习题涉及的概念里已经挂了闪卡的比例, 读读即可, 不是缺口, 不阻塞关课。

publish_lessonA

把一节课上架给学习者 (Publish Gate)。add_lesson 建的课默认草稿态 (published_at 留空, 仅教师/MCP 侧可见); publish_lesson 服务端直接跑验尺 (与 verify_prep 同一套 validate-prep 判定): 存在 ❌ (FAIL 级) → 拒绝上架并返回红灯清单, 红灯不清零不许翻牌; PASS / PASS_WITH_WARNINGS → 写 published_at, 课进学习者书架 (黄灯过目制归人工, 不阻断)。

add_documentA

上架一份新文档 (Markdown) 供学习者阅读/划线/生成闪卡, 不挂靠任何 course/lesson. title 缺省时按 frontmatter title → 首个 H1 → 首行截断 自动派生 (brief §2). source 固定为 mcp.

update_documentA

更新已有文档的标题和/或正文 (报告修订版). 正文变化时自动重新普查这份文档的全部划线 — 失联的进孤儿区, 绝不静默删行 (金缮条款, brief §3 item 3).

add_conceptA

为 lesson 添加一个 concept. course_id 自动取 lesson 所属的 course, 不需要单独传. 新 concept 会自动登记进 lesson.concept_ids, 不需要(也不应该)再手动补写.

update_conceptB

修订已有 concept 的字段 (name / short_definition / source_refs / flashcard_ids).

add_flashcardB

添加一张闪卡; FSRS state 由 server 初始化.

update_flashcardA

修订已有闪卡的内容字段 (front / back / deck_id) — 纯 patch 语义, 只改给出的字段, 不建 revision 快照 (同 update_concept 先例)。编辑卡面不影响复习计划: FSRS 调度状态 (fsrs_state 的 due_at/stability/difficulty/review_count 等) 与 paused 原样保留, 改内容不清进度、不重置排期。只能改当前 pair 的卡, 其他 pair (或不存在) 的卡一律 NOT_FOUND。验尺/复盘抓到卡面问题后走这里修, 不必删卡重建 (重建才会丢调度进度)。

add_mindmap_seedA

为 lesson 或 course 挂一张 agent 出的思维导图 seed (root+branch+detail 基础框架). 一次调用完成建图 + 写关联 — 等价于 REST POST /mindmaps 接 POST /mindmaps/:id/associations 两步的合并版, 省得 agent 备课时绕 REST. 字段合同: 节点七字段 {id,title,level,pos_x,pos_y,is_expanded,sort_order} + 非 root 必带 parent_id, level ∈ root/branch/detail/note; links 只画跨分支联想, 禁止把父子关系抄进 links. 结构: root 1 个 → branch 3-4 个且各自说得出主张 → 每支 detail 2-4 个, 禁止连续独子成链, 禁止辐条伞(root 对每项发一根辐条, 与课文列表同构). 布局: pos_x/pos_y 落在 x 8-92 / y 12-95 内, root 天窗位 (50,8), 同级节点 y 差 ≥14, note 标题 ≤12 字. 完整教程: docs/recipes/mindmap-authoring.md(bench 考生看 candidate-kit/recipes/ 同名文件).

update_mindmap_seedA

修复/迭代你自己播种的课程脑图, 拓扑不再一锤定音. 只对 source=agent 的图开放 (学习者自己长出来的图不许 agent 动, 会打 PERMISSION); content 走与 add_mindmap_seed 一致的全套校验(字段合同见 add_mindmap_seed 说明, 完整教程 docs/recipes/mindmap-authoring.md). 写入会同时同步 content 与 agent_seed_snapshot 两列 — 有过案底: 只改 content 会让 Clear & redo(从 agent_seed_snapshot 复原)诈尸出你改之前的旧方言图, 这里两列一起写, 新内容即是新种子, 免疫诈尸.

add_exerciseC

为 lesson 添加课后习题.

add_simulated_quizA

为指定 course 添加一份模拟卷 (SimulatedQuiz, round 3 Quiz 通电). 与 REST POST /pairs/:pairId/simulated-quizzes 1:1 镜像 — course_id 必须存在, questions 非空; single_choice/multi_choice 题必须带 choices 且 reference_answer 的每一项都在 choices 里 (multi_choice 用逗号分隔编码多个正确项). 开放题 (short_answer/essay, 或省略 question_type) 不判分, 留给学习者自评 reference_answer.

verify_prepA

备课收尾必调: 交付前跑一遍, 清掉每一条 ❌, ⚠️ 逐条过目。检查跨件一致性(课文格式/闪卡/习题引用/脑图拓扑/概念覆盖)——写入门禁看单发, 本工具看全家福。只读, 零写库。lesson_id / course_id 二选一必填(都传或都不传 → code: VALIDATION)。传 lesson_id 返回单课报告(status PASS/PASS_WITH_WARNINGS/FAIL); 传 course_id 按 lessons.order 顺序逐课校验, 给 course 级三档汇总 (lesson_count/overall_status/lessons[])。id 不存在或 course 下无 lesson → code: NOT_FOUND。默认紧凑报告: status + errors/warnings 逐条原文 + check_counts {pass, skip} 计数; verbose:true 取全表 (checks 逐条含 pass/skip 项, 与旧版逐字同形)。等价于 npx tsx scripts/validate-prep.ts <id> --json 的 MCP 化版本(同一份判定实现, CLI 恒为全表)。

grade_exerciseA

批改一条 ExerciseSubmission. agent 异步收到 pair://exercises/pending 后调用. 判错递笔: score 给了且落进判错区间时, 回执带 concept_refs (这道题已解出的概念 id, 白拿, 不用你再走一遍 exercise→concept) + human_note 一句顺手提示——配不配张针对性闪卡纯属你裁量, 不进 next_recommended_actions, 不是义务。重批持证: 已 graded 的提交要改判, 必须显式带 regrade: true——缺省会被 CONFLICT 拒绝。改判自由, 痕迹免费: 放行时旧判决摘要 (previous_score/previous_feedback) 自动写进追加的 exercise.graded 事件 payload, 历史不蒸发。

record_post_lesson_evaluationA

写一条 PostLessonEvaluation (纯事实层, 每节课末尾都写, 不打 confidence 标签). 一次判决原则: 总评做增量, 不复判——agent_observation 只装三样内容: ①整体判断 ②与 Live 表现的对照 ③下一课建议。永不逐题复述习题: 习题的判决在 grade_exercise 记录上, 不把评语再写一遍——要指向具体作业, 把 id 填进 evidence_refs, 正文保持人话。3-课阈值规则见 TEACHING-SPEC §4.3. 空评估拒收: concepts_touched / flashcards_reviewed_count / flashcards_rating_distribution / exercises_submitted_count / live_turns_count / duration_minutes / agent_observation 至少一项非默认值——全默认(空数组+全 0+空字符串) 会污染 learner brief, 直接拒收。(pair_id, lesson_id) 唯一索引(迁移 0030): 一课一份总评——第二次对同一课调用本工具是修订, 服务端 update-in-place(不插新行), 回执里会说明这是 update 而不是新建。回执自带闭环进度——不用另查状态机。

record_live_evaluationA

写一条 LiveSessionEvaluation (现场评估, 挂在单场 live_session 上, 不是课级总评——那是 record_post_lesson_evaluation). 一次判决原则: 收课的正门是 live_session_complete 携可选 evaluation 一笔写完 (收课+场评一次动作)——本工具是收课时漏带场评的补写通道, 不是第二次判决的机会. 前置: live_session 存在且 status=completed(先 live_session_complete 收课, 再写现场评估). 一场一评(live_session_id 唯一索引)——撞了就幂等返回已有那条, 不二次写入、不覆盖。agent_observation 必填非空——短判词, 不复述课堂过程; 要锚到具体对话条目, id 填 evidence_refs, 本段保持人话 (学习者会在折叠区读到它)。回执自带闭环进度(该场挂课时)——不用另查状态机。

record_learner_hypothesisA

写一条 LearnerHypothesis (3 课之后才允许首次写, agent 自己 enforce). 若 domain 命中学习者的观察禁区登记簿, 直接不写入 (不报错, 返回说明). 禁令 (Confidence 主权立法): 关于学习者 confidence 水平/校准好坏的推断——"她的把握度偏低" "她高估/低估自己" 这类判词——不得作为 hypothesis 记录。那是当次反思(reflect_on_teaching)才配装的东西, 不是可教状态, 不许经这个工具进 learner_hypotheses/学生画像的前馈通道。 生命周期扩展 (同一支笔的续写面): 带 hypothesis_id + action 时不再创建, 而是对既有假设做 reinforce(证据续期: last_evidence_at 推到当下, 可附 evidence_event_ids 追加)/revise(新文本超越: 旧行转 expired 留痕, 新行承接在场状态与证据账, 回执给 superseded_hypothesis_id)/retire(老师判旧转 expired, 与学习者 reject 分属两支)。主权层级: confirmed/rejected/frozen 是学习者判决——rejected/frozen 三动作全拒, confirmed 只许 reinforce。没有证据喂养的假设在简报里会读作 stale (纯提示, 不自动退役)——有证据就 reinforce, 被推翻就 revise/retire, 别让账本长灰。

reflect_on_teachingA

写一份 TeacherReflection (每节课末尾, 第 3 课起开始升级). §1-§5: 归因骨架已收紧——必须站队一个主归因、给证据、给反事实、挂一个类型匹配的 action_link;weather(⑥天气)必须带 weather_expires_at 且禁止触发任何学习者画像写入,过期即焚。呈现全静默:返回值只捎带一行近 20 次主归因计数,不进任何 UI。 反思挂锚: lesson_id/live_session_id 可选, 但推荐至少挂 lesson_id —— 反思挂在课上, 下一任老师才能按课读回"这节课到底反思过没有", 而不是靠 pair 级近似猜。两者若填写, server 会校验存在性 + 与当前 pair 一致(lesson 经 courses.pair_id, live_session 经 live_sessions.pair_id), 不属于本 pair 的 id 直接拒写。 挂锚推断: lesson_id 不填时 server 会从现场上下文强推断——依次看 live_session_id 指向的场次的课 / 当前唯一 active 的 Live 教室 / 24h 内最近一场 Live 课; 推断命中会替你挂上并在回执明示来源(created_refs.anchored_lesson_id + human_note), 推不出则落无主反思并在回执警告: 无主反思不计入任何课的 closure(closure_progress.reflection 会一直显示缺)。回执自带闭环进度(带 lesson 锚时, 显式或推断皆算)——不用另查状态机。

record_learner_feedbackA

现场反馈笔: 学习者在日常消息里提出关于产品或教学的 issue/idea 时, 用这支笔落账——反馈没有专用 UI 入口, 她的每一个普通输入框都是入口, 识别是你的义务。逐字纪律: text 存她的原话, 不是你的转述——转述是二次判决, 原话才是证据。挂锚 (lesson_id/live_session_id/exercise_id 可选): 填了就必须真实, server 校验存在性 + 属于当前 pair; source_message_ref 是自由文本引用 (live 消息可能活在 bridge 事件流里), 只存不校验。落账必回执: 记录成功后, 你必须在同一回合向学习者回一句确认——她要知道她的话被记下了, 静默落账等于没落账。软牙齿: open 反馈只在 get_teacher_inbox 发光提醒, 永不阻塞 close_lesson_loop。观察边界(禁区)变更也走这支笔 (Settings 观察禁区 UI 已撤下, 边界协商回到第一序对话)——学习者在对话里谈"不要再观察/记录某类"或"撤回某个边界"时, 用 boundary_update 参数带上; 绝不能凭对话印象私自认定/静默生效, 不填 boundary_update 就不改变任何边界。

update_feedback_statusA

推进一条学习者反馈的生命周期: open → acknowledged → addressed/declined。addressed/declined 是终态, 不可再改。declined 必须带 note——拒绝欠判词, 拒绝的理由保护接受的价值; acknowledged/addressed 的 note 可选。软牙齿: 不推进状态不拦任何闸门 (close_lesson_loop 不看这张表), 但 open 反馈会一直在 get_teacher_inbox 里发光。

get_contextA

一发式冷启动定位: session 醒来先调这个, 拿到"现在这个 pair 处在哪"的紧凑快照, 而不是自己拼 live_pending + snapshot + thread 好几刀. 输入 { pair_id? } (缺省用当前 active pair). 返回: active_contracts (id/title/setup_status/一行 progress/source_material——合约带自带教材条款时的一行亮灯"教材:《书名》·档位"; null=没谈教材) + recent_lessons (最近 1-2 节课的 id/title/status, 来自最近的 PostLessonEvaluation, 没有活动记录时退回 course 前两节) + pending_pool ({count, latest_titles} 脑图待整理池, 不含全量) + live_session (最近一次 id/status/ended_at + 最新 snapshot 的存在性+时间戳, 不含全文) + unread_adhoc_count (最近一次 agent 回复之后学生新发的 adhoc 消息数) + active_reminder_count (未 fire 且未 dismiss 的提醒数). Etag 契约: 返回体带 brief_etag (默认口径 learner brief 的内容指纹) —— 与上次记住的 brief_etag 一致 ⇒ 学生模型没变, 跳过 get_learner_brief 重拉; identity 只给 learner_id/agent_id, 称谓全量在 get_learner_brief。pair_id 不存在时报错并附可用 pair 列表.

get_learner_briefA

开课前先调这个: 读回学生模型 (learner_hypotheses / post_lesson_evaluations / teacher_reflections), 不用自己扒表。输入 { pair_id?, limit? } (limit 默认 5, clamp [1,20]; pair_id 缺省用当前 active pair)。返回: top_confidence_hypotheses (在场假设按 confidence 降序取 top-limit) + needs_reverification (在场假设里 last_verified_at 最老/为空的前 2 条, 该复验了) + recent_evaluations (最近 3 条 PostLessonEvaluation 摘要, 含 agent_observation) + latest_reflection (最近一条 TeacherReflection 的 method/next_action) + confidence_facts (近三课把握度中性事实聚合: lesson_ids + total_count + overall_accuracy + by_level[{level,count,accuracy}], 纯数字词频——没有形容词、没有"她低估/高估自己"这类判词, 也没有百分比锚值; 没数据时为 null) + source_material (自带教材条款一行亮灯: 当前合约带 source_material 时给"教材:《书名》·档位", 档位语义/外延标记纪律见 skill workflow/lesson-prep 教材模式; null=当前合约没谈教材)。学生主权红线: allowed_for_teaching=false 的假设一律不吐 observation/domain/confidence 等内容, 只回 {id, allowed_for_teaching:false, redacted:true} —— 冻结的假设不该被这个读回口子悄悄泄回教学决策。Etag 契约: 返回体带 brief_etag (内容指纹, generated_at 不计入) —— 与上次同参数调用一致 ⇒ 学生模型没变, 可复用上次已读内容不必重读。pair_id 不存在时报错并附可用 pair 列表. 可选 lesson_id — 传了且这节课有挂锚反思(teacher_reflections.lesson_id 命中)时, latest_reflection 优先给这节课的那条; 没有挂锚数据时退回原有的 pair 级最新一条。

get_teacher_inboxA

增量教师待办清单 (Agent Surface Hardening 第一批, P1) — 醒来先看这个而不是自己拼 live_pending + submissions + adhoc 好几刀. 输入 { pair_id?, since? } (since 缺省=全量, ISO 时间戳游标——服务端不维护游标状态, 消费方自己记住 max(occurred_at) 下次传回). 来源: 待批改 submission / 无 reflection 的已结束 live session / 学习者新 adhoc 消息 / 近 24h 同一张卡 ≥3 次 Again / proposed 未签合同. 每项 { item_id(确定性), type, priority, resource_refs, recommended_tool, occurred_at }, 按 priority (high→low) 排序, 同优先级按 occurred_at 升序. 无待办返回空数组. 另附 open_feedback 段 (现场反馈笔): status=open 的学习者反馈 count + 最近若干条摘要 (kind/原话节选/挂锚/账龄)——纯发光提醒, 软牙齿: 不阻塞任何闭环动作, 回应它用 update_feedback_status.

get_lessonA

读回一节课: 标题 / 结构 (概念+习题清单) / 发布状态 (published: published_at 非空=已发布, 空=草稿) / 正文。默认紧凑 (include_content 缺省 false): 只给结构与元数据 + content_chars 全文字数 + 开头节选, 不吐全文 — token 经济。要读全文 (批改前审教材 / resume-teaching 冷启动接课) 显式传 include_content: true, 返回体多一个 content_markdown 字段 (可能很长, 确认要再开)。只能读当前 pair 的课, 其他 pair (或不存在) 的 lesson_id 一律 NOT_FOUND。

get_exerciseA

读回一道习题: prompt / reference_answer / expected_concepts / tags / 所属 lesson (lesson_id + lesson_title + course_id)。批改前先审教材用这个取题面与评分标准。reference_answer 是评分钥匙 (教师侧机密) — 不要原样透给学习者。只能读当前 pair 的题, 其他 pair (或不存在) 的 exercise_id 一律 NOT_FOUND。

get_submissionA

读回一份学习者提交: learner_answer 答案正文 / status 批改状态 (枚举 draft | submitted | pending_grade | graded) / agent_score / agent_feedback / 把握度 (confidence, 可空) / 所属 exercise 链 (exercise_id + exercise_prompt_excerpt + lesson_id + course_id)。批改与复盘的读回面 — 配合 get_exercise 取 reference_answer 后再 grade_exercise。只能读当前 pair 的提交, 其他 pair (或不存在) 的 submission_id 一律 NOT_FOUND。

live_pendingA

这不是值更工具 —— 值更请挂 live_wait 或后台看门脚本 scripts/live-watch.py, 反复空手调用这个属违纪(值更契约红线)。live_pending 只做一件事: 拍一张 Live Teaching pending queue 的快照 (bridge 状态 + 按优先级排序的 sessions, ad_hoc_question > ad_hoc_response > session_start > guided_response), 不阻塞、不等待。没传 pair_id 时用当前 active pair. 牙齿: 同一 pair 在 90s 内连续 6 次空手调用 (queue 里什么都没有) 会在回执里附结构化警告字段, 连续 12 次直接拒答该次查询——真有 pending 数据的调用永远正常返回并重置计数, 牙齿不吞真实数据。值更契约 v3(方法自由): 看门脚本 scripts/live-watch.py 与 live_wait 阻塞调用是平级合法路径, 你家 harness 有更好的监听机制也行——考核只看红线加四条目标, 见 recipe://live-teaching。每个 live_teaching item 带 pending_reason (session_start / learner_response_waiting / agent_owes_move): agent_owes_move 类只在 pending 快照出现, 不走 wait 事件流——欠的 move 是你的债, 不是学习者的事件。

live_heartbeatA

Agent 端 keep-alive. 在 ttl_seconds 内 bridge 算 online. ⚠️ ttl_seconds 是在线判定窗口, NOT 轮询间隔. 值更契约 v3: 等待不烧模型回合(红线: 禁止模型层轮询), 用看门脚本/live_wait/你家自己的监听机制均可, 见 recipe://live-teaching. 看门脚本会替你打心跳; 走 live_wait 的, 它自带 auto-heartbeat. 回应契约(单层 v3): 实质回答质量优先, 不设硬秒数, 在场感由在线灯负责不由报文. (旧 context_status 参数已退役——上下文余量指示灯已整体拆除, 心跳只管在线.)

live_waitA

一次调用 ≈50 秒静默等待, 数据即到即返, 超时重挂即可 —— 这是等待, 不是轮询。阻塞等待下一个 Live Teaching / AdHoc 事件 (与 GET /bridge/wait 共用同一份等待逻辑, lib/live-wait.ts) —— MCP 原生的零空转值更: 比反复调用 live_pending 省 token, 不用自己算轮询间隔。timeout_s 上限 50 (留出 MCP 客户端自身超时的余量), 缺省即用上限. 超时未等到事件 → timeout=true, events=[], 直接再挂一次即可, 不必先调 live_pending 探路。每次调用顺手续一次 heartbeat (ttl 60), 等待期间在线灯不灭。可选 consumer_id: 传了就走服务端 持久化 delivery cursor (断点续传) —— 同一 consumer_id 下次调用不传 since 就自动从上次的断点继续, 传 since 则视为"上一批我已处理完"的确认并推进游标; 不传 consumer_id 时行为与旧版一致(每次都从此刻起等)。契约版本协议: 每个响应都带 contract_version, 把它作为 known_contract_version 传回, 命中现行版时超时/事件响应都不再重发 live_runtime_contract 全文 (只留 contract_version + may_end_turn), 缺省或版本过期则完整合约照发。值更契约 v3(方法自由): 本工具与后台看门脚本 scripts/live-watch.py 是平级合法路径, 你家 harness 有 自己的监听原语也行——考核只看红线加四条目标, 见 recipe://live-teaching。

live_session_getA

读 LiveSession 全貌 (session + 全部 moves + 全部 responses). 决定下一步前必读.

live_message_sendA

追加一条 Teaching Move (Live Teaching 结构化教学). 会话第一条 move (seq=1) 必须 move_type="FRAME"——否则结构化拒绝, 不接受其他类型开场. FRAME content 须覆盖三要素: 本场做什么/多久/怎么算完. ASK/PROBE/CHALLENGE 必须 response_kind="text". REFLECT 必须 "none". content 控制在 300 中文字以内 (EXPLAIN). 一个 move 只做一件事. 自由对话/答疑请用 adhoc_message_send.

live_snapshot_writeA

在 Live Teaching session 中段 flush 一个 rolling checkpoint. 建议每 3 轮写一次. compact 后用 live_snapshot_get_latest 拿回来, 不用重读全部 moves.

live_snapshot_get_latestA

读 session 最近一份 mid-lesson snapshot. compact 恢复时第一步: snapshot + 之后的 moves = 续上 session 的最小集.

adhoc_thread_getA

Get-or-create 这个 pair 的长存 AdHoc thread. 默认用当前 pair. 值更循环里带上你已读到的最后一条 id 只取增量 (after_message_id) —— 全量回读烧的是学习者的钱(值更契约·低损耗);全量仍合法:首次上任/断档补课时用 (不传 after_message_id 即全量, 缺省行为不变).

adhoc_ackA

消账 —— 学习者明说不必回、或你判断该消息无需回应时调用: 它从 pending (live_pending / GET /bridge/pending)、桥事件 (live_wait / GET /bridge/wait) 与 teacher inbox 里退场, 但消息本身仍保留, 可随时用 adhoc_thread_get 读回. 缺省 message_id 时消账到该 thread 当前最新一条. 幂等: 重复 ack 同一条不报错. 滥用即失职: 拿 ack 逃避该回的问题, 学习者看得见.

adhoc_message_sendA

Agent 在 AdHoc thread 里回应用户. 自由对话不限 move_type. 富内容用 payload (component_type: interactive_html | whiteboard_svg | tts_audio + body). 学习相关写 is_learning_related=true 会落 SessionEvent.

live_session_completeA

收课——Live 收尾的一次写作动作 (一次判决原则). REFLECT 三段全部必填, 缺任一即拒收: summary (她这节课学了什么——短判词, 不复述课堂过程) / teacher_reflection (薄弱环节, 直白不吹捧) / next_action (下次课的钩子, 具体到下一步该练什么). 这三段学习者会在课文页直接读到——写成给她看的人话, 内部 id (tr_/evt_/snap_ 等) 一律不进正文; 要给判词锚证据, 填 evaluation.evidence_refs (那才是机器引用通道, 服务端验 id 存在与同 pair 归属)。id 只有一个归宿: evidence_refs (2026-07-26 口径收窄——agent_observation 已在学习者折叠区可见, 不再是纯内账, 故原"写内账或 evidence_refs"的二选一作废)。 可选 evaluation 随行——同一次调用把这场的现场评估一并落库 (等价于紧接着调 record_live_evaluation, 一场一评, 已有场评时不覆盖), 收课+场评从此是一次动作, 不必分两笔写两段长文. status → completed, awaiting_role → none, ended_at 只在首次完成时打. 幂等: session 已是 completed 时重复调用不再改 session, 原样回执 "已于 <首次 ended_at> 完成, 本次为幂等重放, 未改动", ended_at 保留首次值 (带 evaluation 且该场还没有场评时, 场评仍会补写). 收课握手: 调用前确认——学习者最后一题已单独判过 (对错+点评自成回合), 且她已明确表态收课; 顶着未判的消息、或没等她点头就 complete, 违反 live-teaching 红线. 下课铃机器门禁: 本场必须已有学习者收课宣告 (learner_close_declared_at, 她在 Live 房内亲手按的下课铃)——未宣告时本工具 CONFLICT 拒收官; 若她已口头表示结束, 请引导其按下 Live 房内的下课铃后再收官 (铃响会追加 live.learner_close_declared 事件, live_wait/live_pending 都看得见). cancel 不受此门 (取消≠收官).

live_session_cancelA

中止 session (learner 提前结束或 system 超时). idempotent.

live_session_startA

开一场新的 Live session —— 学习者裁决 (2026-07-20): 学习者侧 web 的 Start Session 按钮已退役, 开课正门收窄到这里, 老师(agent)侧主动开课。context_type 默认 "lesson"。同课已有 active 教室时不开新场,直接送你进既有会话(joined_existing)。

Prompts

Interactive templates invoked by user choice

NameDescription
_stackComposite skill stack picked by server based on the currently active TeachingContract. Pull this once at session start to get the full system-prompt prefix (domain + modality + intensity + pace).
workflow/lesson-prepTeaching skill (workflow): lesson-prep — from <learn-shell>/skills/workflow/lesson-prep.md
domain/teach-cfaTeaching skill (domain): teach-cfa — from <learn-shell>/skills/domain/teach-cfa.md
domain/teach-generalTeaching skill (domain): teach-general — from <learn-shell>/skills/domain/teach-general.md
domain/teach-languageTeaching skill (domain): teach-language — from <learn-shell>/skills/domain/teach-language.md
modality/analogy-firstTeaching skill (modality): analogy-first — from <learn-shell>/skills/modality/analogy-first.md
modality/example-firstTeaching skill (modality): example-first — from <learn-shell>/skills/modality/example-first.md
modality/fable-firstTeaching skill (modality): fable-first — from <learn-shell>/skills/modality/fable-first.md
modality/formula-firstTeaching skill (modality): formula-first — from <learn-shell>/skills/modality/formula-first.md
modality/socraticTeaching skill (modality): socratic — from <learn-shell>/skills/modality/socratic.md
modality/visual-heavyTeaching skill (modality): visual-heavy — from <learn-shell>/skills/modality/visual-heavy.md
intensity/hardcoreTeaching skill (intensity): hardcore — from <learn-shell>/skills/intensity/hardcore.md
intensity/relaxedTeaching skill (intensity): relaxed — from <learn-shell>/skills/intensity/relaxed.md
intensity/standardTeaching skill (intensity): standard — from <learn-shell>/skills/intensity/standard.md
tone/directTeaching skill (tone): direct — from <learn-shell>/skills/tone/direct.md
tone/encouragingTeaching skill (tone): encouraging — from <learn-shell>/skills/tone/encouraging.md
tone/neutralTeaching skill (tone): neutral — from <learn-shell>/skills/tone/neutral.md
tone/playfulTeaching skill (tone): playful — from <learn-shell>/skills/tone/playful.md
pace/evening-deepTeaching skill (pace): evening-deep — from <learn-shell>/skills/pace/evening-deep.md
pace/lunch-quickTeaching skill (pace): lunch-quick — from <learn-shell>/skills/pace/lunch-quick.md
pace/morning-burstTeaching skill (pace): morning-burst — from <learn-shell>/skills/pace/morning-burst.md
intake/contract-establishTeaching skill (intake): contract-establish — from <learn-shell>/skills/intake/contract-establish.md
verify/attribution-disciplineTeaching skill (verify): attribution-discipline — from <learn-shell>/skills/verify/attribution-discipline.md
verify/content-verifyTeaching skill (verify): content-verify — from <learn-shell>/skills/verify/content-verify.md

Resources

Contextual data attached and managed by the client

NameDescription
Active TeachingContract当前生效的教学契约 (goal, intensity, interaction_mode, scopes, etc)
Learner profile学生身份 + 偏好
All courses for this pair
Flashcards currently due (FSRS)
ExerciseSubmissions awaiting agent grading (status=submitted/pending_grade)Confidence 主权立法: 每条 submission 带 confidence(序数: guess/likely/certain), 不带 confidence_pct(百分比是学习者建模层的数值, 已在服务端剔除, 不进教师读路径)。
Learner hypotheses (teacher memory)
Teacher reflections
Recipe: bootstrapdocs/recipes/bootstrap.md
Recipe: close-teaching-loopdocs/recipes/close-teaching-loop.md
Recipe: close-teaching-loop.referencedocs/recipes/close-teaching-loop.reference.md
Recipe: first-contract-and-lessondocs/recipes/first-contract-and-lesson.md
Recipe: first-contract-and-lesson.referencedocs/recipes/first-contract-and-lesson.reference.md
Recipe: grade-attribute-revisedocs/recipes/grade-attribute-revise.md
Recipe: grade-attribute-revise.referencedocs/recipes/grade-attribute-revise.reference.md
Recipe: learner-orientationdocs/recipes/learner-orientation.md
Recipe: live-teachingdocs/recipes/live-teaching.md
Recipe: live-teaching.referencedocs/recipes/live-teaching.reference.md
Recipe: mindmap-authoringdocs/recipes/mindmap-authoring.md
Recipe: resume-teachingdocs/recipes/resume-teaching.md
Recipe: resume-teaching.referencedocs/recipes/resume-teaching.reference.md
Capability manifest机器可读的完整能力菜单 — tools/resources/prompts/recipes + 关键规范指引一次拿到。陌生 agent 冷启动第一发读这个, 不用翻 README 撞报错拼地图。

Latest Blog Posts

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/sf-shenfeng/learn-shell'

If you have feedback or need assistance with the MCP directory API, please join our Discord server