Справочник инструментов#
Агент разговаривает с платформой инструментами 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— идентификатор курса, чтобы сузить отчёт до одного курса. Необязательный.status—not_started,in_progressилиcompleted. Необязательный.
В ответе. Строки «человек × курс»: имя и учётная запись, организация, статус, доля пройденного, дедлайн, обязательность, просрочка и дата последней активности.
Отказы. Своих нет. Сотруднику без роли руководителя отчёт приходит пустым, а не отказом: данные закрыты правами, и ошибки здесь нет.
Пример просьбы. «Покажи, кто из моих сотрудников ещё не начал обязательный курс».
remember#
Записывает об ученике то, что пригодится на следующих занятиях.
Параметры
kind—fact(роль, отрасль, проект: живёт у ученика целиком) или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_exhausted(сattempts_used) — попытки кончились.retry_too_soon(сretry_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_exhausted(сlessons_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— идентификатор курса. Обязательный.
В ответе. Курс, признак публикации, главы и уроки (у каждого —
признаки наличия материала и директивы, квиз с эталонами), действующая
директива курса, схемы документов курса и readiness — blocking (что
мешает публикации) и 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— ширина в сетке.layout—sections(столбцом) или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, а не кодом отказа:
это нарушение доступа, и оно должно попадать в журнал как нарушение.