Skip to main content
Glama

anki-mcp

CI

An MCP server that gives agents (Claude Code, Claude Desktop, …) access to your local Anki collection via AnkiConnect.

Blog post about building it: ikristina.github.io/blog/anki-mcp-server.

My other Anki project: anki-new-tab, a Chrome extension that turns every new tab into a quick review of due cards, with a Pomodoro timer. It also talks to Anki through AnkiConnect.

Tool

What it does

list_decks

Decks with counts and source (anki / yanki = synced from Obsidian / mixed)

describe_deck

Works out a deck's format: note types, fields, audio field and its source, code values (e.g. WordType), templates, tag patterns, samples

list_note_types

Note types with fields in order and note counts; filter by name to also see template front/back fields. For empty decks or newly imported types

search_notes

Anki search syntax, paginated compact previews

get_notes

Full content for specific note ids; raw=True returns stored HTML and [sound:] tags, for editing

get_weak_cards

Most-forgotten cards (lapses, then ease), optionally per deck

get_deck_profile / set_deck_profile

Your saved per-deck conventions (note type, audio field + voice, how to fill each field, tags, rules). Stored in a local JSON file, not in Anki

add_audio

Adds pronunciation audio to existing notes that lack it; dry run by default, batches of ≤50, skips notes that already have audio. replace=True re-voices them (e.g. after switching voice), and texts sets the spoken text per note (e.g. with macrons)

update_notes

Edits fields of existing notes and adds tags; dry run by default with an old → new diff, tags mcp-edited, refuses Yanki notes and edits that would drop audio

create_deck

Creates an empty deck (and missing parents) so add_notes can use it; reports similar existing names, leaves an existing deck alone, supports dry_run

export_deck

Writes a deck (with subdecks and media) to an .apkg file to share or back up; review history only if asked; never overwrites silently

sync

Syncs desktop Anki with AnkiWeb (normal syncs only; refuses a full sync and says why), so notes added on a phone can be tidied and voiced remotely. See docs/remote-from-phone.md

add_notes

Batch add with validation, dry_run, duplicate check, auto-tag mcp-added, optional free TTS audio; refuses Yanki-owned decks

Skills in .claude/skills/:

  • flashcards routes cards: technical topics become markdown in the Obsidian vault (synced by Yanki), and everything else goes straight to Anki.

  • language-cards (/language-cards <words>) adds vocabulary with pronunciation audio to any language deck, following that deck's profile. If a deck has no profile yet, it works one out with describe_deck and asks you to confirm it. It also tidies cards you typed on your phone: fixes the text, adds audio and formats alternative answers.

Installation

Requirements

  • macOS (the offline voices and audio conversion use the built-in say and afconvert)

  • uv (brew install uv); it installs Python 3.11+ for you if needed

  • Anki desktop

  • Claude Code

1. Anki + AnkiConnect

  1. In Anki: Tools → Add-ons → Get Add-ons…, enter code 2055492159, and restart Anki.

  2. Keep Anki open whenever you use the server. AnkiConnect listens on http://127.0.0.1:8765.

2. A Latin voice (if you study Latin)

Google's voices have no real Latin. eSpeak NG has a Latin voice, and at first it seemed like a good option even though it is VERY robotic. In practice turned out that its pronunciation is often wrong, so I trained my own Classical Latin voice with Piper instead. It sounds far more natural. It's not shared (the base model's license forbids redistribution), but you can build the same one: docs/building-a-tts-voice.md. Install it as piper:la_LA-vox-medium (see Audio voices).

eSpeak NG is still needed: Piper uses its Latin rules to turn text into phonemes.

brew install espeak-ng

Check it: espeak-ng --voices=la should list Latin.

3. The server

git clone <this repo> ~/Projects/anki-mcp   # or copy the folder
cd ~/Projects/anki-mcp
uv sync
uv run python scripts/smoke.py              # read-only check over stdio; Anki must be running

4. Register with Claude Code

claude mcp add anki --scope user -- uv --directory /absolute/path/to/anki-mcp run anki-mcp

Then start a new Claude Code session and run /mcp: anki should show as connected. --scope user makes the tools available in every project. The skills only load when Claude Code runs inside this folder, unless you copy .claude/skills/* to ~/.claude/skills/.

Other agents (Claude Desktop, Cursor, VS Code, Codex, Gemini CLI, …)

MCP is agent-agnostic, so any MCP client can run this server. No clone is needed: uvx builds it straight from GitHub. Steps 1–2 (Anki + AnkiConnect, Latin voice) still apply.

The command every client runs:

uvx --from git+https://github.com/ikristina/anki-mcp anki-mcp

GUI apps often don't inherit your shell's PATH. If the server fails to start, replace uvx with its absolute path (which uvx, e.g. /Users/you/.local/bin/uvx).

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json), Cursor (~/.cursor/mcp.json), Windsurf, Gemini CLI (~/.gemini/settings.json), and most other clients use the mcpServers format:

{
  "mcpServers": {
    "anki": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/ikristina/anki-mcp", "anki-mcp"]
    }
  }
}

VS Code / GitHub Copilot (.vscode/mcp.json) uses servers:

{
  "servers": {
    "anki": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "git+https://github.com/ikristina/anki-mcp", "anki-mcp"]
    }
  }
}

OpenAI Codex CLI (~/.codex/config.toml):

[mcp_servers.anki]
command = "uvx"
args = ["--from", "git+https://github.com/ikristina/anki-mcp", "anki-mcp"]

The tools work the same everywhere. The skills (.claude/skills/) are Claude Code's format; with other agents, copy the relevant SKILL.md body into that agent's rules/instructions file. Deck-specific conventions live in deck profiles (below), not in the skills, so the skills work with any collection.

Optional

  • ANKI_CONNECT_URL, if AnkiConnect isn't on http://127.0.0.1:8765 (claude mcp add anki -e ANKI_CONNECT_URL=http://... -- ...).

  • ANKI_MCP_EXPORT_DIR: the folder export_deck uses when no path is given (default ~/Desktop), e.g. a synced Google Drive or Dropbox folder.

Observability (optional): OpenTelemetry traces, metrics and logs

The server always logs to stderr (Claude Code keeps it in its MCP logs; ANKI_MCP_LOG_LEVEL=DEBUG for more). To export traces, metrics and logs over OTLP/HTTP, install the otel extra and point it at a collector. The quickest local backend is Grafana's all-in-one image, which stores all three signals and has a UI at http://localhost:3000:

docker run -d --name otel-lgtm -p 3000:3000 -p 4318:4318 grafana/otel-lgtm
claude mcp add anki --scope user -e OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
  -- uv --directory /absolute/path/to/anki-mcp run --extra otel anki-mcp

To fill Grafana with data without using an agent, generate traffic. The script starts its own server with exporting on and makes random read-only calls, dry-run writes and a few deliberate mistakes. It never writes to the collection:

uv run --extra otel python scripts/otel_traffic.py              # 60 scenarios, about 2 minutes
uv run --extra otel python scripts/otel_traffic.py --calls 300  # more data, for rate() and latency graphs

Any OTLP backend works (Jaeger, Honeycomb, Grafana Cloud…); the standard OTEL_* variables apply (OTEL_EXPORTER_OTLP_HEADERS for API keys, OTEL_SERVICE_NAME, OTEL_SDK_DISABLED=true). Without an endpoint, nothing is exported.

  • Traces: one span per tool call (tools/call add_notes, from the MCP SDK), with child spans per AnkiConnect request (ankiconnect findNotes) and per audio clip (tts google). Failed calls carry the error message the model saw.

  • Metrics: anki_mcp.tool.calls / anki_mcp.tool.duration (by tool and outcome), anki_mcp.ankiconnect.duration (by action), anki_mcp.tts.duration (by engine and voice; Google 429s show up here), anki_mcp.notes.written (by operation and deck). Exported every 10s (OTEL_METRIC_EXPORT_INTERVAL).

  • Logs: writes (notes added, voiced, updated, synced) and tool errors.

Note contents are never recorded, but error messages can quote the word being voiced. Queries, troubleshooting, and how to add the same to your own MCP server: docs/observability.md.

Obsidian (optional, for Yanki decks)

This server never reads or writes Obsidian. It only spots Yanki decks (source: yanki) and refuses to add cards to them. To put new cards there, the agent has to write markdown into your vault by some other route: a separate Obsidian MCP server, or plain file access to the vault folder. Either works. A filesystem-based server such as obsidian-mcp (claude mcp add obsidian -- npx -y obsidian-mcp /path/to/vault) edits the files directly, so Obsidian doesn't need to be running. A server built on the Local REST API plugin needs Obsidian open but can also run commands. Either way, you still run Yanki: Sync in Obsidian to get the cards into Anki. Without either kind of access, the flashcards skill can still write cards for Anki-owned decks, but for Yanki decks it can only show you the markdown to paste in yourself.

Related MCP server: Anki MCP Server

Deck profiles

Some things describe_deck can't infer: which voice a deck uses, which field is spoken, "nouns include the article". Save them once as a deck profile, and every session and agent follows them:

  • File: ~/.config/anki-mcp/profiles.json (override with ANKI_MCP_PROFILES=/path/to/file.json). It's plain JSON, so edit it by hand if you like. Nothing is written to your Anki collection.

  • set_deck_profile checks each profile against Anki before saving: the deck and note type must exist, the field names must belong to that note type, and the voice must work.

  • Agents are told to save a profile only after you confirm it. The language-cards skill proposes one the first time you add to a deck that has none.

  • examples/profiles.json holds my Spanish, French and Latin profiles. To start from them, copy the file to ~/.config/anki-mcp/profiles.json and rename the decks to match yours.

Audio voices

add_notes takes audio: {"field": ..., "voice": ...}. All engines are free:

Voice string

Engine

Needs

Used for

es-MX, fr, de, pt-BR, …

Google Translate (gTTS)

internet

Spanish, French (the same voices HyperTTS's GoogleTranslate service uses)

espeak:la

eSpeak NG

brew install espeak-ng

Latin, but robotic and often mispronounced; I replaced it with the Piper voice below

macos:Alice (any say -v '?' voice)

macOS say

macOS

natural offline voices

piper:la_LA-vox-medium (any <name>.onnx + .onnx.json in ~/.local/share/piper-voices/)

Piper (neural)

uv tool install piper-tts + the voice files

natural offline voices, incl. a self-trained Latin one (how)

Google files are MP3; the offline engines produce M4A (AAC). Anki plays both.

Listen before trusting a voice. Even a good one mispronounces rare words: Google en-US gets chimerical wrong where en-GB is right, and only macos:Samantha says kvetch correctly. To fix one card, clear its audio field in Anki and run add_audio on just that note with a different voice (or use replace=True).

Development

uv run pytest -q                # unit tests: fake in-memory AnkiConnect, no Anki/network needed (runs in CI)
uv run python scripts/smoke.py  # end-to-end over stdio against your real collection (read-only; Anki must be running)
uv run python evals/run.py --models haiku sonnet --repeats 5  # agent evals via `claude -p` against fakes (uses plan usage)

Eval results and method: docs/evals.md. See LEARNINGS.md for design notes.

Example use

screenshot anki-preview

Available Tools

5 tools
add_notesA

Add one or more notes. Every note gets tagged 'mcp-added' so the user can review them in Anki.

Only for decks with source='anki' (see list_decks); Yanki decks are rejected. Each note is validated first (deck exists, note type exists, field names match, not a duplicate of an existing first field in the same deck). Invalid notes are reported and skipped; valid ones are still added. Prefer one batched call over many single-note calls. Set audio on a note to generate pronunciation (needs internet; skipped in dry_run).

ParametersJSON Schema
NameRequiredDescriptionDefault
notesYes
dry_runNoValidate only; add nothing. Use to preview a batch.
allow_duplicatesNo

TDQS

A4.8/5.0
Behavior5/5

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

Adds substantial behavior beyond the annotations: automatic 'mcp-added' tagging, per-note validation rules (deck, note type, field names, duplicate first field), partial-success semantics (invalid notes skipped, valid ones still added), and the internet dependency for audio that is skipped in dry_run. With annotations only declaring openWorld/idempotent/destructive hints, this text carries the real behavioral burden well.

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?

Front-loads the action and the preconditions, then validation behavior, then performance advice, then audio. Every sentence carries actionable information with no filler or repetition of the title.

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

Completeness4/5

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

No output schema exists, and the description does explain that invalid notes are 'reported and skipped', giving a rough sense of the result. It does not detail the shape of validation errors or the response of a successful batch, but for an add tool it is nearly complete.

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

Parameters4/5

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

Schema coverage is only 33%, but the description compensates for the important parameters: it explains dry_run ('validate only; add nothing'), the audio pronunciation generation, and batching of the notes array. It leaves allow_duplicates unexplained in the description, which is the one remaining gap.

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

Purpose5/5

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

Opens with a specific verb+resource ('Add one or more notes') and immediately describes the user-visible side effect (each note tagged 'mcp-added'). The write semantics clearly separate it from read-only siblings list_decks, search_notes, get_notes, and get_weak_cards, and list_decks is explicitly referenced.

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

Usage Guidelines5/5

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

States the hard precondition (only decks with source='anki'; Yanki decks rejected), points to list_decks for checking, advises batching over many single-note calls, and explains when to use dry_run and audio. Both when-to-use and when-not are covered explicitly.

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

get_notesA
Read-only

Get the full content of specific notes (HTML stripped, not truncated). Get ids from search_notes.

ParametersJSON Schema
NameRequiredDescriptionDefault
note_idsYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds meaningful output-behavior context beyond the annotations: content is HTML-stripped and not truncated, which tells the agent what form the returned note content takes.

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?

Two compact sentences with zero waste; the core action and its output guarantee are front-loaded, followed by the id-sourcing hint.

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

Completeness4/5

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

An output schema exists so return values need not be explained, and the description adds the content-format guarantee plus the id-source workflow. Only the batch-size limit goes unmentioned, a minor gap for a one-parameter tool.

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 0% for the single note_ids parameter, so the description must compensate. It usefully explains where the ids come from (search_notes) but says nothing about the array nature or the 1-50 item bounds enforced by the schema.

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

Purpose5/5

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

States a specific verb and resource (get full note content) with clear qualifiers (HTML stripped, not truncated). It distinguishes itself from the sibling search_notes by clarifying that this returns full content while ids come from search.

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

Usage Guidelines4/5

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

Explicitly routes the agent to search_notes as the source of note_ids, giving clear context for when to use this tool. It stops short of stating when-not-to-use, but the workflow dependency is well established.

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

get_weak_cardsA
Read-only

Find the cards the user struggles with most: highest lapse count (times forgotten), then lowest ease.

Good for 'quiz me on my weak spots' or deciding which topics need rewritten/extra cards. Suspended cards are excluded.

ParametersJSON Schema
NameRequiredDescriptionDefault
deckNoExact deck name (includes subdecks). Omit for all decks.
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: the ranking algorithm (lapse count then ease) and the exclusion of suspended cards, which an agent would otherwise not know. Return format is not described, but an output schema exists.

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?

Three short sentences, front-loaded with the core purpose and ranking rule, followed by usage and an exclusion note. No filler; every sentence carries information.

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

Completeness4/5

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

For a read-only ranked-query tool with an output schema, the description covers purpose, ranking semantics, usage scenarios, and the suspended-card exclusion. The only gap is that it never addresses the limit parameter, which leaves the agent to rely entirely on the schema's default and bounds.

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

Parameters2/5

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

Schema description coverage is only 50%: 'deck' is documented in the schema ('Exact deck name (includes subdecks). Omit for all decks.') but 'limit' has no description anywhere. The description references no parameters at all, so it fails to compensate for the undocumented limit, its default of 15, or its max of 50.

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

Purpose5/5

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

States a specific verb and resource ('Find the cards'), and goes further by defining exactly what 'weak' means: highest lapse count, then lowest ease. This distinguishes it from siblings like list_decks and search_notes, which serve different retrieval purposes.

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

Usage Guidelines4/5

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

Provides concrete usage contexts ('quiz me on my weak spots', deciding which topics need rewritten/extra cards), which tells the agent when this tool is the right choice. It does not explicitly name when to prefer a sibling instead, but the sibling set (list_decks, search_notes, get_notes, add_notes) has little functional overlap, so the risk of misrouting is low.

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

list_decksA
Read-only

List all Anki decks with card counts (new / learning / due for review / own cards) and source.

source='yanki': generated from markdown in the user's Obsidian vault by the Yanki plugin. Read and quiz freely, but new cards must be written in Obsidian, not added here. source='anki': native deck, accepts add_notes. source='mixed': holds both kinds (or its subdecks do). add_notes works; prefer Obsidian for technical topics. Subdecks use '::' as the separator, e.g. 'DDIA::04_Transactions'. Counts include subdecks except 'own_cards'.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds real behavioral context beyond that: cards generated from an Obsidian vault cannot be created through this server, mixed decks partially accept add_notes, and counts include subdecks except own_cards. It doesn't address ordering or scale, but for a read-only listing that is minor.

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?

Front-loaded one-line summary of the resource and return shape, followed by compact, labeled source definitions and a separator explanation. Every sentence carries information; nothing is restated from the annotations or name.

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

Completeness5/5

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

For a simple, parameterless read tool with an output schema present, the description covers everything an agent needs: what is listed, what each source value implies for writes, and how deck names decompose. Field-level return formatting is legitimately left to the output schema.

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

Parameters4/5

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

There are zero input parameters, so the baseline is 4. The description instead invests in defining the semantics of returned fields (source values, 'own_cards' vs subdeck-inclusive counts) and the '::' subdeck separator with a worked example, which is genuinely useful for interpreting output.

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

Purpose5/5

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

States a specific verb+resource ('List all Anki decks') and immediately enumerates what comes back (new/learning/due/own cards plus source), which no sibling provides. The source taxonomy further distinguishes it from search_notes/get_notes/add_notes by making clear this is a deck-inventory tool, not a content tool.

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

Usage Guidelines4/5

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

Gives concrete routing guidance tied to each source value: read/quiz freely for yanki, 'add_notes works' for anki and mixed, and 'prefer Obsidian for technical topics.' It tells the agent when writes will and won't work. It stops short of explicitly saying when to call list_decks instead of get_weak_cards or search_notes, so it's context rather than a full when/when-not rule set.

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

search_notesA
Read-only

Search notes and return compact previews (HTML stripped, fields truncated).

Returns total match count so you can paginate with offset. Use get_notes for full field content.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYesAnki search syntax. Examples: 'deck:Go', '"deck:DDIA::04_Transactions" isolation', 'tag:leetcode', 'front:*heap*', 'added:7' (last 7 days), 'is:due'. Quote deck names containing spaces.
offsetNo

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already cover readOnlyHint=true and openWorldHint=false, so safety is declared. The description adds real behavioral context beyond them: results are truncated with HTML stripped, and the total match count is returned to support pagination. That is genuinely useful disclosure for a search 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?

Three short sentences, each earning its place, with the core behavior front-loaded and the alternative and pagination note trailing. No waste.

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

Completeness4/5

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

With no output schema, the description carries the return-value burden and does so (previews, truncation, match count). For a read-only search tool this is nearly complete, though it leaves limit/offset defaults and max results undescribed.

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 coverage is only 33% — only 'query' is documented (with rich Anki syntax examples), while 'limit' and 'offset' are bare. The description partially compensates by explaining that the total match count enables offset-based pagination, but says nothing about limit semantics or defaults. Baseline 3 given partial compensation.

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

Purpose5/5

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

States a specific verb and resource ('Search notes') plus the return shape (compact previews, HTML stripped, fields truncated). It explicitly contrasts with the sibling get_notes, so an agent can distinguish them without opening either schema.

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

Usage Guidelines4/5

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

Provides a clear routing rule: use this for search previews, and 'Use get_notes for full field content.' That names the alternative and the condition selecting it. It doesn't cover other siblings (list_decks, get_weak_cards), so it stops short of full when-not guidance.

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. 5 tool updatesv0.1.0
    • First observedadd_notes
    • First observedget_notes
    • First observedget_weak_cards
    • First observedlist_decks
    • First observedsearch_notes

TDQS

A4.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing decks, searching note previews, retrieving full note content, finding weak cards, and adding notes. search_notes and get_notes are complementary rather than overlapping, and get_weak_cards is a specialized query with a clear scope.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: list_decks, search_notes, get_notes, get_weak_cards, add_notes. There is no mixing of conventions or vague naming.

Tool Count5/5

Five tools are well-scoped for an Anki MCP focused on reviewing decks, searching notes, inspecting cards, finding weak spots, and adding notes. Each tool earns its place without unnecessary bloat.

Completeness4/5

The surface covers core read operations (list/search/get/weak cards) and note creation, which supports the stated quiz-and-add workflow. It lacks update/delete operations for existing notes and deck management, but these are minor gaps for the apparent review-focused purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers