UNPKG

anki-mcp-http

Version:

Model Context Protocol server for Anki - enables AI assistants to interact with your Anki flashcards

153 lines 4.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.cleanHtml = cleanHtml; exports.extractCardContent = extractCardContent; exports.getCardType = getCardType; exports.getNoteType = getNoteType; exports.getRatingDescription = getRatingDescription; exports.createSuccessResponse = createSuccessResponse; exports.createErrorResponse = createErrorResponse; exports.formatInterval = formatInterval; exports.parseDeckStats = parseDeckStats; const anki_types_1 = require("../types/anki.types"); const anki_connect_client_1 = require("../clients/anki-connect.client"); function cleanHtml(html) { return html .replace(/<[^>]*>/g, '') .replace(/&nbsp;/g, ' ') .replace(/&amp;/g, '&') .replace(/&lt;/g, '<') .replace(/&gt;/g, '>') .replace(/&quot;/g, '"') .replace(/&#39;/g, "'") .replace(/\n\s*\n/g, '\n') .trim(); } function extractCardContent(fields) { let front = ''; let back = ''; if (!fields) { return { front, back }; } const frontFieldNames = ['Front', '正面', 'Question', 'Text']; const backFieldNames = ['Back', '背面', 'Answer', 'Extra', 'Back Extra']; for (const fieldName of frontFieldNames) { if (fields[fieldName]) { front = fields[fieldName].value; break; } } for (const fieldName of backFieldNames) { if (fields[fieldName]) { back = fields[fieldName].value; break; } } if (!front && !back) { const fieldEntries = Object.entries(fields) .sort((a, b) => a[1].order - b[1].order); if (fieldEntries.length > 0) { front = fieldEntries[0][1].value; } if (fieldEntries.length > 1) { back = fieldEntries[1][1].value; } } return { front: cleanHtml(front), back: cleanHtml(back) }; } function getCardType(type) { switch (type) { case anki_types_1.CardType.New: return 'new'; case anki_types_1.CardType.Learning: return 'learning'; case anki_types_1.CardType.Review: return 'review'; case anki_types_1.CardType.Relearning: return 'relearning'; default: return 'unknown'; } } function getNoteType(modelName) { const lowerName = modelName.toLowerCase(); if (lowerName.includes('basic')) { if (lowerName.includes('reverse')) { return 'Basic (and reversed card)'; } return 'Basic'; } if (lowerName.includes('cloze')) { return 'Cloze'; } return 'Custom'; } function getRatingDescription(rating) { switch (rating) { case anki_types_1.CardRating.Again: return 'Again (failed to recall)'; case anki_types_1.CardRating.Hard: return 'Hard (recalled with difficulty)'; case anki_types_1.CardRating.Good: return 'Good (recalled with some effort)'; case anki_types_1.CardRating.Easy: return 'Easy (recalled instantly)'; default: return 'Unknown'; } } function createSuccessResponse(data) { return { content: [ { type: 'text', text: JSON.stringify(data, null, 2), }, ], }; } function createErrorResponse(error, context) { const errorData = { success: false, error: error instanceof Error ? error.message : 'Unknown error occurred', }; if (error instanceof anki_connect_client_1.AnkiConnectError) { if (error.action) { errorData.action = error.action; } } if (context) { Object.assign(errorData, context); } return { content: [ { type: 'text', text: JSON.stringify(errorData, null, 2), }, ], isError: true, }; } function formatInterval(days) { if (days < 1) { const hours = Math.round(days * 24); return `${hours} hour${hours !== 1 ? 's' : ''}`; } if (days < 30) { return `${Math.round(days)} day${days !== 1 ? 's' : ''}`; } if (days < 365) { const months = Math.round(days / 30); return `${months} month${months !== 1 ? 's' : ''}`; } const years = Math.round(days / 365 * 10) / 10; return `${years} year${years !== 1 ? 's' : ''}`; } function parseDeckStats(stats) { return { new_count: stats.new_count || 0, learn_count: stats.lrn_count || 0, review_count: stats.rev_count || 0, total_cards: stats.total || 0, }; } //# sourceMappingURL=anki.utils.js.map