ypt-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ypt-mcp how many hours did I study today, and what's my rank?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ypt-mcp
MCP-сервер для трекера учёбы YPT (열품타) на базе библиотеки
ypt-python.
Работает по stdio-транспорту и через Model Context Protocol открывает доступ к дневным логам учёбы, рейтингам, учебным группам и таймеру занятий.
Возможности
Профиль и сводка за сегодня (
get_profile)Дневные логи учёбы по датам (
get_day_log)Твоё место в рейтинге категории и таблицы лидеров (
get_my_rank,get_leaderboard)Поиск групп, мои группы, участники (
browse_groups,get_my_groups,get_group_members)Таймер занятий: старт/стоп с учётом сессии (
start_study,stop_study)
Related MCP server: UVG Local MCP Server
Требования
uv (для запуска через
uvx/uv run)Доступ к GitHub-репозиториям
derived-functor/ypt-mcpиderived-functor/ypt-private-client(приватные — нужен настроенный git-auth: SSH-ключ или PAT)
Быстрый старт
Вариант 1 — через uvx (основной)
Одна команда, без клонирования:
uvx --from git+https://github.com/derived-functor/ypt-mcp ypt-mcpuvx сам подтянет ypt-mcp и его зависимость ypt-python
(из git+https://github.com/derived-functor/ypt-private-client), соберёт и
запустит в изолированном окружении.
При необходимости можно пинить версию: --from git+...@main.
Вариант 2 — локальная разработка через uv run
git clone https://github.com/derived-functor/ypt-mcp
cd ypt-mcp
uv sync
uv run ypt-mcpПри работе над самой библиотекой
ypt-pythonудобно временно вернуть вpyproject.tomlлокальный источник:[tool.uv.sources]={ path = "/path/to/ypt-private-client", editable = true }.
Аутентификация
Сервер использует кэш JWT-токена ~/.cache/ypt-python/token (общий с
ypt-cli). Если токена нет, логинится по переменным окружения:
export YPT_EMAIL="you@example.com"
export YPT_PASSWORD="your-password"Либо заранее выполни логин через библиотеку:
cd ~/probe/ypt-private-client && uv run ypt-cli loginПриоритет: закэшированный токен → YPT_EMAIL/YPT_PASSWORD. Если токен
протух, сервер сам перелогинится и обновит кэш. Пароль нигде не хранится
(в кэше только JWT).
Не коммить реальные
YPT_EMAIL/YPT_PASSWORDв файлы конфигов — используй интерполяцию{env:VAR}(см. ниже), тогда значения попадут только в окружение.
Подключение клиентов
opencode (opencode.json)
Проектный opencode.json или глобальный ~/.config/opencode/opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"ypt": {
"type": "local",
"command": ["uvx", "--from", "git+https://github.com/derived-functor/ypt-mcp", "ypt-mcp"],
"environment": {
"YPT_EMAIL": "{env:YPT_EMAIL}",
"YPT_PASSWORD": "{env:YPT_PASSWORD}"
}
}
}
}Заметки:
command— массив строк, оболочка не используется;{env:VAR}подставляет значение из окружения opencode (не$VAR);после изменения конфига перезапусти opencode — конфиг подхватывается только при старте.
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"ypt": {
"command": "uvx",
"args": ["--from", "git+https://github.com/derived-functor/ypt-mcp", "ypt-mcp"],
"env": {
"YPT_EMAIL": "you@example.com",
"YPT_PASSWORD": "your-password"
}
}
}
}Тулы
Тул | Назначение |
| Профиль, категория/страна, предметы, сводка за сегодня |
| Лог учёбы за дату |
| Твоё место в рейтинге категории |
| Таблица лидеров категории |
| Поиск публичных групп |
| Твои группы |
| Участники группы |
| Старт таймера учёбы |
| Стоп таймера учёбы |
Время отдаётся в часах (study_hours/rest_hours, float) и в сырых
миллисекундах (study_ms/rest_ms, int). Даты — YYYY-MM-DD.
get_profile
Без аргументов. Возвращает профиль и сводку за сегодня:
{
"nickname": "derived-functor",
"category_code": "ВУЗ",
"category_id": 94,
"country_id": 6,
"subjects": [
{ "id": 131150462, "title": "матеша задачи", "study_hours": 0.0, "archived": false }
],
"day_log": {
"date": "2026-09-12",
"study_hours": 0.44,
"rest_hours": 2.15,
"subjects": [
{ "subject_id": 131150462, "subject_title": "матеша задачи", "study_hours": 0.44 }
]
}
}get_day_log(date)
Аргумент | Тип | Описание |
|
| Дата в формате |
{
"date": "2026-09-12",
"study_ms": 1586019,
"study_hours": 0.44,
"rest_hours": 2.15,
"max_study_hours": 0.44,
"added_hours": 0.0,
"subjects": [
{ "subject_id": 131150462, "subject_title": "матеша задачи", "study_ms": 1586019, "study_hours": 0.44 }
]
}get_my_rank(category_id, country_id)
Аргумент | Тип | Описание |
|
| ID категории из |
|
| ID страны из |
Вернёт число (номер места) или null, если рейтинга нет.
get_leaderboard(category_id, country_id, date, page, rank_type, limit)
Аргумент | Тип | Дефолт | Описание |
|
| — | ID категории |
|
| — | ID страны |
|
| — | Дата |
|
|
| Номер страницы (20 записей) |
|
|
| Период: |
|
|
| Сколько участников вернуть |
{
"total_count": 729,
"members": [
{ "nickname": "lisha.rix", "user_id": 17526047, "study_hours": 11.08, "studicon_id": 0 }
]
}browse_groups(category_id, page, country_id, order_type, only_available, only_open, only_cam)
Аргумент | Тип | Дефолт | Описание |
|
|
| Фильтр по категории (0 = все) |
|
|
| Номер страницы |
|
|
| Фильтр по стране |
|
|
| Сортировка |
|
|
| Только группы со свободными местами |
|
|
| Только открытые группы |
|
|
| Только с камерой |
get_my_groups
Без аргументов. Список групп с id, title, owner, member_count.
get_group_members(group_id, country_id)
Аргумент | Тип | Описание |
|
| ID группы |
|
| ID страны |
У каждого участника: user_id, nickname, category, study_hours,
studying (учится ли прямо сейчас).
start_study(subject, device_model) / stop_study(started_at, device_model)
Аргумент | Тип | Дефолт | Описание |
|
| — | Название предмета (для start) |
|
|
| Старт сессии epoch ms (для stop) |
|
|
| Модель устройства для API |
start_study возвращает started_at (epoch ms) и дневной лог. stop_study
без started_at использует записанную сессию (state-файл
~/.cache/ypt-python/study_started_at, тот же, что у ypt-cli).
Сценарии-примеры
Все примеры общаются с сервером по stdio через Python-клиент mcp:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
CMD = ["uvx", "--from", "git+https://github.com/derived-functor/ypt-mcp", "ypt-mcp"]
async def call(tool: str, args: dict):
params = StdioServerParameters(command=CMD[0], args=CMD[1:])
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
res = await session.call_tool(tool, args)
return "".join(c.text for c in res.content)
async def main():
# 1. Ежедневный отчёт
profile = await call("get_profile", {})
print(profile)
# 2. Топ категории (id/страну берём из профиля)
top = await call("get_leaderboard", {
"category_id": 94, "country_id": 6, "date": "2026-09-12", "limit": 10,
})
print(top)
# 3. Мои группы и участники
groups = await call("get_my_groups", {})
members = await call("get_group_members", {"group_id": groups[0]["id"], "country_id": 6})
print(members)
# 4. Таймер: старт → рядом повторяющихся вызовов нет → стоп
started = await call("start_study", {"subject": "матеша задачи"})
stopped = await call("stop_study", {"started_at": started["started_at"]})
print(stopped)
asyncio.run(main())Обработка ошибок
Ситуация | Поведение |
Нет токена и нет | Ошибка с сообщением «credentials not found» |
Протухший токен | Сервер перелогинится и повторит вызов автоматически |
| Ошибка — нужен |
Ошибки YPT API / сети | Пробрасываются выше с кодом/текстом из библиотеки |
Архитектура
LLM/клиент (opencode, Claude Desktop)
│ MCP (stdio, JSON-RPC)
▼
ypt-mcp (mcp SDK, тулы, auth-менеджмент)
│ ypt-python (async-клиент, pydantic-модели)
▼
YPT REST API (https://pi.tgclab.com)src/ypt_mcp/server.py— все тулы и логика аутентификации~/.cache/ypt-python/token— кэш JWT~/.cache/ypt-python/study_started_at— старт текущей сессии таймераpyproject.toml— зависимости (mcp,ypt-pythonиз git) и entry point
Проверка
Смоук-тест: запустить сервер, выполнить handshake и вывести список тулов.
uvx --from git+https://github.com/derived-functor/ypt-mcp python - <<'EOF'
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
params = StdioServerParameters(
command="uvx",
args=["--from", "git+https://github.com/derived-functor/ypt-mcp", "ypt-mcp"],
)
async with stdio_client(params) as (r, w):
async with ClientSession(r, w) as s:
await s.initialize()
print([t.name for t in (await s.list_tools()).tools])
asyncio.run(main())
EOFОжидаемый результат — 9 тулов: get_profile, get_day_log, get_my_rank,
get_leaderboard, browse_groups, get_my_groups, get_group_members,
start_study, stop_study.
Известные особенности
Для работы get_leaderboard в репозитории ypt-private-client исправлен
хелпер _get() в src/ypt_python/_models.py: теперь null-значения
(которые API присылает для si/tc) игнорируются и заменяются дефолтом
вместо падения int(None). Фикс входит в текущий HEAD ветки main и
подтягивается автоматически через git-источник ypt-python.
Available Tools
9 toolsbrowse_groupsB
Browse public study groups.
:param category_id: Filter by category ID; ``0`` means all categories.
Default ``0``.
:type category_id: int
:param page: Page number. Default ``1``.
:type page: int
:param country_id: Filter by country ID; omit for all countries.
:type country_id: int | None
:param order_type: Sort order, e.g. ``"promotedAt"``. Default
``"promotedAt"``.
:type order_type: str
:param only_available: Show only groups with free slots. Default
``False``.
:type only_available: bool
:param only_open: Show only open groups. Default ``False``.
:type only_open: bool
:param only_cam: Show only groups with camera verification. Default
``False``.
:type only_cam: bool
:returns: List of group mappings with ``id``, ``title``, ``category``,
``owner``, ``slogan`` and ``member_count``.
:rtype: list[dict[str, Any]]
:raises RuntimeError: If YPT credentials are not configured.
Inputs: page, only_cam, only_open, country_id, +3 more. Returns: result
get_day_logA
Return your study log for the given date.
:param date: Date in YYYY-MM-DD format, e.g. ``"2026-09-12"``.
:type date: str
:returns: Mapping with ``date``, ``study_ms``/``study_hours``,
``rest_ms``/``rest_hours``, ``max_study_ms``/``max_study_hours``,
``added_ms``/``added_hours`` and a ``subjects`` list of
``{subject_id, subject_title, study_ms, study_hours}``.
:rtype: dict[str, Any]
:raises RuntimeError: If YPT credentials are not configured.
Inputs: date (required). Returns: object
get_group_membersA
Return the members of a study group with their study stats.
:param group_id: Study group ID, e.g. from ``get_my_groups``.
:type group_id: int
:param country_id: Country ID, as returned by ``get_profile``.
:type country_id: int
:returns: List of member mappings with ``user_id``, ``nickname``,
``category``, ``study_ms``/``study_hours`` and ``studying``
(bool, whether the member is currently studying).
:rtype: list[dict[str, Any]]
:raises RuntimeError: If YPT credentials are not configured.
Inputs: group_id (required), country_id (required). Returns: result
get_leaderboardA
Return the category leaderboard (top studiers) for a date.
:param category_id: Category ID, as returned by ``get_profile``.
:type category_id: int
:param country_id: Country ID, as returned by ``get_profile``.
:type country_id: int
:param date: Leaderboard date in YYYY-MM-DD format.
:type date: str
:param page: Page number, 20 entries per page. Default ``1``.
:type page: int
:param rank_type: Ranking period, ``"day"`` or ``"week"``. Default
``"day"``.
:type rank_type: str
:param limit: Maximum number of members to return. Default ``20``.
:type limit: int
:returns: Mapping with ``total_count`` and the ``members`` list of
``{nickname, user_id, study_ms, study_hours, studicon_id}``.
:rtype: dict[str, Any]
:raises RuntimeError: If YPT credentials are not configured.
Inputs: date (required), country_id (required), category_id (required), page, +2 more. Returns: object
get_my_groupsA
Return the list of study groups you have joined.
:returns: List of group mappings with ``id``, ``title``, ``category``,
``owner``, ``slogan`` and ``member_count``.
:rtype: list[dict[str, Any]]
:raises RuntimeError: If YPT credentials are not configured.
Inputs: no named parameters. Returns: result
get_my_rankA
Return your position in a category leaderboard.
:param category_id: Category ID, as returned by ``get_profile``.
:type category_id: int
:param country_id: Country ID, as returned by ``get_profile``.
:type country_id: int
:returns: Your 1-based rank as ``int``, or ``None`` when no rank is
available for the category.
:rtype: int | None
:raises RuntimeError: If YPT credentials are not configured.
Inputs: country_id (required), category_id (required). Returns: result
get_profileA
Return the logged-in YPT profile with today's study overview.
:returns: Mapping with ``nickname``, ``email``, ``category_code``,
``category_id``, ``country_id``, the ``subjects`` list
(``id``, ``title``, ``study_ms``/``study_hours``, ``archived``) and
the ``day_log`` for today (see the day-log shape in
``get_day_log``).
:rtype: dict[str, Any]
:raises RuntimeError: If YPT credentials are not configured.
Inputs: no named parameters. Returns: object
start_studyA
Start studying a subject and record the session start time.
The session start timestamp is stored on disk (so ``stop_study`` can be
called without arguments) and also returned as ``started_at`` for the
caller to keep.
:param subject: Subject title to start studying, e.g. ``"Матеша"``.
:type subject: str
:param device_model: Device model reported to the YPT API. Defaults to
``"ypt-mcp"``.
:type device_model: str
:returns: Mapping with ``started_at`` (epoch ms) plus the full day-log
shape described in ``get_day_log``.
:rtype: dict[str, Any]
:raises RuntimeError: If YPT credentials are not configured.
Inputs: subject (required), device_model. Returns: object
stop_studyA
Stop the study timer and finish the current session.
If ``started_at`` is omitted the timestamp recorded by :func:`start_study`
is used; the recorded value is cleared after a successful stop.
:param started_at: Session start time in epoch milliseconds, as returned
by ``start_study``. Optional; defaults to the recorded session.
:type started_at: int | None
:param device_model: Device model reported to the YPT API. Defaults to
``"ypt-mcp"``.
:type device_model: str
:returns: The full day-log shape described in ``get_day_log``.
:rtype: dict[str, Any]
:raises RuntimeError: If there is no recorded session and ``started_at``
is not provided, or if YPT credentials are not configured.
Inputs: started_at, device_model. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 9 tools
Each tool targets a distinct resource or action: groups (joined, browse, members), study sessions (start, stop), profile, day log, rank, and leaderboard. Minor overlap exists because get_profile includes today's day_log, but the descriptions clearly differentiate their primary purposes.
All tool names follow a consistent snake_case verb_noun pattern (get_, browse_, start_, stop_). The 'my' qualifier is used consistently for personal resources, with no mixing of conventions.
Nine tools cover groups, study sessions, logging, and rankings without redundancy. This is well within the 3-15 range for a focused MCP server.
Core read operations and the study timer lifecycle are fully covered. Missing group join/leave actions and subject creation are minor gaps that an agent can work around, but they prevent full group interaction.
Maintenance
Related MCP Connectors
Read-only MCP server for ClassQuill, a tutoring-business-management platform.
Model Context Protocol server for Studex tools, notifications, and profile integrations
Remote MCP server for full read/write access to a Zotero library
timesheet.io MCP server - manage timers, projects, tasks and reports
Related MCP Servers
- FlicenseNot gradedqualityBmaintenanceExposes read-only capabilities from the Baihua home server to any MCP client via stdio, including knowledge base search/reading, budget summary, and task listing.-
- FlicenseNot gradedqualityCmaintenanceEnables local text analysis, statistical calculations, and system information retrieval via the Model Context Protocol over stdio.-

openrhyme-mcpofficial
AlicenseAqualityBmaintenanceEnables any MCP-compatible agent to query a local OpenRhyme activity timeline, search history, and issue control commands over stdio while keeping all data on-machine.51MIT- AlicenseAqualityBmaintenanceEnables MCP clients to connect to Agenzax's REST API over stdio, providing tools for messaging, session management, and review-mode oversight.1874 npm5MIT