Справочник инструментов#

Агент разговаривает с платформой инструментами MCP. Наборов два, и живут они на разных адресах: ученический — <адрес сервиса>/mcp, кураторский — <адрес сервиса>/authoring. Токен у них один и тот же; что человеку доступно, решают роли во Frappe, а не выбор адреса.

Инструменты вызывает агент, а не вы. Поэтому в каждом разделе есть пример просьбы обычными словами — вызов агент подберёт сам.

Раздел устроен одинаково: назначение, параметры, что приходит в ответ и отказы, которые возвращает именно этот метод. Общие правила отказов — в конце страницы.

Обзор#

Инструменты ученика — их получает агент, который ведёт занятие.

Инструмент Назначение
artifact прочитать документы курса ученика — перечень или один целиком
complete_lesson закрыть урок, у которого нет обязательной проверки знаний
course_outline программа курса с отметками пройденного
enroll записать ученика на курс из каталога
forget удалить заметку об ученике по ключу
get_my_progress сводка по ученику: курсы, просрочки, последние занятия
list_catalog курсы, на которые ученик может записаться сам
list_my_courses курсы ученика с прогрессом и дедлайнами
my_notes показать ученику, что о нём запомнено
org_report отчёт по обучению своей организации (для руководителя)
remember запомнить об ученике то, что пригодится дальше
report_checkpoint отметить пройденное по ходу занятия
report_issue сообщить авторам курса, что мешает учиться
report_outcomes отчитаться о покрытии целей урока
request_quiz начать проверку знаний и получить первый вопрос
start_lesson начать занятие или продолжить его следующей частью
student_detail подробности по одному сотруднику (для руководителя)
submit_answer отправить ответ ученика и получить вердикт
update_artifact записать блок документа курса
whoami под какой учётной записью вошёл ученик

Инструменты куратора — ими агент собирает курс.

Инструмент Назначение
add_chapter добавить главу в конец курса
add_lesson добавить урок в конец главы
add_question добавить вопрос в существующий квиз
add_quiz создать квиз урока со всеми вопросами сразу
authoring_guide порядок сборки и ограничения платформы одним текстом
course_draft курс целиком с верными ответами и готовностью к публикации
create_course завести черновик курса
get_lesson прочитать урок целиком: материал, директива, квиз
list_courses курсы платформы и их идентификаторы
move_lesson перенести урок в другую главу или на другое место
publish_course открыть курс ученикам
remove_chapter удалить пустую главу
remove_lesson удалить урок, по которому ещё не занимались
remove_question убрать вопрос из квиза
reorder_chapters задать порядок глав полным списком
reorder_lessons задать порядок уроков главы полным списком
set_course_artifact задать документ, который ученик собирает по ходу курса
set_course_directive задать сквозные указания агенту на все занятия курса
set_directive задать указания агенту на один урок
unpublish_course убрать курс из каталога
update_chapter поправить название главы
update_course поправить название и описания курса
update_lesson поправить название или материал урока
update_question поправить текст вопроса, варианты или образцы ответа

Инструменты ученика#

Этот набор получает агент, подключённый к ученическому адресу /mcp. Он же работает в веб-чате платформы: маршрут занятия там тот же, и различает каналы сама платформа, а не набор инструментов.

Здесь же лежат два инструмента отчётности — org_report и student_detail. Их видит всякий подключившийся, и это осознанно: данные закрыты правами, у не-руководителя отчёт пуст.

Идентификаторы курсов, уроков и занятий агент между сессиями не помнит. Он берёт их из ответов: курс — из списка курсов, урок — из программы курса, занятие и попытку — из ответа на начало занятия и на запрос проверки знаний.

artifact#

Показывает агенту документы, которые ученик собирает по ходу курса, — список или один документ целиком.

Параметры

  • course — идентификатор курса. Обязательный.
  • artifact — ключ документа (например project_summary). Необязательный; без него приходит перечень.

В ответе. Без ключа — перечень документов курса: ключ, название, раскладка, сколько блоков всего и сколько заполнено. С ключом — блоки в порядке схемы: заполненные с текстом ученика, пустые с подсказкой автора, которая адресована агенту.

Отказы

  • not_enrolled — ученик не зачислен на курс; курс ему открывать нечем.
  • organization_suspended — организация ученика приостановлена; зачисление цело, доступ вернётся вместе со статусом.
  • artifact_not_found — в курсе нет документа с таким ключом; посмотрите перечень вызовом без ключа.

Пример просьбы. Ученик: «покажи, что у нас уже записано в резюме проекта».

complete_lesson#

Закрывает урок там, где проверять нечего: у урока нет квиза или он не обязателен по политике организации.

Параметры

  • session — идентификатор занятия из ответа start_lesson. Обязательный.

В ответе. Идентификатор урока, статус занятия и следующий урок курса.

Отказы

  • not_your_session — занятие принадлежит другому ученику.
  • session_closed (с полем status) — занятие уже закрыто или брошено; возвращаться к уроку нужно через start_lesson, он заведёт новое занятие.
  • outcomes_required — не сдан отчёт по целям урока; сначала report_outcomes.
  • quiz_required — у урока обязательная проверка знаний. Закрыть его можно только сдачей: этот инструмент не обход проверки, и зачёт ставит сервер.

Пример просьбы. Ученик: «всё понятно, давай закроем урок».

course_outline#

Показывает программу курса целиком — главы, уроки и что из них пройдено.

Это единственный способ узнать идентификатор уже пройденного урока: start_lesson без аргумента ведёт только вперёд.

Параметры

  • course — идентификатор курса. Обязательный.

В ответе. Курс и его главы; в каждой — уроки с названием, признаком completed и отметкой текущего.

Отказы

  • not_enrolled — ученик не зачислен на курс.
  • organization_suspended — организация ученика приостановлена.

Пример просьбы. Ученик: «а что мы проходили в начале курса? хочу вернуться к главе про циклы».

enroll#

Записывает ученика на курс из каталога.

Параметры

  • course — идентификатор курса из list_catalog. Обязательный.

В ответе. Курс, его название и первый урок — занятие можно начинать сразу, отдельный вызов списка курсов не нужен.

Отказы

  • course_not_published — курс ещё черновик.
  • already_enrolled — ученик уже записан; курс есть в list_my_courses.
  • course_not_allowed — курс не открыт ни одной организации ученика.

Пример просьбы. Ученик: «запиши меня на курс про переговоры».

forget#

Удаляет заметку об ученике по ключу.

Параметры

  • key — ключ заметки, например role или pace. Обязательный.
  • course — идентификатор курса для наблюдения, записанного при курсе. Необязательный; без него ищется заметка-факт.

В ответе. Удалённый ключ.

Отказы

  • note_not_found — заметки с таким ключом нет. Проверьте ключ по my_notes: наблюдение ищется вместе с курсом, факт — без него.

Пример просьбы. Ученик: «забудь, что я работаю в рознице, — я сменил работу».

get_my_progress#

Даёт сводку по ученику: сколько курсов, что просрочено, чем он занимался в последнее время.

Параметры. Нет.

В ответе. Число курсов и число просроченных; по каждому курсу — дедлайн, признак просрочки и доля пройденного; последние занятия со статусом и датой начала.

Отказы. Своих нет — только общие.

Пример просьбы. Ученик: «как у меня дела с обучением, много ли осталось?»

list_catalog#

Показывает курсы, на которые ученик может записаться сам.

Показывает только доступное: уже начатые курсы сюда не попадают, а сотруднику компании видны курсы, открытые его организациям. У кого организаций нет — весь опубликованный каталог.

Параметры. Нет.

В ответе. Список курсов: идентификатор, название и краткое описание для карточки.

Отказы. Своих нет — только общие.

Пример просьбы. Ученик: «что ещё есть на платформе, чему можно поучиться?»

list_my_courses#

Показывает курсы ученика с прогрессом и дедлайнами.

Параметры. Нет.

В ответе. По каждому курсу: название, организация, признак обязательности, дедлайн и просрочка, число уроков и пройденных, следующий урок. У ученика, записавшегося самостоятельно, поля назначения пустые.

Курсы приостановленной организации в список не попадают, а зачисление на них сохраняется.

Отказы. Своих нет — только общие.

Пример просьбы. Ученик: «что у меня в работе и что горит?»

my_notes#

Показывает ученику, что о нём запомнено.

На занятии то же самое приходит вместе с уроком; этот инструмент нужен, когда ученик спрашивает вне занятия.

Параметры

  • course — идентификатор курса. Необязательный; без него приходят только факты, с ним — ещё и наблюдения по этому курсу.

В ответе. Два списка: facts (о человеке) и observations (как он учится). У каждой записи ключ, текст и даты — когда появилась и когда обновлялась.

Отказы. Своих нет — только общие.

Пример просьбы. Ученик: «что ты обо мне запомнил?»

org_report#

Отчёт руководителя по обучению своей организации.

Параметры

  • course — идентификатор курса, чтобы сузить отчёт до одного курса. Необязательный.
  • statusnot_started, in_progress или completed. Необязательный.

В ответе. Строки «человек × курс»: имя и учётная запись, организация, статус, доля пройденного, дедлайн, обязательность, просрочка и дата последней активности.

Отказы. Своих нет. Сотруднику без роли руководителя отчёт приходит пустым, а не отказом: данные закрыты правами, и ошибки здесь нет.

Пример просьбы. «Покажи, кто из моих сотрудников ещё не начал обязательный курс».

remember#

Записывает об ученике то, что пригодится на следующих занятиях.

Параметры

  • kindfact (роль, отрасль, проект: живёт у ученика целиком) или observation (как учится: живёт при курсе). Обязательный.
  • key — короткий повторяемый ключ вроде role или pace. Обязательный. Запись по существующему ключу замещает прежний текст, а не добавляет вторую.
  • text — сама заметка. Обязательный.
  • session — идентификатор занятия. Обязателен для наблюдения: из него берётся курс.

В ответе. Ключ и вид записанной заметки.

Отказы

  • unknown_note_kind — вид не fact и не observation, либо пустой ключ.
  • not_your_session — для наблюдения не передан session или занятие чужое.
  • note_limit_reached (с полем limit) — ключей в наборе уже предельно много. Заметки по существующим ключам замещаются и предела не двигают.

Пример просьбы. Ученик: «запомни, что я веду две команды, — объясняй с оглядкой на это».

report_checkpoint#

Отмечает пройденное по ходу занятия. Это телеметрия, а не зачёт: на прогресс и на зачёт отметка не влияет.

Параметры

  • session — идентификатор занятия. Обязательный.
  • note — что именно пройдено, словами агента. Обязательный.

В ответе. Время, которым отметка записана.

Отказы

  • not_your_session — занятие принадлежит другому ученику.

Пример просьбы. Отдельно просить не нужно: агент отмечает ход занятия сам.

report_issue#

Сообщает авторам курса о том, что мешает учиться на этом уроке.

Параметры

  • session — идентификатор занятия. Обязательный. Курс, урок и действующую редакцию указаний сервер проставляет сам.
  • kind — вид репорта. Обязательный: stuck, misconception, material_issue, quiz_question_issue, directive_mismatch, out_of_scope.
  • text — что не так. Обязательный; режется по 2000 символов.
  • question — вопрос квиза этого урока, если репорт о вопросе. Необязательный.
  • objective — цель урока строкой. Необязательный; режется по 140 символов.

В ответе. Номер репорта и его вид — этого хватает, чтобы агент сказал ученику, что передал.

Отказы

  • not_your_session — занятие принадлежит другому ученику.
  • unknown_report_kind (с полем kind) — вид не из списка.
  • report_text_required — описание пустое.
  • question_mismatch (с полем question) — вопрос не из квиза этого урока.

Пример просьбы. Ученик: «передай методологу, что второй вопрос понять невозможно».

report_outcomes#

Отчёт агента о том, какие цели урока разобраны. Сдаётся до проверки знаний и до закрытия урока.

Параметры

  • session — идентификатор занятия. Обязательный.
  • outcomes — список пар «цель — статус». Обязательный. Статус один из трёх: covered (разобрали), touched (задели вскользь), skipped (не дошли).

Состав сверяется с целями урока: отчёт должен покрывать ровно их, ни больше ни меньше.

В ответе. Занятие и число целей, принятых в отчёт.

Отказы

  • not_your_session — занятие принадлежит другому ученику.
  • objectives_mismatch — статус не из трёх допустимых либо состав целей разошёлся; в отказе приходят missing и unexpected. Повторный отчёт замещает прежний целиком.

Пример просьбы. Отдельно просить не нужно: агент сдаёт отчёт сам, прежде чем закрыть урок.

request_quiz#

Начинает проверку знаний и возвращает первый вопрос.

Параметры

  • session — идентификатор занятия. Обязательный.

В ответе. Идентификатор попытки и первый вопрос: текст, вид (choice или input), варианты без признака правильности, номер вопроса и сколько их всего. Начатая попытка не заводится второй раз — возвращается открытая.

Отказы

  • not_your_session — занятие принадлежит другому ученику.
  • outcomes_required — не сдан отчёт по целям урока.
  • objectives_skipped (со списком skipped) — в отчёте есть цели, до которых не дошли. Разберите их и сдайте отчёт заново.
  • quiz_not_configured — у урока нет квиза; урок закрывается через complete_lesson.
  • quiz_not_checkable — квиз состоит из открытых вопросов, которые сервер не проверяет.
  • quiz_attempts_exhaustedattempts_used) — попытки кончились.
  • retry_too_soonretry_after) — не прошла пауза между попытками.
  • not_enrolled, organization_suspended — доступ к курсу отозван.

Пример просьбы. Ученик: «давай проверим, как я это усвоил».

start_lesson#

Начинает занятие по уроку или продолжает его следующей частью.

Без аргументов берётся следующий незакрытый урок с ближайшим дедлайном: обязательные и просроченные идут вперёд. Повторный вызов по тому же уроку продолжает начатое занятие, а не заводит второе.

Параметры

  • lesson — идентификатор урока. Необязательный.
  • segment — номер части длинного урока, считая с единицы. По умолчанию 1.

В ответе. Занятие; урок с названием, курсом и признаком просрочки; материал (и total_segments — сколько всего частей); медиа; цели урока и курса; политика проверки знаний — нужна ли она, порог и сколько попыток осталось; что известно об ученике и какие цели прошлых уроков остались незакрытыми; блоки документов курса, привязанные к этому уроку.

Отдельным полем directive приходят указания куратора — урочные и сквозные курсовые вместе, в рамке с явной пометкой адресата. Они адресованы агенту; ученику их не показывают.

Отказы

  • not_enrolled — ученик не зачислен на курс.
  • organization_suspended — организация ученика приостановлена.
  • lesson_not_found — такого урока нет.
  • nothing_to_study — незакрытых уроков не осталось (только при вызове без lesson).
  • web_demo_exhaustedlessons_used и lessons_limit) — в веб-чате пройдены все пробные уроки; занятие не заводится, продолжать нужно своим агентом.
  • unknown_channel — канал занятия не agent и не web.

Прошедший дедлайн отказом не является: урок отдаётся, в ответе overdue, а зачёт фиксируется как поздний.

Пример просьбы. Ученик: «давай заниматься» — или «открой урок про дедлайны ещё раз».

student_detail#

Подробности по одному сотруднику своей организации: чем занимался и как сдал проверки знаний.

Параметры

  • user — учётная запись сотрудника. Обязательный.

В ответе. Имя и учётная запись; курсы, назначенные вашими организациями, с дедлайнами; занятия со статусами и покрытием целей; попытки проверок знаний с баллом и признаком зачёта.

Тексты ответов ученика, его разговоры с агентом и заметки о нём не отдаются — отчёт про результат, а не про содержание диалога.

Отказы

  • not_your_student — сотрудник не состоит ни в одной вашей организации.

Пример просьбы. «Покажи подробности по Иванову: где он застрял».

submit_answer#

Отправляет ответ ученика и получает вердикт со следующим вопросом.

Вердикт выносит сервер. Проверять ответы самостоятельно агенту нельзя: зачёт ставится только по итогам этой проверки.

Параметры

  • attempt — идентификатор попытки из request_quiz. Обязательный.
  • question — идентификатор вопроса, на который отвечают. Обязательный.
  • answer — ответ. Обязательный. Для вопроса с вариантами это их идентификаторы: строкой ("2", "1,3") или списком (["1", "3"]); текст варианта тоже принимается и сопоставляется с идентификатором. Для вопроса со свободным вводом — ответ ученика как есть; он сверяется без учёта регистра и лишних пробелов.

В ответе. Вердикт (верно или нет; пояснение — только вместе с верным ответом), следующий вопрос или null и признак завершения попытки. На последнем вопросе добавляется результат: балл, порог, признак зачёта и статус занятия.

Отказы

  • attempt_finished — попытка уже завершена.
  • question_mismatch — вопрос не из этой попытки или на него уже отвечено.
  • not_your_session — попытка принадлежит другому ученику.
  • not_enrolled, organization_suspended — доступ к курсу отозван, пока шла попытка. Доступ перепроверяется на каждом ответе.

Пример просьбы. Отдельно просить не нужно: агент передаёт ответ ученика сам и зачитывает вердикт сервера.

update_artifact#

Записывает блок документа курса.

Запись замещает прежнюю, поэтому блок отдаётся целиком: дописывание кусками превращает документ в стенограмму разговора.

Параметры

  • course — идентификатор курса. Обязательный.
  • artifact — ключ документа. Обязательный.
  • key — ключ блока. Обязательный; регистр не важен.
  • content — содержимое блока в markdown. Обязательный, непустой.

В ответе. Документ, ключ блока и заполненность: сколько блоков всего и сколько уже написано.

Сервер проверяет только форму — документ и блок есть в схеме, текст непуст. Отвечает ли текст подсказке автора, смотрит агент: на зачёт документ не влияет.

Отказы

  • not_enrolled, organization_suspended — курс ученику сейчас недоступен.
  • artifact_not_found — в курсе нет документа с таким ключом.
  • artifact_block_not_found — в документе нет такого блока.
  • artifact_content_required — содержимое пустое.

Пример просьбы. Ученик: «запиши в резюме проекта, что цель — открыть седьмую кофейню к весне».

whoami#

Говорит, под какой учётной записью вошёл ученик и в каких он организациях.

Нужен, когда список курсов или каталог пуст: «курсов нет» и «вошли не тем аккаунтом» выглядят одинаково, и различает их только это.

Параметры. Нет.

В ответе. Учётная запись, полное имя и организации: название, роль в организации и признак suspended. Приостановленная организация закрывает доступ к своим курсам — без этого признака пустой каталог необъясним.

Отказы. Своих нет — только общие.

Пример просьбы. Ученик: «почему у меня пусто? под кем я вообще вошёл?»

Инструменты куратора#

Этот набор живёт на кураторском адресе /authoring. Он требует роли Course Creator или Moderator; вызов без неё отклоняется ошибкой доступа (403), а не кодом отказа — у агента ученика нет сценария, в котором он с этим что-то сделает, и нарушение должно попадать в журнал как нарушение. Удаление уроков дополнительно требует роли Moderator.

Отдельный адрес ничего не защищает: он известен, и токен у ученика тот же. Отказывает авторская роль на стороне Frappe.

Порядок сборки и ограничения платформы агент получает вызовом authoring_guide. Курсы на платформе общие: список курсов полный, а не «мои».

add_chapter#

Добавляет главу в конец курса.

Параметры

  • course — идентификатор курса. Обязательный.
  • title — название главы. Обязательный.

В ответе. Идентификатор главы, её название и курс.

Отказы

  • course_not_found — курса с таким идентификатором нет.

Пример просьбы. «Заведи в курсе главу „Работа с возражениями“».

add_lesson#

Добавляет урок в конец главы.

Отдельной привязки урока к главе не нужно — он встаёт в конец сразу. Длинный материал платформа режет по заголовкам и отдаёт агенту ученика частями.

Параметры

  • chapter — идентификатор главы. Обязательный.
  • title — название урока. Обязательный.
  • body — материал урока в markdown. Обязательный.

В ответе. Идентификатор урока, название, глава и курс.

Отказы

  • chapter_not_found — главы с таким идентификатором нет.

Пример просьбы. «Добавь в эту главу урок „Цена и ценность“, текст я сейчас пришлю».

add_question#

Добавляет вопрос в существующий квиз урока.

Параметры

  • lesson — идентификатор урока. Обязательный.
  • question — вопрос одним объектом, в том же виде, что в add_quiz. Обязательный.

В ответе. Квиз, идентификатор созданного вопроса и сколько вопросов стало.

Отказы

  • lesson_not_found — такого урока нет.
  • quiz_missing — у урока ещё нет квиза; создайте его целиком через add_quiz.
  • unknown_question_type (с полем received) — тип не Choices и не User Input.
  • too_many_options (с полем received) — вариантов или образцов ответа больше десяти; столько хранит Frappe Learning.
  • invalid_question — состав вариантов не прошёл проверку: меньше двух вариантов, ни одного верного, повторы. Вопрос не создаётся.

Пример просьбы. «Добавь к проверке по этому уроку ещё один вопрос — про сроки».

add_quiz#

Создаёт квиз урока со всеми вопросами сразу.

У урока может быть только один квиз: если он уже есть, правьте его вопросами. Зачёт по квизу ставит сервер, а не агент.

Параметры

  • lesson — идентификатор урока. Обязательный.
  • questions — список вопросов. Обязательный, непустой. Вопрос с вариантами: {"text": "…", "type": "Choices", "marks": 1, "options": [{"text": "…", "correct": true, "explanation": "…"}, {"text": "…"}]}. Вопрос со свободным ответом: {"text": "…", "type": "User Input", "answers": ["for", "while"]} — сверка идёт по строке, поэтому перечисляйте все формулировки, которые засчитываете. Тип по умолчанию Choices; Open Ended платформа не принимает.
  • title — название квиза. Необязательный; по умолчанию берётся название урока.
  • passing_percentage — порог зачёта в процентах. По умолчанию 70.

explanation показывается ученику после верного ответа и только после него.

В ответе. Идентификатор квиза, урок и идентификаторы созданных вопросов.

Отказы

  • lesson_not_found — такого урока нет.
  • empty_quiz — список вопросов пуст.
  • quiz_exists (с полем quiz) — у урока уже есть квиз.
  • unknown_question_type (с полем received) — тип не Choices и не User Input.
  • too_many_options (с полем received) — вариантов или образцов ответа больше десяти.
  • invalid_question (с полем question_index — номером вопроса) — состав вариантов не прошёл проверку: минимум два варианта, хотя бы один верный, без повторов. Вопросы этого квиза откатываются целиком.

Пример просьбы. «Сделай по этому уроку проверку из пяти вопросов с вариантами, порог 80».

authoring_guide#

Отдаёт агенту порядок сборки курса и ограничения платформы одним текстом.

Нужен клиентам, которые передают модели только инструменты: там ни инструкции сервера, ни prompts до модели не доходят. Содержание то же, что в prompt author.

Параметры. Нет.

В ответе. Текст гайда: что за чем вызывать, какие отказы ожидать и что показывать куратору до создания.

Отказы. Своих нет — только общие.

Пример просьбы. «Прочитай гайд по сборке и расскажи, с чего начнём».

course_draft#

Показывает курс целиком, как его собрали, — вместе с верными ответами и готовностью к публикации.

Смотрите его после перерыва в работе и перед публикацией: в диалоге легко потерять, что уже создано.

Параметры

  • course — идентификатор курса. Обязательный.

В ответе. Курс, признак публикации, главы и уроки (у каждого — признаки наличия материала и директивы, квиз с эталонами), действующая директива курса, схемы документов курса и readinessblocking (что мешает публикации) и warnings (что стоит знать).

Содержимого уроков здесь нет — только признак наличия. Чтобы сверить материал с исходником, читайте get_lesson поурочно.

Отказы

  • course_not_found — курса с таким идентификатором нет.

Пример просьбы. «Покажи, что у нас в курсе уже собрано и чего не хватает для публикации».

create_course#

Заводит курс. Он создаётся черновиком и ученикам пока не виден.

Параметры

  • title — название курса. Обязательный.
  • summary — короткий текст для карточки в каталоге. Обязательный: без него курс не опубликуется.
  • description — полное описание на странице курса. Необязательный; без него берётся summary.

В ответе. Идентификатор курса, название и признак публикации.

Отказы. Своих нет — только общие.

Пример просьбы. «Заведи курс „Переговоры для руководителей групп“, в каталоге пиши, что он про подготовку к сложному разговору».

get_lesson#

Читает урок целиком: материал, действующую директиву и квиз с верными ответами.

Этим сверяют, что на платформе лежит ровно тот текст, который утвердил куратор: материал уезжает параметром вызова, и обрезанный текст ничем себя не проявит.

Параметры

  • lesson — идентификатор урока. Обязательный.

В ответе. Урок, глава и курс; материал целиком; действующая директива урока с версией; сквозная директива курса; квиз с вопросами, вариантами, признаком верного и образцами ответа — или null, если квиза нет.

Отказы

  • lesson_not_found — такого урока нет.

Пример просьбы. «Прочитай третий урок и сверь с текстом, который я присылал».

list_courses#

Показывает курсы платформы — черновики и опубликованные, свежие сверху.

С этого начинается работа после перерыва: идентификатор курса нужен всем остальным инструментам, а между сессиями агент его не помнит.

Параметры

  • published — да или нет: сузить список до опубликованных или до черновиков. Необязательный; без него приходят все.

В ответе. По каждому курсу: идентификатор, название, краткое описание, признак публикации, число уроков и когда курс правили в последний раз.

Отказы. Своих нет — только общие.

Пример просьбы. «Найди курс про переговоры, который мы начали на той неделе».

move_lesson#

Переносит урок в другую главу или на другое место в своей.

Для одной перестановки берите этот инструмент, а не reorder_lessons: полный список нужен, когда порядок меняется весь сразу.

Параметры

  • lesson — идентификатор урока. Обязательный.
  • chapter — идентификатор главы, куда переносим. Необязательный; без него меняется только место внутри текущей главы.
  • position — место в главе, считая с единицы. Необязательный; без него урок встаёт в конец.

В ответе. Урок, глава, в которой он оказался, и новый порядок уроков этой главы.

Отказы

  • lesson_not_found — такого урока нет.
  • chapter_not_found — главы, в которую переносим, нет.

Пример просьбы. «Перенеси урок про возражения во вторую главу, поставь его первым».

publish_course#

Открывает курс ученикам.

Проверяет готовность и возвращает все причины отказа разом, а не первую найденную.

Параметры

  • course — идентификатор курса. Обязательный.

В ответе. Курс, признак публикации и warnings — предупреждения, которые публикацию не блокируют: урок без директивы, курс без сквозной директивы, курс без единого квиза, документ курса без блоков. Их стоит пересказать куратору.

Отказы

  • course_not_found — курса с таким идентификатором нет.
  • course_not_ready — курс не готов; список причин приходит в поле problems. Что туда попадает: empty_course (нет уроков), empty_lesson (урок без материала), empty_quiz (квиз без вопросов), blank_question (вопрос без текста), no_summary (нет краткого описания).

Пример просьбы. «Публикуй курс».

remove_chapter#

Удаляет пустую главу.

Уроки удаляются по одному и с проверкой прогресса — каскадом эту проверку обходить нельзя.

Параметры

  • chapter — идентификатор главы. Обязательный.

В ответе. Удалённая глава и курс.

Отказы

  • chapter_not_found — главы с таким идентификатором нет.
  • chapter_not_empty (со списком lessons) — в главе есть уроки; удалите их по одному.

Пример просьбы. «Убери пустую главу, которую мы завели по ошибке».

remove_lesson#

Удаляет урок вместе с его квизом и директивами.

Работает, только пока по уроку никто не занимался. Требует роли Moderator: у Course Creator такого права нет, и обходить это платформа не станет — агент получил бы то, чего не может тот же человек в браузере.

Параметры

  • lesson — идентификатор урока. Обязательный.

В ответе. Удалённый урок, его глава и оставшийся порядок уроков.

Отказы

  • lesson_not_found — такого урока нет.
  • lesson_in_use — по уроку уже занимались; в отказе приходят числа записей прогресса, занятий и попыток. Урок остаётся: переписывайте его через update_lesson.

Пример просьбы. «Удали лишний урок, который мы создали дважды, — по нему ещё никто не занимался».

remove_question#

Убирает вопрос из квиза урока.

Сам вопрос остаётся в базе: на него ссылаются ответы прошлых попыток, и стирание испортило бы историю зачётов.

Параметры

  • lesson — идентификатор урока. Обязательный.
  • question — идентификатор вопроса. Обязательный.

В ответе. Квиз и сколько вопросов в нём осталось.

Отказы

  • lesson_not_found — такого урока нет.
  • quiz_missing — у урока нет квиза.
  • question_not_found — в этом квизе такого вопроса нет.

Пример просьбы. «Убери из проверки вопрос про регламент — он уже не актуален».

reorder_chapters#

Задаёт порядок глав курса.

Параметры

  • course — идентификатор курса. Обязательный.
  • chapters — весь список глав в нужной последовательности. Обязательный.

В ответе. Курс и записанный порядок глав.

Отказы

  • course_not_found — курса с таким идентификатором нет.
  • order_mismatch (с полями expected и received) — состав списка разошёлся с текущим. Порядок остаётся прежним: так забытая глава не выпадет из курса.

Пример просьбы. «Поменяй местами вторую и третью главы».

reorder_lessons#

Задаёт порядок уроков главы.

Передаётся весь список целиком, в нужной последовательности: неполный отклоняется, чтобы забытый урок не выпал из программы.

Параметры

  • chapter — идентификатор главы. Обязательный.
  • lessons — весь список уроков главы в нужном порядке. Обязательный.

В ответе. Глава и записанный порядок уроков.

Отказы

  • chapter_not_found — главы с таким идентификатором нет.
  • order_mismatch (с полями expected и received) — состав списка разошёлся с текущим; порядок остаётся прежним.

Пример просьбы. «Расставь уроки в этой главе так: сначала подготовка, потом разговор, потом разбор».

set_course_artifact#

Задаёт документ, который ученик собирает по ходу курса: резюме проекта, канвас, таблицу.

Это не квиз: на зачёт документ не влияет, а проверяет его агент по подсказке автора, а не сервер.

Параметры

  • course — идентификатор курса. Обязательный.
  • artifact — ключ документа в курсе, например project_summary. Обязательный; регистр не важен.
  • title — название документа. Обязательный.
  • blocks — список блоков в порядке чтения. Обязательный. Блок: {"key": "goal", "title": "Цель проекта", "hint": "Одной фразой; готов, когда назван результат", "lesson": "<id урока>", "span": 1}. hint адресована агенту ученика — что должно оказаться в блоке и когда он готов; lesson — на каком уроке блок обычно собирают, это подсказка, а не ограничение; span — ширина в сетке.
  • layoutsections (столбцом) или canvas (сеткой по span). По умолчанию sections.

В ответе. Идентификатор схемы, курс, ключ документа и номер версии.

Каждый вызов создаёт новую версию схемы. Содержимое, которое ученик уже написал, хранится по ключам блоков и правку схемы переживает: добавленный блок появится пустым, убранный исчезнет со страницы, не стирая написанного.

Отказы

  • course_not_found — курса с таким идентификатором нет.
  • lesson_not_found — блок ссылается на несуществующий урок.

Повторяющийся ключ блока отклоняется как некорректный запрос.

Пример просьбы. «Заведи в курсе документ „Резюме проекта“ из четырёх блоков: цель, границы, риски, сроки».

set_course_directive#

Задаёт сквозные указания агенту — те, что действуют на всех занятиях курса.

Сюда идёт роль и тон преподавателя, формат занятия, что выяснить у ученика на старте, чем занятие завершать. Агент получает курсовую и урочную директивы вместе, поэтому повторять сквозное в каждом уроке не нужно.

Параметры

  • course — идентификатор курса. Обязательный.
  • teaching_directive — как вести занятия курса, свободным текстом. Обязательный.
  • objectives — цели курса, по строке на пункт. Необязательный.
  • student_profile — кого учим и что ученик уже знает. Необязательный.
  • glossary — термины курса, по строке на пункт. Необязательный.
  • remember_about_student — что об ученике стоит помнить между занятиями, по строке на пункт. Необязательный. Заметки агент ведёт сам; здесь задаётся, чему в них место.

В ответе. Идентификатор директивы, курс и номер версии.

Каждый вызов создаёт новую версию; прежняя перестаёт действовать, но остаётся в истории — занятие, идущее сейчас, уже получило свою.

Отказы

  • course_not_found — курса с таким идентификатором нет.

Пример просьбы. «Запиши на весь курс: преподаватель — практик, обращение на „ты“, каждое занятие начинаем с разбора его случая».

set_directive#

Задаёт указания агенту на один урок.

Директиву получает агент ученика, а сам ученик её не видит: она приходит ему отдельным полем с пометкой адресата.

Параметры

  • lesson — идентификатор урока. Обязательный.
  • teaching_directive — как вести этот урок, свободным текстом. Обязательный.
  • objectives — цели урока, по строке на пункт. Необязательный. По ним агент отчитывается о покрытии, и незакрытая цель закрывает проверку знаний.
  • probing_questions — чем проверять понимание по ходу. Необязательный.
  • common_misconceptions — типичные заблуждения. Необязательный.
  • success_criteria — что считать усвоенным. Необязательный.

В ответе. Идентификатор директивы, урок и номер версии.

Каждый вызов создаёт новую версию; прежняя перестаёт действовать, но остаётся в истории.

Отказы

  • lesson_not_found — такого урока нет.

Пример просьбы. «Для этого урока запиши цели: различать цену и ценность, уметь назвать три аргумента. И предупреди, что путают со скидкой».

unpublish_course#

Убирает курс из каталога. Прогресс учеников сохраняется.

Удаления курсов на платформе нет — снятие с публикации и есть способ убрать курс.

Параметры

  • course — идентификатор курса. Обязательный.

В ответе. Курс и признак публикации.

Отказы

  • course_not_found — курса с таким идентификатором нет.

Пример просьбы. «Сними курс с публикации, пока мы переписываем вторую главу».

update_chapter#

Правит название главы.

Параметры

  • chapter — идентификатор главы. Обязательный.
  • title — новое название. Обязательный.

В ответе. Идентификатор главы и её название.

Отказы

  • chapter_not_found — главы с таким идентификатором нет.

Пример просьбы. «Переименуй вторую главу в „Сложные разговоры“».

update_course#

Правит название, краткое или полное описание курса.

Параметры

  • course — идентификатор курса. Обязательный.
  • title — новое название. Необязательный.
  • summary — новый текст для карточки в каталоге. Необязательный.
  • description — новое полное описание. Необязательный.

Поле, которое не передали, остаётся прежним.

В ответе. Идентификатор курса, название и краткое описание.

Отказы

  • course_not_found — курса с таким идентификатором нет.

Пример просьбы. «Перепиши описание курса в каталоге: он для руководителей групп, а не для продавцов».

update_lesson#

Правит название или материал урока.

Так же переписывают урок, который удалить уже нельзя, — по нему занимались.

Параметры

  • lesson — идентификатор урока. Обязательный.
  • title — новое название. Необязательный.
  • body — новый материал в markdown. Необязательный. Записывается целиком, замещая прежний.

Поле, которое не передали, остаётся прежним.

В ответе. Идентификатор урока и его название.

Отказы

  • lesson_not_found — такого урока нет.

Пример просьбы. «Замени текст четвёртого урока на исправленный, сейчас пришлю».

update_question#

Правит вопрос: текст, варианты или образцы ответа.

Правка разрешена и после того, как по квизу отвечали: блокировать исправление опечатки в опубликованном курсе хуже, чем оставить её.

Параметры

  • question — идентификатор вопроса. Обязательный.
  • text — новый текст вопроса. Необязательный.
  • options — варианты ответа. Необязательный; заменяют прежние целиком, поэтому передавайте весь набор.
  • answers — образцы ответа для вопроса со свободным вводом. Необязательный; так же заменяют прежние целиком.

В ответе. Вопрос, его текст и affects_attempts — сколько ответов учеников уже дано на этот вопрос. Если число не ноль, скажите об этом куратору: он меняет вопрос, который ученики видели.

Отказы

  • question_not_found — вопроса с таким идентификатором нет.
  • too_many_options (с полем received) — вариантов или образцов больше десяти.
  • invalid_question — правка ломает состав вариантов: меньше двух, ни одного верного, повторы. Правка отменяется целиком, вопрос остаётся прежним.

Пример просьбы. «Во втором вопросе исправь опечатку и сделай верным третий вариант вместо первого».

Когда сервер откажет#

Отказы бывают двух видов, и путать их не нужно.

Ожидаемый отказ — это нормальный ход дела: попытки кончились, урок уже в работе, курс не готов к публикации. Платформа отвечает на такой вызов успешно, а причину кладёт машинным кодом в тело ответа. Ошибкой транспорта ожидаемый отказ не приходит: HTTP-ошибку формирует фреймворк, и машинного кода в ней не остаётся — в проде она не несёт ничего, кроме имени исключения.

Вот настоящий ответ платформы на попытку удалить урок, по которому уже занимались:

{ "ok": false,
  "error": { "code": "lesson_in_use",
             "message": "По этому уроку уже занимались: его можно только переписать",
             "lesson": "lesson-6",
             "progress": 12, "sessions": 14, "attempts": 9 } }

Три вещи в этом ответе важны по отдельности. code — по нему агент решает, что делать дальше. message — то, что можно пересказать человеку. Остальные поля — подробности именно этого отказа: сколько записей мешает удалению, когда можно повторить попытку, каких целей не хватило в отчёте.

Ветвиться нужно по коду, а не по тексту. Тексты меняются и переводятся, коды — нет. Именно поэтому в разделах этой страницы перечислены коды: они и есть контракт.

MCP-сервис доносит отказ до агента целиком — тем же кодом и теми же подробностями, — но подаёт его как ошибку инструмента. Агент видит строку вида По этому уроку уже занимались: его можно только переписать [lesson_in_use] lesson: lesson-6 progress: 12 sessions: 14 attempts: 9.

Сбой — другое дело. Он приходит HTTP-статусом, кода отказа в нём нет, и тело разбирать не следует: там внутренние структуры. Сервис переводит такой ответ в одну фразу для агента:

Что случилось Что говорит сервис
Токен истёк или отозван «сессия истекла, требуется повторная авторизация»
Нет прав на эти данные (403) «нет доступа к этим данным»
Объекта не существует (404) «запрошенного объекта не существует»
Запрос нарушает инвариант (417) «сервис отклонил запрос как некорректный»
Слишком много запросов (429) «слишком много запросов, попробуйте чуть позже»
Сбой или недоступность (5xx, обрыв связи) «учебный сервис сейчас недоступен, попробуйте позже»

Автоматических повторов нет: решение о повторе принимает агент — у него есть контекст занятия.

Отдельно стоит ошибка доступа у кураторских инструментов. Вызов без роли Course Creator или Moderator отклоняется именно 403, а не кодом отказа: это нарушение доступа, и оно должно попадать в журнал как нарушение.