The server exposes 49 tools with basic schema definitions using Zod validators. Tool naming follows verb_noun conventions well (create_flashcard, delete_decks, find_cards). However, descriptions are universally minimal (10-30 characters), falling well below the 194-char baseline for production tools. Input schemas are present and type-correct, but parameter descriptions are sparse or missing domain context. Output schemas are not documented, responses are JSON-stringified with no declared structure. Error handling is absent; no guidance for LLM recovery. The 'multi' tool is particularly problematic, accepting arbitrary nested objects without validation. Tools like 'gui_exit_anki' (IRREVERSIBLE risk) lack confirmation patterns. Missing idempotency guarantees, permission gates, and audit guidance.
Creates a note using the given deck and model, with the provided field values and tags
Creates multiple notes using the given deck and model, with the provided field values and tags
Adds tags to notes by note ID
Returns an array indicating whether each of the given cards is due (in the same order)
Returns an array indicating whether each of the given cards is suspended (in the same order)
Accepts an array of objects which define parameters for candidate notes and returns an array of booleans indicating whether or not the parameters at the corresponding index could be used to create a new note
Universal description brevity: ALL 49 tools have descriptions under 30 characters, far below the 194-char baseline. Examples: 'Creates a flashcard in the Default deck with Basic model' (54 chars is above average, but most are 10-30 chars like 'Get all tags from Anki'). LLMs need context on WHEN to use tools and WHAT they return. Current descriptions lack this pedagogical content.
No output schemas documented. All tools return JSON.stringify(response), but the structure of each response is not declared. LLMs cannot plan downstream calls or extract fields without this contract. Critical for tools like deck_names_and_ids, cards_info, notes_info which return structured lists.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Returns a list of objects containing for each card ID the card fields, front and back sides including CSS, note type, the note that the card belongs to, and deck name, as well as ease and interval
Returns an unordered array of note IDs for the given card IDs. For cards with the same note, the ID is only given once in the array
Move cards with the given IDs to a different deck, creating the deck if it doesn't exist yet
Create a new configuration group with the given name, cloning from the group with the given ID
Creates a flashcard in the Default deck with Basic model
Get the complete list of deck names for the current user
Get the complete list of deck names and their respective IDs for the current user
Delete decks with the given names
Delete the specified file inside the media folder
Returns an array of card IDs for a given query. Functionally identical to guiBrowse but doesn't use the GUI for better performance
Returns an array of note IDs for a given query. Same query syntax as guiBrowse
Get the configuration group object for the given deck
Accept an array of card IDs and return an object with each deck name as a key, and its value an array of the given cards which belong to it
Returns an array of the most recent intervals for each given card ID, or a 2-dimensional array of all the intervals for each given card ID when complete is true
Get all tags from Anki
Invokes the Add Cards dialog
Answers the current card; returns true if succeeded or false otherwise
Invokes the Card Browser dialog and searches for a given query
Returns information about the current card or null if not in review mode
Opens the Deck Browser dialog
Opens the Deck Overview dialog for the deck with the given name
Starts review for the deck with the given name
Schedules a request to gracefully close Anki
Shows answer text for the current card; returns true if in review mode or false otherwise
Shows question text for the current card; returns true if in review mode or false otherwise
Starts or resets the timerStarted value for the current card
Get the complete list of field names for the provided model name
Returns an object indicating the fields on the question and answer side of each card template for the given model name
Get the complete list of model names for the current user
Get the complete list of model names and their corresponding IDs for the current user
Execute multiple AnkiConnect requests in a single call
Returns a list of objects containing for each note ID the note fields, tags, note type and the cards belonging to the note
Remove the configuration group with the given ID
Remove tags from notes by note ID
Retrieve the base64-encoded contents of the specified file. Returns false if the file does not exist
Save the given configuration group, returning true on success or false if the ID is invalid
Change the configuration group for the given decks to the one with the given ID
Store a file with the specified base64-encoded contents inside the media folder
Suspend cards by card ID; returns true if successful (at least one card wasn't already suspended) or false otherwise
Unsuspend cards by card ID; returns true if successful (at least one card was previously suspended) or false otherwise
Modify the fields of an existing note
Upgrade Anki Connect (if available)
Get Anki Connect API version
Irreversible operations (gui_exit_anki, delete_decks, remove_deck_config_id, delete_media_file) lack confirmation or dry-run patterns. gui_exit_anki gracefully closes the entire Anki application, an agent should confirm before calling this. delete_decks with cardsToo:true can destroy entire learning collections with no undo.
'multi' tool accepts arbitrary nested objects without schema validation. Parameters: actions is array of {action: string, version: number, params: object}. The 'params' field is an unconstrained object, LLMs can pass anything. This tool is a meta-executor and should either be removed (it duplicates individual tools) or heavily constrained with examples and validation.
Parameter descriptions are missing or trivial. Examples: add_note takes 'note' parameter described as 'Note object containing deck name, model name, fields, tags, and optional audio', but the object structure is not shown. add_tags takes 'tags' as a space-separated string with no guidance on format or escaping. Parameter descriptions should state format, range, and constraints explicitly.
No error handling or recovery guidance. The code calls callAnkiConnect and returns JSON.stringify(responseData) with no try-catch, validation, or error message. If AnkiConnect is unavailable, returns a socket error to the LLM with no guidance on retry. If a card ID is invalid, returns AnkiConnect's error unchanged. LLMs need actionable error messages: 'Card not found. Try find_cards() with a search query.'
No idempotency guarantees. add_note, add_notes, store_media_file lack idempotent keys or deduplication. If an agent retries due to ambiguous network failure, duplicate notes/files are created. Critical for write operations, the code must track operation IDs or support conflict resolution.
No permission gating or audit logging. Tools directly call AnkiConnect with no access control. An agent can delete entire decks or exit Anki with no checks. No logging of who called what tool, when, and why. This is unacceptable for production use, destructive tools must be gated and logged.
save_deck_config accepts a deeply nested 'config' object with no schema validation. The object structure is shown in the input schema but is complex (lapse, new, rev sub-objects with numeric arrays and booleans). No guidance on valid ranges for numeric fields like leechFails, delays, perDay, or ivlFct. Incorrect values are silently accepted and may cause AnkiConnect to fail.
Pagination is not supported. Tools like deck_names, find_cards, find_notes return entire result sets with no limit or offset. If a user has thousands of cards, find_cards returns all of them, wasting tokens and risking context exhaustion. Tools should cap results (e.g., 50 items) and provide pagination params (limit, offset) or cursor support.