MCP server addon for Anki that provides tools for managing notes, decks, cards, models, and media through the Model Context Protocol
The Anki MCP server demonstrates good definition quality with well-structured tool definitions, clear descriptions, and comprehensive input schemas. All 8 tools are explicitly registered with descriptions and JSON schemas. Tool names follow verb_noun conventions (add_note, create_deck, change_note_type). Most parameters are typed and described. However, there are gaps in output schema documentation, limited error guidance for recovery, and inconsistent parameter constraint documentation. The change_note_type tool includes exceptional documentation (multi-paragraph explanation of destructive behavior and recovery paths), which is exemplary, but other tools lack comparable depth in error handling guidance.
Add a new note to Anki. Use model_names to see available note types and model_field_names to see required fields. Returns the note ID on success. IMPORTANT: Only create notes that were explicitly requested by the user.
Add multiple notes to Anki in a single batch sharing the same deck and model. Uses Anki's native batch API for atomic undo support. Supports partial success - individual failures don't affect others. IMPORTANT: Only create notes that were explicitly requested by the user. Returns summary counts (created, skipped, failed) and a per-note results array with status and note_id. Each note is {"fields": {...}, "tags": [...]}; tags is a JSON array.
Manage card organization
Bulk per-card scheduling stats for a deck (subdecks included), FSRS-independent. For every matching card returns a compact record: cid, nid, the note's tags, and raw Anki ints for type (0 new, 1 learning, 2 review, 3 relearning) and queue (-3/-2 buried, -1 suspended, 0 new, 1 lrn, 2 rev, 3 day-lrn), plus interval (days) and a computed dueToday flag. No note fields, no HTML, no human-readable names -- just the scheduling metrics, for bulk analytics. Paginated with limit (default 1000, max 1000) and offset; cards are ordered by card id for stable paging. Prefer this over find_notes + notes_info + get_card_memory_state when you only need scheduling metrics: it is one compact read and does not require FSRS.
Missing output schema documentation for all tools. While input schemas are comprehensive, there is no visible documentation of what each tool returns, field names, types, structure. LLMs cannot plan downstream tool calls without knowing what data to expect.
card_management tool conflates multiple responsibilities into a single action parameter. The 'action' string accepts 9 different operations (reposition, change_deck, bury, unbury, suspend, unsuspend, set_flag, set_due_date, forget_cards), each with different optional parameters. This forces the LLM to construct complex action strings and makes the tool hard to discover and reason about.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 71 | 2025-06-18+ | v2 |
| 2026-03-09 | F | 48 | - | v1 |
DESTRUCTIVE. Move existing notes to a different note type (model), remapping their fields. Hidden from clients unless the operator opts in via the "enabled_destructive_tools" addon config containing "change_note_type". WHAT IT DOES TO THE NOTES: each note's field layout is REWRITTEN to the target note type's fields. Content moves only where the mapping says it moves; any old field with no target is DROPPED, permanently, for every note in the batch. There is no per-field undo beyond Anki's single undo step. TWO-STEP FLOW, ALWAYS. Call with dry_run=true FIRST: a dry run writes nothing and returns the fully resolved plan -- the field mapping both directions, which fields would be dropped and how many of the selected notes actually have content there, the card-template mapping, and how many cards would be removed. Then repeat the SAME call with dry_run=false AND confirm=true. A real run without confirm=true is REFUSED; confirm is ignored during dry runs. field_mapping is {old field name: new field name or null}, e.g. {"Front": "Text", "Back": "Back Extra", "Notes": null}. null (or simply omitting an old field) drops that field's content. Two old fields may not target the same new field. The reverse -- one old field feeding TWO new fields -- is supported by Anki but NOT expressible in this mapping shape, which allows one target per source; copy the content into the second field afterwards with update_note_fields. If field_mapping is omitted, the default is an EXACT NAME MATCH between the two note types; a real run is REFUSED if that default would drop content that actually exists, so pass an explicit mapping in that case. note_ids must contain no duplicates (a repeated id would have the field remap applied to it twice, scrambling its content) and ALL of them must currently share the SAME note type -- a mixed batch is rejected, because the mapping is index-based and would scramble notes of the other type. Query them per type (find_notes with note:"Type Name") and call once per type. CARDS AND REVIEW HISTORY: cards are matched to the new note type's templates by Anki's own default template map (same name first, then position), and every matched card keeps its id, due date, interval, ease and full review log. Cards whose template has NO counterpart in the new note type are DELETED along with their scheduling -- the dry run reports that count as cards_to_remove. When EITHER note type is a cloze type, templates are not remapped at all: existing cards keep their ordinal and their full scheduling, and are removed only if the TARGET is a normal note type and the card's ordinal is past that type's last template. Anki's card generation then runs in every case and may ADD cards for target templates that now render; the dry run does NOT predict additions, a real run reports them as cards_added. Full Sync Behavior: setting a flag on response helps the sync algorithm. If this is true, the next sync WILL be a full one-way sync. To safely call the server in production during a sync, wait for completion or call with dry_run=true (dry runs write nothing). More details: https://github.com/ankimcp/anki-mcp-server-addon/blob/main/docs/schema-state-tracking.md Changing note types always marks the schema modified (rslib's change_notetype_of_notes_inner calls set_schema_modified), so after a real run it is always true -- the next sync WILL be a full one-way sync. Sync everything before running this. A dry run writes nothing, so its will_force_full_sync is the collection's CURRENT state; the separate would_force_full_sync key carries the prediction.
Create a new empty Anki deck. Supports parent::child structure (e.g., "Japanese::Tokyo" creates parent deck "Japanese" and child deck "Tokyo"). Maximum 2 levels of nesting allowed. Will not overwrite existing decks. IMPORTANT: This tool ONLY creates an empty deck. DO NOT add cards or notes after creating a deck unless the user EXPLICITLY asks to add them. Wait for user instructions before adding any content. Returns deckId and created flag (false if deck already existed).
Create a new note type (model) in Anki with custom fields, card templates, and styling. Useful for creating specialized models like RTL (Right-to-Left) language models for Hebrew, Arabic, etc. Each model defines the structure of notes and how cards are generated from them. Returns model_id, fields list, template_count, and any template warnings. Full Sync Behavior: setting a flag on response helps the sync algorithm. If this is true, the next sync WILL be a full one-way sync. To safely call the server in production during a sync, wait for completion or call with dry_run=true (dry runs write nothing). More details: https://github.com/ankimcp/anki-mcp-server-addon/blob/main/docs/schema-state-tracking.md Creating a note type does not itself modify the schema, so this is typically false unless the collection was already dirty.
Move a media file to Anki's trash folder. The file can be recovered via Anki's 'Check Media' dialog until the trash is emptied. Sync to propagate the deletion to other devices. Confirm with the user before deleting.
Insufficient error guidance. Descriptions state what tools do but do not explain when calls might fail, what errors are recoverable, or what the LLM should do next. E.g., add_note says 'Returns the note ID on success' but does not explain what failure looks like or whether to retry. change_note_type is the sole exception with detailed recovery documentation.
Parameter constraint documentation varies widely. Some tools (e.g., cards_stats with 'limit: max 1000') include bounds; others do not state ranges or valid values. The 'action' parameter in card_management does not list its 9 accepted values as an enum, forcing LLMs to guess or memorize from the description.
Dry-run and confirmation patterns are used only for change_note_type (destructive), but add_notes and add_note (WRITE operations) lack confirmation or rollback guidance. Users should be prompted before bulk creation to prevent accidental data addition, especially in multi-turn conversations.
Tool composition issue: add_note and add_notes both exist, but there is no batch-first guidance or sizing guidance. LLMs may make sequential add_note calls when add_notes would be more efficient. Documentation should recommend add_notes for >1 note.