itmo-mcp
# itmo-mcp
MCP-сервер для сервисов Университета ИТМО: [my.itmo.ru](https://my.itmo.ru) и [БАРС](https://bars.itmo.ru).
Подключите его к Claude, Codex, Cursor или другому MCP-клиенту и спрашивайте обычным языком:
"какие пары завтра?", "сколько баллов по матану в БАРС?", "куда записаться на волейбол на этой неделе?",
"когда приходила стипендия?".
Сервер только читает данные: он ничего не меняет, не записывает на занятия и не подаёт заявки.
> Неофициальный проект. Не связан с Университетом ИТМО. API сервисов может измениться без предупреждения.
## Быстрая настройка через агента
Отправьте своему агенту (Claude Code, Codex, Cursor):
```text
Настрой мне MCP-сервер itmo-mcp по README https://github.com/alllexey-dev/itmo-mcp
```
## Что умеет
| Инструмент | Что возвращает |
|---|---|
| `itmo_get_profile` | Ваш профиль: ИСУ, ФИО, факультет, группа, курс |
| `itmo_get_schedule` | Расписание пар за период (по умолчанию 7 дней) |
| `itmo_get_grades` | Зачётка за семестр: баллы, оценки, тип контроля |
| `itmo_get_grade_details` | Разбивка баллов по одной дисциплине зачётки |
| `itmo_get_study_plan` | Дисциплины учебного плана за семестр: ЗЕТ, часы, кафедра |
| `bars_get_scores` | Баллы БАРС текущего семестра по контрольным точкам |
| `itmo_get_sport_status` | Физкультура: баллы, секции, ближайшие занятия, долги |
| `itmo_get_sport_points_history` | История начисления баллов по физкультуре |
| `itmo_get_sport_schedule` | Занятия по физкультуре со свободными местами |
| `itmo_get_sport_filters` | Виды спорта, корпуса и семестры для фильтров |
| `itmo_get_sport_competitions` | Спортивные соревнования |
| `itmo_get_scholarship` | Стипендия и выплаты: суммы по категориям и история |
| `itmo_get_dormitory` | Общежитие: статус, договор, баланс и график оплаты |
| `itmo_get_room_bookings` | Ваши брони аудиторий и коворкингов |
| `itmo_get_queue_appointments` | Записи в электронную очередь |
| `itmo_get_requests` | Ваши заявки и справки |
| `itmo_get_election_status` | Сроки выбора дисциплин |
| `itmo_search_people`, `itmo_get_person` | Поиск студентов и сотрудников, профиль по ИСУ |
## Вход в ИТМО
Сервер входит в ITMO.ID от вашего имени. Подойдёт любой из вариантов (переменные окружения):
| Переменные | Доступ | Комментарий |
|---|---|---|
| `ITMO_USERNAME` + `ITMO_PASSWORD` | my.itmo.ru и БАРС | Проще всего. Пароль хранится в конфиге MCP-клиента |
| `ITMO_KEYCLOAK_IDENTITY` | my.itmo.ru и БАРС | Без пароля. Cookie живёт около 90 дней |
| `ITMO_REFRESH_TOKEN` | только my.itmo.ru | Токен живёт 30 дней и обновляется сам |
Как получить `KEYCLOAK_IDENTITY`: войдите на [my.itmo.ru](https://my.itmo.ru), откройте DevTools
(F12) -> Application -> Cookies -> `https://id.itmo.ru` и скопируйте значение `KEYCLOAK_IDENTITY`.
ITMO.ID меняет токены при каждом входе. Сервер сохраняет свежие значения в `~/.config/itmo-mcp/state.json`
(права `600`), поэтому после первого входа переменные можно не обновлять. Папку можно поменять через
`ITMO_MCP_STATE_DIR`.
## Подключение
Нужен [Node.js](https://nodejs.org) 20 или новее.
### Claude Desktop
Settings -> Developer -> Edit Config, добавьте в `claude_desktop_config.json`:
```json
{
"mcpServers": {
"itmo": {
"command": "npx",
"args": ["-y", "itmo-mcp"],
"env": {
"ITMO_USERNAME": "123456",
"ITMO_PASSWORD": "ваш пароль"
}
}
}
}
```
### Claude Code
```bash
claude mcp add itmo -e ITMO_USERNAME=123456 -e ITMO_PASSWORD='ваш пароль' -- npx -y itmo-mcp
```
### Codex
```bash
codex mcp add itmo --env ITMO_USERNAME=123456 --env ITMO_PASSWORD='ваш пароль' -- npx -y itmo-mcp
```
Или вручную в `~/.codex/config.toml`. Первый запуск `npx` скачивает пакет, поэтому таймаут старта увеличен:
```toml
[mcp_servers.itmo]
command = "npx"
args = ["-y", "itmo-mcp"]
startup_timeout_sec = 60
env = { ITMO_USERNAME = "123456", ITMO_PASSWORD = "ваш пароль" }
```
### Cursor, VS Code и другие клиенты
Используйте ту же команду (`npx -y itmo-mcp`) и те же переменные окружения в настройках MCP вашего клиента.
### Docker вместо Node.js
```json
{
"mcpServers": {
"itmo": {
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "ITMO_USERNAME", "-e", "ITMO_PASSWORD",
"-v", "itmo-mcp:/state", "ghcr.io/alllexey-dev/itmo-mcp:v0.1.0", "--stdio"],
"env": { "ITMO_USERNAME": "123456", "ITMO_PASSWORD": "ваш пароль" }
}
}
}
```
## Свой сервер (HTTP)
Сервер умеет Streamable HTTP: `POST /mcp`, health check на `GET /healthz`.
```bash
docker run -d --name itmo-mcp -p 8080:8080 \
-e ITMO_USERNAME=123456 -e ITMO_PASSWORD='ваш пароль' \
-e ITMO_MCP_HTTP_TOKEN="$(openssl rand -hex 32)" \
-e ITMO_MCP_HTTP_ALLOWED_HOSTS=mcp.example.com \
-v itmo-mcp:/state \
ghcr.io/alllexey-dev/itmo-mcp:v0.1.0
```
| Переменная | Назначение |
|---|---|
| `ITMO_MCP_HTTP_TOKEN` | Клиент должен прислать `Authorization: Bearer <токен>` |
| `ITMO_MCP_HTTP_ALLOWED_HOSTS` | Допустимые значения заголовка `Host`, через запятую (защита от DNS rebinding) |
Один сервер обслуживает один аккаунт ИТМО. Не открывайте его в интернет без токена или прокси с авторизацией:
любой, кто до него достучится, увидит ваши данные. Подключение из Claude Code:
```bash
claude mcp add --transport http itmo https://mcp.example.com/mcp --header "Authorization: Bearer <токен>"
```
Из Codex (токен берётся из переменной окружения `ITMO_MCP_TOKEN`):
```bash
codex mcp add itmo --url https://mcp.example.com/mcp --bearer-token-env ITMO_MCP_TOKEN
```
## Приватность
- Сервер обращается напрямую к `id.itmo.ru`, `my.itmo.ru` и `bars.itmo.ru`. Других адресатов у данных нет.
- Ответы инструментов попадают в контекст модели и, значит, к провайдеру LLM, которым вы пользуетесь.
- Пароль и токены не попадают в ответы инструментов и в логи.
## OpenAPI и клиент
В `openapi/` лежат описания API (OpenAPI 3.1), восстановленные по веб-клиентам и проверенные на живых ответах:
- `openapi/my-itmo.yaml`: расписание, зачётка, учебный план, физкультура, финансы, общежитие и другое;
- `openapi/bars.yaml`: БАРС.
По ним сгенерирован типизированный клиент на [openapi-fetch](https://openapi-ts.dev/openapi-fetch/), который можно
использовать как библиотеку:
```ts
import { createToolDeps, loadConfig, result } from "itmo-mcp";
const { my } = createToolDeps(loadConfig());
const requests = await result("getMyRequests", my.GET("/api/requests/my"));
```
## Разработка
```bash
npm install
npm test # юнит-тесты и проверка спек на фикстурах
npm run lint:spec # линтер OpenAPI
npm run gen # перегенерировать src/generated после правки openapi/
npm run verify:live # сверить спеки с живыми ответами (нужны ITMO_* переменные)
npm run build
```
`verify:live` выводит только названия операций, HTTP-статусы и пути ошибок схемы, без самих данных.
Новые фикстуры добавляйте только после `scripts/sanitize-fixture.ts`, он убирает персональные данные.
## Лицензия
MIT
TDQS
Scored across 19 tools
Most tools target distinct resources or actions (people, schedule, sport, dormitory, etc.). The main overlap is among the three grade/points tools (itmo_get_grades, itmo_get_grade_details, bars_get_scores), which come from different systems and could confuse an agent without careful reading.
All tools use snake_case verb_noun names, but 18 of 19 are prefixed with itmo_, while bars_get_scores breaks the server prefix. This minor inconsistency is the only deviation.
19 tools is borderline heavy (rubric: 16-25 feels heavy). While each tool covers a distinct facet of the student portal, the count could be reduced by consolidating some sport-related tools.
The surface is almost entirely read-only; there are no create/update/delete or action tools (e.g., enrolling in sport, submitting requests, booking rooms). This is a significant gap for a student portal domain.