@ankimcp/anki-mcp-server 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +756 -0
  3. package/bin/ankimcp.js +12 -0
  4. package/dist/anki-config.service.d.ts +10 -0
  5. package/dist/anki-config.service.js +42 -0
  6. package/dist/anki-config.service.js.map +1 -0
  7. package/dist/app.module.d.ts +5 -0
  8. package/dist/app.module.js +84 -0
  9. package/dist/app.module.js.map +1 -0
  10. package/dist/bootstrap.d.ts +3 -0
  11. package/dist/bootstrap.js +39 -0
  12. package/dist/bootstrap.js.map +1 -0
  13. package/dist/cli.d.ts +9 -0
  14. package/dist/cli.js +114 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/http/guards/origin-validation.guard.d.ts +7 -0
  17. package/dist/http/guards/origin-validation.guard.js +52 -0
  18. package/dist/http/guards/origin-validation.guard.js.map +1 -0
  19. package/dist/main-http.d.ts +1 -0
  20. package/dist/main-http.js +42 -0
  21. package/dist/main-http.js.map +1 -0
  22. package/dist/main-stdio.d.ts +1 -0
  23. package/dist/main-stdio.js +20 -0
  24. package/dist/main-stdio.js.map +1 -0
  25. package/dist/mcp/clients/__mocks__/anki-connect.client.d.ts +6 -0
  26. package/dist/mcp/clients/__mocks__/anki-connect.client.js +18 -0
  27. package/dist/mcp/clients/__mocks__/anki-connect.client.js.map +1 -0
  28. package/dist/mcp/clients/anki-connect.client.d.ts +15 -0
  29. package/dist/mcp/clients/anki-connect.client.js +145 -0
  30. package/dist/mcp/clients/anki-connect.client.js.map +1 -0
  31. package/dist/mcp/config/anki-config.interface.d.ts +7 -0
  32. package/dist/mcp/config/anki-config.interface.js +5 -0
  33. package/dist/mcp/config/anki-config.interface.js.map +1 -0
  34. package/dist/mcp/primitives/essential/index.d.ts +32 -0
  35. package/dist/mcp/primitives/essential/index.js +130 -0
  36. package/dist/mcp/primitives/essential/index.js.map +1 -0
  37. package/dist/mcp/primitives/essential/prompts/review-session.prompt.d.ts +12 -0
  38. package/dist/mcp/primitives/essential/prompts/review-session.prompt.js +113 -0
  39. package/dist/mcp/primitives/essential/prompts/review-session.prompt.js.map +1 -0
  40. package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/content.md +195 -0
  41. package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.d.ts +12 -0
  42. package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js +89 -0
  43. package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js.map +1 -0
  44. package/dist/mcp/primitives/essential/resources/system-info.resource.d.ts +21 -0
  45. package/dist/mcp/primitives/essential/resources/system-info.resource.js +115 -0
  46. package/dist/mcp/primitives/essential/resources/system-info.resource.js.map +1 -0
  47. package/dist/mcp/primitives/essential/tools/add-note.tool.d.ts +93 -0
  48. package/dist/mcp/primitives/essential/tools/add-note.tool.js +185 -0
  49. package/dist/mcp/primitives/essential/tools/add-note.tool.js.map +1 -0
  50. package/dist/mcp/primitives/essential/tools/create-deck.tool.d.ts +83 -0
  51. package/dist/mcp/primitives/essential/tools/create-deck.tool.js +121 -0
  52. package/dist/mcp/primitives/essential/tools/create-deck.tool.js.map +1 -0
  53. package/dist/mcp/primitives/essential/tools/create-model.tool.d.ts +88 -0
  54. package/dist/mcp/primitives/essential/tools/create-model.tool.js +144 -0
  55. package/dist/mcp/primitives/essential/tools/create-model.tool.js.map +1 -0
  56. package/dist/mcp/primitives/essential/tools/delete-notes.tool.d.ts +84 -0
  57. package/dist/mcp/primitives/essential/tools/delete-notes.tool.js +120 -0
  58. package/dist/mcp/primitives/essential/tools/delete-notes.tool.js.map +1 -0
  59. package/dist/mcp/primitives/essential/tools/find-notes.tool.d.ts +83 -0
  60. package/dist/mcp/primitives/essential/tools/find-notes.tool.js +106 -0
  61. package/dist/mcp/primitives/essential/tools/find-notes.tool.js.map +1 -0
  62. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.d.ts +84 -0
  63. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js +108 -0
  64. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js.map +1 -0
  65. package/dist/mcp/primitives/essential/tools/list-decks.tool.d.ts +83 -0
  66. package/dist/mcp/primitives/essential/tools/list-decks.tool.js +117 -0
  67. package/dist/mcp/primitives/essential/tools/list-decks.tool.js.map +1 -0
  68. package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.d.ts +10 -0
  69. package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.js +18 -0
  70. package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.js.map +1 -0
  71. package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.d.ts +12 -0
  72. package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js +22 -0
  73. package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js.map +1 -0
  74. package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.d.ts +12 -0
  75. package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.js +29 -0
  76. package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.js.map +1 -0
  77. package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.d.ts +15 -0
  78. package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js +41 -0
  79. package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js.map +1 -0
  80. package/dist/mcp/primitives/essential/tools/mediaActions/index.d.ts +5 -0
  81. package/dist/mcp/primitives/essential/tools/mediaActions/index.js +6 -0
  82. package/dist/mcp/primitives/essential/tools/mediaActions/index.js.map +1 -0
  83. package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.d.ts +89 -0
  84. package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js +141 -0
  85. package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js.map +1 -0
  86. package/dist/mcp/primitives/essential/tools/model-field-names.tool.d.ts +83 -0
  87. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js +119 -0
  88. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js.map +1 -0
  89. package/dist/mcp/primitives/essential/tools/model-names.tool.d.ts +81 -0
  90. package/dist/mcp/primitives/essential/tools/model-names.tool.js +80 -0
  91. package/dist/mcp/primitives/essential/tools/model-names.tool.js.map +1 -0
  92. package/dist/mcp/primitives/essential/tools/model-styling.tool.d.ts +83 -0
  93. package/dist/mcp/primitives/essential/tools/model-styling.tool.js +93 -0
  94. package/dist/mcp/primitives/essential/tools/model-styling.tool.js.map +1 -0
  95. package/dist/mcp/primitives/essential/tools/notes-info.tool.d.ts +83 -0
  96. package/dist/mcp/primitives/essential/tools/notes-info.tool.js +111 -0
  97. package/dist/mcp/primitives/essential/tools/notes-info.tool.js.map +1 -0
  98. package/dist/mcp/primitives/essential/tools/present-card.tool.d.ts +84 -0
  99. package/dist/mcp/primitives/essential/tools/present-card.tool.js +100 -0
  100. package/dist/mcp/primitives/essential/tools/present-card.tool.js.map +1 -0
  101. package/dist/mcp/primitives/essential/tools/rate-card.tool.d.ts +84 -0
  102. package/dist/mcp/primitives/essential/tools/rate-card.tool.js +101 -0
  103. package/dist/mcp/primitives/essential/tools/rate-card.tool.js.map +1 -0
  104. package/dist/mcp/primitives/essential/tools/sync.tool.d.ts +81 -0
  105. package/dist/mcp/primitives/essential/tools/sync.tool.js +61 -0
  106. package/dist/mcp/primitives/essential/tools/sync.tool.js.map +1 -0
  107. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.d.ts +84 -0
  108. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js +119 -0
  109. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js.map +1 -0
  110. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.d.ts +96 -0
  111. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js +154 -0
  112. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js.map +1 -0
  113. package/dist/mcp/primitives/gui/index.d.ts +23 -0
  114. package/dist/mcp/primitives/gui/index.js +94 -0
  115. package/dist/mcp/primitives/gui/index.js.map +1 -0
  116. package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.d.ts +88 -0
  117. package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js +111 -0
  118. package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js.map +1 -0
  119. package/dist/mcp/primitives/gui/tools/gui-browse.tool.d.ts +87 -0
  120. package/dist/mcp/primitives/gui/tools/gui-browse.tool.js +99 -0
  121. package/dist/mcp/primitives/gui/tools/gui-browse.tool.js.map +1 -0
  122. package/dist/mcp/primitives/gui/tools/gui-current-card.tool.d.ts +81 -0
  123. package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js +76 -0
  124. package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js.map +1 -0
  125. package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.d.ts +81 -0
  126. package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js +64 -0
  127. package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js.map +1 -0
  128. package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.d.ts +83 -0
  129. package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js +88 -0
  130. package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js.map +1 -0
  131. package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.d.ts +83 -0
  132. package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js +80 -0
  133. package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js.map +1 -0
  134. package/dist/mcp/primitives/gui/tools/gui-select-card.tool.d.ts +83 -0
  135. package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js +90 -0
  136. package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js.map +1 -0
  137. package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.d.ts +81 -0
  138. package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js +83 -0
  139. package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js.map +1 -0
  140. package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.d.ts +81 -0
  141. package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js +74 -0
  142. package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js.map +1 -0
  143. package/dist/mcp/primitives/gui/tools/gui-show-question.tool.d.ts +81 -0
  144. package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js +74 -0
  145. package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js.map +1 -0
  146. package/dist/mcp/primitives/gui/tools/gui-undo.tool.d.ts +81 -0
  147. package/dist/mcp/primitives/gui/tools/gui-undo.tool.js +74 -0
  148. package/dist/mcp/primitives/gui/tools/gui-undo.tool.js.map +1 -0
  149. package/dist/mcp/types/anki.types.d.ts +180 -0
  150. package/dist/mcp/types/anki.types.js +18 -0
  151. package/dist/mcp/types/anki.types.js.map +1 -0
  152. package/dist/mcp/utils/anki.utils.d.ts +19 -0
  153. package/dist/mcp/utils/anki.utils.js +157 -0
  154. package/dist/mcp/utils/anki.utils.js.map +1 -0
  155. package/dist/mcp/utils/markdown.utils.d.ts +4 -0
  156. package/dist/mcp/utils/markdown.utils.js +60 -0
  157. package/dist/mcp/utils/markdown.utils.js.map +1 -0
  158. package/dist/mcp/utils/mcpb-workarounds.d.ts +1 -0
  159. package/dist/mcp/utils/mcpb-workarounds.js +13 -0
  160. package/dist/mcp/utils/mcpb-workarounds.js.map +1 -0
  161. package/dist/services/ngrok.service.d.ts +15 -0
  162. package/dist/services/ngrok.service.js +120 -0
  163. package/dist/services/ngrok.service.js.map +1 -0
  164. package/dist/test-fixtures/mock-data.d.ts +126 -0
  165. package/dist/test-fixtures/mock-data.js +112 -0
  166. package/dist/test-fixtures/mock-data.js.map +1 -0
  167. package/dist/test-fixtures/test-helpers.d.ts +12 -0
  168. package/dist/test-fixtures/test-helpers.js +24 -0
  169. package/dist/test-fixtures/test-helpers.js.map +1 -0
  170. package/dist/tsconfig.build.tsbuildinfo +1 -0
  171. package/package.json +168 -0
@@ -0,0 +1,84 @@
1
+ import type { Context } from "@rekog/mcp-nest";
2
+ import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
3
+ export declare class DeleteNotesTool {
4
+ private readonly ankiClient;
5
+ private readonly logger;
6
+ constructor(ankiClient: AnkiConnectClient);
7
+ deleteNotes({ notes, confirmDeletion }: {
8
+ notes: number[];
9
+ confirmDeletion: boolean;
10
+ }, context: Context): Promise<{
11
+ [x: string]: unknown;
12
+ content: ({
13
+ [x: string]: unknown;
14
+ type: "text";
15
+ text: string;
16
+ _meta?: {
17
+ [x: string]: unknown;
18
+ } | undefined;
19
+ } | {
20
+ [x: string]: unknown;
21
+ type: "image";
22
+ data: string;
23
+ mimeType: string;
24
+ _meta?: {
25
+ [x: string]: unknown;
26
+ } | undefined;
27
+ } | {
28
+ [x: string]: unknown;
29
+ type: "audio";
30
+ data: string;
31
+ mimeType: string;
32
+ _meta?: {
33
+ [x: string]: unknown;
34
+ } | undefined;
35
+ } | {
36
+ [x: string]: unknown;
37
+ type: "resource_link";
38
+ name: string;
39
+ uri: string;
40
+ _meta?: {
41
+ [x: string]: unknown;
42
+ } | undefined;
43
+ mimeType?: string | undefined;
44
+ title?: string | undefined;
45
+ description?: string | undefined;
46
+ icons?: {
47
+ [x: string]: unknown;
48
+ src: string;
49
+ mimeType?: string | undefined;
50
+ sizes?: string[] | undefined;
51
+ }[] | undefined;
52
+ } | {
53
+ [x: string]: unknown;
54
+ type: "resource";
55
+ resource: {
56
+ [x: string]: unknown;
57
+ text: string;
58
+ uri: string;
59
+ _meta?: {
60
+ [x: string]: unknown;
61
+ } | undefined;
62
+ mimeType?: string | undefined;
63
+ } | {
64
+ [x: string]: unknown;
65
+ uri: string;
66
+ blob: string;
67
+ _meta?: {
68
+ [x: string]: unknown;
69
+ } | undefined;
70
+ mimeType?: string | undefined;
71
+ };
72
+ _meta?: {
73
+ [x: string]: unknown;
74
+ } | undefined;
75
+ })[];
76
+ _meta?: {
77
+ [x: string]: unknown;
78
+ } | undefined;
79
+ structuredContent?: {
80
+ [x: string]: unknown;
81
+ } | undefined;
82
+ isError?: boolean | undefined;
83
+ }>;
84
+ }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var DeleteNotesTool_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.DeleteNotesTool = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const mcp_nest_1 = require("@rekog/mcp-nest");
16
+ const zod_1 = require("zod");
17
+ const anki_connect_client_1 = require("../../../clients/anki-connect.client");
18
+ const anki_utils_1 = require("../../../utils/anki.utils");
19
+ let DeleteNotesTool = DeleteNotesTool_1 = class DeleteNotesTool {
20
+ ankiClient;
21
+ logger = new common_1.Logger(DeleteNotesTool_1.name);
22
+ constructor(ankiClient) {
23
+ this.ankiClient = ankiClient;
24
+ }
25
+ async deleteNotes({ notes, confirmDeletion }, context) {
26
+ try {
27
+ if (!confirmDeletion) {
28
+ return (0, anki_utils_1.createErrorResponse)(new Error("Deletion not confirmed"), {
29
+ requestedNotes: notes,
30
+ noteCount: notes.length,
31
+ hint: "Set confirmDeletion to true to permanently delete these notes and all their cards",
32
+ warning: "This action cannot be undone!",
33
+ });
34
+ }
35
+ this.logger.log(`Deleting ${notes.length} note(s)`);
36
+ await context.reportProgress({ progress: 25, total: 100 });
37
+ const notesInfo = await this.ankiClient.invoke("notesInfo", {
38
+ notes: notes,
39
+ });
40
+ const validNotes = notesInfo.filter((note) => note && note.noteId);
41
+ const validNoteIds = validNotes.map((note) => note.noteId);
42
+ const notFoundCount = notes.length - validNotes.length;
43
+ if (validNoteIds.length === 0) {
44
+ this.logger.warn("No valid notes found to delete");
45
+ await context.reportProgress({ progress: 100, total: 100 });
46
+ return (0, anki_utils_1.createSuccessResponse)({
47
+ success: true,
48
+ deletedCount: 0,
49
+ notFoundCount: notes.length,
50
+ requestedIds: notes,
51
+ message: "No notes were deleted (none of the provided IDs were valid)",
52
+ hint: "The notes may have already been deleted or the IDs are invalid",
53
+ });
54
+ }
55
+ const totalCards = validNotes.reduce((sum, note) => sum + (note.cards?.length || 0), 0);
56
+ await context.reportProgress({ progress: 50, total: 100 });
57
+ await this.ankiClient.invoke("deleteNotes", {
58
+ notes: validNoteIds,
59
+ });
60
+ await context.reportProgress({ progress: 100, total: 100 });
61
+ this.logger.log(`Successfully deleted ${validNoteIds.length} note(s) and ${totalCards} card(s)`);
62
+ const message = notFoundCount > 0
63
+ ? `Successfully deleted ${validNoteIds.length} note(s) and ${totalCards} card(s). ${notFoundCount} note(s) were not found.`
64
+ : `Successfully deleted ${validNoteIds.length} note(s) and ${totalCards} card(s)`;
65
+ return (0, anki_utils_1.createSuccessResponse)({
66
+ success: true,
67
+ deletedCount: validNoteIds.length,
68
+ deletedNoteIds: validNoteIds,
69
+ cardsDeleted: totalCards,
70
+ notFoundCount,
71
+ requestedIds: notes,
72
+ message: message,
73
+ warning: "These notes and cards have been permanently deleted",
74
+ hint: "Consider syncing with AnkiWeb to propagate deletions to other devices",
75
+ });
76
+ }
77
+ catch (error) {
78
+ this.logger.error("Failed to delete notes", error);
79
+ if (error instanceof Error) {
80
+ if (error.message.includes("permission")) {
81
+ return (0, anki_utils_1.createErrorResponse)(error, {
82
+ requestedNotes: notes,
83
+ hint: "Permission denied. Check if Anki allows deletions via AnkiConnect.",
84
+ });
85
+ }
86
+ }
87
+ return (0, anki_utils_1.createErrorResponse)(error, {
88
+ requestedNotes: notes,
89
+ hint: "Make sure Anki is running and the note IDs are valid",
90
+ });
91
+ }
92
+ }
93
+ };
94
+ exports.DeleteNotesTool = DeleteNotesTool;
95
+ __decorate([
96
+ (0, mcp_nest_1.Tool)({
97
+ name: "deleteNotes",
98
+ description: "Delete notes by their IDs. This will permanently remove the notes and ALL associated cards. " +
99
+ "This action cannot be undone unless you have a backup. CRITICAL: This is destructive and permanent - only delete notes the user explicitly confirmed for deletion.",
100
+ parameters: zod_1.z.object({
101
+ notes: zod_1.z
102
+ .array(zod_1.z.number())
103
+ .min(1)
104
+ .max(100)
105
+ .describe("Array of note IDs to delete (max 100 at once for safety). " +
106
+ "Get these IDs from findNotes tool. ALL cards associated with these notes will be deleted."),
107
+ confirmDeletion: zod_1.z
108
+ .boolean()
109
+ .describe("Must be set to true to confirm you want to permanently delete these notes and their cards"),
110
+ }),
111
+ }),
112
+ __metadata("design:type", Function),
113
+ __metadata("design:paramtypes", [Object, Object]),
114
+ __metadata("design:returntype", Promise)
115
+ ], DeleteNotesTool.prototype, "deleteNotes", null);
116
+ exports.DeleteNotesTool = DeleteNotesTool = DeleteNotesTool_1 = __decorate([
117
+ (0, common_1.Injectable)(),
118
+ __metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
119
+ ], DeleteNotesTool);
120
+ //# sourceMappingURL=delete-notes.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-notes.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/essential/tools/delete-notes.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import type { Context } from "@rekog/mcp-nest";
2
+ import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
3
+ export declare class FindNotesTool {
4
+ private readonly ankiClient;
5
+ private readonly logger;
6
+ constructor(ankiClient: AnkiConnectClient);
7
+ findNotes({ query }: {
8
+ query: string;
9
+ }, context: Context): Promise<{
10
+ [x: string]: unknown;
11
+ content: ({
12
+ [x: string]: unknown;
13
+ type: "text";
14
+ text: string;
15
+ _meta?: {
16
+ [x: string]: unknown;
17
+ } | undefined;
18
+ } | {
19
+ [x: string]: unknown;
20
+ type: "image";
21
+ data: string;
22
+ mimeType: string;
23
+ _meta?: {
24
+ [x: string]: unknown;
25
+ } | undefined;
26
+ } | {
27
+ [x: string]: unknown;
28
+ type: "audio";
29
+ data: string;
30
+ mimeType: string;
31
+ _meta?: {
32
+ [x: string]: unknown;
33
+ } | undefined;
34
+ } | {
35
+ [x: string]: unknown;
36
+ type: "resource_link";
37
+ name: string;
38
+ uri: string;
39
+ _meta?: {
40
+ [x: string]: unknown;
41
+ } | undefined;
42
+ mimeType?: string | undefined;
43
+ title?: string | undefined;
44
+ description?: string | undefined;
45
+ icons?: {
46
+ [x: string]: unknown;
47
+ src: string;
48
+ mimeType?: string | undefined;
49
+ sizes?: string[] | undefined;
50
+ }[] | undefined;
51
+ } | {
52
+ [x: string]: unknown;
53
+ type: "resource";
54
+ resource: {
55
+ [x: string]: unknown;
56
+ text: string;
57
+ uri: string;
58
+ _meta?: {
59
+ [x: string]: unknown;
60
+ } | undefined;
61
+ mimeType?: string | undefined;
62
+ } | {
63
+ [x: string]: unknown;
64
+ uri: string;
65
+ blob: string;
66
+ _meta?: {
67
+ [x: string]: unknown;
68
+ } | undefined;
69
+ mimeType?: string | undefined;
70
+ };
71
+ _meta?: {
72
+ [x: string]: unknown;
73
+ } | undefined;
74
+ })[];
75
+ _meta?: {
76
+ [x: string]: unknown;
77
+ } | undefined;
78
+ structuredContent?: {
79
+ [x: string]: unknown;
80
+ } | undefined;
81
+ isError?: boolean | undefined;
82
+ }>;
83
+ }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var FindNotesTool_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.FindNotesTool = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const mcp_nest_1 = require("@rekog/mcp-nest");
16
+ const zod_1 = require("zod");
17
+ const anki_connect_client_1 = require("../../../clients/anki-connect.client");
18
+ const anki_utils_1 = require("../../../utils/anki.utils");
19
+ let FindNotesTool = FindNotesTool_1 = class FindNotesTool {
20
+ ankiClient;
21
+ logger = new common_1.Logger(FindNotesTool_1.name);
22
+ constructor(ankiClient) {
23
+ this.ankiClient = ankiClient;
24
+ }
25
+ async findNotes({ query }, context) {
26
+ try {
27
+ this.logger.log(`Searching for notes with query: "${query}"`);
28
+ await context.reportProgress({ progress: 25, total: 100 });
29
+ const noteIds = await this.ankiClient.invoke("findNotes", {
30
+ query: query,
31
+ });
32
+ await context.reportProgress({ progress: 75, total: 100 });
33
+ if (!noteIds || noteIds.length === 0) {
34
+ this.logger.log("No notes found matching the query");
35
+ await context.reportProgress({ progress: 100, total: 100 });
36
+ return (0, anki_utils_1.createSuccessResponse)({
37
+ success: true,
38
+ noteIds: [],
39
+ count: 0,
40
+ query: query,
41
+ message: "No notes found matching the search criteria",
42
+ hint: "Try a broader search query or check your deck/tag names",
43
+ });
44
+ }
45
+ await context.reportProgress({ progress: 100, total: 100 });
46
+ this.logger.log(`Found ${noteIds.length} notes matching the query`);
47
+ return (0, anki_utils_1.createSuccessResponse)({
48
+ success: true,
49
+ noteIds: noteIds,
50
+ count: noteIds.length,
51
+ query: query,
52
+ message: `Found ${noteIds.length} note${noteIds.length === 1 ? "" : "s"} matching the query`,
53
+ hint: noteIds.length > 100
54
+ ? "Large result set. Consider using notesInfo with smaller batches for detailed information."
55
+ : "Use notesInfo tool to get detailed information about these notes",
56
+ });
57
+ }
58
+ catch (error) {
59
+ this.logger.error("Failed to search for notes", error);
60
+ if (error instanceof Error) {
61
+ if (error.message.includes("query")) {
62
+ return (0, anki_utils_1.createErrorResponse)(error, {
63
+ query,
64
+ hint: "Invalid query syntax. Check Anki documentation for valid search syntax.",
65
+ examples: [
66
+ '"deck:DeckName" - all notes in a deck',
67
+ '"tag:important" - notes with specific tag',
68
+ '"is:due" - cards that are due for review',
69
+ '"added:7" - notes added in last 7 days',
70
+ '"front:word" - notes with "word" in front field',
71
+ ],
72
+ });
73
+ }
74
+ }
75
+ return (0, anki_utils_1.createErrorResponse)(error, {
76
+ query,
77
+ hint: "Make sure Anki is running and the query syntax is valid",
78
+ });
79
+ }
80
+ }
81
+ };
82
+ exports.FindNotesTool = FindNotesTool;
83
+ __decorate([
84
+ (0, mcp_nest_1.Tool)({
85
+ name: "findNotes",
86
+ description: "Search for notes using Anki query syntax. Returns an array of note IDs matching the query. " +
87
+ 'Examples: "deck:Spanish", "tag:verb", "is:due", "front:hello", "added:1" (cards added today), ' +
88
+ '"prop:due<=2" (cards due within 2 days), "flag:1" (red flag), "is:suspended"',
89
+ parameters: zod_1.z.object({
90
+ query: zod_1.z
91
+ .string()
92
+ .min(1)
93
+ .describe('Anki search query. Use Anki query syntax like "deck:DeckName", "tag:tagname", ' +
94
+ '"is:due", "is:new", "is:review", "front:text", "back:text", or combine with spaces for AND, ' +
95
+ "OR for alternatives. Empty string returns all notes."),
96
+ }),
97
+ }),
98
+ __metadata("design:type", Function),
99
+ __metadata("design:paramtypes", [Object, Object]),
100
+ __metadata("design:returntype", Promise)
101
+ ], FindNotesTool.prototype, "findNotes", null);
102
+ exports.FindNotesTool = FindNotesTool = FindNotesTool_1 = __decorate([
103
+ (0, common_1.Injectable)(),
104
+ __metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
105
+ ], FindNotesTool);
106
+ //# sourceMappingURL=find-notes.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-notes.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/essential/tools/find-notes.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import type { Context } from "@rekog/mcp-nest";
2
+ import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
3
+ export declare class GetDueCardsTool {
4
+ private readonly ankiClient;
5
+ private readonly logger;
6
+ constructor(ankiClient: AnkiConnectClient);
7
+ getDueCards({ deck_name, limit }: {
8
+ deck_name?: string;
9
+ limit?: number;
10
+ }, context: Context): Promise<{
11
+ [x: string]: unknown;
12
+ content: ({
13
+ [x: string]: unknown;
14
+ type: "text";
15
+ text: string;
16
+ _meta?: {
17
+ [x: string]: unknown;
18
+ } | undefined;
19
+ } | {
20
+ [x: string]: unknown;
21
+ type: "image";
22
+ data: string;
23
+ mimeType: string;
24
+ _meta?: {
25
+ [x: string]: unknown;
26
+ } | undefined;
27
+ } | {
28
+ [x: string]: unknown;
29
+ type: "audio";
30
+ data: string;
31
+ mimeType: string;
32
+ _meta?: {
33
+ [x: string]: unknown;
34
+ } | undefined;
35
+ } | {
36
+ [x: string]: unknown;
37
+ type: "resource_link";
38
+ name: string;
39
+ uri: string;
40
+ _meta?: {
41
+ [x: string]: unknown;
42
+ } | undefined;
43
+ mimeType?: string | undefined;
44
+ title?: string | undefined;
45
+ description?: string | undefined;
46
+ icons?: {
47
+ [x: string]: unknown;
48
+ src: string;
49
+ mimeType?: string | undefined;
50
+ sizes?: string[] | undefined;
51
+ }[] | undefined;
52
+ } | {
53
+ [x: string]: unknown;
54
+ type: "resource";
55
+ resource: {
56
+ [x: string]: unknown;
57
+ text: string;
58
+ uri: string;
59
+ _meta?: {
60
+ [x: string]: unknown;
61
+ } | undefined;
62
+ mimeType?: string | undefined;
63
+ } | {
64
+ [x: string]: unknown;
65
+ uri: string;
66
+ blob: string;
67
+ _meta?: {
68
+ [x: string]: unknown;
69
+ } | undefined;
70
+ mimeType?: string | undefined;
71
+ };
72
+ _meta?: {
73
+ [x: string]: unknown;
74
+ } | undefined;
75
+ })[];
76
+ _meta?: {
77
+ [x: string]: unknown;
78
+ } | undefined;
79
+ structuredContent?: {
80
+ [x: string]: unknown;
81
+ } | undefined;
82
+ isError?: boolean | undefined;
83
+ }>;
84
+ }
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var GetDueCardsTool_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.GetDueCardsTool = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const mcp_nest_1 = require("@rekog/mcp-nest");
16
+ const zod_1 = require("zod");
17
+ const anki_connect_client_1 = require("../../../clients/anki-connect.client");
18
+ const anki_utils_1 = require("../../../utils/anki.utils");
19
+ let GetDueCardsTool = GetDueCardsTool_1 = class GetDueCardsTool {
20
+ ankiClient;
21
+ logger = new common_1.Logger(GetDueCardsTool_1.name);
22
+ constructor(ankiClient) {
23
+ this.ankiClient = ankiClient;
24
+ }
25
+ async getDueCards({ deck_name, limit }, context) {
26
+ try {
27
+ const cardLimit = Math.min(limit || 10, 50);
28
+ this.logger.log(`Getting due cards from deck: ${deck_name || "all"}, limit: ${cardLimit}`);
29
+ await context.reportProgress({ progress: 10, total: 100 });
30
+ let query = "is:due";
31
+ if (deck_name) {
32
+ const escapedDeckName = deck_name.replace(/"/g, '\\"');
33
+ query = `"deck:${escapedDeckName}" ${query}`;
34
+ }
35
+ const cardIds = await this.ankiClient.invoke("findCards", {
36
+ query,
37
+ });
38
+ if (cardIds.length === 0) {
39
+ this.logger.log("No due cards found");
40
+ await context.reportProgress({ progress: 100, total: 100 });
41
+ return (0, anki_utils_1.createSuccessResponse)({
42
+ success: true,
43
+ message: "No cards are due for review",
44
+ cards: [],
45
+ total: 0,
46
+ });
47
+ }
48
+ await context.reportProgress({ progress: 50, total: 100 });
49
+ const selectedCardIds = cardIds.slice(0, cardLimit);
50
+ const cardsInfo = await this.ankiClient.invoke("cardsInfo", {
51
+ cards: selectedCardIds,
52
+ });
53
+ const dueCards = cardsInfo.map((card) => {
54
+ const { front, back } = (0, anki_utils_1.extractCardContent)(card.fields);
55
+ return {
56
+ cardId: card.cardId,
57
+ front: front || card.question || "",
58
+ back: back || card.answer || "",
59
+ deckName: card.deckName,
60
+ modelName: card.modelName,
61
+ due: card.due || 0,
62
+ interval: card.interval || 0,
63
+ factor: card.factor || 2500,
64
+ };
65
+ });
66
+ await context.reportProgress({ progress: 100, total: 100 });
67
+ this.logger.log(`Retrieved ${dueCards.length} due cards out of ${cardIds.length} total`);
68
+ return (0, anki_utils_1.createSuccessResponse)({
69
+ success: true,
70
+ cards: dueCards,
71
+ total: cardIds.length,
72
+ returned: dueCards.length,
73
+ message: `Found ${cardIds.length} due cards, returning ${dueCards.length}`,
74
+ });
75
+ }
76
+ catch (error) {
77
+ this.logger.error("Failed to get due cards", error);
78
+ return (0, anki_utils_1.createErrorResponse)(error);
79
+ }
80
+ }
81
+ };
82
+ exports.GetDueCardsTool = GetDueCardsTool;
83
+ __decorate([
84
+ (0, mcp_nest_1.Tool)({
85
+ name: "get_due_cards",
86
+ description: "Retrieve cards that are due for review from Anki. IMPORTANT: Use sync tool FIRST before getting cards to ensure latest data. After getting cards, use present_card to show them one by one to the user",
87
+ parameters: zod_1.z.object({
88
+ deck_name: zod_1.z
89
+ .string()
90
+ .optional()
91
+ .describe("Specific deck name to get cards from. If not specified, gets cards from all decks"),
92
+ limit: zod_1.z
93
+ .number()
94
+ .min(1)
95
+ .max(50)
96
+ .default(10)
97
+ .describe("Maximum number of cards to return"),
98
+ }),
99
+ }),
100
+ __metadata("design:type", Function),
101
+ __metadata("design:paramtypes", [Object, Object]),
102
+ __metadata("design:returntype", Promise)
103
+ ], GetDueCardsTool.prototype, "getDueCards", null);
104
+ exports.GetDueCardsTool = GetDueCardsTool = GetDueCardsTool_1 = __decorate([
105
+ (0, common_1.Injectable)(),
106
+ __metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
107
+ ], GetDueCardsTool);
108
+ //# sourceMappingURL=get-due-cards.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-due-cards.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/essential/tools/get-due-cards.tool.ts"],"names":[],"mappings":"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"}