@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,88 @@
1
+ import type { Context } from "@rekog/mcp-nest";
2
+ import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
3
+ export declare class GuiAddCardsTool {
4
+ private readonly ankiClient;
5
+ private readonly logger;
6
+ constructor(ankiClient: AnkiConnectClient);
7
+ guiAddCards({ note, }: {
8
+ note: {
9
+ deckName: string;
10
+ modelName: string;
11
+ fields: Record<string, string>;
12
+ tags?: string[];
13
+ };
14
+ }, context: Context): Promise<{
15
+ [x: string]: unknown;
16
+ content: ({
17
+ [x: string]: unknown;
18
+ type: "text";
19
+ text: string;
20
+ _meta?: {
21
+ [x: string]: unknown;
22
+ } | undefined;
23
+ } | {
24
+ [x: string]: unknown;
25
+ type: "image";
26
+ data: string;
27
+ mimeType: string;
28
+ _meta?: {
29
+ [x: string]: unknown;
30
+ } | undefined;
31
+ } | {
32
+ [x: string]: unknown;
33
+ type: "audio";
34
+ data: string;
35
+ mimeType: string;
36
+ _meta?: {
37
+ [x: string]: unknown;
38
+ } | undefined;
39
+ } | {
40
+ [x: string]: unknown;
41
+ type: "resource_link";
42
+ name: string;
43
+ uri: string;
44
+ _meta?: {
45
+ [x: string]: unknown;
46
+ } | undefined;
47
+ mimeType?: string | undefined;
48
+ title?: string | undefined;
49
+ description?: string | undefined;
50
+ icons?: {
51
+ [x: string]: unknown;
52
+ src: string;
53
+ mimeType?: string | undefined;
54
+ sizes?: string[] | undefined;
55
+ }[] | undefined;
56
+ } | {
57
+ [x: string]: unknown;
58
+ type: "resource";
59
+ resource: {
60
+ [x: string]: unknown;
61
+ text: string;
62
+ uri: string;
63
+ _meta?: {
64
+ [x: string]: unknown;
65
+ } | undefined;
66
+ mimeType?: string | undefined;
67
+ } | {
68
+ [x: string]: unknown;
69
+ uri: string;
70
+ blob: string;
71
+ _meta?: {
72
+ [x: string]: unknown;
73
+ } | undefined;
74
+ mimeType?: string | undefined;
75
+ };
76
+ _meta?: {
77
+ [x: string]: unknown;
78
+ } | undefined;
79
+ })[];
80
+ _meta?: {
81
+ [x: string]: unknown;
82
+ } | undefined;
83
+ structuredContent?: {
84
+ [x: string]: unknown;
85
+ } | undefined;
86
+ isError?: boolean | undefined;
87
+ }>;
88
+ }
@@ -0,0 +1,111 @@
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 GuiAddCardsTool_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.GuiAddCardsTool = 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 GuiAddCardsTool = GuiAddCardsTool_1 = class GuiAddCardsTool {
20
+ ankiClient;
21
+ logger = new common_1.Logger(GuiAddCardsTool_1.name);
22
+ constructor(ankiClient) {
23
+ this.ankiClient = ankiClient;
24
+ }
25
+ async guiAddCards({ note, }, context) {
26
+ try {
27
+ this.logger.log(`Opening Add Cards dialog for deck "${note.deckName}"`);
28
+ await context.reportProgress({ progress: 25, total: 100 });
29
+ const emptyFields = Object.entries(note.fields).filter(([_, value]) => !value || value.trim() === "");
30
+ if (emptyFields.length > 0) {
31
+ return (0, anki_utils_1.createErrorResponse)(new Error(`Fields cannot be empty: ${emptyFields.map(([key]) => key).join(", ")}`), {
32
+ deckName: note.deckName,
33
+ modelName: note.modelName,
34
+ emptyFields: emptyFields.map(([key]) => key),
35
+ });
36
+ }
37
+ await context.reportProgress({ progress: 50, total: 100 });
38
+ const noteId = await this.ankiClient.invoke("guiAddCards", { note });
39
+ await context.reportProgress({ progress: 100, total: 100 });
40
+ this.logger.log(`Add Cards dialog opened, potential note ID: ${noteId}`);
41
+ return (0, anki_utils_1.createSuccessResponse)({
42
+ success: true,
43
+ noteId,
44
+ deckName: note.deckName,
45
+ modelName: note.modelName,
46
+ message: `Add Cards dialog opened with preset details for deck "${note.deckName}"`,
47
+ hint: "The user can now review and finalize the note in the Anki GUI. The note will be created when they click Add.",
48
+ });
49
+ }
50
+ catch (error) {
51
+ this.logger.error("Failed to open Add Cards dialog", error);
52
+ if (error instanceof Error) {
53
+ const errorMessage = error.message.toLowerCase();
54
+ if (errorMessage.includes("field")) {
55
+ return (0, anki_utils_1.createErrorResponse)(error, {
56
+ modelName: note.modelName,
57
+ providedFields: Object.keys(note.fields),
58
+ hint: "Field mismatch. Use modelFieldNames tool to see required fields.",
59
+ });
60
+ }
61
+ if (errorMessage.includes("model")) {
62
+ return (0, anki_utils_1.createErrorResponse)(error, {
63
+ modelName: note.modelName,
64
+ hint: "Model not found. Use modelNames tool to see available models.",
65
+ });
66
+ }
67
+ if (errorMessage.includes("deck")) {
68
+ return (0, anki_utils_1.createErrorResponse)(error, {
69
+ deckName: note.deckName,
70
+ hint: "Deck not found. Use list_decks tool to see available decks.",
71
+ });
72
+ }
73
+ }
74
+ return (0, anki_utils_1.createErrorResponse)(error, {
75
+ deckName: note.deckName,
76
+ modelName: note.modelName,
77
+ hint: "Make sure Anki is running and the deck/model names are correct",
78
+ });
79
+ }
80
+ }
81
+ };
82
+ exports.GuiAddCardsTool = GuiAddCardsTool;
83
+ __decorate([
84
+ (0, mcp_nest_1.Tool)({
85
+ name: "guiAddCards",
86
+ description: "Open Anki Add Cards dialog with preset note details (deck, model, fields, tags). Returns potential note ID. " +
87
+ "IMPORTANT: Only use when user explicitly requests opening the Add Cards dialog. " +
88
+ "This tool is for note editing/creation workflows. Use this when user wants to manually review and finalize note creation in the GUI.",
89
+ parameters: zod_1.z.object({
90
+ note: zod_1.z.object({
91
+ deckName: zod_1.z.string().min(1).describe("Deck to add the note to"),
92
+ modelName: zod_1.z
93
+ .string()
94
+ .min(1)
95
+ .describe('Note type/model (e.g., "Basic", "Cloze")'),
96
+ fields: zod_1.z
97
+ .record(zod_1.z.string())
98
+ .describe('Field values to pre-fill (e.g., {"Front": "question", "Back": "answer"})'),
99
+ tags: zod_1.z.array(zod_1.z.string()).optional().describe("Optional tags to add"),
100
+ }),
101
+ }),
102
+ }),
103
+ __metadata("design:type", Function),
104
+ __metadata("design:paramtypes", [Object, Object]),
105
+ __metadata("design:returntype", Promise)
106
+ ], GuiAddCardsTool.prototype, "guiAddCards", null);
107
+ exports.GuiAddCardsTool = GuiAddCardsTool = GuiAddCardsTool_1 = __decorate([
108
+ (0, common_1.Injectable)(),
109
+ __metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
110
+ ], GuiAddCardsTool);
111
+ //# sourceMappingURL=gui-add-cards.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-add-cards.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/gui/tools/gui-add-cards.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import type { Context } from "@rekog/mcp-nest";
2
+ import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
3
+ export declare class GuiBrowseTool {
4
+ private readonly ankiClient;
5
+ private readonly logger;
6
+ constructor(ankiClient: AnkiConnectClient);
7
+ guiBrowse({ query, reorderCards, }: {
8
+ query: string;
9
+ reorderCards?: {
10
+ order: "ascending" | "descending";
11
+ columnId: string;
12
+ };
13
+ }, context: Context): Promise<{
14
+ [x: string]: unknown;
15
+ content: ({
16
+ [x: string]: unknown;
17
+ type: "text";
18
+ text: string;
19
+ _meta?: {
20
+ [x: string]: unknown;
21
+ } | undefined;
22
+ } | {
23
+ [x: string]: unknown;
24
+ type: "image";
25
+ data: string;
26
+ mimeType: string;
27
+ _meta?: {
28
+ [x: string]: unknown;
29
+ } | undefined;
30
+ } | {
31
+ [x: string]: unknown;
32
+ type: "audio";
33
+ data: string;
34
+ mimeType: string;
35
+ _meta?: {
36
+ [x: string]: unknown;
37
+ } | undefined;
38
+ } | {
39
+ [x: string]: unknown;
40
+ type: "resource_link";
41
+ name: string;
42
+ uri: string;
43
+ _meta?: {
44
+ [x: string]: unknown;
45
+ } | undefined;
46
+ mimeType?: string | undefined;
47
+ title?: string | undefined;
48
+ description?: string | undefined;
49
+ icons?: {
50
+ [x: string]: unknown;
51
+ src: string;
52
+ mimeType?: string | undefined;
53
+ sizes?: string[] | undefined;
54
+ }[] | undefined;
55
+ } | {
56
+ [x: string]: unknown;
57
+ type: "resource";
58
+ resource: {
59
+ [x: string]: unknown;
60
+ text: string;
61
+ uri: string;
62
+ _meta?: {
63
+ [x: string]: unknown;
64
+ } | undefined;
65
+ mimeType?: string | undefined;
66
+ } | {
67
+ [x: string]: unknown;
68
+ uri: string;
69
+ blob: string;
70
+ _meta?: {
71
+ [x: string]: unknown;
72
+ } | undefined;
73
+ mimeType?: string | undefined;
74
+ };
75
+ _meta?: {
76
+ [x: string]: unknown;
77
+ } | undefined;
78
+ })[];
79
+ _meta?: {
80
+ [x: string]: unknown;
81
+ } | undefined;
82
+ structuredContent?: {
83
+ [x: string]: unknown;
84
+ } | undefined;
85
+ isError?: boolean | undefined;
86
+ }>;
87
+ }
@@ -0,0 +1,99 @@
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 GuiBrowseTool_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.GuiBrowseTool = 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 GuiBrowseTool = GuiBrowseTool_1 = class GuiBrowseTool {
20
+ ankiClient;
21
+ logger = new common_1.Logger(GuiBrowseTool_1.name);
22
+ constructor(ankiClient) {
23
+ this.ankiClient = ankiClient;
24
+ }
25
+ async guiBrowse({ query, reorderCards, }, context) {
26
+ try {
27
+ this.logger.log(`Opening Card Browser with query: "${query}"`);
28
+ await context.reportProgress({ progress: 25, total: 100 });
29
+ const params = { query };
30
+ if (reorderCards) {
31
+ params.reorderCards = reorderCards;
32
+ }
33
+ const cardIds = await this.ankiClient.invoke("guiBrowse", params);
34
+ await context.reportProgress({ progress: 100, total: 100 });
35
+ this.logger.log(`Card Browser opened with ${cardIds.length} card(s) found`);
36
+ return (0, anki_utils_1.createSuccessResponse)({
37
+ success: true,
38
+ cardIds,
39
+ cardCount: cardIds.length,
40
+ query,
41
+ message: `Card Browser opened with ${cardIds.length} card(s) matching query "${query}"`,
42
+ hint: cardIds.length === 0
43
+ ? "No cards found. Try adjusting your search query."
44
+ : "Use guiSelectCard to select a specific card, or guiSelectedNotes to get selected notes.",
45
+ });
46
+ }
47
+ catch (error) {
48
+ this.logger.error("Failed to open Card Browser", error);
49
+ if (error instanceof Error) {
50
+ if (error.message.includes("query") ||
51
+ error.message.includes("syntax")) {
52
+ return (0, anki_utils_1.createErrorResponse)(error, {
53
+ query,
54
+ hint: 'Invalid search query. Check Anki search syntax. Examples: "deck:MyDeck", "tag:important", "is:due"',
55
+ });
56
+ }
57
+ }
58
+ return (0, anki_utils_1.createErrorResponse)(error, {
59
+ query,
60
+ hint: "Make sure Anki is running and the GUI is visible",
61
+ });
62
+ }
63
+ }
64
+ };
65
+ exports.GuiBrowseTool = GuiBrowseTool;
66
+ __decorate([
67
+ (0, mcp_nest_1.Tool)({
68
+ name: "guiBrowse",
69
+ description: "Open Anki Card Browser and search for cards using Anki query syntax. Returns array of card IDs found. " +
70
+ "IMPORTANT: Only use when user explicitly requests opening the browser. " +
71
+ "This tool is for note editing/creation workflows, NOT for review sessions. " +
72
+ "Use this to find and select cards/notes that need editing.",
73
+ parameters: zod_1.z.object({
74
+ query: zod_1.z
75
+ .string()
76
+ .min(1)
77
+ .describe('Anki search query using standard syntax (e.g., "deck:Spanish tag:verb", "is:due", "added:7")'),
78
+ reorderCards: zod_1.z
79
+ .object({
80
+ order: zod_1.z
81
+ .enum(["ascending", "descending"])
82
+ .describe("Sort order for the cards in browser"),
83
+ columnId: zod_1.z
84
+ .string()
85
+ .describe('Column to sort by (e.g., "noteFld", "noteCrt", "cardDue")'),
86
+ })
87
+ .optional()
88
+ .describe("Optional reordering of cards in the browser"),
89
+ }),
90
+ }),
91
+ __metadata("design:type", Function),
92
+ __metadata("design:paramtypes", [Object, Object]),
93
+ __metadata("design:returntype", Promise)
94
+ ], GuiBrowseTool.prototype, "guiBrowse", null);
95
+ exports.GuiBrowseTool = GuiBrowseTool = GuiBrowseTool_1 = __decorate([
96
+ (0, common_1.Injectable)(),
97
+ __metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
98
+ ], GuiBrowseTool);
99
+ //# sourceMappingURL=gui-browse.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-browse.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/gui/tools/gui-browse.tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { Context } from "@rekog/mcp-nest";
2
+ import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
3
+ export declare class GuiCurrentCardTool {
4
+ private readonly ankiClient;
5
+ private readonly logger;
6
+ constructor(ankiClient: AnkiConnectClient);
7
+ guiCurrentCard(_args: Record<string, never>, context: Context): Promise<{
8
+ [x: string]: unknown;
9
+ content: ({
10
+ [x: string]: unknown;
11
+ type: "text";
12
+ text: string;
13
+ _meta?: {
14
+ [x: string]: unknown;
15
+ } | undefined;
16
+ } | {
17
+ [x: string]: unknown;
18
+ type: "image";
19
+ data: string;
20
+ mimeType: string;
21
+ _meta?: {
22
+ [x: string]: unknown;
23
+ } | undefined;
24
+ } | {
25
+ [x: string]: unknown;
26
+ type: "audio";
27
+ data: string;
28
+ mimeType: string;
29
+ _meta?: {
30
+ [x: string]: unknown;
31
+ } | undefined;
32
+ } | {
33
+ [x: string]: unknown;
34
+ type: "resource_link";
35
+ name: string;
36
+ uri: string;
37
+ _meta?: {
38
+ [x: string]: unknown;
39
+ } | undefined;
40
+ mimeType?: string | undefined;
41
+ title?: string | undefined;
42
+ description?: string | undefined;
43
+ icons?: {
44
+ [x: string]: unknown;
45
+ src: string;
46
+ mimeType?: string | undefined;
47
+ sizes?: string[] | undefined;
48
+ }[] | undefined;
49
+ } | {
50
+ [x: string]: unknown;
51
+ type: "resource";
52
+ resource: {
53
+ [x: string]: unknown;
54
+ text: string;
55
+ uri: string;
56
+ _meta?: {
57
+ [x: string]: unknown;
58
+ } | undefined;
59
+ mimeType?: string | undefined;
60
+ } | {
61
+ [x: string]: unknown;
62
+ uri: string;
63
+ blob: string;
64
+ _meta?: {
65
+ [x: string]: unknown;
66
+ } | undefined;
67
+ mimeType?: string | undefined;
68
+ };
69
+ _meta?: {
70
+ [x: string]: unknown;
71
+ } | undefined;
72
+ })[];
73
+ _meta?: {
74
+ [x: string]: unknown;
75
+ } | undefined;
76
+ structuredContent?: {
77
+ [x: string]: unknown;
78
+ } | undefined;
79
+ isError?: boolean | undefined;
80
+ }>;
81
+ }
@@ -0,0 +1,76 @@
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 GuiCurrentCardTool_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.GuiCurrentCardTool = 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 GuiCurrentCardTool = GuiCurrentCardTool_1 = class GuiCurrentCardTool {
20
+ ankiClient;
21
+ logger = new common_1.Logger(GuiCurrentCardTool_1.name);
22
+ constructor(ankiClient) {
23
+ this.ankiClient = ankiClient;
24
+ }
25
+ async guiCurrentCard(_args, context) {
26
+ try {
27
+ this.logger.log("Getting current card information from GUI");
28
+ await context.reportProgress({ progress: 50, total: 100 });
29
+ const cardInfo = await this.ankiClient.invoke("guiCurrentCard");
30
+ await context.reportProgress({ progress: 100, total: 100 });
31
+ if (!cardInfo) {
32
+ this.logger.log("Not currently in review mode");
33
+ return (0, anki_utils_1.createSuccessResponse)({
34
+ success: true,
35
+ cardInfo: null,
36
+ inReview: false,
37
+ message: "Not currently in review mode",
38
+ hint: "Open a deck in Anki and start reviewing to see current card information.",
39
+ });
40
+ }
41
+ this.logger.log(`Retrieved current card: ${cardInfo.cardId} from deck "${cardInfo.deckName}"`);
42
+ return (0, anki_utils_1.createSuccessResponse)({
43
+ success: true,
44
+ cardInfo,
45
+ inReview: true,
46
+ message: `Current card: ${cardInfo.cardId} from deck "${cardInfo.deckName}"`,
47
+ hint: "Use guiEditNote to edit the note associated with this card.",
48
+ });
49
+ }
50
+ catch (error) {
51
+ this.logger.error("Failed to get current card information", error);
52
+ return (0, anki_utils_1.createErrorResponse)(error, {
53
+ hint: "Make sure Anki is running and the GUI is visible",
54
+ });
55
+ }
56
+ }
57
+ };
58
+ exports.GuiCurrentCardTool = GuiCurrentCardTool;
59
+ __decorate([
60
+ (0, mcp_nest_1.Tool)({
61
+ name: "guiCurrentCard",
62
+ description: "Get information about the current card displayed in review mode. Returns card details (question, answer, deck, model, etc.) or null if not in review. " +
63
+ "CRITICAL: This tool is ONLY for note editing/creation workflows when user needs to check what card is currently displayed in the GUI. " +
64
+ "NEVER use this for conducting review sessions. Use the dedicated review tools (get_due_cards, present_card, rate_card) instead. " +
65
+ "IMPORTANT: Only use when user explicitly requests current card information.",
66
+ parameters: zod_1.z.object({}),
67
+ }),
68
+ __metadata("design:type", Function),
69
+ __metadata("design:paramtypes", [Object, Object]),
70
+ __metadata("design:returntype", Promise)
71
+ ], GuiCurrentCardTool.prototype, "guiCurrentCard", null);
72
+ exports.GuiCurrentCardTool = GuiCurrentCardTool = GuiCurrentCardTool_1 = __decorate([
73
+ (0, common_1.Injectable)(),
74
+ __metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
75
+ ], GuiCurrentCardTool);
76
+ //# sourceMappingURL=gui-current-card.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-current-card.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/gui/tools/gui-current-card.tool.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,8CAAuC;AAEvC,6BAAwB;AACxB,8EAAsE;AAEtE,0DAGgC;AAMzB,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAGA;IAFZ,MAAM,GAAG,IAAI,eAAM,CAAC,oBAAkB,CAAC,IAAI,CAAC,CAAC;IAE9D,YAA6B,UAA6B;QAA7B,eAAU,GAAV,UAAU,CAAmB;IAAG,CAAC;IAWxD,AAAN,KAAK,CAAC,cAAc,CAAC,KAA4B,EAAE,OAAgB;QACjE,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;YAC7D,MAAM,OAAO,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAG3D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAC3C,gBAAgB,CACjB,CAAC;YAEF,MAAM,OAAO,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YAE5D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;gBAChD,OAAO,IAAA,kCAAqB,EAAC;oBAC3B,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI;oBACd,QAAQ,EAAE,KAAK;oBACf,OAAO,EAAE,8BAA8B;oBACvC,IAAI,EAAE,0EAA0E;iBACjF,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,2BAA2B,QAAQ,CAAC,MAAM,eAAe,QAAQ,CAAC,QAAQ,GAAG,CAC9E,CAAC;YAEF,OAAO,IAAA,kCAAqB,EAAC;gBAC3B,OAAO,EAAE,IAAI;gBACb,QAAQ;gBACR,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,iBAAiB,QAAQ,CAAC,MAAM,eAAe,QAAQ,CAAC,QAAQ,GAAG;gBAC5E,IAAI,EAAE,6DAA6D;aACpE,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;YAEnE,OAAO,IAAA,gCAAmB,EAAC,KAAK,EAAE;gBAChC,IAAI,EAAE,kDAAkD;aACzD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF,CAAA;AAxDY,gDAAkB;AAcvB;IATL,IAAA,eAAI,EAAC;QACJ,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,wJAAwJ;YACxJ,wIAAwI;YACxI,kIAAkI;YAClI,6EAA6E;QAC/E,UAAU,EAAE,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KACzB,CAAC;;;;wDA0CD;6BAvDU,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;qCAI8B,uCAAiB;GAH/C,kBAAkB,CAwD9B"}
@@ -0,0 +1,81 @@
1
+ import type { Context } from "@rekog/mcp-nest";
2
+ import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
3
+ export declare class GuiDeckBrowserTool {
4
+ private readonly ankiClient;
5
+ private readonly logger;
6
+ constructor(ankiClient: AnkiConnectClient);
7
+ guiDeckBrowser(_args: Record<string, never>, context: Context): Promise<{
8
+ [x: string]: unknown;
9
+ content: ({
10
+ [x: string]: unknown;
11
+ type: "text";
12
+ text: string;
13
+ _meta?: {
14
+ [x: string]: unknown;
15
+ } | undefined;
16
+ } | {
17
+ [x: string]: unknown;
18
+ type: "image";
19
+ data: string;
20
+ mimeType: string;
21
+ _meta?: {
22
+ [x: string]: unknown;
23
+ } | undefined;
24
+ } | {
25
+ [x: string]: unknown;
26
+ type: "audio";
27
+ data: string;
28
+ mimeType: string;
29
+ _meta?: {
30
+ [x: string]: unknown;
31
+ } | undefined;
32
+ } | {
33
+ [x: string]: unknown;
34
+ type: "resource_link";
35
+ name: string;
36
+ uri: string;
37
+ _meta?: {
38
+ [x: string]: unknown;
39
+ } | undefined;
40
+ mimeType?: string | undefined;
41
+ title?: string | undefined;
42
+ description?: string | undefined;
43
+ icons?: {
44
+ [x: string]: unknown;
45
+ src: string;
46
+ mimeType?: string | undefined;
47
+ sizes?: string[] | undefined;
48
+ }[] | undefined;
49
+ } | {
50
+ [x: string]: unknown;
51
+ type: "resource";
52
+ resource: {
53
+ [x: string]: unknown;
54
+ text: string;
55
+ uri: string;
56
+ _meta?: {
57
+ [x: string]: unknown;
58
+ } | undefined;
59
+ mimeType?: string | undefined;
60
+ } | {
61
+ [x: string]: unknown;
62
+ uri: string;
63
+ blob: string;
64
+ _meta?: {
65
+ [x: string]: unknown;
66
+ } | undefined;
67
+ mimeType?: string | undefined;
68
+ };
69
+ _meta?: {
70
+ [x: string]: unknown;
71
+ } | undefined;
72
+ })[];
73
+ _meta?: {
74
+ [x: string]: unknown;
75
+ } | undefined;
76
+ structuredContent?: {
77
+ [x: string]: unknown;
78
+ } | undefined;
79
+ isError?: boolean | undefined;
80
+ }>;
81
+ }