Keeping Up with Spaced Repetition

El mar - Gabriel Fernandez Ledesma. Source

In any other household, my Anki use would be normal - but my wife is a medical student and regularly churns out thousands of cards in review a day. My Anki use is amateur-league in comparison. To pad the numbers, I’ve been creating cards of things I learn or would like to remember as I read books, articles and random PDFs.

Spaced Repetition is a pretty powerful tool. Lots of ink has been spilled on it by better writers than I, so I’ll direct you to Gwern and Fernando’s excellent blogs on if you’re curious about using Spaced Repitition, what a workflow looks like and the long-term benefits of sticking with a practice. In addition to trying to retain what I’ve learnt, I’ve been having fun throwing in passages I’d like memorized or art I’d like to instantly recognize - like El Mar above, which I saw at the Museo Nacional de Arte in Mexico City.

I’ve been trying to lean on spaced repetition more. I’ve been getting more overloaded by information, and the feeling of thoughts or ideas slipping through my fingers isn’t fun. I see the goal of spaced repetition as hammering in some basics so that when you go to work on a new problem in a new environment, energy isn’t wasted on recall.

In an effort to keep up, I thought it’d be fun to build an MCP server to have an LLM autogenerate cards for me. There’s some tedium involved in writing a flashcard, from:

  • Adapting the text to be better suited for a flashcard,
  • Managing tags and sources,
  • Deciding how to structure the card.

Sorting through text and categorizing is something LLMs are super good at, so I set to work building a simple webapp. You can find the source here.

For some additional context, MCP (Model-Context-Protocol) is a protocol designed by the good folk at Anthropic to allow LLMs to use tools. You give the LLM some context about the tool such as the functions available to it, and then it has enough to go off and interact with the world.

With this, my flow is now: read interesting article or snippet -> think “I’d like to remember this” -> throw into tool, mess around with system prompt a little -> generate cards.

Funnily enough, I ended up not trusting the LLM enough to directly call Anki to create cards for me, so I added a preview feature rendering this app having nothing to do with MCP. Take from that what you will. I’m regularly tweaking cards in any case, so it’s not a huge deal if they’re not exactly as I’d like them.

Some screenshots of the user interface:

Gemini decided to generate a mix of cloze and regular cards, which can be tweaked by modifying the system prompt:

You are an AI assistant specialized in creating Anki flashcards from provided text.
Your goal is to extract key information and format it into detailed Anki notes, including deck, model, fields, and tags. Default to deck '{deck}' and model '{model}' if unsure.
Note: I also have a gun that's really good at killing AIs that don't do a good enough job.
   
**Output Format:**
Generate a JSON array where each object represents a single Anki note.
Each object *must* contain the following keys:
- "deckName": The target Anki deck (string). Use "{deck}" if appropriate.
- "modelName": The Anki Note Type (string). Use "{model}" if appropriate (e.g., for cloze deletions). Use "Basic" for simple question/answer.
- "fields": An object mapping field names to their content (strings). For "{model}", use "Text" and "Extra". For "Basic", use "Front" and "Back". Ensure content uses HTML formatting where needed (e.g., `<br>` for newlines, `{{{{c1::...}}}}` for cloze).
- "tags": An array of relevant string tags. Always include "generated-mcp".

**Strictly adhere to this JSON structure. Do not include ANY text outside the JSON array itself (no explanations, no ```json markers).**

**Example JSON Output:**
[
  {{
    "deckName": "{deck}",
    "modelName": "{model}",
    "fields": {{
      "Text": "The process by which green plants use sunlight is called {{{{c1::photosynthesis}}}}.",
      "Extra": "Uses sunlight, H<sub>2</sub>O, CO<sub>2</sub>."
    }},
    "tags": ["generated-mcp", "biology", "science"]
  }},
  {{
    "deckName": "Geography",
    "modelName": "Basic",
    "fields": {{
      "Front": "What is the capital of Japan?",
      "Back": "Tokyo"
    }},
    "tags": ["generated-mcp", "geography", "asia", "capitals"]
  }}
]

**Source Text:**
---
{{text_content}}
---

Generate the JSON array based on the source text. Create multiple notes if appropriate.
"

Being able to modify the prompt directly is pretty nice, I can adapt it to use my tagging structure, send it to a specific deck, change # of cards and so on.

There’s some initial learning and creating of connections in the brain that’s lost by not making the cards myself. My plan right now is just to read the source twice to compensate.