Clanki - Claude's Anki Integration

Permite que assistentes de IA interajam com baralhos de flashcards do Anki através do plugin AnkiConnect.

Documentação

MseeP.ai Security Assessment Badge License: MIT

Clanki - Claude's Anki Integration

Um servidor MCP que permite que assistentes de IA como o Claude interajam com baralhos de flashcards do Anki através do Model Context Protocol (MCP).

Recursos

  • Criar e gerenciar baralhos do Anki
  • Criar notas básicas com conteúdo frente/verso
  • Criar notas cloze
  • Criar várias notas de uma vez em uma única solicitação
  • Anexar imagens e áudio de URLs - baixados e incorporados automaticamente
  • Suporte a formatação HTML nos campos das notas
  • Atualizar notas existentes e exclusões cloze
  • Adicionar e gerenciar tags
  • Pesquisar notas com a sintaxe de consulta do Anki
  • Excluir notas permanentemente
  • Visualizar o conteúdo do baralho e informações das notas
  • Integração completa com o AnkiConnect

Pré-requisitos

  • Anki instalado e em execução
  • Plugin AnkiConnect instalado no Anki
  • Node.js 16 ou superior

Instalação

  1. Clone este repositório:
git clone https://github.com/yourusername/clanki.git
cd clanki
  1. Instale as dependências:
npm install
  1. Compile o projeto:
npm run build

Configuração

  1. Certifique-se de que o Anki esteja em execução e o plugin AnkiConnect esteja instalado e habilitado.

  2. Anote o caminho absoluto para build/index.js no seu checkout do clanki. Cada cliente abaixo precisa dele, e nenhum aceita um caminho relativo — eles não executam a partir do diretório do seu projeto, então ./build/index.js não será resolvido.

    # from the clanki directory
    node -e "console.log(require('path').resolve('build/index.js'))"
    

    No Windows, isso imprime barras invertidas. Elas funcionam como estão para os dois comandos CLI abaixo, mas devem ser duplicadas ou substituídas por barras normais se você colar o caminho em uma configuração JSON — veja a nota do Claude Desktop.

  3. Registre o servidor com seu cliente, usando uma das seções abaixo.

  4. Verifique se o servidor consegue alcançar o Anki. Com o Anki em execução:

curl -X POST http://127.0.0.1:8765 -d "{\"action\":\"version\",\"version\":6}"

Uma configuração funcional responde {"result": 6, "error": null}. Se não responder, veja docs/troubleshooting.md — falhas de conexão são de longe o problema mais comum, e a configuração padrão do AnkiConnect não precisa de alterações.

Claude Desktop

Edite claude_desktop_config.json:

PlataformaLocalização
macOS~/Library/Application Support/Claude/claude_desktop_config.json
Windows%APPDATA%\Claude\claude_desktop_config.json
Linux~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "clanki": {
      "command": "node",
      "args": ["/absolute/path/to/clanki/build/index.js"]
    }
  }
}

Substitua /absolute/path/to/clanki pelo caminho real para sua instalação do clanki. No Windows, escreva o caminho com barras normais ou barras invertidas escapadas (C:\\Users\\you\\clanki\\build\\index.js) — uma barra invertida simples é um caractere de escape em JSON e não será analisada.

Reinicie o Claude Desktop depois; ele lê a configuração apenas na inicialização.

Claude Code

claude mcp add clanki -- node /absolute/path/to/clanki/build/index.js

O -- é obrigatório. Ele marca o fim das opções próprias do claude mcp add, então tudo depois dele é tratado como o comando para iniciar. Sem ele, os argumentos são analisados como opções para o claude mcp add e você obtém uma entrada quebrada em vez de um erro.

Por padrão, isso registra o servidor para você apenas no projeto atual (--scope local). Dois outros escopos estão disponíveis:

EscopoO que faz
--scope localVocê, apenas neste projeto. O padrão.
--scope userVocê, em todos os projetos nesta máquina.
--scope projectGravado em .mcp.json na raiz do repositório, para commit para que colegas também o recebam.

Verifique se funcionou:

claude mcp list

clanki deve aparecer como conectado. Se aparecer como falha na conexão, claude mcp get clanki mostra o erro.

Você também pode escrever .mcp.json manualmente, usando o mesmo formato da configuração do Claude Desktop acima. O Claude Code o lê no início da sessão, então reinicie a sessão após editá-lo.

Codex

codex mcp add clanki -- node /absolute/path/to/clanki/build/index.js

Assim como no Claude Code, o -- separa as opções próprias do Codex do comando que inicia o servidor, e é obrigatório.

Isso grava em ~/.codex/config.toml. O Codex usa TOML em vez de JSON, então se você preferir editar o arquivo diretamente, a entrada fica assim:

[mcp_servers.clanki]
command = "node"
args = ["/absolute/path/to/clanki/build/index.js"]

Observe que a tabela TOML é mcp_servers com sublinhado, não mcpServers como nas configurações JSON acima.

Liste os servidores configurados com:

codex mcp list

Configuração

O Clanki não precisa de configuração em uma instalação normal. Cada variável abaixo é opcional.

Usando o Anki em um idioma diferente do inglês

O Anki traduz os nomes de seus tipos de nota integrados, e seus campos, quando uma coleção é criada — uma coleção em alemão tem Einfach com os campos Vorderseite e Rückseite, não Basic com Front e Back. O Clanki os encontra pela estrutura em vez dos nomes, então isso funciona sem nenhuma configuração, independentemente do idioma que você usar.

Se sua coleção contiver vários tipos de nota semelhantes, o Clanki não consegue saber qual você quis dizer. Ele para e lista os candidatos em vez de adivinhar, porque adivinhar errado escreveria seu texto em um campo que não existe, e o Anki o descarta sem erro. Nomeie o que você quer:

VariávelO que faz
CLANKI_BASIC_NOTE_TYPETipo de nota para notas comuns de dois lados, ex.: Einfach
CLANKI_CLOZE_NOTE_TYPETipo de nota para notas cloze, ex.: Lückentext
CLANKI_BASIC_FIELDSSeus dois campos, frente primeiro, ex.: Vorderseite,Rückseite
CLANKI_CLOZE_FIELDSSeus dois campos, texto primeiro, ex.: Text,Extra

Nomear o tipo de nota geralmente é suficiente — o Clanki lê seus campos da sua coleção em ordem. As variáveis _FIELDS só são necessárias para um tipo de nota cujos campos não estão na ordem frente-depois-verso. Ambas são verificadas na sua coleção na inicialização, então um erro de digitação é relatado em vez de perder conteúdo silenciosamente.

Conectando ao AnkiConnect em outro lugar

VariávelPadrão
CLANKI_ANKI_CONNECT_URLhttp://127.0.0.1:8765

Defina isso apenas se você alterou a porta do AnkiConnect ou acessa o Anki em outra máquina.

Onde as variáveis vão depende do seu cliente.

Nas configurações JSON (Claude Desktop, e .mcp.json para Claude Code), elas vão em um bloco env junto com command e args:

{
  "mcpServers": {
    "clanki": {
      "command": "node",
      "args": ["/path/to/clanki/build/index.js"],
      "env": {
        "CLANKI_BASIC_NOTE_TYPE": "Einfach"
      }
    }
  }
}

Em ~/.codex/config.toml, elas vão em uma sub-tabela env sob o servidor:

[mcp_servers.clanki]
command = "node"
args = ["/path/to/clanki/build/index.js"]

[mcp_servers.clanki.env]
CLANKI_BASIC_NOTE_TYPE = "Einfach"

Ambos os CLIs podem defini-las ao registrar o servidor, com --env repetido uma vez por variável:

claude mcp add clanki --env CLANKI_BASIC_NOTE_TYPE=Einfach -- node /path/to/clanki/build/index.js
codex mcp add clanki --env CLANKI_BASIC_NOTE_TYPE=Einfach -- node /path/to/clanki/build/index.js

Reinicie o servidor após alterá-las.

Ferramentas Disponíveis

create-deck

Cria um novo baralho do Anki

  • Parâmetros:
    • name: Nome para o novo baralho

create-card

Cria uma nova nota em um baralho especificado. Suporta formatação HTML e anexos de mídia.

  • Parâmetros:
    • deckName: Nome do baralho para adicionar a nota
    • front: Conteúdo do lado da frente da nota (suporta HTML)
    • back: Conteúdo do lado do verso da nota (suporta HTML)
    • tags: (Opcional) Matriz de tags para a nota
    • frontImages: (Opcional) Matriz de URLs de imagens para a frente
    • backImages: (Opcional) Matriz de URLs de imagens para o verso
    • frontAudio: (Opcional) Matriz de URLs de áudio para a frente
    • backAudio: (Opcional) Matriz de URLs de áudio para o verso

create-cloze-card

Cria uma nova nota cloze em um baralho especificado. Suporta formatação HTML e anexos de mídia.

  • Parâmetros:
    • deckName: Nome do baralho para adicionar a nota
    • text: Texto contendo exclusões cloze usando a sintaxe {{c1::texto}} (suporta HTML)
    • backExtra: (Opcional) Informações extras para mostrar no verso do cartão (suporta HTML)
    • tags: (Opcional) Matriz de tags para a nota
    • textImages: (Opcional) Matriz de URLs de imagens para o campo de texto
    • backImages: (Opcional) Matriz de URLs de imagens para o campo extra do verso
    • textAudio: (Opcional) Matriz de URLs de áudio para o campo de texto
    • backAudio: (Opcional) Matriz de URLs de áudio para o campo extra do verso

create-cards-bulk

Cria várias notas básicas em uma solicitação. Prefira isso a chamadas repetidas de create-card para um lote: envia uma única solicitação ao Anki independentemente do tamanho. Não suporta mídia — use create-card para notas que precisam de imagens ou áudio.

  • Parâmetros:
    • deckName: Nome do baralho para adicionar as notas
    • cards: Matriz de objetos { front, back, tags? } (pelo menos um)

O addNotes do Anki é tudo-ou-nada — uma única duplicata falharia o lote inteiro — então a ferramenta pergunta quais notas são adicionáveis primeiro e envia apenas essas. A resposta informa quantas foram adicionadas, e a posição de entrada e o motivo do próprio Anki para cada nota ignorada, para que você possa corrigir e reenviar apenas essas.

create-cloze-cards-bulk

Cria várias notas cloze em uma solicitação. Mesmas compensações que create-cards-bulk; use create-cloze-card quando precisar de mídia.

  • Parâmetros:
    • deckName: Nome do baralho para adicionar as notas
    • cards: Matriz de objetos { text, backExtra?, tags? } (pelo menos um)

A sintaxe cloze é validada para todo o lote antes de qualquer envio, então uma entrada malformada falha a chamada em vez de deixar um lote parcial no baralho.

update-card

Atualiza uma nota existente

  • Parâmetros:
    • noteId: ID da nota para atualizar
    • front: (Opcional) Novo conteúdo do lado da frente
    • back: (Opcional) Novo conteúdo do lado do verso
    • tags: (Opcional) Novas tags para a nota

update-cloze-card

Atualiza uma nota cloze existente

  • Parâmetros:
    • noteId: ID da nota para atualizar
    • text: (Opcional) Novo texto com exclusões cloze
    • backExtra: (Opcional) Novas informações extras para o verso
    • tags: (Opcional) Novas tags para a nota

find-cards

Pesquisa notas com a sintaxe de consulta do Anki e retorna seus IDs de nota, tipo de nota, tags e um breve trecho de cada campo. Use para obter o noteId que update-card, update-cloze-card e delete-card precisam.

O conteúdo do campo é truncado e o número de resultados é limitado, então restrinja a consulta se a nota que você quer não estiver listada — a resposta sempre informa quantas notas corresponderam no total.

  • Parâmetros:
    • query: Consulta de pesquisa do Anki, ex.: deck:Spanish, tag:vocab, deck:Spanish tag:verbs

delete-card

Exclui notas permanentemente. Isso não pode ser desfeito — não há lixeira para recuperá-las, e cada cartão gerado a partir de uma nota excluída vai junto.

Os IDs de nota devem ser listados explicitamente; não há exclusão por consulta. Use find-cards primeiro para obtê-los e verificar se você tem as notas certas. A resposta informa quais IDs foram realmente excluídos e quais não existiam, porque o Anki relata sucesso de qualquer forma.

  • Parâmetros:
    • noteIds: IDs das notas para excluir, no máximo 50 por chamada
    • confirm: Deve ser true

Recursos

Além das ferramentas acima, os baralhos são expostos como um recurso legível.

anki://deck/<name>

Lê um baralho e retorna todas as notas nele — ID da nota, frente, verso e tags. Diferente de find-cards, o conteúdo é retornado por completo em vez de truncado.

Exemplos de Uso

Cartão básico apenas com texto

"Create a flashcard in my Spanish deck with 'Hola' on the front and 'Hello' on the back"

Cartão com imagens

"Create a flashcard about the Eiffel Tower with an image from https://example.com/eiffel.jpg on the front"

Cartão com áudio

"Create a pronunciation card with audio from https://example.com/pronunciation.mp3"

Cartão com múltiplas mídias

"Create a card with images on both sides and audio on the back for studying animals"

Cartão cloze com mídia

"Create a cloze card: 'The capital of {{c1::France}} is {{c2::Paris}}' with an image of the Eiffel Tower"

Nota: Os arquivos de mídia são baixados automaticamente das URLs e incorporados aos cartões. Certifique-se de que as URLs estejam acessíveis e apontem para arquivos de mídia válidos. Uma URL que não pode ser usada é relatada na resposta da ferramenta; a nota ainda é criada sem esse anexo.

Posicionamento da mídia: Os anexos são adicionados ao final do campo ao qual pertencem, após qualquer texto. Você não pode posicionar uma imagem inline com HTML, porque o nome do arquivo é gerado no momento do upload e não é conhecido antecipadamente. Formatação HTML e anexos de mídia, portanto, não se combinam: use HTML para formatar seu texto e os parâmetros de mídia para anexar arquivos depois dele.

Problema Conhecido: Extra do Verso Ausente em Cartões Cloze Antigos

Versões anteriores gravavam o valor de backExtra em um campo chamado Back. O tipo de nota Cloze embutido do Anki não possui esse campo — seus campos são Text e Back Extra — e o AnkiConnect descarta silenciosamente valores enviados a um campo que não existe.

Como resultado, cartões cloze criados antes desta correção não possuem conteúdo extra armazenado, mesmo que o cartão tenha sido reportado como criado com sucesso. O texto nunca foi gravado no Anki, portanto não pode ser recuperado automaticamente; reinserir o texto nos cartões afetados é a única solução.

Cartões cloze criados a partir desta versão armazenam backExtra corretamente.

Desenvolvimento

Para modificar ou estender o servidor:

  1. Faça alterações em src/index.ts
  2. Recompile com npm run build
  3. Depure com npx @modelcontextprotocol/inspector node build/index.js

Licença

Este projeto é licenciado sob a Licença MIT — consulte o arquivo LICENSE para detalhes.

Contribuições

Contribuições são bem-vindas! Sinta-se à vontade para enviar um Pull Request.

Agradecimentos