npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

quiz-mcp

v1.1.1

Published

MCP server for interactive quizzes with a polished web UI

Readme

Quiz MCP

A Model Context Protocol (MCP) server for running interactive quizzes. This tool bridges the gap between AI generation and user interaction by allowing agents to generate quizzes and immediately present them to users in a polished web interface.

Features

  • Interactive Web UI: Built with SvelteKit 5 + Tailwind CSS + DaisyUI for a responsive and smooth experience.
  • MCP Support: Fully compatible with Model Context Protocol for AI agent integration.
  • 8 Question Types:
    • Single Choice - Radio button selection
    • Multiple Choice - Checkbox selection
    • Remove Extra - Identify and select incorrect items
    • Order - Drag-and-drop reordering
    • Match - Click-to-match pairs
    • Text - Free-form textarea input
    • Input - Single-line text input
    • Input List - Dynamic list of text inputs
  • Flexible Configuration: Theme, timer, shuffling, progress indicators, and more.
  • CLI Tool: Easy-to-use command line interface for local testing and usage.
  • i18n Ready: Built-in internationalization support (English, Spanish, Russian, Ukrainian).
  • Storybook: Component documentation and development.

Local-first & Privacy by Design

Quiz MCP runs entirely on your machine.

  • No external APIs
  • No cloud services
  • No telemetry
  • No user data leaves your system

AI agents communicate with the quiz UI through a local MCP server. All interactions stay within your local environment (unless you explicitly configure a webhook).

Installation

pnpm install
pnpm build

Usage

CLI Commands

Quiz MCP provides two CLI commands:

quiz run

Run interactive quizzes via CLI with browser interface.

Usage:

node bin/quiz-mcp run [options]

Options:

| Option | Description | | ------------------------- | ------------------------------------------------------------- | | -f, --file <PATH> | Path to quiz JSON file | | -q, --quiz <JSON> | Direct JSON quiz data | | -u, --url <URL> | URL to fetch quiz JSON from | | -c, --config <PATH> | Path to configuration file | | -o, --output <PATH> | Output results file path | | -w, --webhook-url <URL> | Webhook URL for results | | -p, --port <NUMBER> | Server port (default: 3000) | | -h, --host <STRING> | Server host (default: localhost) | | --auto-port | Automatically use a free port if the requested port is in use | | -O, --open | Auto-open browser | | -v, --verbose | Verbose logging |

Examples:

# Run a quiz from a file
node bin/quiz-mcp run --file ./my-quiz.json

# Run with auto-open browser
node bin/quiz-mcp run --file ./quiz.json --open

# Run and save results to file
node bin/quiz-mcp run --file ./quiz.json --output ./results.json

# Run on custom port
node bin/quiz-mcp run --file ./quiz.json --port 8080

# Run with inline JSON
node bin/quiz-mcp run --quiz '{"title":"Test","questions":[{"id":"q1","type":"single","question":"Test?","options":["A","B"]}]}'

# Run a quiz from a URL
node bin/quiz-mcp run --url "https://raw.githubusercontent.com/karerckor/quiz-mcp/main/quiz-examples/javascript-fundamentals.jsonc"

Try Example Quizzes

You can run the example quizzes directly from the GitHub repository without cloning:

# Run JavaScript Fundamentals quiz (via npx)
npx quiz-mcp run --url "https://raw.githubusercontent.com/karerckor/quiz-mcp/main/quiz-examples/javascript-fundamentals.jsonc"

# Run Web Development quiz (via pnpx)
pnpx quiz-mcp run --url "https://raw.githubusercontent.com/karerckor/quiz-mcp/main/quiz-examples/web-development.jsonc"

# Run with auto-open browser
npx quiz-mcp run --url "https://raw.githubusercontent.com/karerckor/quiz-mcp/main/quiz-examples/javascript-fundamentals.jsonc" --open

quiz mcp

Run as MCP server for AI agent integration.

Usage:

node bin/quiz-mcp mcp [options]

Options:

| Option | Description | | ----------------------------- | --------------------------------------------------------------- | | -c, --config <PATH> | MCP configuration file path | | --quiz-config <PATH> | Quiz configuration file path (layout, theme, language, webhook) | | -s, --storage <PATH> | Session storage directory | | -m, --max-sessions <NUMBER> | Maximum concurrent sessions | | -q, --quiz <PATH> | Default quiz file path | | -l, --log-level <LEVEL> | Log level (debug, info, warn, error) | | -p, --port <NUMBER> | Server port (default: 3000) | | -h, --host <STRING> | Server host (default: localhost) | | --auto-port | Automatically use a free port if the requested port is in use | | -v, --verbose | Verbose logging |

Examples:

# Start MCP server with default settings
node bin/quiz-mcp mcp

# Start on custom port
node bin/quiz-mcp mcp --port 8080

# With custom quiz configuration
node bin/quiz-mcp mcp --quiz-config ./quiz-config.json

# With custom session storage
node bin/quiz-mcp mcp --storage ./sessions --max-sessions 50

# With verbose logging
node bin/quiz-mcp mcp --log-level debug

Running with Package Managers

Quiz MCP can be run directly with npx, pnpx, or bunx without manual installation:

# Using npx (npm)
npx quiz-mcp run --file ./my-quiz.json

# Using pnpx (pnpm)
pnpx quiz-mcp run --file ./my-quiz.json

# Using bunx (bun)
bunx quiz-mcp run --file ./my-quiz.json

# Run MCP server
npx quiz-mcp mcp
pnpx quiz-mcp mcp
bunx quiz-mcp mcp

# Run a quiz from URL (try example quizzes)
npx quiz-mcp run --url "https://raw.githubusercontent.com/karerckor/quiz-mcp/main/quiz-examples/javascript-fundamentals.jsonc"
pnpx quiz-mcp run --url "https://raw.githubusercontent.com/karerckor/quiz-mcp/main/quiz-examples/web-development.jsonc"

Standalone Mode (CLI)

Run a quiz directly from a local JSON file:

# Run a JavaScript quiz
pnpm quiz:js

# Run a Web Development quiz
pnpm quiz:web

Or run any custom file:

node bin/quiz-mcp run --file ./my-quiz.json --open

MCP Mode (AI Agent)

Start the MCP server to allow AI agents to connect:

node bin/quiz-mcp mcp

The server runs on port 3000 (default) or the port specified in your configuration.

MCP Client Setup

Configure Quiz MCP as an MCP server in your AI editor:

Claude Code

Add to ~/.claude/mcp.json:

{
	"mcpServers": {
		"quiz": {
			"command": "npx",
			"args": ["quiz-mcp", "mcp"],
			"env": {}
		}
	}
}

Or using the local build:

{
	"mcpServers": {
		"quiz": {
			"command": "node",
			"args": ["/path/to/quiz-mcp/bin/quiz-mcp", "mcp"],
			"env": {}
		}
	}
}

OpenCode

Add to ~/.opencode/mcp.json or in OpenCode settings under MCP Servers:

{
	"mcpServers": {
		"quiz": {
			"command": "npx",
			"args": ["quiz-mcp", "mcp"],
			"disabled": false
		}
	}
}

Cursor

Add to ~/.cursor/mcp.json:

{
	"mcpServers": {
		"quiz": {
			"command": "npx",
			"args": ["quiz-mcp", "mcp"],
			"env": {}
		}
	}
}

VSCode (with MCP Extension)

Add to your VSCode settings (JSON) or .vscode/mcp.json:

{
	"mcpServers": {
		"quiz": {
			"command": "npx",
			"args": ["quiz-mcp", "mcp"],
			"env": {}
		}
	}
}

Development

  1. Start the development server:

    pnpm dev
  2. Run the CLI in dev mode:

    pnpm quiz:js
  3. Run tests:

    pnpm test        # All tests (e2e + unit)
    pnpm test:e2e    # Playwright e2e tests
    pnpm test:unit   # Vitest unit tests
  4. Run Storybook:

    pnpm storybook

Architecture

The project follows a modular SvelteKit architecture:

src/
├── cli/              # CLI entry points (unified quiz CLI)
│   ├── cli.ts        # Main CLI with run/mcp commands
│   ├── mcp.ts        # MCP server setup
│   └── args.ts       # CLI argument parsing
├── lib/              # Shared logic and types
│   ├── components/   # Svelte components
│   │   ├── questions/# Question type components (8 types)
│   │   ├── ui/       # UI components (QuizProgress, QuestionNav, etc.)
│   │   └── QuizRenderer.svelte
│   ├── server/       # Server-side logic
│   │   └── sessions.ts  # In-memory session management
│   ├── stores/       # Svelte stores
│   │   └── quiz.svelte.ts
│   ├── utils/        # Utilities
│   │   └── markdown.ts
│   └── types.ts      # Comprehensive TypeScript types + Zod schemas
├── routes/           # SvelteKit routes
│   ├── api/          # API endpoints
│   │   ├── demo/     # Demo endpoint
│   │   └── quiz/     # Quiz session management endpoints
│   └── [quizId]/     # Quiz session routes
├── server/           # Custom Node.js server
│   └── index.ts      # QuizServer implementation
├── stories/          # Storybook stories
└── hooks.*           # SvelteKit hooks

Key Components

| Component | Purpose | | ------------------- | -------------------------------------------------------- | | QuizRenderer | Main quiz container that orchestrates question rendering | | QuestionContainer | Wrapper for individual questions with validation | | SingleChoice | Single selection (radio buttons) | | MultipleChoice | Multiple selection (checkboxes) | | RemoveExtra | Error-finding question type | | Order | Drag-and-drop ordering | | Match | Pair matching | | Text | Free-form text input | | Input | Single-line text input | | InputList | Dynamic input list |

Server Architecture

The QuizServer class provides:

  • Session Management: In-memory session storage with expiration
  • Session Lifecycle: Create, poll status, cancel sessions
  • Result Collection: Answers, time spent, metadata
  • Webhook Support: Optional POST results to external URL

Session Flow

┌─────────────────┐     ┌────────────────┐     ┌─────────────────┐
│  AI Agent/MCP   │────▶│  QuizServer    │────▶│  SvelteKit App  │
│  (create quiz)  │     │  (sessions)    │     │  (web UI)       │
└─────────────────┘     └────────────────┘     └─────────────────┘
        │                      │                        │
        │  sessionId/quizId    │                        │
        │◀─────────────────────│                        │
        │                      │                        │
        │                      │    user completes      │
        │                      │◀───────────────────────┘
        │   poll status        │                        │
        │─────────────────────▶│                        │
        │                      │                        │
        │   results (optional) │                        │
        │◀─────────────────────│                        │

MCP Tools

get_quiz_format

Returns the JSON schema and examples for creating valid quiz content.

Input: {}

Output: JSON schema for QuizData and example question objects.

start_quiz

Starts a new quiz session.

Input:

{
  "quiz": "QuizData object or JSON string",
  "config": {
    "theme": "light|dark|auto",
    "timerEnabled": boolean,
    "shuffleQuestions": boolean,
    "shuffleOptions": boolean,
    "webhook": "url"
  },
  "open": boolean // (Optional) Auto-open browser
}

Output:

{
	"ok": true,
	"openUrl": "http://localhost:3000/quiz/session-id",
	"quizId": "...",
	"sessionId": "...",
	"expiresAt": "..."
}

get_quiz_status

Checks the status of an active session.

Input:

{
  "quizId": "string",
  "sessionId": "string",
  "includeAnswers": boolean // (Optional) Include detailed results
}

Output:

{
	"status": "active|completed|expired|not_found|error",
	"startedAt": "ISO timestamp",
	"completedAt": "ISO timestamp (if completed)",
	"progress": {
		"answered": 5,
		"total": 10,
		"percentage": 50
	},
	"answers": {
		/* Only if completed and includeAnswers=true */
	}
}

cancel_quiz

Terminates an active session.

Input:

{
	"quizId": "string",
	"sessionId": "string",
	"reason": "string"
}

Output:

{
	"ok": true,
	"message": "Session cancelled",
	"cancelledAt": "ISO timestamp"
}

Quiz Data Format

The QuizData object structure:

{
	"title": "Quiz Title",
	"description": "Optional description",
	"version": "1.0.0",
	"metadata": {
		"author": "Author Name",
		"difficulty": "easy|medium|hard",
		"estimatedTime": 15,
		"tags": ["tag1", "tag2"]
	},
	"questions": [
		{
			"id": "unique-id",
			"type": "single|multiple|remove-extra|order|match|text|input|input-list",
			"question": "Question text (Markdown supported)",
			"explanation": "Explanation shown after submission",
			"points": 1,
			"required": true,
			"options": ["Option A", "Option B"], // or MatchOptions/InputListOptions
			"attachments": [{ "type": "image", "url": "..." }],
			"validation": { "minLength": 10, "maxLength": 500 }
		}
	]
}

Question Type Options

Simple Options (single, multiple, remove-extra, order):

{
	"options": ["Option A", "Option B", "Option C"]
}

Match Options:

{
	"options": {
		"left": ["Cat", "Dog"],
		"right": ["Meow", "Woof"]
	}
}

Input List Options:

{
	"options": {
		"minItems": 1,
		"maxItems": 5,
		"placeholder": "Enter item...",
		"addButtonText": "Add Item"
	}
}

Configuration

CLI Config File (config.json)

{
	"layout": {
		"title": "Custom Quiz Title",
		"logo": "/logo.png",
		"hideThemeSwitcher": false,
		"hideLanguageSwitcher": false
	},
	"theme": "auto",
	"shuffleQuestions": false,
	"shuffleOptions": false,
	"allowBackNavigation": true,
	"showProgress": true,
	"showQuestionNumbers": true,
	"timerEnabled": false,
	"timerDuration": 30,
	"language": "en",
	"webhook": "https://your-webhook.com/results",
	"analytics": {
		"enabled": true,
		"provider": "plausible",
		"trackingId": "..."
	}
}

Integration Guide for Agents

  1. Discovery: Call get_quiz_format to understand how to structure a quiz.
  2. Creation: Generate a valid QuizData object based on the user's topic or request.
  3. Execution: Call start_quiz with the generated data.
  4. Handoff: Provide the openUrl to the user so they can take the quiz.
  5. Monitoring: Use get_quiz_status to track progress if needed, or wait for the user to confirm completion.

License

MIT