{"slug": "study-like-a-sloth-echodeck-turns-your-notes-into-self-grading-flashcards", "title": "Study Like a Sloth: EchoDeck Turns Your Notes into Self-Grading Flashcards, Offline", "summary": "A developer built EchoDeck, an open-source voice-first flashcard coach that generates cards from notes and grades spoken answers, adding a fully local mode for the Hacktoberfest Open-Source AI Challenge. The local mode runs on Ollama with small open-weight models, whisper.cpp for speech-to-text and Piper for text-to-speech, while Leitner-box spaced repetition scheduling stays deterministic code so malformed model output cannot corrupt review schedules. The server is written in TypeScript on Node 24, exposes its features as Model Context Protocol tools, and stores data in a JSON file with atomic writes and corrupt-file recovery.", "body_md": "*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady](https://dev.to/challenges/hacktoberfest-week3-2026-10-19)*\n\n**EchoDeck** is a flashcard coach for people who want to learn without running a study system.\n\nFlashcards work, but the chores around them are what make people quit: writing the cards, deciding what to review today, and keeping a streak alive. EchoDeck takes those chores over.\n\nEchoDeck started as an **Alexa+ MCP add-on** for hands-free study on an Echo Show. For this challenge I added a **fully local mode** that runs on your own machine with no internet connection and no cloud account. Both modes share the same scheduling engine and the same data file, so nothing about your progress depends on which mode you use.\n\nIt is for students, language learners, and anyone cramming for an exam or certification who would rather spend their effort answering questions than building cards.\n\nEchoDeck runs on a laptop, so the quickest way to see it is to run it. This is the whole setup:\n\n```\n# 1. Start Ollama with a small open-weight model\nollama pull llama3.2        # or: ollama pull qwen2.5-coder:3b\nollama serve\n\n# 2. Run EchoDeck in local mode\ncd server\nnpm run build\nMODE=local npm start\n```\n\nThen open `http://127.0.0.1:3000/`:\n\nIf the model is down or returns something unusable, self-rating buttons appear so a study session never gets stuck.\n\n**Voice-first flashcard coach with spaced repetition** — an Alexa+ MCP add-on server.\n\nEchoDeck lets learners create study decks, get quizzed, and track progress entirely by voice through Alexa+. It uses Leitner-box spaced repetition to schedule reviews and provides a visual card UI for Echo Show devices.\n\nThis project uses **ES modules** throughout:\n\n`\"type\": \"module\"` in `package.json`\n`\"module\": \"Node16\"` and `\"moduleResolution\": \"Node16\"` in `tsconfig.json`\n`.js` extensions (TypeScript resolves these to `.ts` at\ncompile time)`node --version`)\n\n```\ncd server\n\nnpm install @modelcontextprotocol/sdk @modelcontextprotocol/ext-apps express zod\nnpm install -D typescript tsx vitest vite vite-plugin-singlefile @types/node @types/express\n```\n\nAfter installing, verify:\n\n```\nnode --version        # Must be >= 24.0.0\nnpm ls --depth=0      # All packages should be listed without ERR\n```\n\nAlso check that the installed `zod` version satisfies…\n\nThe server is TypeScript (ES modules, Node 24) with Express and zod, and it exposes its features as tools over the **Model Context Protocol (MCP)**. Data lives in a JSON file with atomic writes and corrupt-file recovery. The UI is a single-file Vite build that works both as an Echo Show card and as a standalone browser app.\n\n| Piece | What it does | Open tool | \n|---|---|---|\n| LLM | Generates cards from notes and judges answers | **Ollama** , with small open-weight models (`llama3.2` ,`qwen2.5-coder:3b` ,`mistral` ) | \n| Speech to text | Transcribes spoken answers | **whisper.cpp** adapter, with browser speech recognition as a fallback | \n| Text to speech | Reads questions aloud | **Piper** adapter, with browser speech synthesis as a fallback | \n\nLeitner scheduling and streak math are plain deterministic code. The LLM does only two language jobs: it creates cards, and it judges an answer and returns a rating. That rating is validated with zod and then passed into the existing SRS function. A wrong or malformed model output can never corrupt your review schedule, and the scheduling tests stay exact.\n\n`server/src/local/`): `LlmProvider`, `SttProvider` and `TtsProvider` interfaces with Ollama, whisper.cpp and Piper implementations. Core domain and storage code has zero dependency on any provider, so swapping a model is a setting (`OLLAMA_MODEL`), not a rewrite.` CardGenerator``validateCards` step so limits, trimming and de-duplication apply to AI-generated cards exactly as they do to hand-made ones.`AnswerJudge``/api` in `local` and `both` modes): `status`, `decks`, `generate-deck`, `study/next`, `study/judge`, `study/self-grade`, `stt` and `tts`.` MODE=alexa|local|both`, defaulting to `alexa`, so existing behavior is unchanged. In local mode the server binds to `127.0.0.1` by default.`generate_deck_from_notes`, available when the local controller is configured. The four original tools are untouched.\nSmall models (3B to 8B parameters) drift on formatting. They return a single object instead of an array, or wrap JSON in markdown code fences even when told not to. Three things made it reliable:\n\n`{\"cards\": [...]}`) instead of a bare array.\nThe back of a card is never rendered in the DOM or returned over HTTP before you submit an answer. `/api/study/next` returns the front only, and the back is revealed in the response to `/api/study/judge`. This holds in both the REST API and the UI, and it is covered by tests.\n\n`MODE=alexa`.` qwen2.5-coder:3b`. It covers health, provider status, card generation from notes, confirming `next_card` omits the back, answer judging with model feedback, revealing the back, and streak persistence.\nI want to be upfront about this. The whole local flow (card generation, judging, SRS, streaks, answer-leak prevention) was verified end to end with a real local model. The **whisper.cpp and Piper adapters are covered by unit tests with mocked servers, but I did not run the real binaries**, because neither was installed on my machine. I tested voice input and output through the browser's built-in speech features instead. Those browser features are convenient, but depending on your browser, speech recognition may use an online service. If you need strictly offline voice, use the whisper.cpp and Piper path. Typed answers are always fully local.\n\nMy first version of EchoDeck only worked through Alexa+. That made it great on an Echo Show, and it also made me notice what I'd given up: all of the intelligence belonged to someone else's platform. Moving the language work to open-weight models changed what was possible.\n\nEchoDeck removes the three chores that make flashcards a hassle:\n\nAfter the one-time setup, a study session is: open the page, answer what you're asked, and close it.", "url": "https://wpnews.pro/news/study-like-a-sloth-echodeck-turns-your-notes-into-self-grading-flashcards", "canonical_source": "https://dev.to/attlar/study-like-a-sloth-echodeck-turns-your-notes-into-self-grading-flashcards-offline-53on", "published_at": "2026-10-24 10:33:51+00:00", "updated_at": "2026-10-24 10:43:30.368127+00:00", "lang": "en", "topics": ["ai-tools", "ai-agents", "agent-protocols", "large-language-models", "developer-tools"], "entities": ["EchoDeck", "Ollama", "whisper.cpp", "Piper", "Model Context Protocol", "Alexa+", "Hacktoberfest", "llama3.2"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/study-like-a-sloth-echodeck-turns-your-notes-into-self-grading-flashcards", "markdown": "https://wpnews.pro/news/study-like-a-sloth-echodeck-turns-your-notes-into-self-grading-flashcards.md", "text": "https://wpnews.pro/news/study-like-a-sloth-echodeck-turns-your-notes-into-self-grading-flashcards.txt", "jsonld": "https://wpnews.pro/news/study-like-a-sloth-echodeck-turns-your-notes-into-self-grading-flashcards.jsonld"}}