Skip to main content
Glama

anki-mcp

MCP server for Anki. This server allows interaction with Anki through the Model Context Protocol (MCP). It enables users to manage flashcards, decks, and review processes programmatically.

Watch the video

Prerequisites

  • Node.js and npm installed.

  • AnkiConnect plugin installed and running in Anki.

  • For audio features: Azure API key (set in .env file as AZURE_API_KEY) and Anki Media Directory (set as ANKI_MEDIA_DIR).

Related MCP server: Anki MCP Server

Setup and Execution

Highly recommended to run locally, since AnkiConnect only works locally.

Was only tested on windows.

Running locally via npx

If you only wish to use the tool and not develop the tool, you may launch an MCP STDIO server locally using npx:

npx -y github:nietus/anki-mcp

This can be used in Desktop MCP clients such as Msty Studio or others.

Running locally via source code

Alternatively, you can run locally via source code using these instructions:

  1. Clone the repository:

    git clone https://github.com/nietus/anki-mcp
  2. Install dependencies:

    npm install
  3. Build the project

    npm run build
  4. Setup for Audio Features (If you want to use audio tools):

    Create a .env file in the root directory with your Azure API key and Anki media directory:

    AZURE_API_KEY=your_azure_api_key_here
    ANKI_MEDIA_DIR=path/to/your/anki/media/directory

    For Anki media directory, use the path to your Anki collection.media folder. This is where audio files will be stored. If you have trouble, paste it directly into the code.

    • Windows example: C:\Users\username\AppData\Roaming\Anki2\User 1\collection.media

    • macOS example: /Users/username/Library/Application Support/Anki2/User 1/collection.media

    • Linux example: /home/username/.local/share/Anki2/User 1/collection.media

    Note: The ANKI_MEDIA_DIR is required for audio generation to work properly as Anki needs to find the audio files in its media collection.

  5. Integrate with Cursor settings (for local execution):

    To run your local build of anki-mcp with Cursor, you need to tell Cursor how to start the server. Below are example configurations which you can access on cursor settings. Replace YOUR_USERNAME and adjust the path if you cloned anki-mcp to a different location than Downloads.

    Windows:

    "anki": {
          "command": "cmd",
          "args": [
            "/c",
            "node",
            "c:/Users/YOUR_USERNAME/Downloads/anki-mcp/build/client.js"
        ]
    }
  6. Integrate with Claude Desktop using an .mcpb bundle:

    The recommended way to use this server with Claude Desktop is to install it as an MCP extension bundle (.mcpb file).

    1. Build and package the extension:

      npm install
      npm run build
      npm run pack:mcpb

      This will produce a file at dist/anki-mcp.mcpb.

    2. Install the bundle in Claude Desktop:

      • Open Claude Desktop.

      • Go to Settings → Extensions.

      • Drag and drop the dist/anki-mcp.mcpb file into the Extensions panel.

      Claude will handle launching the server automatically when needed.

    3. Configure environment variables:

      When prompted during installation, provide your AZURE_API_KEY and ANKI_MEDIA_DIR (the path to your Anki collection.media folder). These are required for audio features and media file handling.

    That’s it! No manual configuration is needed—Claude Desktop will manage the server for you once the .mcpb bundle is installed. macOS / Linux:

 "anki": {
       "command": "bash",
       "args": [
         "-c",
         "node /Users/YOUR_USERNAME/Downloads/anki-mcp/build/client.js"
       ]
     }

Create a Claude Desktop extension bundle (.mcpb)

If you want one-click installation inside Claude Desktop, you can package this server as an MCP bundle:

  1. Install dependencies and build the project:

    npm install
    npm run build
  2. Generate the .mcpb bundle (requires the @anthropic-ai/mcpb CLI, which expects Node.js 18+):

    npm run pack:mcpb

The script stages the compiled server (build/), copies runtime dependencies, and produces dist/anki-mcp.mcpb. Drag that file into Claude Desktop's Settings → Extensions panel to install. When prompted, provide the Azure Speech API key and Anki media directory so audio tools can save files in your collection.media folder.

Available Tools

To debug the tools, use

npm run inspector

The server provides the following tools for interacting with Anki:

  • update_cards:

    • Description: After the user answers cards you've quizzed them on, use this tool to mark them answered and update their ease.

    • Input: An array of answers, each with cardId (number) and ease (number, 1-4).

  • add_card:

    • Description: Create a NEW flashcard in Anki. Use ONLY for creating new cards, NOT for updating existing ones (will throw an error if the card already exists). For updating existing cards, use update_note_fields with the noteId instead. Note content uses HTML.

      • Line breaks: <br>

      • Code: <pre style="background-color: transparent; padding: 10px; border-radius: 5px;">

      • Lists: <ol> and <li>

      • Bold: <strong>

      • Italic: <em>

    • Input:

      • fields: (object) An object where keys are field names (e.g., "Hanzi", "Pinyin") and values are their HTML content.

      • modelName: (string) The name of the Anki note type (model) to use.

      • deckName: (optional string) The name of the deck to add the card to. Defaults to the current deck or 'Default'.

      • tags: (optional array of strings) A list of tags to add to the note.

  • add_card_with_audio:

    • Description: Create a NEW flashcard in Anki with automatically generated audio from Azure TTS. Use ONLY for creating new cards, NOT for updating existing ones (will throw an error if the card already exists). For updating audio on existing cards, use update_card_with_audio with the noteId instead.

    • Input:

      • fields, modelName, deckName, tags: Same as add_card.

      • sourceField: (string) Field name containing the text to generate audio from.

      • audioField: (string) Field name where the generated audio will be stored.

      • language: (optional string) Language code for TTS (e.g., 'en', 'es', 'fr'). Defaults to 'en'.

    • Supported languages: en, es, fr, de, it, ja, ko, pt, ru, zh, ar, nl, hi, tr, pl, sv, fi, da, no, cs, hu, el, he, th, vi, id, ms, ro.

  • update_card_with_audio:

    • Description: Update an EXISTING card by generating audio from a specified field and adding it to an audio field. Use ONLY for cards that already exist (you must have the noteId). For creating new cards with audio, use add_card_with_audio instead.

    • Input:

      • noteId: (number) The ID of the Anki note to update.

      • sourceField: (string) Field name containing the text to generate audio from.

      • audioField: (string) Field name where the generated audio will be stored.

      • language: (optional string) Language code for TTS. Defaults to 'en'.

  • get_due_cards:

    • Description: Returns a given number of cards due for review.

    • Input: num (number).

  • get_new_cards:

    • Description: Returns a given number of new and unseen cards.

    • Input: num (number).

  • get_deck_names:

    • Description: Get a list of all Anki deck names.

    • Input: None.

  • find_cards:

    • Description: Find cards using a raw Anki search query. Returns detailed card information including fields.

    • Input: query (string, e.g., 'deck:Default -tag:test', or '"deck:My Deck" tag:important'). To filter for empty fields, use '-FieldName:_*' (e.g., '-Hanzi:_*').

  • update_note_fields:

    • Description: Update specific fields of an EXISTING Anki note. Use ONLY when you already have the noteId of an existing card. For creating new cards, use add_card instead.

    • Input: noteId (number), fields (object, e.g., {"Front": "New Q", "Back": "New A"}).

  • create_deck:

    • Description: Create a new Anki deck.

    • Input: deckName (string).

  • bulk_update_notes:

    • Description: RECOMMENDED FOR MULTIPLE CARDS: Update specific fields for multiple EXISTING Anki notes in a single operation. Much more efficient than updating cards one by one. Use ONLY when you have noteIds for cards that already exist. For creating new cards in bulk, use add_bulk instead. Always complete all updates in a single operation whenever possible.

    • Input: An array of notes, where each note has noteId (number) and fields (object).

  • get_model_names:

    • Description: Lists all available Anki note type/model names.

    • Input: None.

  • get_model_details:

    • Description: Retrieves the fields, card templates, and CSS styling for a specified note type.

    • Input: modelName (string).

  • get_deck_model_info:

    • Description: Retrieves information about the note types (models) used within a specified deck. Helps determine if a single model is used, multiple, or if the deck is empty or non-existent.

    • Input: deckName (string).

    • Output: An object with deckName, status (e.g., "single_model_found", "multiple_models_found", "no_notes_found", "deck_not_found"), and conditionally modelName (string) or modelNames (array of strings).

  • add_note_type_field:

    • Description: Adds a new field to a note type.

    • Input: modelName (string), fieldName (string).

  • remove_note_type_field:

    • Description: Removes an existing field from a note type.

    • Input: modelName (string), fieldName (string).

  • rename_note_type_field:

    • Description: Renames a field in a note type.

    • Input: modelName (string), oldFieldName (string), newFieldName (string).

  • reposition_note_type_field:

    • Description: Changes the order (index) of a field in a note type.

    • Input: modelName (string), fieldName (string), index (number).

  • update_note_type_templates:

    • Description: Updates the HTML templates (e.g., front and back) for the cards of a note type.

    • Input: modelName (string), templates (object, e.g., {"Card 1": {"Front": "html", "Back": "html"}}).

  • update_note_type_styling:

    • Description: Updates the CSS styling for a note type.

    • Input: modelName (string), css (string).

  • create_model:

    • Description: Creates a new Anki note type (model).

    • Input: modelName (string), fieldNames (array of strings), cardTemplates (array of objects, each with Name, Front, Back HTML strings), css (optional string), isCloze (optional boolean, defaults to false), modelType (optional string, defaults to 'Standard').

  • add_bulk:

    • Description: RECOMMENDED FOR MULTIPLE CARDS: Adds multiple NEW flashcards to Anki in a single operation. Much more efficient than adding cards one by one. Use ONLY for creating new cards, NOT for updating existing ones (will throw errors for any cards that already exist). For updating existing cards, use bulk_update_notes with noteIds instead. Always complete all additions in a single operation whenever possible. Must use HTML formatting for card content.

    • Input: An array of notes, where each note object has:

      • fields: (object) An object where keys are field names and values are their HTML content.

      • modelName: (string) The name of the Anki note type (model) to use for this note.

      • deckName: (optional string) The name of the deck for this note. Defaults to 'Default'.

      • tags: (optional array of strings) A list of tags for this note.

  • undo:

    • Description: Undo the most recent action in Anki's collection — a card review, a field edit, a suspend, etc. Only undoes one action at a time; call repeatedly to undo further back.

    • Input: None.

More information can be found here Anki Integration | Smithery

Available Tools

3 tools
anki_add_noteC

Add a flashcard to an Anki deck

ParametersJSON Schema
NameRequiredDescriptionDefault
backYesBack of the flashcard
deckNameYesThe target deck name
frontYesFront of the flashcard

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It states the action ('Add') which implies a write/mutation operation, but doesn't disclose any behavioral traits like whether it requires specific permissions, what happens if the deck doesn't exist, error conditions, or how the system responds to successful addition. The description is minimal and lacks operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with a single, clear sentence that communicates the core purpose without any wasted words. It's appropriately sized for a straightforward tool and gets directly to the point with no unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and no output schema, the description is insufficiently complete. It doesn't explain what happens after adding the flashcard, potential error conditions, or how to verify success. Given the tool's complexity as a write operation and the lack of structured behavioral information, more context about the operation's behavior and outcomes would be valuable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds no parameter information beyond what's already in the schema, which has 100% coverage with clear descriptions for all three parameters. The baseline score of 3 reflects adequate schema documentation, but the description doesn't provide additional context about parameter relationships, constraints, or usage patterns.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Add') and resource ('flashcard to an Anki deck'), making the purpose immediately understandable. It distinguishes from sibling 'anki_add_notes' by specifying singular 'flashcard' vs. plural 'notes', but doesn't explicitly differentiate from 'anki_create_deck' which creates decks rather than flashcards.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention when to choose this over 'anki_add_notes' (for single vs. multiple cards) or 'anki_create_deck' (for creating decks before adding cards). No prerequisites or contextual usage information is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

anki_add_notesC

Add multiple flashcards to an Anki deck

ParametersJSON Schema
NameRequiredDescriptionDefault
cardsYes
deckNameYesThe target deck name

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action ('Add multiple flashcards') but doesn't cover critical aspects like whether this is a write operation (implied but not confirmed), error handling (e.g., if the deck doesn't exist), or response format. This leaves significant gaps for an agent to understand the tool's behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence that efficiently conveys the core purpose without unnecessary words. It's front-loaded and appropriately sized for the tool's complexity, with no wasted information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of annotations, no output schema, and incomplete parameter documentation (50% coverage), the description is insufficient. It doesn't address key contextual elements like mutation effects, error scenarios, or return values, making it inadequate for safe and effective tool invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description mentions 'multiple flashcards' and 'Anki deck', which loosely maps to the 'cards' array and 'deckName' parameters. However, with 50% schema description coverage (only 'deckName' has a description), the description doesn't add meaningful details about parameter formats, constraints, or the structure of card objects (front/back fields). It partially compensates but not fully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Add multiple flashcards') and resource ('to an Anki deck'), making the purpose immediately understandable. However, it doesn't explicitly differentiate from the sibling tool 'anki_add_note' (singular vs. plural), which could cause confusion about when to use each.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'anki_add_note' (for single cards) or 'anki_create_deck' (for deck creation). There's no mention of prerequisites, such as whether the deck must already exist, or any contextual limitations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

anki_create_deckC

Create a new Anki deck

ParametersJSON Schema
NameRequiredDescriptionDefault
deckNameYesThe name of the deck to create

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states the basic action. It doesn't disclose behavioral traits such as error handling (e.g., what happens if the deck already exists), permission requirements, side effects, or response format, which are critical for a creation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, direct sentence with no wasted words, making it highly concise and front-loaded. It efficiently communicates the core purpose without unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a creation tool with no annotations and no output schema, the description is insufficient. It lacks details on behavior, error cases, and output, leaving gaps that could hinder an agent's ability to use the tool effectively in complex scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the parameter 'deckName' clearly documented in the schema. The description doesn't add any meaning beyond the schema, such as naming conventions or constraints, but the schema provides adequate baseline information.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Create') and resource ('new Anki deck'), making the purpose immediately understandable. However, it doesn't differentiate from sibling tools like 'anki_add_note' or 'anki_add_notes', which are about adding content rather than creating deck structure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. The description doesn't mention prerequisites (e.g., whether the deck must not already exist), constraints, or relationships to sibling tools, leaving the agent to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 3 tool updatesv1.0.0
    • First observedanki_add_note
    • First observedanki_add_notes
    • First observedanki_create_deck

TDQS

C2.9/5.0

Scored across 3 tools

Disambiguation3/5

The tools have overlapping purposes, as 'anki_add_note' and 'anki_add_notes' both handle adding flashcards, which could cause confusion for an agent deciding between single vs. batch operations. However, the descriptions clarify the distinction (single vs. multiple), mitigating some ambiguity. The 'anki_create_deck' tool is clearly distinct, focusing on deck management rather than note addition.

Naming Consistency5/5

All tool names follow a consistent 'anki_' prefix and snake_case pattern (e.g., anki_add_note, anki_add_notes, anki_create_deck), with clear verb_noun structures. This predictability makes it easy for agents to understand and navigate the tool set without confusion from mixed conventions.

Tool Count2/5

With only 3 tools, the server feels thin for managing Anki flashcards, a domain that typically involves operations like updating, deleting, reviewing, or searching notes and decks. The count is too low for the apparent scope, lacking essential CRUD lifecycle coverage beyond basic creation, which may limit agent functionality.

Completeness2/5

The tool set is severely incomplete for Anki management, covering only note addition and deck creation. Obvious gaps include updating or deleting notes/decks, listing or searching existing content, and handling reviews or scheduling—core aspects of flashcard workflows. This will likely cause agent failures when trying to perform common tasks beyond initial setup.

Maintenance

ActivitySlowing
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers