Skip to main content

Baraja MCP Server - Connect Claude Desktop to Anki via AnkiConnect

Project description

Baraja MCP Server

A Model Context Protocol (MCP) server that connects Claude Desktop to your local Anki instance via AnkiConnect. Enables Claude to create, manage, and search flashcards directly in your Anki decks.

Note: While this MCP works with any Anki collection, many features and examples are geared towards Spanish language learning.

Features

  • Health Check: Verify Anki and AnkiConnect are running
  • Deck Management: List and create decks
  • Flashcard Creation: Add single or batch flashcards
  • Cloze Deletions: Create cloze deletion cards for sentence learning
  • Search: Find existing notes using Anki's search syntax
  • Sync: Trigger AnkiWeb synchronization
  • Statistics & Analytics: Deck stats, collection overview, study streaks, retention metrics, learning curves
  • Card Management: Suspend/unsuspend cards, update content, delete notes, move cards between decks, manage tags
  • Problem Detection: Identify struggling cards with low ease or high lapse counts
  • Scheduling Control: View due cards, reset card progress, adjust ease factors
  • Spanish Helpers: Built-in utilities for formatting Spanish vocabulary cards

Prerequisites

Before using this MCP server, you need:

  1. Anki Desktop - Download from ankiweb.net
  2. AnkiConnect Add-on - Install from Anki:
    • Open Anki
    • Go to Tools → Add-ons → Get Add-ons
    • Enter code: 2055492159
    • Restart Anki
  3. Python 3.11+ - Required for running the server

Verify AnkiConnect is Running

After installing AnkiConnect, verify it's working:

curl http://localhost:8765

You should see: "AnkiConnect v.6"

Installation

Option 1: Install from PyPI (Recommended)

The easiest way to get started. No need to clone the repository.

pip install baraja-mcp

Or with uv:

uv pip install baraja-mcp

Option 2: Install from source

git clone https://github.com/jbkroner/baraja-mcp.git
cd baraja-mcp
pip install .

Configuration

Claude Desktop Setup

Add this to your Claude Desktop configuration file:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

Using uvx (Recommended)

This runs the server directly from PyPI with no manual install needed. Requires uv.

{
  "mcpServers": {
    "anki": {
      "command": "uvx",
      "args": [
        "--from", "baraja-mcp",
        "baraja-mcp-server"
      ]
    }
  }
}

Using pip install

If you installed with pip install baraja-mcp:

{
  "mcpServers": {
    "anki": {
      "command": "baraja-mcp-server",
      "args": []
    }
  }
}

Note: If baraja-mcp-server isn't on your PATH, use the full path instead (e.g., ~/.local/bin/baraja-mcp-server or your virtualenv's bin/ directory).

Restart Claude Desktop

After updating the configuration, completely quit and restart Claude Desktop for changes to take effect.

Available Tools

anki_health_check

Check if Anki is running with AnkiConnect enabled.

Example:

User: "Is Anki running?"
Claude: [Uses anki_health_check]

list_decks

List all available Anki decks.

Example:

User: "What decks do I have?"
Claude: [Uses list_decks]

list_note_types

List all note types (models) and their fields.

Example:

User: "What note types are available?"
Claude: [Uses list_note_types]

add_flashcard

Add a single flashcard to Anki.

Parameters:

  • deck (required): Target deck name
  • front (required): Front of the card
  • back (required): Back of the card
  • tags (optional): List of tags
  • model (optional): Note type (default: "Basic")

Example:

User: "Add a flashcard: 'What is the capital of France?' → 'Paris' to my Geography deck"
Claude: [Uses add_flashcard with deck="Geography", front="What is the capital of France?", back="Paris"]

add_flashcards_batch

Add multiple flashcards in one operation (much faster than adding individually).

Parameters:

  • deck (required): Target deck name
  • cards (required): List of card objects with front, back, and optional tags
  • tags (optional): Tags applied to all cards
  • model (optional): Note type (default: "Basic")

Example:

User: "Add these Spanish words to my Spanish::Vocabulary deck:
- perro = dog
- gato = cat
- casa = house"

Claude: [Uses add_flashcards_batch with appropriate cards]

search_notes

Search for existing notes using Anki's search syntax.

Parameters:

  • query (required): Search query
  • limit (optional): Max results (default: 20)

Search Syntax Examples:

  • deck:Spanish - All notes in Spanish deck
  • tag:verb - All notes tagged "verb"
  • deck:Spanish tag:verb - Spanish verbs
  • front:hablar - Notes with "hablar" in front field

Example:

User: "Find all my Spanish verb cards"
Claude: [Uses search_notes with query="deck:Spanish tag:verb"]

add_cloze_card

Create a cloze deletion card for learning sentences/phrases.

Parameters:

  • deck (required): Target deck name
  • text (required): Text with {{c1::deletions}} markup
  • extra (optional): Additional context
  • tags (optional): List of tags

Example:

User: "Make a cloze card: 'I have to wake up early tomorrow' focusing on 'have to'"
Claude: [Creates: "I {{c1::have to}} wake up early tomorrow"]

sync_anki

Synchronize the local collection with AnkiWeb.

Example:

User: "Sync my Anki collection"
Claude: [Uses sync_anki]

Statistics & Analytics Tools

get_deck_stats

Get statistics for a specific deck including new, learning, and review card counts.

Parameters:

  • deck (required): Deck name to get statistics for

Example:

User: "How many cards are in my Spanish deck?"
Claude: [Uses get_deck_stats with deck="Spanish"]

get_collection_stats

Get overall collection statistics including cards reviewed today, review history, and totals across all decks.

Example:

User: "Give me an overview of my Anki stats"
Claude: [Uses get_collection_stats]

get_card_stats

Get detailed statistics for specific cards matching a search query. Returns comprehensive data including ease factor, interval, lapses, review count, and card content.

Parameters:

  • query (required): Anki search query (e.g., "deck:Spanish", "tag:verb")
  • limit (optional): Maximum cards to return (default: 10)

Example:

User: "Show me detailed stats for my verb cards"
Claude: [Uses get_card_stats with query="tag:verb"]

get_problem_cards

Find cards that may need attention: low ease factor, high lapse count. Useful for identifying struggling cards.

Parameters:

  • deck (optional): Deck name to filter
  • criteria (optional): "low_ease", "high_lapses", or "all" (default: "all")
  • limit (optional): Maximum cards to return (default: 20)

Example:

User: "Which cards am I struggling with?"
Claude: [Uses get_problem_cards]

get_review_history

Get review history for a deck showing recent reviews and their outcomes (Again/Hard/Good/Easy).

Parameters:

  • deck (required): Deck name
  • limit (optional): Maximum reviews to return (default: 100)

Example:

User: "How have my Spanish reviews been going?"
Claude: [Uses get_review_history with deck="Spanish"]

get_retention_stats

Calculate retention metrics for a deck based on review history. Shows success rate and lapse patterns.

Parameters:

  • deck (optional): Deck name to filter
  • days (optional): Number of days to analyze (default: 30)

Example:

User: "What's my retention rate for the past month?"
Claude: [Uses get_retention_stats with days=30]

get_study_streak

Calculate your study streak - consecutive days with at least one review.

Example:

User: "What's my current study streak?"
Claude: [Uses get_study_streak]

get_learning_curve

Analyze learning progress over time showing review counts, retention, and workload trends.

Parameters:

  • days (optional): Number of days to analyze (default: 30)

Example:

User: "Show me my learning progress over the past month"
Claude: [Uses get_learning_curve with days=30]

Card State Management Tools

suspend_cards

Suspend cards to exclude them from reviews. Suspended cards won't appear in study sessions.

Parameters:

  • card_ids (optional): List of card IDs to suspend
  • query (optional): Anki search query to find cards to suspend

Example:

User: "Suspend all cards tagged 'difficult' for now"
Claude: [Uses suspend_cards with query="tag:difficult"]

unsuspend_cards

Unsuspend cards to include them in reviews again.

Parameters:

  • card_ids (optional): List of card IDs to unsuspend
  • query (optional): Anki search query to find cards to unsuspend

Example:

User: "Unsuspend my difficult cards, I'm ready to review them"
Claude: [Uses unsuspend_cards with query="tag:difficult is:suspended"]

get_suspended_cards

List all suspended cards, optionally filtered by deck.

Parameters:

  • deck (optional): Deck name to filter
  • limit (optional): Maximum cards to return (default: 50)

Example:

User: "Show me which cards are suspended"
Claude: [Uses get_suspended_cards]

get_due_cards

Find cards that are due for review.

Parameters:

  • deck (optional): Deck name to filter
  • limit (optional): Maximum cards to return (default: 50)

Example:

User: "What cards are due for review today?"
Claude: [Uses get_due_cards]

Content Management Tools

update_note

Update the content of an existing note's fields.

Parameters:

  • note_id (required): The note ID to update
  • fields (required): Dictionary of field names to new values

Example:

User: "Update note 1234567890 - change the back to 'nuevo significado'"
Claude: [Uses update_note with note_id=1234567890, fields={"Back": "nuevo significado"}]

delete_notes

Permanently delete notes and all their associated cards. This action cannot be undone!

Parameters:

  • note_ids (required): List of note IDs to delete
  • confirm (required): Must be true to confirm deletion

Example:

User: "Delete notes 123 and 456, I confirm"
Claude: [Uses delete_notes with note_ids=[123, 456], confirm=true]

move_cards

Move cards to a different deck.

Parameters:

  • card_ids (optional): List of card IDs to move
  • query (optional): Anki search query to find cards to move
  • target_deck (required): Destination deck name

Example:

User: "Move all cards tagged 'advanced' to Spanish::Advanced"
Claude: [Uses move_cards with query="tag:advanced", target_deck="Spanish::Advanced"]

remove_tags

Remove tags from notes.

Parameters:

  • note_ids (optional): List of note IDs
  • query (optional): Anki search query to find notes
  • tags (required): List of tags to remove

Example:

User: "Remove the 'new' tag from all my Spanish cards"
Claude: [Uses remove_tags with query="deck:Spanish", tags=["new"]]

Scheduling Tools

reset_card_progress

Reset cards to 'new' state, removing all review history. Useful for relearning material.

Parameters:

  • card_ids (optional): List of card IDs to reset
  • query (optional): Anki search query to find cards to reset
  • confirm (required): Must be true to confirm reset

Example:

User: "Reset my verb conjugation cards, I want to relearn them"
Claude: [Uses reset_card_progress with query="tag:conjugation", confirm=true]

set_ease_factor

Adjust the ease factor for cards. Higher ease = longer intervals between reviews.

Parameters:

  • card_ids (required): List of card IDs
  • ease (required): New ease factor in permille (e.g., 2500 = 250%). Range: 1300-5000 recommended.

Example:

User: "These cards are too easy, increase the ease factor to 300%"
Claude: [Uses set_ease_factor with card_ids=[...], ease=3000]

Usage Examples

Spanish Vocabulary Workflow

Quick Vocab Add:

User: "Add these words to Spanish::Vocabulary:
- madrugada = dawn/early morning
- trasnochar = to stay up late
- madrugar = to wake up early"

Claude: I'll add these Spanish vocabulary words to your deck.
[Uses add_flashcards_batch with formatted cards]

Verb with Conjugation Notes:

User: "Add the verb 'poder' (to be able to) with a note that it's stem-changing o→ue"

Claude: [Creates verb card with conjugation note and appropriate tags]

Sentence Mining with Cloze:

User: "I heard 'Tengo que madrugar mañana' in my podcast. Make a cloze card for 'madrugar'"

Claude: [Creates: "Tengo que {{c1::madrugar}} mañana" with translation and tags]

General Flashcard Workflows

Study Set Creation:

User: "Create a deck called 'Japanese::JLPT N5::Verbs' and add these:
- 食べる (taberu) = to eat
- 飲む (nomu) = to drink
- 見る (miru) = to see"

Claude: [Creates deck and adds cards in batch]

Finding Duplicates:

User: "Do I already have a card for 'ephemeral'?"
Claude: [Uses search_notes with query="front:ephemeral"]

Spanish Helper Functions

The server includes Python helper functions for formatting Spanish cards (located in src/baraja_mcp/spanish.py):

format_vocab_card()

Creates consistently formatted vocabulary cards with:

  • Gender indicators (el/la)
  • Example sentences
  • Proper structure

format_verb_card()

Creates verb cards with:

  • Verb type identification (AR/ER/IR)
  • Conjugation notes
  • Example usage

format_sentence_cloze()

Automatically creates cloze deletions from sentences.

suggest_tags()

Suggests appropriate tags based on:

  • Part of speech
  • Verb characteristics (reflexive, irregular, etc.)
  • Custom categories

Recommended Deck Structure

For Spanish learning:

Spanish/
├── Vocabulary/
│   ├── Core
│   └── Thematic
├── Verbs/
│   ├── Present
│   ├── Past
│   └── Irregular
└── Sentences/
    └── Cloze

Recommended Tags

Part of Speech

verb, noun, adjective, adverb, phrase, expression

Verb Specifics

verb-ar, verb-er, verb-ir, irregular, reflexive

Noun Specifics

masculine, feminine

Frequency

freq-high, freq-medium, freq-low

Source Tracking

source-podcast, source-book, source-conversation, source-lingoda

Topics

topic-food, topic-travel, topic-work, topic-daily

Development

Running Tests

# Make sure Anki is running with AnkiConnect
uv run pytest

# Or with pip
pytest

Note: Tests require Anki to be running with AnkiConnect installed. They will create test decks in your collection.

Project Structure

baraja-mcp/
├── pyproject.toml              # Project configuration
├── README.md                   # This file
├── src/
│   └── baraja_mcp/
│       ├── __init__.py        # Package initialization
│       ├── server.py          # MCP server + tool definitions
│       ├── anki_client.py     # AnkiConnect API wrapper
│       └── spanish.py         # Spanish-specific helpers
└── tests/
    ├── test_anki_client.py    # AnkiConnect tests
    └── test_spanish.py        # Spanish helper tests

Troubleshooting

"AnkiConnect error" messages

Solution: Make sure Anki is running and AnkiConnect is installed. Test with:

curl http://localhost:8765

Cards not appearing in Anki

Solution: Check that:

  1. The deck name is correct (case-sensitive)
  2. You're looking in the right deck
  3. Anki is in the main window (not the browser)

MCP server not connecting

Solution:

  1. Verify the path in Claude Desktop config is absolute (not relative)
  2. Check that uv or python is in your system PATH
  3. Restart Claude Desktop completely
  4. Check Claude Desktop logs for errors

Duplicate cards being skipped

Solution: This is expected behavior. AnkiConnect prevents duplicate cards. Use search_notes to find existing cards.

Links

License

MIT

Contributing

Contributions welcome! Please feel free to submit issues or pull requests.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

baraja_mcp-0.1.1.tar.gz (119.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

baraja_mcp-0.1.1-py3-none-any.whl (23.3 kB view details)

Uploaded Python 3

File details

Details for the file baraja_mcp-0.1.1.tar.gz.

File metadata

  • Download URL: baraja_mcp-0.1.1.tar.gz
  • Upload date:
  • Size: 119.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for baraja_mcp-0.1.1.tar.gz
Algorithm Hash digest
SHA256 c3598f27b454133cef8ad2a5710f9dc76d2d06b8e46307992dd7400f13837457
MD5 c2224a69d5330ed1c2c92d073c592dd7
BLAKE2b-256 f8d031b77942ea45a88ae8bc8b87c77fd4f728ee880582dae5c90beed6d114d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for baraja_mcp-0.1.1.tar.gz:

Publisher: publish.yml on jbkroner/baraja-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file baraja_mcp-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: baraja_mcp-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 23.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for baraja_mcp-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e0501fefa94c688172679c88387ae428e8742225df50f14b69db2480edb40f24
MD5 5ebd514c78ff0f9783aada9e130a2002
BLAKE2b-256 a9922648b0f379aafaf1e50068a6775579bdd44b378667fe85c78ce01adb20af

See more details on using hashes here.

Provenance

The following attestation bundles were made for baraja_mcp-0.1.1-py3-none-any.whl:

Publisher: publish.yml on jbkroner/baraja-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page