# Quizzard Quizzard is an **MCP server for trivia and quizzing enthusiasts**. The overarching goal of the project is to have as many useful features to help quizzers stay on top of their game. A number of popular quizzing resources have been integrated (see section titled 'Data Soruces and Attribution') - - Open Trivia DB - J! Archive - user-uploaded PDFs, and - user-input URLs (such as Wikipedia pages). Although these provide sufficient breadth and depth across common trivia question categories, it is crucial to extend this list to include a few other commonly used ones (Jetpunk, Sporcle, etc.; these currently have Cloudflare-related restrictions), as well as handling the user's presence and statistics on these platforms on their behalf. A number of core features have been implemented as tools (see sections 'Features' and 'Tools' for complete list) - - persistent progress tracking - weak area detection - personalised recommendations. The MCP client chosen for testing has been Claude Desktop on Windows; as yet untested on other clients (though incompatibility with others seems unlikely). Kindly report bugs, feature requests, and any relevant thoughts through issues. --- ## Features - **Multiple quiz sources** - OpenTDB (over 4k questions), Jeopardy! (over 200k clues), and any custom source you add - **Custom sources** - ingest PDFs, webpages, or manually enter questions. You can, say, quiz yourself on your own study material - **Mixed quizzes** - draw questions from multiple sources in one session - **Progress tracking** - every session is saved to a local SQLite database - **Weak area detection** - identifies categories where your accuracy is lowest - **Personal bests** - tracks your best score per category and difficulty - **Smart recommendations** - suggests what to play next based on your history --- ## Installation ### 1. Clone the repo ```bash git clone https://github.com/hrmtsh2/quizzard.git cd quizzard ``` ### 2. Create and activate a virtual environment ```bash python -m venv venv # Windows venv\Scripts\activate # macOS/Linux [NOT TESTED YET] source venv/bin/activate ``` ### 3. Install dependencies Install through `pip freeze`-generated requirements.txt - ```bash pip install -r requirements.txt ``` Alternatively, just install the most critical ones - ```bash pip install fastmcp httpx beautifulsoup4 pdfplumber ``` ### 4. Configure your MCP client For Claude Desktop, for example, add the following to your `claude_desktop_config.json`: - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json` - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json` [NOT TESTED YET] ```json { "mcpServers": { "quizzard": { "command": "C:/path/to/quizzard/venv/Scripts/python.exe", "args": ["C:/path/to/quizzard/server.py"] } } } ``` Replace paths with your actual project path. Make sure to use forward slashes on Windows! ### 5. For Claude Desktop - Restart Claude Desktop Quizzard will initialise automatically on first run, creating a local database at `~/.quizzard/quizzard.db`. --- ## Usage Just talk to the LLM naturally (again, tested on Claude Sonnet 4.6). Some sample prompts to get you started - ``` "Quiz me on geography, medium difficulty, 10 questions" "Quiz me on Jeopardy! science clues" "Enable Jeopardy as a source" "What are my weak areas?" "What should I play next?" "Ingest this PDF and quiz me on it" "Quiz me on a mix of OpenTDB and Jeopardy" "Show my recent sessions" "What sources do I have?" ``` --- ## Tools Implemented | Tool | Description | |------|-------------| | `quiz_me` | Start a tracked quiz session | | `submit_quiz_results` | Save results after a quiz (called automatically) | | `get_questions` | Browse/preview questions without starting a session | | `start_session` | Enable deduplication so you never see repeat questions | | `list_categories` | List available categories for a source | | `search_categories` | Search categories by keyword | | `enable_jeopardy` | Download and import the Jeopardy! dataset (~75MB, one-time) | | `ingest_pdf` | Extract questions from a PDF and save as a custom source | | `ingest_url` | Extract questions from a webpage and save as a custom source | | `save_custom_questions` | Manually save a set of questions as a custom source | | `list_sources` | List all available quiz sources | | `recommend_quiz` | Get a personalised quiz recommendation based on your history | | `my_weak_areas` | See your weakest categories (min 5 attempts) | | `my_personal_bests` | See your best scores per category and difficulty | | `my_recent_sessions` | See your recent quiz sessions | | `my_stats` | See accuracy stats across all categories | --- ## Architecture Quizzard is built to be source-agnostic, even with the few sources included so far. Each quiz source implements a common interface, so `server.py` never needs to know which source it's talking to. ``` quizzard/ ├── server.py # core FastMCP server with all the tools ├── client.py # httpx wrapper for external APIs ├── db.py # SQLite database for storing sessions, attempts, stats └── sources/ ├── base.py # QuizSource class (the common interface) ├── opentdb.py # Open Trivia Database ├── jeopardy.py # Jeopardy! dataset (local SQLite) └── user.py # User-defined sources ``` Adding a new source ideally means creating one file in `sources/` and registering it in `question_sources` in `server.py`, with no other changes elsewhere. User data is stored locally at: ``` ~/.quizzard/ ├── quizzard.db # all sessions, attempts, stats, custom questions └── data/ └── combined_season1-41.tsv # Jeopardy dataset (downloaded on first enable) ``` --- ## Data Sources & Attribution - **General trivia** — [Open Trivia Database](https://opentdb.com), licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) - **Jeopardy! clues** — Dataset compiled by [jwolle1](https://github.com/jwolle1/jeopardy_clue_dataset), sourced from [J! Archive](https://j-archive.com) - Jeopardy! is a registered trademark of Jeopardy Productions, Inc. This project is not affiliated with or endorsed by Jeopardy Productions, Inc. This project is for personal, non-commercial use only. ---