@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.
- package/LICENSE +7 -0
- package/README.md +756 -0
- package/bin/ankimcp.js +12 -0
- package/dist/anki-config.service.d.ts +10 -0
- package/dist/anki-config.service.js +42 -0
- package/dist/anki-config.service.js.map +1 -0
- package/dist/app.module.d.ts +5 -0
- package/dist/app.module.js +84 -0
- package/dist/app.module.js.map +1 -0
- package/dist/bootstrap.d.ts +3 -0
- package/dist/bootstrap.js +39 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +114 -0
- package/dist/cli.js.map +1 -0
- package/dist/http/guards/origin-validation.guard.d.ts +7 -0
- package/dist/http/guards/origin-validation.guard.js +52 -0
- package/dist/http/guards/origin-validation.guard.js.map +1 -0
- package/dist/main-http.d.ts +1 -0
- package/dist/main-http.js +42 -0
- package/dist/main-http.js.map +1 -0
- package/dist/main-stdio.d.ts +1 -0
- package/dist/main-stdio.js +20 -0
- package/dist/main-stdio.js.map +1 -0
- package/dist/mcp/clients/__mocks__/anki-connect.client.d.ts +6 -0
- package/dist/mcp/clients/__mocks__/anki-connect.client.js +18 -0
- package/dist/mcp/clients/__mocks__/anki-connect.client.js.map +1 -0
- package/dist/mcp/clients/anki-connect.client.d.ts +15 -0
- package/dist/mcp/clients/anki-connect.client.js +145 -0
- package/dist/mcp/clients/anki-connect.client.js.map +1 -0
- package/dist/mcp/config/anki-config.interface.d.ts +7 -0
- package/dist/mcp/config/anki-config.interface.js +5 -0
- package/dist/mcp/config/anki-config.interface.js.map +1 -0
- package/dist/mcp/primitives/essential/index.d.ts +32 -0
- package/dist/mcp/primitives/essential/index.js +130 -0
- package/dist/mcp/primitives/essential/index.js.map +1 -0
- package/dist/mcp/primitives/essential/prompts/review-session.prompt.d.ts +12 -0
- package/dist/mcp/primitives/essential/prompts/review-session.prompt.js +113 -0
- package/dist/mcp/primitives/essential/prompts/review-session.prompt.js.map +1 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/content.md +195 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.d.ts +12 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js +89 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js.map +1 -0
- package/dist/mcp/primitives/essential/resources/system-info.resource.d.ts +21 -0
- package/dist/mcp/primitives/essential/resources/system-info.resource.js +115 -0
- package/dist/mcp/primitives/essential/resources/system-info.resource.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/add-note.tool.d.ts +93 -0
- package/dist/mcp/primitives/essential/tools/add-note.tool.js +185 -0
- package/dist/mcp/primitives/essential/tools/add-note.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/create-deck.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/create-deck.tool.js +121 -0
- package/dist/mcp/primitives/essential/tools/create-deck.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/create-model.tool.d.ts +88 -0
- package/dist/mcp/primitives/essential/tools/create-model.tool.js +144 -0
- package/dist/mcp/primitives/essential/tools/create-model.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/delete-notes.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/delete-notes.tool.js +120 -0
- package/dist/mcp/primitives/essential/tools/delete-notes.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/find-notes.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/find-notes.tool.js +106 -0
- package/dist/mcp/primitives/essential/tools/find-notes.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/get-due-cards.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js +108 -0
- package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/list-decks.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/list-decks.tool.js +117 -0
- package/dist/mcp/primitives/essential/tools/list-decks.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.d.ts +10 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.js +18 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.d.ts +12 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js +22 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.d.ts +12 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.js +29 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.d.ts +15 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js +41 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/index.d.ts +5 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/index.js +6 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/index.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.d.ts +89 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js +141 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.js +119 -0
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/model-names.tool.d.ts +81 -0
- package/dist/mcp/primitives/essential/tools/model-names.tool.js +80 -0
- package/dist/mcp/primitives/essential/tools/model-names.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/model-styling.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/model-styling.tool.js +93 -0
- package/dist/mcp/primitives/essential/tools/model-styling.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/notes-info.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/notes-info.tool.js +111 -0
- package/dist/mcp/primitives/essential/tools/notes-info.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/present-card.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/present-card.tool.js +100 -0
- package/dist/mcp/primitives/essential/tools/present-card.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/rate-card.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/rate-card.tool.js +101 -0
- package/dist/mcp/primitives/essential/tools/rate-card.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/sync.tool.d.ts +81 -0
- package/dist/mcp/primitives/essential/tools/sync.tool.js +61 -0
- package/dist/mcp/primitives/essential/tools/sync.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/update-model-styling.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js +119 -0
- package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/update-note-fields.tool.d.ts +96 -0
- package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js +154 -0
- package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/index.d.ts +23 -0
- package/dist/mcp/primitives/gui/index.js +94 -0
- package/dist/mcp/primitives/gui/index.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.d.ts +88 -0
- package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js +111 -0
- package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-browse.tool.d.ts +87 -0
- package/dist/mcp/primitives/gui/tools/gui-browse.tool.js +99 -0
- package/dist/mcp/primitives/gui/tools/gui-browse.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-current-card.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js +76 -0
- package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js +64 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.d.ts +83 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js +88 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.d.ts +83 -0
- package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js +80 -0
- package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-select-card.tool.d.ts +83 -0
- package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js +90 -0
- package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js +83 -0
- package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js +74 -0
- package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-show-question.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js +74 -0
- package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-undo.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-undo.tool.js +74 -0
- package/dist/mcp/primitives/gui/tools/gui-undo.tool.js.map +1 -0
- package/dist/mcp/types/anki.types.d.ts +180 -0
- package/dist/mcp/types/anki.types.js +18 -0
- package/dist/mcp/types/anki.types.js.map +1 -0
- package/dist/mcp/utils/anki.utils.d.ts +19 -0
- package/dist/mcp/utils/anki.utils.js +157 -0
- package/dist/mcp/utils/anki.utils.js.map +1 -0
- package/dist/mcp/utils/markdown.utils.d.ts +4 -0
- package/dist/mcp/utils/markdown.utils.js +60 -0
- package/dist/mcp/utils/markdown.utils.js.map +1 -0
- package/dist/mcp/utils/mcpb-workarounds.d.ts +1 -0
- package/dist/mcp/utils/mcpb-workarounds.js +13 -0
- package/dist/mcp/utils/mcpb-workarounds.js.map +1 -0
- package/dist/services/ngrok.service.d.ts +15 -0
- package/dist/services/ngrok.service.js +120 -0
- package/dist/services/ngrok.service.js.map +1 -0
- package/dist/test-fixtures/mock-data.d.ts +126 -0
- package/dist/test-fixtures/mock-data.js +112 -0
- package/dist/test-fixtures/mock-data.js.map +1 -0
- package/dist/test-fixtures/test-helpers.d.ts +12 -0
- package/dist/test-fixtures/test-helpers.js +24 -0
- package/dist/test-fixtures/test-helpers.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- 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
|
+
}
|