Daily Tutor MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Daily Tutor MCPquiz me on CCNA today, 5 questions please"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
🎓 Daily Tutor MCP
Duolingo-style daily practice on any topics you choose, as an MCP server. Spaced repetition · adaptive difficulty · 13 question types · streaks · certification tracks
What is this?
You tell your AI assistant what you want to learn, for example sysadmin, devops, network engineer, or a
certification like CCNA or CKA. Every day it asks you one punchy, real-world question, grades your
answer, explains it, and brings back what you got wrong at the right time.
The MCP server owns the state and the rules. The LLM only writes the questions and the explanations. That split is the whole point: the things LLMs are bad at (counting, scheduling, grading, being unbiased) are done in plain code.
You ▸ quiz me
Tutor ▸ 🚨 3 AM pager: nginx returns 502 right after a deploy. systemctl says it is running.
Which do you check FIRST? A) DNS B) upstream/app logs C) disk quota D) cron
(reply with one letter)
You ▸ b
Tutor ▸ ✅ Correct! +10 XP · 🔥 4-day streak · daily goal reached
502 = the proxy is fine, the upstream is not. Gotcha: `proxy_next_upstream` can hide a flapping backend…Related MCP server: Flashcard MCP
Features
🧠 Multi-topic | Any topics, each with its own level and subtopics. ~25% of questions deliberately mix two topics (a DNS fault that looks like a sysadmin problem). |
🎲 13 question types | Multiple choice, multi-select, true/false, fill-the-blank, command challenge, predict-the-output, troubleshooting, ordering, match pairs, spot-the-bug, explain, design trade-off, flashcard. |
✅ Exact grading | Letters, ordering, matching, true/false and accepted commands are graded by the server, not by the LLM. Free-text goes to the LLM with a rubric. |
⚖️ No "always B" bias | The server dictates where the correct answer goes and rejects anything else. Duplicate wording and repeated concepts are rejected too. |
🔁 Spaced repetition | Missed concepts return after 1 → 3 → 7 → 14 → 30 days, from a different angle. |
📈 Adaptive difficulty | Levels go up after a strong run and down after a weak one, per topic. Lock a level any time. |
🏆 Duolingo mechanics | XP, daily goal, streaks with freezes, hints (half XP), skip, 5-question sessions, weekly recap. |
📜 Certification tracks | CCNA · CKA · RHCSA · AWS Solutions Architect Associate · Terraform Associate, with per-objective coverage. |
📚 Your own material | Feed it notes, runbooks or postmortems and get questions grounded in your content. |
🔐 Safe to host | Authenticated HTTP transport with per-user isolation, non-root Docker image, versioned DB migrations. |
Quick start
Option A: Docker (recommended)
git clone https://github.com/fritnes/daily-tutor-mcp.git && cd daily-tutor-mcp
cp .env.example .env # then set TUTOR_API_TOKENS (openssl rand -hex 32)
docker compose up -d --build
curl -i localhost:8000/mcp # 401 = running, auth required ✅Option B: pip
pip install git+https://github.com/fritnes/daily-tutor-mcp.git
python -m daily_tutor # stdio (for local clients), data in ~/.daily-tutorOption C: from source
git clone https://github.com/fritnes/daily-tutor-mcp.git && cd daily-tutor-mcp
python -m venv .venv && source .venv/bin/activate
make install && make testConnect your client
{
"mcpServers": {
"daily-tutor": {
"command": "python",
"args": ["-m", "daily_tutor"],
"env": { "TUTOR_DATA_PATH": "/Users/me/.daily-tutor", "TUTOR_TZ": "Europe/Kyiv" }
}
}
}Using the Docker image instead:
{
"mcpServers": {
"daily-tutor": {
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "daily-tutor-data:/data",
"-e", "TUTOR_TRANSPORT=stdio", "-e", "TUTOR_TZ=Europe/Kyiv",
"ghcr.io/fritnes/daily-tutor-mcp:latest"]
}
}
}# local (stdio)
claude mcp add daily-tutor -e TUTOR_DATA_PATH=$HOME/.daily-tutor -- python -m daily_tutor
# remote (HTTP + bearer token)
claude mcp add --transport http daily-tutor https://tutor.example.com/mcp \
--header "Authorization: Bearer <your-token>"Use stdio (python -m daily_tutor) or Streamable HTTP at /mcp with an Authorization: Bearer <token> header.
Clients that only support OAuth are not supported yet (see Roadmap).
Teach your assistant the flow
Install skill/SKILL.md as an agent skill. It tells the model how to run setup, ask, evaluate
and session flows, so you can simply say "quiz me". For scheduled daily questions, use the built-in
daily_question prompt from a cron/scheduler.
How it works
sequenceDiagram
participant U as You
participant L as LLM (Claude)
participant S as daily-tutor MCP server
participant D as SQLite
U->>L: "quiz me"
L->>S: get_next_question_brief
S->>D: topics, history, due reviews
S-->>L: topic, subtopic, type, REQUIRED answer position
L->>S: save_question (key must match)
S-->>L: ok / rejected (duplicate, wrong position)
L-->>U: the question
U->>L: "b"
L->>S: check_answer
alt deterministic type
S->>D: grade, XP, streak, review schedule, level
S-->>L: result
else free text
S-->>L: rubric
L->>S: record_result
end
L-->>U: explanation + XP + streakMore detail in docs/ARCHITECTURE.md.
Question types
Type | You answer with | Graded by |
|
| server |
|
| server (partial credit) |
|
| server verdict + LLM reason |
| the missing word(s) | server for known variants, else LLM |
| the command | server for known variants, else LLM |
|
| server (partial credit) |
|
| server (partial credit) |
| free text | LLM with a rubric |
Configuration
Variable | Default | Meaning |
|
| Folder for the SQLite database |
| system | Default IANA timezone (per-user override with |
|
|
|
| none | Required for HTTP. |
|
| HTTP bind address |
|
| Public URL when behind a proxy |
| none | Comma-separated hostnames; enables DNS-rebinding protection |
All tools are documented in docs/TOOLS.md (generated from the code).
Running it for other people
The user identity comes from the verified bearer token; a
user_idargument is ignored over HTTP, so users cannot read each other's data.Put the container behind a TLS reverse proxy (Caddy, nginx, Traefik).
docker-compose.ymlbinds to127.0.0.1on purpose.Use long random tokens:
openssl rand -hex 32. Tokens are compared in constant time.The image runs as a non-root user, with a read-only root filesystem and all capabilities dropped. State lives in the
/datavolume: back it up. (If you bind-mount a host folder instead of the named volume, make it writable by UID10001.)
See SECURITY.md for the threat model and how to report a vulnerability.
Development
make install # editable install + pytest + ruff
make test # 42 tests
make lint # ruff
make docs # regenerate docs/TOOLS.md
make docker-buildProject layout:
src/daily_tutor/ server.py (tools, DB, migrations) · grading.py (pure grading) · tracks.py (exam presets)
tests/ pytest suite (grading, streaks/timezones, SRS, adaptive levels, sessions, migrations…)
skill/SKILL.md agent skill that drives the tools
docs/ architecture + generated tool reference
.specify/ .claude/ Spec Kit templates, constitution and agent skills (spec-driven workflow)
specs/ one folder per feature: spec, plan, tasks (created by Spec Kit)New features follow spec-driven development with GitHub Spec Kit:
the project principles live in .specify/memory/constitution.md and the
workflow is described in CONTRIBUTING.md.
AI-assisted workflow
This project is maintained by fritnes, with AI agents supporting different parts of development:
Hermes reviews how the MCP is used and proposes features based on that usage.
Claude assists with creating and refining code for proposed features.
GitHub Copilot is the primary coding agent in the main repository, coordinating implementation and integrating code changes.
GitHub Spec Kit organizes the spec-driven development (SDD) workflow through specifications, plans, and task lists.
This is currently a small personal experiment maintained by fritnes. External contributions and pull requests are not being accepted at this time. This may change in the future.
Roadmap
OAuth for remote mode (claude.ai custom connectors)
More tracks (Security+, LFCS, Azure AZ-104, CKAD)
Optional web dashboard for streaks and coverage
Leaderboards for teams (shared instance)
PyPI release
License
MIT. Track objective lists are study outlines based on public exam domains; always check the official exam guide for the current blueprint.
This server cannot be deployed
Maintenance
Related MCP Connectors
Save the courses you make with AI and review them with spaced repetition and a daily session.
Schedule spaced reviews and exam study plans from each learner's forgetting curve.
Files what you learn into a personal wiki and quizzes you before you forget it.
Spaced-repetition flashcards your AI writes, quizzes you on by voice, and schedules with FSRS.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceImplements cognitive science-backed interleaved learning techniques to create study plans, generate mixed-topic quizzes, manage flashcard decks, and track learning progress for optimal knowledge retention.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables users to create, review, and manage flashcards using the SM-2 spaced repetition algorithm for optimized learning. It supports organizing cards into projects and automatically handles review scheduling based on user performance.7 npm2MIT
- AlicenseBqualityDmaintenanceAn MCP server for tracking student learning via a knowledge graph, with spaced repetition scheduling and intelligent queries to identify gaps, misconceptions, and optimal next steps.728 PyPI1MIT
- AlicenseBqualityAmaintenanceEnables AI agents to act as a state-driven tutoring engine over MCP, with server-side mastery estimation, prerequisite checks, evidence-based assessment, and FSRS spaced review scheduling.581MIT