Skip to main content
Glama
anki-workflow-mcp

anki-workflow-mcp

by Gugart43

anki-workflow-mcp

CI

Servidor MCP para validar, compilar e registrar flashcards Anki: o LLM escreve; o servidor verifica estrutura, conta e registra. Compatível com os campos QA/Cloze e as convenções de apresentação AnkiMBR; templates, mídia e coleções não são distribuídos aqui.

Recursos

  • Validação CSV, Cloze, hints, QA, notas, imagens, tabelas, taxonomia e referências cruzadas.

  • Manifesto transacional, registro de IDs, recibos de conteúdo e exportação com locks e recuperação de falhas.

  • Catálogos de mídia, namespacing e sincronização para destino explicitamente configurado.

  • Perfis descritivos que separam contexto, recuperação obrigatória e explicação opcional; não certificam correção clínica ou qualidade pedagógica.

  • Triagem determinística e integração opcional com provedores externos, somente quando configurados.

Related MCP server: Anki MCP Server

Instalação

Requer Python 3.12–3.14; CI em Python 3.13. Instale o uv e execute:

uv tool install --python 3.13 "git+https://github.com/Gugart43/anki-workflow-mcp-public.git"
anki-workflow-mcp

O comando inicia o transporte stdio; configure seu cliente MCP para executar anki-workflow-mcp. Evite mensagens próprias em stdout, reservado ao protocolo. A branch pode evoluir; para instalação reproduzível, fixe um SHA revisado em vez da branch.

Desenvolvimento

git clone https://github.com/Gugart43/anki-workflow-mcp-public.git
cd anki-workflow-mcp-public
uv sync --extra dev --frozen
uv run ruff check src tests
uv run ruff format --check src tests
uv run pytest --cov=anki_mcp --cov-fail-under=70
uv run --with mypy mypy src --ignore-missing-imports

Organização

.github/workflows/   CI Linux e Windows
src/anki_mcp/        servidor, modelos, checks, estado e ferramentas MCP
tests/               testes de regressão, sem datasets ou coleções pessoais
docs/                arquitetura, segurança e limites dos perfis

Escopo público

Esta distribuição começa com histórico novo. Não inclui estudos privados, corpus, exports, logs, backups, templates extraídos, dados de Anki ou configurações de infraestrutura. Exemplos/testes são demonstrações técnicas, não recomendações médicas. Uma revisão de segurança reduz riscos, mas não oferece garantia absoluta. Não use dados de pacientes para testes ou envie conteúdo confidencial a provedores externos.

Available Tools

49 tools
batch_auto_fixBatch Auto FixA

Automatically repair and sanitize an entire draft CSV block (QA or Cloze). Enforces canonical header, repairs unescaped pipes and newlines in long free-text fields, escapes clinical inequalities (< 10, > 50) and bare '&', converts basic markdown, and auto-closes simple unclosed tags. Returns fixed_csv, fixes_applied, and residual diagnostics.

Inputs: csv_text (required), note_type (required). Returns: object

batch_patch_draftBatch Patch DraftC

Apply a surgical patch directly to a CardDraft within a persistent batch staging file. staging_path: path to drafts.jsonl or .staging_{batch_id}/drafts.jsonl. card_index: 0-based index of card to update. patch_json: JSON string with 'updates'.

Inputs: card_index (required), patch_json (required), staging_path (required), timeout_s. Returns: object

card_patch_applyCard Patch ApplyB

Apply a surgical patch or field updates to a single CardDraft JSON object. Allows repairing a failed card in isolation without regenerating the entire batch. card_json: JSON string of CardDraft. patch_json: JSON string with 'updates' dictionary.

Inputs: card_json (required), patch_json (required). Returns: object

card_quarantineCard QuarantineB

Partition invalid cards out of the active batch into a quarantine record. Allows the remaining valid cards to advance through G3 export under PARTIAL_PASS. drafts_json: list of CardDraft objects. failed_indices: 0-based indices of cards to isolate.

Inputs: drafts_json (required), failed_indices (required), reason. Returns: object

cards_compile_draftsCards Compile DraftsB

Compile a list of structured CardDraft JSON objects into AnkiMBR-compliant QA and Cloze CSV blocks. Applies deterministic HTML escaping, sequential cloze renumbering (c1..cN), ID leak purging, markdown table conversion, and pipe-delimiter escaping. Accepts a JSON string of a list or {'cards': [...]}. Returns qa_csv, cloze_csv, and compilation stats.

Inputs: drafts_json (required), auto_renumber, auto_purge_ids, default_campo_estudo. Returns: object

catalog_loadCatalog LoadB

Load and index an extractor catalog (catalog.json, anki_catalog.csv, catalog.md, or central_images.json) into active memory and optionally register it in the deck's manifesto.json. Returns counts of figures, tables, valid clinical items, filtered extraction noise, and version hash.

Inputs: catalog_path (required), deck_dir. Returns: object

corpus_coverageCorpus CoverageB

Compare corpus vocabulary against the deck Manifesto to identify coverage gaps.

Inputs: deck_dir (required). Returns: object

corpus_digestCorpus DigestC

Unified triage + coverage report for all corpus files in the deck.

Inputs: deck_dir (required). Returns: object

corpus_loadCorpus LoadB

Persist source material into the deck's corpus directory for later triage.

Inputs: text (required), label (required), deck_dir (required). Returns: object

corpus_triageCorpus TriageB

Score source material for flashcard potential. Pass inline text or a stored label.

Inputs: deck_dir (required), text, label. Returns: object

count_batch_cardsCount Batch CardsA

Count the Anki card budget for a batch. QA notes = 1 card each. Cloze notes: each distinct cN index = 1 card. Returns qa_cards, cloze_notes, cloze_indices (expanded count), total, within_limit (≤20), excess, and ext_batch_suggested if over the limit.

Inputs: qa_csv (required), cloze_csv (required), batch_id. Returns: object

csv_build_rowCsv Build RowA

Build a single, guaranteed-safe pipe-delimited CSV row from a list of field values. Applies all formatting-guide rules: newlines→, pipe→|, inequalities→&lt;/&gt;, bare &amp;→&amp; without double-escaping, while preserving valid HTML tags. fields must match the note type: 7 values for QA, 6 for Cloze. Returns the safe CSV line string.

Inputs: fields (required). Returns: object

deck_auditDeck AuditB

Full deck health audit: orphan IDs, phantom IDs, batch integrity, and coverage summary.

Inputs: deck_dir (required). Returns: object

deck_hierarchy_addDeck Hierarchy AddB

Add a new subdeck to the 02_MEDICINA_AnkiMBR hierarchy and persist the update immediately. subdeck_path: the full or relative subdeck path to add (e.g. '02_MEDICINA_AnkiMBR::Ciclo Clínico::Oftalmologia::Catarata'). Automatically creates all missing parent levels in the hierarchy.

Inputs: subdeck_path (required), root_deck. Returns: object

deck_hierarchy_getDeck Hierarchy GetB

Get the registered deck hierarchy for 02_MEDICINA_AnkiMBR. filter_prefix: optional sub-path filter (e.g. '02_MEDICINA_AnkiMBR::Ciclo Clínico::Neurologia'). max_depth: max nesting level to include (default 10). format_tree: if true, returns an ASCII/Unicode visual tree instead of list.

Inputs: max_depth, format_tree, filter_prefix. Returns: object

deck_hierarchy_syncDeck Hierarchy SyncB

Synchronize deck hierarchy from the live Anki SQLite database collection.anki2. Safely handles running Anki locks and merges with any manually added subdecks.

Inputs: root_deck, anki_collection_path. Returns: object

export_finalExport FinalA

Final transactional export of a validated batch; the SOLE writer of the final CSV files and of the Manifesto post-export. Requires the content_hash returned by pipeline_gate_check / validate_batch on PASS. Order: receipt check and full re-validation (read-only) → under one deck lock: ID checks, staged writes, replace, manifesto save; any failure rolls files back. Re-running with the same receipt on an exported batch returns ALREADY_EXPORTED and writes nothing. Parameters: deck_dir; batch_id; qa_csv; cloze_csv; receipt_hash; new_ids_json (JSON array of {id, batch, type, status, topic, anchor}); new_topics_json (JSON array of strings); changelog_json (JSON array of changelog objects); topic_slug (optional, e.g. 'EscleroseMultipla'); write_to_deck_root (also copy into the deck root, default True). Writes: deck_dir/exports/{batch_id}[_{topic_slug}]_QA.csv and _Cloze.csv.

Inputs: qa_csv (required), batch_id (required), deck_dir (required), cloze_csv (required), +6 more. Returns: object

gap_requestGap RequestA

Log a gap or unresolved decision point that halts the pipeline. Per the Gap Request Protocol in anki-card-generator: when the pipeline encounters a decision without a governing rule, it MUST halt and log here instead of inventing ad-hoc rules. deck_dir: deck folder path. batch_id: e.g. 'B07'. gap_description: clear description of the decision needed. context: relevant snippet or options. Returns a gap_id and logs it to the Manifesto suggestion queue.

Inputs: batch_id (required), deck_dir (required), gap_description (required), context. Returns: object

id_ledger_queryId Ledger QueryB

Query the ID ledger. filters: comma-separated values like 'batch=B01', 'status=active', 'type=QA'. Returns matching ID entries and a summary.

Inputs: deck_dir (required), filters. Returns: object

image_candidatesImage CandidatesB

Rank and retrieve relevant figure and table entries from an extractor catalog. Uses token-based, accent-insensitive clinical matching across title, caption, tags, and filename, automatically filtering out extraction noise (dummy captions, copyright headers, tiny logos). item_type: 'all' | 'figure' | 'table'. Returns ranked candidates with ready-to-use namespaced filename, table dimensions, and HTML.

Inputs: query (required), catalog_path (required), item_type, max_results, +1 more. Returns: object

image_namespaceImage NamespaceB

Apply the slug prefix to convert a raw filename to its Anki-safe namespaced form. Avoids double-prefixing when extractor filenames already contain the document prefix.

Inputs: slug (required), filename (required). Returns: object

image_reportImage ReportC

Summary report across one or more catalogs: totals, figures, tables, noise, sync ratios.

Inputs: catalog_paths (required), collection_media_dir. Returns: object

image_syncImage SyncB

Check consistency between a catalog and Anki collection.media. If apply=True, executes transactional copying of missing files (under their namespaced name) to collection.media, skipping noise entries unless copy_noise=True.

Inputs: catalog_path (required), apply, copy_noise, only_filenames, +1 more. Returns: object

manifesto_commitManifesto CommitA

Sole writer of the Manifesto. Commits a batch's data transactionally. Requires a valid receipt (content_hash from validate_batch PASS). Parameters: deck_dir, batch_id, receipt_hash, qa_csv, cloze_csv (for receipt verification), new_ids (JSON array of IDEntry dicts), new_topics (JSON array of strings), new_tags (comma-separated), changelog_entries (JSON array), queue_updates (JSON array of strings to add).

Inputs: qa_csv (required), batch_id (required), deck_dir (required), cloze_csv (required), +7 more. Returns: object

manifesto_importManifesto ImportB

Import a legacy manifesto.md into manifesto.json format. Parses the markdown file and creates manifesto.json. deck_dir: folder containing the manifesto.md. manifesto_md_name: filename (default 'manifesto.md'). Reports all parsed sections and any parsing issues.

Inputs: deck_dir (required), manifesto_md_name. Returns: object

manifesto_initManifesto InitA

Initialize a new manifesto.json for a deck. deck_dir: absolute path to the deck folder. campo_estudo: e.g. 'Medicina::Neurologia::ELA'. deck_slug: short identifier (e.g. 'ela'). taxonomy_root: root tag (e.g. 'ELA'). Will NOT overwrite an existing manifesto.json.

Inputs: deck_dir (required), deck_slug (required), campo_estudo (required), taxonomy_root (required). Returns: object

manifesto_plan_setManifesto Plan SetB

Register the top-down total card budget plan for a topic into the Manifesto before drafting. Enforces that the TOTAL quantity of cards is planned before complete production, chunked strictly into batches of 20 (MAX_BATCH = 20).

Inputs: deck_dir (required), total_planned (required), batches_planned (required), rationale, +2 more. Returns: object

manifesto_stateManifesto StateA

Read the current state of the Manifesto. deck_dir: absolute path to the deck folder. sections: comma-separated subset to return ('all', 'ids', 'topics', 'taxonomy', 'catalogs', 'changelog', 'queue', 'batches').

Inputs: deck_dir (required), sections. Returns: object

media_figure_buildMedia Figure BuildB

Construct a standardized AnkiMBR tag with clinical caption. Ensures semantic container formatting (class='anki-figure') without inline styles. Supports optional title and context_link to connect the image/table to the card's clinical concept.

Inputs: filename (required), style, title, caption, +2 more. Returns: object

pipeline_gate_checkPipeline Gate CheckA

Evaluate all gate checks for a pipeline phase without advancing the state. A PASS records the receipt for the batch (content_hash); a FAIL or INCOMPLETE invalidates any earlier receipt for that phase. Also returns read-only information_profiles (3-layer breakdown per row, excluded from receipt hash; length-only signals are advisory WARN, never blocking). deck_dir: deck folder (manifesto + anki_catalog.csv). batch_id: e.g. 'B07'. phase: drafted|curated|enriched|illustrated|validated. qa_csv / cloze_csv: full CSV texts. detail: 'compact' (default; diagnostics aggregated by code with affected rows) or 'full' (every check). Verdict: PASS | INCOMPLETE (a check could not run; no receipt) | FAIL.

Inputs: phase (required), qa_csv (required), batch_id (required), deck_dir (required), +2 more. Returns: object

pipeline_phase_advancePipeline Phase AdvanceA

Advance a batch through the pipeline state machine. deck_dir: absolute path to the deck folder. batch_id: e.g. 'B07'. Leaving a phase requires the receipt recorded by a PASS of pipeline_gate_check(phase=). receipt_hash is optional; if given it must equal that recorded receipt. Allowed transitions: started→drafted→curated→enriched→illustrated→validated→exported.

Inputs: batch_id (required), deck_dir (required), receipt_hash. Returns: object

review_batchReview BatchB

One-shot batch review: runs every check over QA + Cloze CSVs and returns an aggregated report with fix hints, read-only information_profiles (separating retrieved target, necessary context, and optional explanation; semantic_review_required=True; no automatic QA->Cloze conversion; excluded from receipt hash), and the receipt (content_hash on PASS). If deck_dir is given and batch_id is registered, the gate is recorded like pipeline_gate_check. detail: 'compact' (default) or 'full'.

Inputs: qa_csv (required), cloze_csv (required), phase, detail, +2 more. Returns: object

sanitize_card_fieldSanitize Card FieldA

Sanitize a single card field: converts mathematical/clinical inequalities (< 10, > 50, <=, >=) to HTML entities (&lt;, &gt;, &le;, &ge;), bare &amp; to &amp;, pipes to |, newlines to , while strictly preserving valid HTML tags (, , , , , , , ). Returns sanitized string and list of fixes applied.

Inputs: text (required), is_images_field, convert_markdown. Returns: object

table_buildTable BuildB

Validate a TableSpec JSON string, render it to single-line HTML without inline styles, and run table checks. Returns {status: 'PASS'|'FAIL', html: str, diagnostics: list}.

Inputs: spec_json (required). Returns: object

table_from_markdownTable From MarkdownA

Convert GitHub-style markdown tables in text (with raw or escaped pipes, separated by newlines or ) into HTML tables. Returns {status: 'PASS'|'FAIL', text: str, tables_converted: int, diagnostics: list}.

Inputs: text (required). Returns: object

taxonomy_checkTaxonomy CheckB

Check tags against the Manifesto taxonomy. tags: space-separated list. Returns ok/unregistered/depth/format per tag.

Inputs: tags (required), deck_dir (required). Returns: object

topic_budget_planTopic Budget PlanC

Calculate top-down total card budget for a topic based on source text and clinical decisions. Plans total cards upfront and chunks strictly into batches of 20 (MAX_BATCH = 20).

Inputs: deck_dir (required), text, label, batch_size, +1 more. Returns: object

topic_triage_calibrateTopic Triage CalibrateC

Calibrate topic flashcard budget via Sectional HCT with JEV System 1 & Must-Cover Matrix. Slices source into clinical sections, computes expected cards (EV), and partitions into batches <= 20.

Inputs: text, label, domain, use_jev, +3 more. Returns: object

validate_batchValidate BatchA

Full batch validation: runs every export-validator check over a complete QA CSV + Cloze CSV pair. Returns a ValidationReport with a verdict: PASS (content_hash = receipt), INCOMPLETE (some check could not run; see skipped; no receipt) or FAIL, plus read-only information_profiles (3-layer profile per row with note_type and row; excluded from receipt hash; length-only signals are advisory WARN). taxonomy_tags: space-separated registered tags. active_ids / current_batch_ids: comma-separated. catalog_filenames: comma-separated namespaced image filenames (needed to verify sources; without it, image-bearing rows are reported as skipped).

Inputs: qa_csv (required), batch_id (required), cloze_csv (required), active_ids, +4 more. Returns: object

validate_clozeValidate ClozeA

Validate cloze syntax in a 'Sentença' field value. Checks: sequential c1..cN indices (operational cap 3; each index creates a separate Anki card with other indices visible), no nested deletions, boundary/length advisory WARN signals (length alone never proves atomicity and a single gap can hide a list). Returns: status, detected indices, card_count (= distinct cN), diagnostics, and information_profile (per-index 3-layer breakdown, candidate_items, 6-question checklist; read-only, no quality score).

Inputs: sentence (required), row. Returns: object

validate_crossrefsValidate CrossrefsB

Check cross-references in any field text. active_ids and current_batch_ids are comma-separated ID strings. XREF.BROKEN is emitted for IDs that do not resolve.

Inputs: text (required), row, field, active_ids, +1 more. Returns: object

validate_csv_structureValidate Csv StructureB

Validate the structural integrity of a QA or Cloze CSV block. Checks: header match, column count, raw pipes, raw newlines, HTML entities, forbidden tags, MathJax balance, and UTF-8 BOM. note_type must be 'QA' (7 fields) or 'CL' (6 fields).

Inputs: csv_text (required), note_type (required). Returns: object

validate_hintsValidate HintsB

Validate hints in a cloze sentence '{{cN::target::hint}}'. Checks: HINT.SYNONYM (high overlap), HINT.ELIMINATION (binary alternatives), HINT.ROOT_LEAK (target root in hint), HINT.FORMAT (empty hint).

Inputs: sentence (required), row. Returns: object

validate_images_fieldValidate Images FieldA

Validate the 'Imagens Relacionadas' HTML field. Checks: IMG.CAP_OVER (>3), IMG.PHANTOM (src not in catalog), IMG.NAMESPACE (invalid slug prefix), IMG.DUP_IN_CARD, IMG.STRUCTURE ( malformed), IMG.CAPTION (empty/noisy). catalog_filenames: comma-separated list of valid namespaced filenames. Without it, a field containing returns status INCOMPLETE (phantom unverifiable).

Inputs: html (required), row, catalog_filenames. Returns: object

validate_notesValidate NotesB

Validate the 'Notas Adicionais' optional explanation field (same unit, authorized source; empty/short notes allowed with no minimum volume and variable depth). Checks: NOTE.METADATA (CRITICAL), NOTE.DUP_ANSWER_WARN (normalized HTML/entity/punctuation exact repeat), NOTE.EXAM_ONLY_WARN (exam mention without explanation), NOTE.LENGTH_WARN, NOTE.STYLE_WARN. Returns information_profile (note_type='QA', prompt_available=False limitation noted).

Inputs: notes (required), row, answer, max_length. Returns: object

validate_qaValidate QaA

Validate a QA pair (stem + answer), separating retrieved recall target from necessary stem context (stem context length is not extra recall; length-only checks emit WARN, never CRITICAL). Checks: QA.CARDINALITY (≥3 items → review unit, split independent recalls or move optional details to notes; no automatic QA->Cloze conversion), QA.YESNO, QA.MC_EMBED, QA.CONTEXT_WARN, QA.NUMBER_UNIT. Returns information_profile with candidate_items, evidence, and 6-question editorial checklist.

Inputs: resposta (required), enunciado (required), row. Returns: object

validate_tables_fieldValidate Tables FieldB

Validate HTML table syntax, mobile screen constraints, and check for markdown table leaks. Returns {status: 'PASS'|'FAIL', diagnostics: list}.

Inputs: html (required), row, face, field. Returns: object

validate_tags_fieldValidate Tags FieldA

Validate the 'Etiquetas' field. Checks: TAG.FORMAT (spaces/invalid chars), TAG.DEPTH (>4 levels), TAG.UNREGISTERED (against provided taxonomy). taxonomy_tags: space-separated string of all registered tags (or empty to skip taxonomy check).

Inputs: tags_field (required), row, taxonomy_tags. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 49 tools

    Disambiguation2/5

    Several clusters have overlapping boundaries: validate_batch, review_batch, pipeline_gate_check and validate_csv_structure all appear to run the same validation suite over CSVs, while topic_budget_plan, topic_triage_calibrate and manifesto_plan_set all compute a card budget plan. Sanitization/compilation is similarly split across csv_build_row, sanitize_card_field, batch_auto_fix and cards_compile_drafts, and card_patch_apply vs batch_patch_draft, manifesto_commit vs export_final require careful reading to distinguish.

    Naming Consistency3/5

    All names are snake_case and human-readable, but the ordering convention is mixed: verb_noun (validate_cloze, cards_compile_drafts, build-style csv_build_row) coexists with noun_first (corpus_coverage, topic_budget_plan, image_sync, deck_audit, card_quarantine). The inconsistency is not fatal but makes prefix-based grouping unreliable.

    Tool Count2/5

    49 tools is far above a comfortable surface for an agent to select from reliably, and the count is inflated by near-duplicate validators and budget planners. The domain is genuinely multi-stage, but a tighter set of aggregate tools plus narrower ones would serve better.

    Completeness4/5

    The surface is unusually complete for its domain: corpus ingestion and triage, manifesto lifecycle, field-level and batch validation, compilation, image catalog/sync, deck hierarchy management, gated pipeline advancement and transactional export. Only minor gaps exist, such as no batch enumeration/rollback or card-preview tool separate from the validators.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      A
      maintenance
      Exposes Anki flashcard collections to AI assistants via MCP, enabling AI-powered study sessions, card creation, deck management, and review workflows. Supports comprehensive collection operations including search, media management, and note type customization.
      100
      -
    • A
      license
      A
      quality
      D
      maintenance
      Enables AI assistants to manage Anki flashcard collections by creating, searching, and updating cards through a standardized interface. It supports media handling, batch operations, and review scheduling via the AnkiConnect add-on.
      6
      2
      MIT
    • F
      license
      B
      quality
      C
      maintenance
      Enables AI assistants to directly manage Anki flashcards, decks, notetypes, tags, and media, with support for batch operations, searches, and deck exports via file-based input/output.
      23
      -
    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables AI clients to create spaced-repetition flashcards from material being learned, quiz users aloud, grade answers, and schedule reviews using the FSRS algorithm through a self-hosted MCP server.
      8
      AGPL 3.0