A Claude Code skill for generating, reviewing, and improving Moodle quiz questions
Create exam-ready Moodle quizzes directly from Claude Code. Supports GIFT (~6x fewer tokens than XML), Moodle XML (with syntax highlighting), and Aiken formats. Enforces answer-length balancing, self-contained stems, and plausible distractors based on real pedagogical best practices.
# Install
mkdir -p ~/.claude/skills
git clone https://github.com/danielcregg/moodle-mcq.git ~/.claude/skills/moodle-mcq
# Use in Claude Code
/moodle-mcq
Generate 20 MCQ questions on Python data structures for first-year students| Mode | Invoke With | What It Does | Target Success Rate |
|---|---|---|---|
| Create Easy | /moodle-mcq easy |
Revision quizzes, formative assessment, confidence building | 85-95% |
| Create Standard | /moodle-mcq |
Balanced conceptual questions with plausible distractors | 75-85% |
| Create Challenging | /moodle-mcq challenging |
Exam-grade questions testing judgment and trade-offs | 60-75% |
| Review & Improve | /moodle-mcq review |
Assess existing MCQs, fix weak distractors, rebalance lengths | N/A |
| Format | Tokens per 10 Qs | Best For | Moodle Import Path |
|---|---|---|---|
| GIFT (default) | ~550 | Standard quizzes, fastest generation | Question bank > Import > GIFT |
| Moodle XML | ~3,500 | Code with syntax highlighting, images, tags | Question bank > Import > Moodle XML |
| Aiken | ~300 | Quick review, simplest format | Question bank > Import > Aiken |
GIFT uses approximately 6x fewer tokens than Moodle XML for the same questions. For a 50-question quiz, that is ~2,750 tokens (GIFT) vs ~17,500 tokens (XML).
| Easy (85-95% success rate) | Standard (75-85% success rate) | Challenging (60-75% success rate) |
|---|---|---|
Tests: single-fact recall Distractors from other languages |
Tests: conceptual understanding Distractors are real Java keywords |
Tests: prioritization across 4 real security concerns |
| Before (too easy, 90%+ success rate) | After (appropriate, ~60% success rate) |
|---|---|
Problems:
|
Fixes: no lecture ref, all plausible, balanced lengths |
| Type | GIFT | XML | Aiken |
|---|---|---|---|
| Multiple choice (single answer) | Yes | Yes | Yes |
| Multiple choice (multi-answer) | Yes | Yes | - |
| True / False | Yes | Yes | - |
| Short answer | Yes | Yes | - |
| Numerical | Yes | Yes | - |
| Matching | Yes | Yes | - |
| Cloze / Fill-in-the-blank | Yes | Yes | - |
| Calculated | - | Yes | - |
| Drag and drop | - | Yes | - |
Students exploit patterns when correct answers are systematically longer. This skill enforces a mandatory distribution and includes a verification table in every review document:
| Correct Answer Position | Target | Purpose |
|---|---|---|
| Shortest option | ~15% | Prevents "longest = correct" bias |
| Longest option | ~15% | Prevents "shortest = correct" bias |
| Middle length | ~70% | No exploitable pattern |
How it works
- After drafting all questions, the skill computes each option's character count (excluding HTML markup)
- Classifies each correct answer as Shortest / Longest / Middle
- Tallies across all questions to verify the 15/15/70 target
- Rebalances if needed by adjusting distractor verbosity or trimming correct answers
- Includes the distribution table in the review document for instructor verification
Every question must stand alone without external references:
| Rule | Bad Example | Good Example |
|---|---|---|
| No lecture refs | "According to the lecture..." | "In Python..." |
| No slide refs | "As shown on slide 12..." | Context in the stem |
| No example refs | "In the Person class example..." | Include the actual code |
| Code included | "What does the setter do?" | Show the full code in the question |
Click to expand
| Strategy | Description | Example |
|---|---|---|
| Overcorrection | Takes a good practice too far | "Review every line with the entire team" |
| Outdated Practice | Was correct in older versions | "Use class components for all React code" |
| Wrong Context | Correct for different situations | "Use SELECT * for better performance" |
| Incomplete Solution | Addresses part of the problem | "Add unit tests" (when security review also needed) |
| Reasonable Misunderstanding | Based on incomplete knowledge | "Copilot adapts based on package.json versions" |
Each distractor is tested against: Can an expert eliminate this without thinking? Would a B-grade student find it tempting? Does it represent a real misconception?
When generating Moodle XML, code questions include inline CSS syntax highlighting that renders correctly in Moodle without any plugins:
Java: blue keywords, green numbers, red strings, green comments Python: blue keywords, teal built-ins, green numbers, red strings
Example: Java code in Moodle XML
<questiontext format="html">
<text><![CDATA[<p>What happens when a username longer than 10 characters is passed?</p>
<pre style="background-color: #f4f4f4; padding: 10px; border-radius: 5px;
border-left: 3px solid #4CAF50; font-family: 'Courier New', monospace;">
<span style="color: #0000ff;">public void</span> setUsername(String username) {
<span style="color: #0000ff;">if</span> (username.length() > <span style="color: #098658;">10</span>) {
<span style="color: #0000ff;">this</span>.username = username.substring(<span style="color: #098658;">0</span>, <span style="color: #098658;">10</span>);
}
}</pre>]]></text>
</questiontext>Built-in fixes for common Moodle import issues:
| Issue | Fix |
|---|---|
<n> instead of <name> |
Enforces full <name> tag (prevents "Missing question name" error) |
| Penalty tags | Omitted entirely (no penalty for wrong answers) |
| Generic titles | Requires descriptive names (e.g., "Array_Index_Exception") |
| Missing CDATA | All text wrapped in <![CDATA[...]]> sections |
| Category format | Uses $course$/Category Name structure |
Every generation includes a human-readable review document (_review.md) for instructor verification:
# Python Data Structures - Quiz Review
## Difficulty Mode: Standard
## Output Format: GIFT
## Length Distribution Summary
| Correct Answer Position | Count | Percentage | Target |
|------------------------|-------|------------|--------|
| Shortest | 3 | 15% | ~15% |
| Longest | 3 | 15% | ~15% |
| Middle | 14 | 70% | ~70% |
## Category: Lists and Tuples
### Question 1: List_vs_Tuple_Mutability
*Correct answer length: MIDDLE*
What is the key difference between a list and a tuple in Python?
A) Tuples are faster but have no other difference
B) **Lists are mutable, tuples are immutable**
C) Lists can store multiple types, tuples cannot
D) Lists use square brackets, tuples use parentheses$CATEGORY: Programming/Python/Data Types
::List vs Tuple::What is the key difference between
a list and a tuple in Python?{
=Lists are mutable, tuples are immutable#Correct!
Lists can be modified after creation while tuples cannot.
~Lists use square brackets, tuples use parentheses#Syntax
differs, but the key functional difference is mutability.
~Lists can store multiple types, tuples cannot#Both
can store mixed data types.
~Tuples are faster but have no other difference#Tuples
are slightly faster, but immutability is the key difference.
}
Note for programming questions: GIFT requires escaping
~ = { } # :characters. For code-heavy questions, Moodle XML with<![CDATA[<pre>...</pre>]]>is recommended to avoid escaping issues.
~/.claude/skills/moodle-mcq/
SKILL.md # Skill definition (the brain)
README.md # This file
LICENSE # MIT
| Platform | Supported | How |
|---|---|---|
| Claude Code (CLI) | Yes | Install as skill, invoke with /moodle-mcq |
| Claude Desktop | Yes | Add as skill via Settings > Skills |
| Moodle 4.x | Yes | Import generated GIFT/XML/Aiken files |
| Moodle 3.x | Yes | Import generated GIFT/XML/Aiken files |
| Windows / macOS / Linux | Yes | All platforms supported |
mkdir -p ~/.claude/skills
git clone https://github.com/danielcregg/moodle-mcq.git ~/.claude/skills/moodle-mcqVerify: type /moodle-mcq in Claude Code — if the skill loads, you are good to go.
- Download
SKILL.mdfrom this repo (or download the repo as a.zip) - Open Claude Desktop
- Go to Settings > Skills
- Click Upload skill
- Drag and drop the
SKILL.mdfile, or the.zipfile containing it
File requirements:
.mdfile must contain skill name and description formatted in YAML frontmatter.zipor.skillfile must include aSKILL.mdfile
Download SKILL.md from this repo and place it at:
~/.claude/skills/moodle-mcq/SKILL.md
/moodle-mcq easy
Generate 10 easy revision questions on Python basics (variables, loops, functions)
for students preparing for their first exam.
/moodle-mcq
I have a lecture on Java OOP (inheritance, polymorphism, encapsulation).
Generate 15 MCQ questions in GIFT format, 5 per topic.
/moodle-mcq challenging
Create 20 hard questions on Python error handling and exceptions.
Use Moodle XML format with syntax-highlighted code snippets.
Target 60-70% success rate.
/moodle-mcq review
[paste existing questions in any format]
Fix weak distractors, balance answer lengths, remove any lecture references.
/moodle-mcq
Extract content from lecture.pptx and generate 25 questions across all topics.
The skill uses python -m markitdown lecture.pptx to extract slide content when PowerPoint files are provided.
- Log into Moodle as a teacher or admin
- Navigate to your course
- Go to Question bank > Import
- Select the format matching your file:
.giftfiles: select GIFT format.xmlfiles: select Moodle XML format.txtfiles: select Aiken format
- Upload the file and click Import
- Review the imported questions in the question bank
| Version | Date | Changes |
|---|---|---|
| 3.0.0 | 2026-03-24 | Major merge: combined 4 skills into one. Added GIFT + Aiken formats. Added Python syntax highlighting. Published to GitHub. |
| 3.1.0 | 2026-03-24 | Added Easy difficulty mode (85-95% success rate) for revision quizzes and formative assessment. Four modes: easy, standard, challenging, review. |
| 2.3 | 2026-02-12 | Merged reviewer skills into single mcq-reviewer |
| 2.2 | 2026-02-12 | Merged creator skills with difficulty mode parameter |
| 2.1 | 2025-12-03 | XML tag docs fix, length distribution tables |
| 2.0 | 2025-11-06 | Difficulty calibration overhaul, 5 distractor strategies |
| 1.4 | 2025-10-30 | Java syntax highlighting CSS template |
| 1.3 | 2025-10-30 | Self-contained code requirement |
| 1.2 | 2025-10-30 | Critical <name> tag fix for Moodle import |
| 1.0 | 2025-10-23 | Initial skill for AI Assisted Programming module |
Contributions are welcome. If you have ideas for improving question generation quality, supporting additional Moodle question types, or fixing edge cases:
- Fork this repository
- Create a feature branch (
git checkout -b feature/your-feature) - Commit your changes
- Push to the branch (
git push origin feature/your-feature) - Open a Pull Request
MIT - use it however you like.