Первая версия кастомного MCP-сервера для работы с SDO ТУСУР.
Сервер позволяет MCP-клиенту, например LM Studio или MCP Inspector, получать доступ к учебной платформе SDO TUSUR через браузерную автоматизацию Playwright.
Версия: 0.2.0
Текущая версия является тестовой и предназначена для локального использования.
На данный момент сервер умеет:
- открывать SDO TUSUR;
- проверять, авторизован ли пользователь;
- выполнять вход через профиль ТУСУР;
- сохранять авторизационную сессию;
- получать список курсов;
- получать список материалов внутри курса;
- читать страницу задания или ресурса;
- скачивать файлы только из конкретного модуля курса;
- сохранять текст страницы модуля в
.txt.
В SDO TUSUR есть разные типы страниц. Их нельзя обрабатывать одинаково.
Пример:
https://sdo.tusur.ru/course/view.php?id=21380
Это главная страница курса. На ней находятся ссылки на задания, презентации, ресурсы, тесты и другие элементы.
Для неё используется tool:
list_course_modules
Страницу курса нельзя передавать в скачивание одного модуля, иначе можно случайно начать обходить весь курс.
Пример:
https://sdo.tusur.ru/mod/resource/view.php?id=559755
Это конкретный ресурс Moodle, например презентация:
Презентация 1.1. на тему Введение в экономику
Для него используется tool:
download_module_files
Пример:
https://sdo.tusur.ru/mod/assign/view.php?id=559759
Это конкретное задание Moodle.
Для него также используется tool:
download_module_files
При скачивании задания сервер сохраняет текст задания и скачивает только файлы, прикреплённые к этому заданию.
MCP Client
|
| stdio
v
custom-sdo-mcp
|
| Playwright
v
profile.tusur.ru / sdo.tusur.ru
Сервер работает через stdio, поэтому его можно подключать к локальным MCP-клиентам.
Для ChatGPT напрямую этот вариант не подходит, потому что ChatGPT требует удалённый HTTPS MCP-сервер и отдельную настройку авторизации.
Получает список курсов из SDO.
Пример результата:
[
{
"title": "Экономика и финансы предприятий",
"url": "https://sdo.tusur.ru/course/view.php?id=21380"
}
]Получает список материалов и заданий на странице конкретного курса.
Аргументы:
{
"courseUrl": "https://sdo.tusur.ru/course/view.php?id=21380"
}Пример результата:
{
"courseUrl": "https://sdo.tusur.ru/course/view.php?id=21380",
"modules": [
{
"title": "Презентация 1.1. на тему Введение в экономику Файл",
"url": "https://sdo.tusur.ru/mod/resource/view.php?id=559755",
"type": "resource"
},
{
"title": "Задание №1 Кейсы",
"url": "https://sdo.tusur.ru/mod/assign/view.php?id=559759",
"type": "assign"
}
]
}Открывает страницу задания или ресурса и возвращает текст страницы.
Аргументы:
{
"assignmentUrl": "https://sdo.tusur.ru/mod/assign/view.php?id=559759"
}Также может использоваться для ресурса:
{
"assignmentUrl": "https://sdo.tusur.ru/mod/resource/view.php?id=559755"
}Скачивает файлы только из одного конкретного модуля SDO TUSUR.
Поддерживаемые типы:
/mod/resource/view.php
/mod/assign/view.php
Аргументы:
{
"moduleUrl": "https://sdo.tusur.ru/mod/resource/view.php?id=559755"
}или:
{
"moduleUrl": "https://sdo.tusur.ru/mod/assign/view.php?id=559759"
}Не поддерживается напрямую:
/course/view.php
Для страницы курса сначала нужно вызвать:
list_course_modules
а затем передать конкретный resource или assign URL в:
download_module_files
Скачивание работает по правилу:
course URL → только получить список модулей
resource URL → скачать только этот ресурс
assign URL → скачать только файлы этого задания
Сервер специально игнорирует ссылки на соседние страницы:
/course/view.php
/mod/assign/view.php
/mod/resource/view.php
/mod/forum/
/mod/quiz/
/user/
/grade/
/calendar/
Это сделано, чтобы случайно не скачать весь курс при обработке одного задания.
Реальными файлами считаются ссылки вида:
/pluginfile.php/
/webservice/pluginfile.php/
а также прямые ссылки на файлы:
.pdf
.doc
.docx
.xls
.xlsx
.ppt
.pptx
.zip
.rar
.7z
.txt
.jpg
.jpeg
.png
Файлы сохраняются в папку:
downloads/
Для каждого модуля создаётся отдельная папка:
downloads/resource-559755 - Презентация 1.1. на тему Введение в экономику/
или:
downloads/assign-559759 - Задание №1 Кейсы/
Внутри всегда сохраняется текст страницы:
module-text.txt
Если на странице есть прикреплённые файлы, они сохраняются рядом.
Пример результата:
{
"moduleType": "resource",
"moduleId": "559755",
"moduleUrl": "https://sdo.tusur.ru/mod/resource/view.php?id=559755",
"title": "Презентация 1.1. на тему Введение в экономику",
"outputDir": "downloads\\resource-559755 - Презентация 1.1. на тему Введение в экономику",
"textPath": "downloads\\resource-559755 - Презентация 1.1. на тему Введение в экономику\\module-text.txt",
"foundLinks": 1,
"files": [
{
"title": "presentation.pdf",
"url": "https://sdo.tusur.ru/pluginfile.php/...",
"path": "downloads\\resource-559755 - ...\\presentation.pdf",
"status": "downloaded"
}
]
}Установить зависимости:
npm installВ корне проекта создать файл .env:
SDO_URL=https://sdo.tusur.ru
TUSUR_PROFILE_LOGIN_URL=https://profile.tusur.ru/en/users/sign_in
SDO_USERNAME=your_login_or_email
SDO_PASSWORD=your_password
HEADLESS=falseГде:
SDO_URL— адрес SDO TUSUR;TUSUR_PROFILE_LOGIN_URL— адрес страницы входа через профиль ТУСУР;SDO_USERNAME— логин или email;SDO_PASSWORD— пароль;HEADLESS=false— браузер будет открываться визуально.
Для первого тестирования рекомендуется оставить:
HEADLESS=falseТак можно видеть, где именно останавливается вход.
Вход работает по следующей схеме:
- Сервер открывает
https://sdo.tusur.ru/. - Проверяет, видны ли курсы.
- Если курсы уже видны, сервер считает пользователя авторизованным.
- Если авторизации нет, сервер открывает
https://profile.tusur.ru/en/users/sign_in. - Заполняет логин и пароль.
- После успешного входа пользователь перенаправляется в SDO.
- Сервер сохраняет состояние авторизации в
storage/auth.json.
Файл storage/auth.json содержит cookies и данные сессии. Его нельзя публиковать или добавлять в Git.
Сервер не должен начинать вход с:
https://sdo.tusur.ru/login/index.php
Потому что при наличии токена Moodle может показать страницу выхода или подтверждения смены состояния сессии.
Правильная стартовая страница:
https://sdo.tusur.ru/
src/
index.ts # MCP server и регистрация tools
browser.ts # запуск Playwright и сохранение auth state
sdo.ts # логика входа, курсов, модулей и скачивания
test-login.ts # ручной тест логина без MCP-клиента
test-module-download.ts # ручной тест скачивания одного модуля
storage/
auth.json # сохранённая сессия Playwright
downloads/
... # скачанные материалы
dist/
index.js # собранный MCP-сервер
Рекомендуемый .gitignore:
node_modules/
dist/
.env
storage/
downloads/
debug-*.pngnpm run buildПосле сборки должен появиться файл:
dist/index.js
Проверить:
Test-Path "dist/index.js"Ожидаемый результат:
True
npx tsx src/test-login.tsЕсли всё работает, откроется браузер, произойдёт вход в SDO, а в терминале появится список курсов.
Пример для презентации:
npx tsx src/test-module-download.ts "https://sdo.tusur.ru/mod/resource/view.php?id=559755"Этот тест должен скачать только конкретный ресурс:
Презентация 1.1. на тему Введение в экономику
Он не должен обходить весь курс.
npx tsx src/test-module-download.ts "https://sdo.tusur.ru/mod/assign/view.php?id=559759"Этот тест должен сохранить текст конкретного задания и скачать только файлы, прикреплённые к нему.
Сначала собрать проект:
npm run buildЗапустить MCP Inspector:
npx @modelcontextprotocol/inspector node dist/index.jsПосле запуска Inspector откроет браузер.
В интерфейсе должны быть доступны tools:
list_courses
list_course_modules
get_assignment_details
download_module_files
Пример конфига MCP для LM Studio:
{
"mcpServers": {
"sdo-tsu": {
"command": "C:/Program Files/nodejs/node.exe",
"args": ["C:/Users/New/Documents/tusur/sdo_mcp/dist/index.js"],
"cwd": "C:/Users/New/Documents/tusur/sdo_mcp"
}
}
}Важно:
- использовать полный путь к
node.exe; - использовать прямые слэши
/; - указать правильный
cwd, чтобы.envбыл найден; - перед подключением выполнить
npm run build.
В MCP через stdio нельзя писать обычные логи в stdout.
Нельзя использовать:
console.log('text')Потому что stdout используется MCP-протоколом для JSON-RPC сообщений.
Для логов нужно использовать:
console.error('text')Правило:
stdout = только MCP JSON-RPC
stderr = debug-логи
Если нарушить это правило, появится ошибка вида:
Unexpected token 'L', "Logging in"... is not valid JSON
## Подключение к LM Studio на Windows
Пример конфига MCP для LM Studio:
```json
{
"mcpServers": {
"sdo-tsu": {
"command": "C:/Program Files/nodejs/node.exe",
"args": ["C:/Users/New/Documents/tusur/sdo_mcp/dist/index.js"],
"cwd": "C:/Users/New/Documents/tusur/sdo_mcp"
}
}
}
Важно:
- использовать полный путь к
node.exe; - использовать прямые слэши
/; - указать правильный
cwd, чтобы.envбыл найден; - перед подключением выполнить
npm run build.
LM Studio не может найти Node.js.
Решение: указать полный путь к node.exe:
"command": "C:/Program Files/nodejs/node.exe"Проект не был собран.
Решение:
npm run buildФайл теста ещё не создан.
Решение: создать файл:
src/test-module-download.ts
В коде есть console.log.
Решение: заменить console.log на console.error.
Проблема в проверке авторизации.
Решение: в isLoggedIntoSdo сначала проверять наличие ссылок курсов:
page.locator('a[href*="/course/view.php"]')Если ссылки курсов есть, значит пользователь уже авторизован.
Не нужно открывать:
https://sdo.tusur.ru/login/index.php
Вместо этого нужно открывать:
https://sdo.tusur.ru/
Если SDO показывает страницу выхода, нельзя нажимать подтверждение выхода. Нужно вернуться на главную страницу SDO.
Значит в функцию скачивания был передан URL курса или старая версия функции собирает все ссылки курса.
Правильная логика:
/course/view.php → list_course_modules
/mod/resource/view.php → download_module_files
/mod/assign/view.php → download_module_files
Для скачивания нельзя передавать:
https://sdo.tusur.ru/course/view.php?id=21380
Сначала нужно получить список модулей, потом скачать конкретный модуль:
https://sdo.tusur.ru/mod/resource/view.php?id=559755
или:
https://sdo.tusur.ru/mod/assign/view.php?id=559759
Не публиковать:
.env
storage/auth.json
debug-*.png
downloads/
Эти файлы могут содержать:
- логин;
- пароль;
- cookies;
- данные авторизационной сессии;
- содержимое личного кабинета;
- учебные материалы.
Версия 0.2.0 не умеет:
- скачивать весь курс одной командой;
- автоматически выбирать нужное задание по названию;
- отправлять готовые работы;
- работать через удалённый HTTPS MCP;
- реализовывать OAuth;
- обходить CAPTCHA или 2FA;
- гарантированно работать после изменения интерфейса SDO.
- добавить
download_course_materials(courseUrl)с явным подтверждением; - добавить фильтр по типам модулей:
resource,assign,quiz; - добавить поиск модуля по названию;
- добавить сохранение JSON-индекса курса;
- добавить защиту от повторного скачивания уже скачанных файлов.
- добавить парсинг дедлайнов;
- добавить список активных заданий;
- добавить
prepare_assignment_context; - добавить чтение скачанных PDF/DOCX/TXT.
- добавить remote HTTP MCP;
- добавить HTTPS;
- добавить авторизацию MCP-клиента;
- подготовить вариант для ChatGPT Custom MCP.
Этот MCP предназначен для помощи в организации учебных материалов:
- читать задания;
- скачивать материалы;
- готовить конспекты;
- помогать разбирать требования;
- формировать черновики;
- напоминать о дедлайнах.
Не рекомендуется использовать MCP для полной автоматической сдачи работ без проверки пользователем.