Skip to main content
Glama

getcourse-mcp

Automate a GetCourse account from an AI agent — grant lesson/training access, manage users and groups — with no official API.

npm version license MCP TypeScript PRs welcome

English · Русский

Why

GetCourse has no public API for the things admins do every day — opening a lesson for a student, adding someone to a training, moving users between groups. Those actions live only in the admin UI.

getcourse-mcp exposes them as MCP tools. It drives a browser you're already logged into over CDP, so it reuses your real session cookie and CSRF token — no scraping of passwords, no fragile API keys. An AI agent (Claude, etc.) can then find a user, inspect their groups and grant access in one turn.

  • 🔑 Uses your live session — connects over CDP to a logged-in Chromium/Yandex browser

  • 👥 Access by groups — the GetCourse model: training/lesson access = group membership

  • 🧩 5 focused tools — status, find user, list groups, check membership, add to groups

  • 🪶 TypeScript, ESM — thin, strict, MIT, no account secrets in the repo

Related MCP server: MoyKlass MCP Server

How access works in GetCourse

Access to a training (and its lessons) is granted by group membership. "Full access" to a course often means membership in a Module 1 group plus a group that starts the drip schedule (module 1 now, the rest on a timer). To "give access like another student", read their groups and reproduce them:

gc_find_user            # student@example.com → id, name
gc_check_membership     # which of these groups is student X in?
gc_add_user_to_groups   # add student Y to the same groups

Franchise / "buyers-only" offers → access via a completed purchase

Some offers (franchises, "только купившие" trainings) deliver access only from a completed purchase — group membership grants nothing there. Grant it in one call:

gc_find_offers   {"query":"Трафик Формула"}                            # → offer id, e.g. 6510356
gc_create_order  {"email":"user@x.ru","offerIds":["6510356"],"complete":true}
#   creates the order AND completes a 0₽ payment → access is live immediately

⚠️ A priced deal left in «Новый» delivers NO access — it must be paid. complete:true (or a later gc_pay_order {"dealId":"…"}) completes it → «Завершен» → access granted. GetCourse rejects a zero payment («Платеж не может быть нулевым»), so a 0₽ deal is completed via the status dropdown (payed = «Завершен»); a priced one via a received payment. The result is read from the deal's own «Статус:» field after a reload. Use complete only for 0₽/comp offers.

A 0₽ order has nothing to pay, so GetCourse flips it «Новый → Завершен» on creation by itself; complete:true then detects the finished deal and touches nothing. Purchase-based access does not appear in the user's groups — that's by design, not a bug. Verify it on /teach/control/stat/user/id/<userId> (Training / Lesson access), which reflects the grant immediately.

Requirements

  1. A Chromium-based browser (Chrome / Yandex) launched with a debug port on a separate profile, logged into your account:

    browser.exe --remote-debugging-port=9222 --user-data-dir=C:\gc-cdp-profile
  2. Node ≥ 18.

Setup

npm install
cp .env.example .env      # set GETCOURSE_BASE_URL (and GETCOURSE_CDP_URL if not :9222)
npm run build

Register it with your MCP client (see .mcp.json.example):

{
  "mcpServers": {
    "getcourse": {
      "command": "node",
      "args": ["dist/index.js"],
      "env": { "GETCOURSE_BASE_URL": "https://your-account.getcourse.ru" }
    }
  }
}

Tools

Tool

Purpose

gc_status

Check the CDP browser session actually has admin rights (not merely that a session exists). Reports the "logged in as a student" case separately.

gc_find_user

Find a user by email → id, name, type, status.

gc_list_training_groups

Access groups of a training (id + name).

gc_list_user_groups

Groups a user belongs to (id + name).

gc_check_membership

Is a user in the given groups? (instant, via the user list)

gc_add_to_groups

Add an existing user to groups via the card (preserves other groups). dryRun.

gc_remove_from_groups

Remove a user from groups = revoke access. dryRun.

gc_add_user_to_groups

Add via the bulk import (creates the user if new) = grant access. dryRun.

gc_copy_access

Give a user the same groups as a reference student. dryRun.

gc_update_user

Edit card fields (first/last name, phone, city, comment). Email is out of scope. dryRun.

gc_find_offers

Search sales offers by name → id + price + actuality.

gc_find_orders

List a user's orders (dealId + status).

gc_create_order

Create an order = grant access via a purchase (the only way for "buyers-only" trainings, where groups don't grant access). Reports the created deal's id and status; a priced deal in «Новый» means no access until paid, complete:true drives it to «Завершён». ⚠️ single-step: dryRun:false creates the order immediately.

gc_pay_order

Complete a deal → «Завершен» → access delivered. amount "0" (default) → status payed; amount > 0 → received payment. Verified by the reloaded «Статус:». ⚠️ don't use 0 on a real paid deal. dryRun.

gc_set_order_status

Change a deal's status (e.g. cancel a duplicate: cancelled + cancelReasonId; payed = «Завершен»). OK only if the reloaded card shows the target status.

gc_refund_order

File a money refund for an order via the GetCourse payment module (real money back to the buyer's card). Only for payments processed by the platform; VAT must mirror the original receipt. dryRun.

gc_unlock_modules

Open modules for a stuck (but paid) student: advance the module-delivery process past its «завершил модуль N» wait (clicks «перейти далее»). all:true opens the whole course; default opens the next module. Needs manager/supervisor rights on the process. dryRun.

gc_grant_full_access

Open ALL lessons of a training locked by stop-lessons: (optional offerId granted first, 0₽) → sublogin as the student → answer every open task with a stub (text, first test option, 1x1 png for required files) → accept the answers in the admin feed → repeat. Success = the admin-side student stats show no «Недоступен (стоп-урок)». Sends answers on the student's behalf — course-owner decision only; lesson/training settings untouched. dryRun only counts locked lessons per block.

gc_user_summary

One call: profile + groups + orders for a user.

gc_list_mailing_categories

List mailing categories (tag-like segmentation) — id + name.

gc_add_to_mailing_category

Add a user to a mailing category.

gc_remove_from_mailing_category

Remove a user from a mailing category.

Usage

Run the MCP server over stdio, or call a tool directly for scripting:

node dist/index.js                                   # MCP (stdio)

npx tsx src/run.ts gc_find_user '{"email":"user@example.com"}'
# → Found: Jane Doe | user@example.com | student | active | id: 100200300

npx tsx src/run.ts gc_add_user_to_groups \
  '{"email":"user@example.com","groupIds":["100001","100002"]}'
# → OK [done] import submitted

npx tsx src/run.ts gc_check_membership \
  '{"email":"user@example.com","groups":[{"id":"100001","name":"Module 1"}]}'
# → ✅ Module 1 (100001)

Implementation notes

  • Granting access (gc_add_user_to_groups) uses the bulk Add users form (/pl/user/user/import?type=text): email + selected groups. For an existing user the "overwrite on match" flag is required (overwriteExisting, default true), otherwise the groups are not applied — the import carries only the email, so no profile data is touched.

  • A direct mass action exists (POST /pl/logic/operation/prepare?operationType=user_addtogroup), but in the current UI it is a selection-builder wizard — a candidate to wire up as an alternative path.

  • Membership is checked through the user list filtered by a user_ingrouprule rule (params.value.selected_id), which reflects membership immediately (the training student list mirrors access asynchronously and is not reliable for verification).

  • Writes never trust their own exit code. A single-step operation can throw after the mutation landed, so gc_create_order snapshots the user's deals first and reports the deal that actually appeared — which also removes the "newest deal must be ours" guess.

  • The session check tests rights, not the mere presence of a session. gc_status probes the admin user list (/pl/user/user) — the endpoint gc_find_user/resolveUserId depend on. It used to check /teach/control, which renders for students too: a student session reported "✅ logged in" and every later read silently ran as that student. The "denied" signal is anchored on GetCourse's own error-page wording so stray list content can't lock an admin out.

  • __name shim. page.evaluate callbacks are serialized and run inside the page. esbuild (what tsx runs on) rewrites named inner functions into __name(...) calls, which do not exist there — hence ReferenceError: __name is not defined under tsx src/*.ts while the compiled dist/*.js works. Every navigation installs a no-op shim (ensureEvalShim), so both entry points behave the same. If you drive page.goto yourself, call ensureEvalShim(page) after it.

Contributing

Contributions are welcome — open an issue or a PR. Good first ideas:

  • direct user_addtogroup mass action instead of the import form

  • a "copy all groups from one student to another" tool

  • revoking access (gc_remove_user_from_groups)

  • exporting students; test coverage

  1. Fork and branch: git checkout -b feature/my-change

  2. npm install, make changes; npm run build and npx tsc --noEmit must pass

  3. Never commit secrets (cookies/passwords/.env) or real account data

  4. Open a PR describing what and why

Security

Secrets (cookies/passwords) live only in the browser and your environment — never in the repo. .env and a local .mcp.json are git-ignored.

License

MIT

Available Tools

19 tools
gc_add_to_groupsB

Добавить существующего пользователя в группы через карточку (чисто, без импорта; сохраняет остальные группы). dryRun — предпросмотр.

Inputs: email (required), groupIds (required), dryRun.

gc_add_to_mailing_categoryA

Добавить пользователя в категорию рассылок (по categoryId из gc_list_mailing_categories).

Inputs: email (required), categoryId (required).

gc_add_user_to_groupsA

Добавить пользователя в группы через импорт (создаёт нового при отсутствии) = выдать доступ. dryRun — предпросмотр.

Inputs: email (required), groupIds (required), dryRun, sendInvitation, +1 more.

gc_check_membershipA

Проверить, состоит ли пользователь (по email) в указанных группах (по списку пользователей — мгновенно).

Inputs: email (required), groups (required).

gc_copy_accessA

Выдать пользователю такой же доступ, как у эталонного ученика (копирует его группы). filter — только группы с подстрокой. dryRun — предпросмотр.

Inputs: toEmail (required), fromEmail (required), dryRun, filter.

gc_create_orderA

Создать заказ по офферам = выдать доступ покупкой (для тренингов «только купившие» группы доступ НЕ дают). 0₽ комп-оффер = доступ без денег. ⚠️ dryRun=false создаёт заказ СРАЗУ (без предпросмотра).

Inputs: email (required), offerIds (required), dryRun, tryPayFromDeposit.

gc_find_offersA

Найти офферы продажи по подстроке названия (id + цена + актуальность). Нужно для gc_create_order.

Inputs: query (required).

gc_find_ordersA

Список заказов (сделок) пользователя по email: dealId + статус + сумма.

Inputs: email (required).

gc_find_userA

Найти пользователя по email в списке пользователей (id, имя, тип, статус).

Inputs: email (required).

gc_list_mailing_categoriesA

Список категорий рассылок (tag-подобная сегментация): id + название. GetCourse не имеет свободных user-тегов — это группы + категории рассылок.

Inputs: email (required).

gc_list_training_groupsA

Список групп доступа, связанных с тренингом (id + название). filter — подстрока по названию.

Inputs: trainingId (required), filter.

gc_list_user_groupsA

Список групп, в которых состоит пользователь (id + название). filter — подстрока по названию.

Inputs: email (required), filter.

gc_refund_orderA

Оформить возврат денег по заказу через платёжный модуль Геткурса (реальный возврат на карту покупателя). Только для платежей через платформу Геткурс. НДС — как в чеке прихода (none = «без НДС»). dryRun — сводка без отправки.

Inputs: dealId (required), vat, amount, dryRun, +1 more.

gc_remove_from_groupsB

Убрать пользователя из групп = закрыть доступ (сохраняет остальные группы). dryRun — предпросмотр.

Inputs: email (required), groupIds (required), dryRun.

gc_remove_from_mailing_categoryC

Убрать пользователя из категории рассылок (по categoryId).

Inputs: email (required), categoryId (required).

gc_set_order_statusB

Изменить статус сделки (напр. отменить дубль: status=cancelled + cancelReasonId).

Inputs: dealId (required), status (required), cancelReasonId.

gc_statusA

Проверить сессию GetCourse: залогинен ли администратор в браузере по CDP.

Inputs: no named parameters.

gc_update_userB

Изменить поля профиля на карточке (имя/фамилия/телефон/город/комментарий). Email вне области. dryRun — без сохранения.

Inputs: email (required), city, phone, dryRun, +3 more.

gc_user_summaryA

Сводка по пользователю за один вызов: профиль + группы + заказы.

Inputs: email (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 19 tools

    Disambiguation4/5

    Most tools have distinct purposes, though gc_add_to_groups and gc_add_user_to_groups both add users to groups, requiring careful reading of descriptions to differentiate (one is clean, the other imports). Overall, descriptions are detailed enough to avoid confusion.

    Naming Consistency5/5

    All tools follow a consistent gc_verb_noun pattern (e.g., gc_add_to_groups, gc_find_offers), with only minor exceptions like gc_status and gc_user_summary, but the style remains uniform and predictable.

    Tool Count5/5

    With 19 tools covering user, group, order, and mailing management, the count is well-scoped for a GetCourse MCP server. Each tool serves a clear purpose without unnecessary redundancy.

    Completeness4/5

    The tool set covers core workflows (CRUD for users, groups, orders) but lacks tools for creating groups or listing all groups. These gaps are minor and can be worked around using existing tools.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to programmatically interact with Coursera, including enrolling in courses, completing lectures, solving quizzes, submitting assignments, earning certificates, and pushing them to LinkedIn.
      1
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables an AI agent to write, check, and run infrastructure tests on students' machines with confirmation, read per-student results and grades, export Moodle-ready grades, and drive a classroom panel from chat while keeping credentials away from the AI.
      1
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables agents to automate icourse163 course workflows, including browser-based login, inspecting course structure, completing task points, submitting quizzes with simulated timing, replying to discussions, and verifying progress.
      13
      MIT