使用说明
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:
- Anki Desktop - Download from ankiweb.net
- AnkiConnect Add-on - Install from Anki:
- Open Anki
- Go to Tools → Add-ons → Get Add-ons
- Enter code:
2055492159 - Restart Anki
- 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-serverisn't on your PATH, use the full path instead (e.g.,~/.local/bin/baraja-mcp-serveror your virtualenv'sbin/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 namefront(required): Front of the cardback(required): Back of the cardtags(optional): List of tagsmodel(optional): Note type (default: "Basic")duplicate_scope(optional): How broadly to check for duplicates —"collection"(default, matches Anki's default),"deck"(only the target deck), or"deck_and_subdecks"
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). Duplicates are skipped rather than failing the whole batch — the response lists which cards were skipped, their index in the input, and the note ID(s) they collided with.
Parameters:
deck(required): Target deck namecards(required): List of card objects withfront,back, and optionaltagstags(optional): Tags applied to all cardsmodel(optional): Note type (default: "Basic")allow_duplicates(optional): Add cards even if they duplicate an existing note (default: false)duplicate_scope(optional): How broadly to check for duplicates —"collection"(default, matches Anki's default),"deck"(only the target deck), or"deck_and_subdecks"
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. Field values are
truncated to ~50 chars by default — use full/fields for exact values, or
get_notes if you already have the note IDs.
Parameters:
query(required): Search querylimit(optional): Max results per page (default: 20)offset(optional): Number of matching notes to skip, for paging through large result sets (default: 0)full(optional): Return complete, untruncated field values (default: false)fields(optional): Only include these field names in the output, with complete values
Search Syntax Examples:
deck:Spanish- All notes in Spanish decktag:verb- All notes tagged "verb"deck:Spanish tag:verb- Spanish verbsfront: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"]
get_notes
Get complete, untruncated data (fields, tags, model, card IDs) for specific
note IDs. Use this after search_notes when you need exact field values
instead of the truncated preview.
Parameters:
note_ids(required): List of note IDs to fetch
Example:
User: "What's the exact back text on note 1774317432278?"
Claude: [Uses get_notes with note_ids=[1774317432278]]
add_cloze_card
Create a cloze deletion card for learning sentences/phrases.
Parameters:
deck(required): Target deck nametext(required): Text with{{c1::deletions}}markupextra(optional): Additional contexttags(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 filtercriteria(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 namelimit(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 filterdays(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 suspendquery(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 unsuspendquery(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 filterlimit(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 filterlimit(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 updatefields(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 deleteconfirm(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 movequery(optional): Anki search query to find cards to movetarget_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 IDsquery(optional): Anki search query to find notestags(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 resetquery(optional): Anki search query to find cards to resetconfirm(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 IDsease(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:
- The deck name is correct (case-sensitive)
- You're looking in the right deck
- Anki is in the main window (not the browser)
MCP server not connecting
Solution:
- Verify the path in Claude Desktop config is absolute (not relative)
- Check that
uvorpythonis in your system PATH - Restart Claude Desktop completely
- 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.