sernobre-moodle-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MOODLE_URL | Yes | URL of the Moodle instance (must be HTTPS, except in development) | |
| MCP_LOG_LEVEL | No | error | warn | info | debug (default: info) | info |
| MOODLE_WS_TOKEN | Yes | Moodle Web Service token | |
| MOODLE_WS_TIMEOUT_MS | No | Timeout per request (default: 30000) | 30000 |
| MOODLE_ALLOW_INSECURE | No | true allows HTTP URLs (development only) | false |
| MOODLE_WS_MAX_RETRIES | No | Number of retries (default: 3) | 3 |
| MOODLE_WS_RATE_LIMIT_PER_SEC | No | Requests per second limit (default: 10) | 10 |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| ws_rawA | Escape hatch: call any Moodle Web Services function with arbitrary parameters. Returns |
| publish_class_lessonA | Publish a LessonPlan markdown file as a Moodle section with component modules. Idempotent: republishing the same lesson updates in place, never duplicates. Default mode is |
| publish_previewA | Publish a LessonPlan in hidden preview mode. Returns the same shape as publish_class_lesson plus |
| confirm_previewA | Make a previewed section visible to students. Propagates visibility to all modules inside the section. Idempotent. |
| generate_videoA | Generate a short Italian-language video with Google Veo 3.1 and embed it in a new mod_page in Moodle. Requires GEMINI_API_KEY env. Returns |
| delete_resourceA | Delete a Moodle course module by idnumber. By default only deletes MCP-managed idnumbers (mcp: prefix). Use force=true to delete any idnumber. Returns noop if the module does not exist. |
| create_sectionA | Create a new section in a course with a given name, summary, position and initial visibility. Idempotent by name: reusing an existing section name returns that section instead of creating a duplicate. |
| update_sectionA | Update a course section (name/summary/visible) identified by section_id. At least one field is required. Visibility propagates to all modules inside the section. |
| hide_sectionA | Hide a course section (and its modules) from students. Visibility propagates to all modules inside the section. |
| release_sectionA | Make a course section visible to students (reverse of hide_section). |
| reorder_sectionsB | Reorder sections in a course. Accepts an array of {section_id, position} and applies the full deterministic layout in one batched call. |
| duplicate_sectionA | Duplicate all modules from a source section into a new section in the same course. New section is named per the |
| get_course_contextA | Returns a compact radiograph of a Moodle course: metadata, sections with module counts, recent MCP-published lessons, and enrolment counts (teachers vs students). Call this before publishing a lesson so the agent knows where it fits. |
| create_courseA | Create a new Moodle course with a stable idnumber. Throws MOODLE_WS_COURSE_EXISTS if the idnumber is already in use. Default: hidden (visible=false), topics format, 10 sections. |
| update_courseB | Update one or more fields of a course (fullname / shortname / summary / visible / lang / categoryid). At least one field is required. |
| duplicate_courseA | Clone a course into a new one (backup+restore under the hood). Defaults copy activities/blocks/filters, NOT users/enrolments/grades. New course is hidden by default. |
| archive_courseA | Archive (visible=0) or un-archive (visible=1) a course. Non-destructive: data, enrolments and teacher access stay intact. Use it for end-of-year cleanup or hiding a course in preparation. |
| list_my_coursesA | List courses where a user is enrolled. Accepts userid (e.g. obtain from get_site_info for the bot, or pass a student_id-mapped Moodle userid). |
| configure_quizA | Create or update a quiz shell (no questions). Idempotent by slug. Default: hidden, unlimited attempts, grade=10, method=highest. The plugin resolves section_num (section number) to section ID internally. Combine with import_gift to populate questions, or use publish_exam_lesson for both in one call. |
| import_giftA | Import GIFT-formatted questions into a quiz. Creates the questions in a bank category and appends them to the quiz slots by default. Idempotent (plugin dedupes by question name within the category). |
| modify_questionA | Edit an existing question (typo fix, reformulation, feedback tweak). Writes directly to DB, bypass Moodle 5.0.2 qbank form bug. Input: course_id, question_id, optional name / question_text / answers[]. Coverage: name, text, answers (answer/feedback/fraction). |
| publish_exam_lessonA | Create or update a quiz and populate it with GIFT questions in one call. Runs plugin repair+promote steps after import so the quiz is immediately attemptable. Idempotent by (course_id, slug). |
| get_quiz_questionsA | List all questions attached to a quiz (identified by its slug). Read-only. Returns question id, name, type, and slot number for each question. |
| list_studentsA | List enrolled users in a course. Filter by role shortname (default: student). Returns id, fullname, email, lastaccess, roles and groups per user. |
| enrol_csvA | Batch-enrol users in a course from a CSV (email,firstname,lastname[,role]). Creates missing users by default with a random temp password. Returns per-row status. |
| unenrol_studentB | Unenrol one or more users from a course. Non-destructive: user data is preserved, only the course enrolment link is removed. |
| create_groupA | Create a group inside a course. Use assign_to_group to populate it after. |
| assign_to_groupA | Add one or more users to a group by group_id. |
| change_roleA | Assign a course-level role to a user (student / teacher / editingteacher / manager). Does NOT unassign previous roles — Moodle supports multiple roles per user per context. |
| reset_passwordA | Reset a user's password. If new_password is omitted, generates a random strong one and returns it (you MUST forward to the user out-of-band). |
| get_gradesA | Get gradebook entries for a user in a course (or for every enrolled user if user_id is omitted). Returns raw/max grade, item name, module type, feedback. |
| get_completionB | Activity completion status for a user in a course: per cmid, the state (incomplete / complete / complete_pass / complete_fail) plus completion timestamp. |
| get_quiz_attemptsA | Quiz attempts for a user on a given quiz. Default: only finished attempts. Set include_review=true to also fetch per-question details (heavier). |
| get_assign_submissionsA | Submissions for an assignment (default: only submitted state). Optionally fetch per-user grading status. |
| grade_manuallyA | Manually grade an assignment submission (mod_assign_save_grade). Feedback text is HTML-safe. Supports team grading and marking workflow state. |
| send_moodle_messageA | Send a private Moodle message to one or more user ids. Max 50 recipients per call. Uses core_message_send_instant_messages. |
| create_forum_announcementB | Post a new discussion in a course forum. If forum_id is omitted, uses the course Announcements (type=news) forum. |
| create_forumA | Create or update a forum (discussion, announcement, Q&A, etc.) in a course section. Idempotent by slug. Default: hidden forum of type "general". Requires the plugin companion. |
| get_course_logsA | Approximate activity log for a course: per-user firstaccess/lastaccess derived from core_enrol_get_enrolled_users. Flags users active within the last N hours (default 24). Moodle core does not expose a generic activity-log WS. |
| get_site_infoA | Get site + user + token info (core_webservice_get_site_info). Use include_functions=true at bootstrap to verify which plugin WS functions are exposed to the token. |
| create_calendar_eventA | Create a calendar event. Default eventtype=course. Set repeat_count>0 to create weekly recurrences. Returns the created event id and metadata. |
| list_calendar_eventsB | List calendar events by courses/groups/categories, optionally filtered by a timestart/timeend range. |
| update_eventA | Reschedule a calendar event to a new timestart. To change name/description/location, delete + re-create (Moodle WS does not expose full event update). |
| delete_eventA | Delete one or more calendar events. Set delete_repeats=true to remove repeat instances as well. |
| list_user_badgesA | List badges earned by a user. Optionally filtered by course_id. Read-only — awarding badges is deferred to v0.6. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/sernobre/moodle-mcp-sernobre'
If you have feedback or need assistance with the MCP directory API, please join our Discord server