Skip to main content
Glama

anki_operations

Perform Anki utility operations including syncing, exporting/importing decks, and managing media files to maintain your flashcard system.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationYesAnki utility operation
deckNameNoDeck name to export
filePathNoFile path for export/import
includeSchedNoInclude scheduling in export
filenameNoMedia filename
mediaDataNoBase64 encoded media data
mediaUrlNoURL to download media from
patternNoPattern to match media files

Implementation Reference

  • The main handler function for the 'anki_operations' tool. It handles multiple operations including sync, version check, export/import decks, and media file operations (store, retrieve, delete, list) using AnkiConnect API.
    async ({ operation, deckName, filePath, includeSched, filename, mediaData, mediaUrl, pattern, }) => { try { switch (operation) { case 'sync': { await ankiClient.miscellaneous.sync(); return { content: [ { type: 'text', text: '✓ Sync initiated successfully', }, ], }; } case 'version': { const version = await ankiClient.miscellaneous.version(); return { content: [ { type: 'text', text: `AnkiConnect version: ${version}`, }, ], }; } case 'export_deck': { if (!deckName || !filePath) { throw new Error('export_deck requires deckName and filePath'); } const params: any = { deck: deckName, path: filePath }; if (includeSched !== undefined) params.includeSched = includeSched; await ankiClient.miscellaneous.exportPackage(params); return { content: [ { type: 'text', text: `✓ Exported deck "${deckName}" to ${filePath}`, }, ], }; } case 'import_package': { if (!filePath) { throw new Error('import_package requires filePath'); } await ankiClient.miscellaneous.importPackage({ path: filePath }); return { content: [ { type: 'text', text: `✓ Imported package from ${filePath}`, }, ], }; } case 'store_media': { if (!filename) { throw new Error('store_media requires filename'); } if (!mediaData && !mediaUrl) { throw new Error('store_media requires either mediaData or mediaUrl'); } const params: any = { filename }; if (mediaData) params.data = mediaData; if (mediaUrl) params.url = mediaUrl; const storedName = await ankiClient.media.storeMediaFile(params); return { content: [ { type: 'text', text: `✓ Stored media file as: ${storedName}`, }, ], }; } case 'retrieve_media': { if (!filename) { throw new Error('retrieve_media requires filename'); } const content = await ankiClient.media.retrieveMediaFile({ filename }); if (content === false) { return { content: [ { type: 'text', text: `Media file "${filename}" not found`, }, ], }; } return { content: [ { type: 'text', text: `Retrieved "${filename}" (${content.length} chars)`, }, ], }; } case 'delete_media': { if (!filename) { throw new Error('delete_media requires filename'); } await ankiClient.media.deleteMediaFile({ filename }); return { content: [ { type: 'text', text: `✓ Deleted media file: ${filename}`, }, ], }; } case 'list_media': { if (!pattern) { throw new Error('list_media requires pattern (e.g., "*.jpg", "*")'); } const files = await ankiClient.media.getMediaFilesNames({ pattern }); return { content: [ { type: 'text', text: `Media files matching "${pattern}" (${files.length}):\n${JSON.stringify(files, null, 2)}`, }, ], }; } case 'get_profiles': { const profiles = await ankiClient.miscellaneous.getProfiles(); return { content: [ { type: 'text', text: `Available profiles:\n${JSON.stringify(profiles, null, 2)}`, }, ], }; } default: throw new Error(`Unknown operation: ${operation}`); } } catch (error) { throw new Error( `anki_operations failed: ${error instanceof Error ? error.message : String(error)}` ); } }
  • Zod input schema defining the parameters for the 'anki_operations' tool, including the required 'operation' enum and optional parameters for various sub-operations.
    { operation: z .enum([ 'sync', 'version', 'export_deck', 'import_package', 'store_media', 'retrieve_media', 'delete_media', 'list_media', 'get_profiles', ]) .describe('Anki utility operation'), // Export/import deckName: z.string().optional().describe('Deck name to export'), filePath: z.string().optional().describe('File path for export/import'), includeSched: z.boolean().optional().describe('Include scheduling in export'), // Media filename: z.string().optional().describe('Media filename'), mediaData: z.string().optional().describe('Base64 encoded media data'), mediaUrl: z.string().optional().describe('URL to download media from'), pattern: z.string().optional().describe('Pattern to match media files'), },
  • Registration of the 'anki_operations' tool using server.tool(), including inline schema and handler function.
    server.tool( 'anki_operations', { operation: z .enum([ 'sync', 'version', 'export_deck', 'import_package', 'store_media', 'retrieve_media', 'delete_media', 'list_media', 'get_profiles', ]) .describe('Anki utility operation'), // Export/import deckName: z.string().optional().describe('Deck name to export'), filePath: z.string().optional().describe('File path for export/import'), includeSched: z.boolean().optional().describe('Include scheduling in export'), // Media filename: z.string().optional().describe('Media filename'), mediaData: z.string().optional().describe('Base64 encoded media data'), mediaUrl: z.string().optional().describe('URL to download media from'), pattern: z.string().optional().describe('Pattern to match media files'), }, async ({ operation, deckName, filePath, includeSched, filename, mediaData, mediaUrl, pattern, }) => { try { switch (operation) { case 'sync': { await ankiClient.miscellaneous.sync(); return { content: [ { type: 'text', text: '✓ Sync initiated successfully', }, ], }; } case 'version': { const version = await ankiClient.miscellaneous.version(); return { content: [ { type: 'text', text: `AnkiConnect version: ${version}`, }, ], }; } case 'export_deck': { if (!deckName || !filePath) { throw new Error('export_deck requires deckName and filePath'); } const params: any = { deck: deckName, path: filePath }; if (includeSched !== undefined) params.includeSched = includeSched; await ankiClient.miscellaneous.exportPackage(params); return { content: [ { type: 'text', text: `✓ Exported deck "${deckName}" to ${filePath}`, }, ], }; } case 'import_package': { if (!filePath) { throw new Error('import_package requires filePath'); } await ankiClient.miscellaneous.importPackage({ path: filePath }); return { content: [ { type: 'text', text: `✓ Imported package from ${filePath}`, }, ], }; } case 'store_media': { if (!filename) { throw new Error('store_media requires filename'); } if (!mediaData && !mediaUrl) { throw new Error('store_media requires either mediaData or mediaUrl'); } const params: any = { filename }; if (mediaData) params.data = mediaData; if (mediaUrl) params.url = mediaUrl; const storedName = await ankiClient.media.storeMediaFile(params); return { content: [ { type: 'text', text: `✓ Stored media file as: ${storedName}`, }, ], }; } case 'retrieve_media': { if (!filename) { throw new Error('retrieve_media requires filename'); } const content = await ankiClient.media.retrieveMediaFile({ filename }); if (content === false) { return { content: [ { type: 'text', text: `Media file "${filename}" not found`, }, ], }; } return { content: [ { type: 'text', text: `Retrieved "${filename}" (${content.length} chars)`, }, ], }; } case 'delete_media': { if (!filename) { throw new Error('delete_media requires filename'); } await ankiClient.media.deleteMediaFile({ filename }); return { content: [ { type: 'text', text: `✓ Deleted media file: ${filename}`, }, ], }; } case 'list_media': { if (!pattern) { throw new Error('list_media requires pattern (e.g., "*.jpg", "*")'); } const files = await ankiClient.media.getMediaFilesNames({ pattern }); return { content: [ { type: 'text', text: `Media files matching "${pattern}" (${files.length}):\n${JSON.stringify(files, null, 2)}`, }, ], }; } case 'get_profiles': { const profiles = await ankiClient.miscellaneous.getProfiles(); return { content: [ { type: 'text', text: `Available profiles:\n${JSON.stringify(profiles, null, 2)}`, }, ], }; } default: throw new Error(`Unknown operation: ${operation}`); } } catch (error) { throw new Error( `anki_operations failed: ${error instanceof Error ? error.message : String(error)}` ); } } );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/arielbk/anki-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server