@ankimcp/anki-mcp-server 0.11.0 → 0.12.1
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/README.md +19 -1
- package/dist/mcp/primitives/essential/index.d.ts +7 -1
- package/dist/mcp/primitives/essential/index.js +13 -1
- package/dist/mcp/primitives/essential/index.js.map +1 -1
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.d.ts +104 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.js +212 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.types.d.ts +32 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.types.js +3 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.types.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/index.d.ts +2 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/index.js +6 -0
- package/dist/mcp/primitives/essential/tools/collection-stats/index.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/deck-stats.tool.d.ts +107 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/deck-stats.tool.js +165 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/deck-stats.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/deck-stats.types.d.ts +25 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/deck-stats.types.js +3 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/deck-stats.types.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/index.d.ts +2 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/index.js +6 -0
- package/dist/mcp/primitives/essential/tools/deck-stats/index.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/review-stats/index.d.ts +2 -0
- package/dist/mcp/primitives/essential/tools/review-stats/index.js +6 -0
- package/dist/mcp/primitives/essential/tools/review-stats/index.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/review-stats/review-stats.tool.d.ts +108 -0
- package/dist/mcp/primitives/essential/tools/review-stats/review-stats.tool.js +149 -0
- package/dist/mcp/primitives/essential/tools/review-stats/review-stats.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/review-stats/review-stats.types.d.ts +47 -0
- package/dist/mcp/primitives/essential/tools/review-stats/review-stats.types.js +3 -0
- package/dist/mcp/primitives/essential/tools/review-stats/review-stats.types.js.map +1 -0
- package/dist/mcp/utils/stats.utils.d.ts +28 -0
- package/dist/mcp/utils/stats.utils.js +139 -0
- package/dist/mcp/utils/stats.utils.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ Just tell Claude where the image is, and it will handle the upload automatically
|
|
|
73
73
|
## Prerequisites
|
|
74
74
|
|
|
75
75
|
- [Anki](https://apps.ankiweb.net/) with [AnkiConnect](https://github.com/FooSoft/anki-connect) plugin installed
|
|
76
|
-
- Node.js 20+
|
|
76
|
+
- Node.js 20.19.0+
|
|
77
77
|
|
|
78
78
|
## Installation
|
|
79
79
|
|
|
@@ -389,6 +389,24 @@ For a comprehensive list of known issues and limitations, please visit our docum
|
|
|
389
389
|
|
|
390
390
|
For more details and other known issues, see the [full documentation](https://ankimcp.ai/docs/known-issues/).
|
|
391
391
|
|
|
392
|
+
## Troubleshooting
|
|
393
|
+
|
|
394
|
+
### ERR_REQUIRE_ESM Error
|
|
395
|
+
|
|
396
|
+
If you see an error like:
|
|
397
|
+
```
|
|
398
|
+
Error [ERR_REQUIRE_ESM]: require() of ES Module not supported
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
This means your Node.js version is too old. The server requires **Node.js 20.19.0 or later**.
|
|
402
|
+
|
|
403
|
+
**Check your version:**
|
|
404
|
+
```bash
|
|
405
|
+
node --version
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**Solution:** Update Node.js to version 20.19.0 or later. You can download it from [nodejs.org](https://nodejs.org/) or use a version manager like [nvm](https://github.com/nvm-sh/nvm).
|
|
409
|
+
|
|
392
410
|
## Development
|
|
393
411
|
|
|
394
412
|
### Transport Modes
|
|
@@ -23,6 +23,9 @@ export { DeleteNotesTool } from "./tools/delete-notes.tool";
|
|
|
23
23
|
export { MediaActionsTool } from "./tools/mediaActions";
|
|
24
24
|
export { GetTagsTool } from "./tools/get-tags.tool";
|
|
25
25
|
export { TagActionsTool } from "./tools/tagActions";
|
|
26
|
+
export { DeckStatsTool } from "./tools/deck-stats";
|
|
27
|
+
export { CollectionStatsTool } from "./tools/collection-stats";
|
|
28
|
+
export { ReviewStatsTool } from "./tools/review-stats";
|
|
26
29
|
export { ReviewSessionPrompt } from "./prompts/review-session.prompt";
|
|
27
30
|
export { TwentyRulesPrompt } from "./prompts/twenty-rules.prompt";
|
|
28
31
|
export { SystemInfoResource } from "./resources/system-info.resource";
|
|
@@ -47,10 +50,13 @@ import { DeleteNotesTool } from "./tools/delete-notes.tool";
|
|
|
47
50
|
import { MediaActionsTool } from "./tools/mediaActions";
|
|
48
51
|
import { GetTagsTool } from "./tools/get-tags.tool";
|
|
49
52
|
import { TagActionsTool } from "./tools/tagActions";
|
|
53
|
+
import { DeckStatsTool } from "./tools/deck-stats";
|
|
54
|
+
import { CollectionStatsTool } from "./tools/collection-stats";
|
|
55
|
+
import { ReviewStatsTool } from "./tools/review-stats";
|
|
50
56
|
import { ReviewSessionPrompt } from "./prompts/review-session.prompt";
|
|
51
57
|
import { TwentyRulesPrompt } from "./prompts/twenty-rules.prompt";
|
|
52
58
|
import { SystemInfoResource } from "./resources/system-info.resource";
|
|
53
|
-
export declare const ESSENTIAL_MCP_TOOLS: (typeof SyncTool | typeof ListDecksTool | typeof CreateDeckTool | typeof GetDueCardsTool | typeof GetCardsTool | typeof PresentCardTool | typeof RateCardTool | typeof ModelNamesTool | typeof ModelFieldNamesTool | typeof ModelStylingTool | typeof CreateModelTool | typeof UpdateModelStylingTool | typeof AddNoteTool | typeof FindNotesTool | typeof NotesInfoTool | typeof UpdateNoteFieldsTool | typeof DeleteNotesTool | typeof MediaActionsTool | typeof GetTagsTool | typeof TagActionsTool | typeof ReviewSessionPrompt | typeof TwentyRulesPrompt | typeof SystemInfoResource)[];
|
|
59
|
+
export declare const ESSENTIAL_MCP_TOOLS: (typeof SyncTool | typeof ListDecksTool | typeof CreateDeckTool | typeof GetDueCardsTool | typeof GetCardsTool | typeof PresentCardTool | typeof RateCardTool | typeof ModelNamesTool | typeof ModelFieldNamesTool | typeof ModelStylingTool | typeof CreateModelTool | typeof UpdateModelStylingTool | typeof AddNoteTool | typeof FindNotesTool | typeof NotesInfoTool | typeof UpdateNoteFieldsTool | typeof DeleteNotesTool | typeof MediaActionsTool | typeof GetTagsTool | typeof TagActionsTool | typeof DeckStatsTool | typeof CollectionStatsTool | typeof ReviewStatsTool | typeof ReviewSessionPrompt | typeof TwentyRulesPrompt | typeof SystemInfoResource)[];
|
|
54
60
|
export interface McpPrimitivesAnkiEssentialModuleOptions {
|
|
55
61
|
ankiConfigProvider: Provider;
|
|
56
62
|
}
|
|
@@ -21,7 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
};
|
|
22
22
|
var McpPrimitivesAnkiEssentialModule_1;
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.McpPrimitivesAnkiEssentialModule = exports.ESSENTIAL_MCP_TOOLS = exports.SystemInfoResource = exports.TwentyRulesPrompt = exports.ReviewSessionPrompt = exports.TagActionsTool = exports.GetTagsTool = exports.MediaActionsTool = exports.DeleteNotesTool = exports.UpdateNoteFieldsTool = exports.NotesInfoTool = exports.FindNotesTool = exports.AddNoteTool = exports.UpdateModelStylingTool = exports.CreateModelTool = exports.ModelStylingTool = exports.ModelFieldNamesTool = exports.ModelNamesTool = exports.RateCardTool = exports.PresentCardTool = exports.GetCardsTool = exports.GetDueCardsTool = exports.CreateDeckTool = exports.ListDecksTool = exports.SyncTool = exports.AnkiConnectError = exports.AnkiConnectClient = exports.ANKI_CONFIG = void 0;
|
|
24
|
+
exports.McpPrimitivesAnkiEssentialModule = exports.ESSENTIAL_MCP_TOOLS = exports.SystemInfoResource = exports.TwentyRulesPrompt = exports.ReviewSessionPrompt = exports.ReviewStatsTool = exports.CollectionStatsTool = exports.DeckStatsTool = exports.TagActionsTool = exports.GetTagsTool = exports.MediaActionsTool = exports.DeleteNotesTool = exports.UpdateNoteFieldsTool = exports.NotesInfoTool = exports.FindNotesTool = exports.AddNoteTool = exports.UpdateModelStylingTool = exports.CreateModelTool = exports.ModelStylingTool = exports.ModelFieldNamesTool = exports.ModelNamesTool = exports.RateCardTool = exports.PresentCardTool = exports.GetCardsTool = exports.GetDueCardsTool = exports.CreateDeckTool = exports.ListDecksTool = exports.SyncTool = exports.AnkiConnectError = exports.AnkiConnectClient = exports.ANKI_CONFIG = void 0;
|
|
25
25
|
var anki_config_interface_1 = require("../../config/anki-config.interface");
|
|
26
26
|
Object.defineProperty(exports, "ANKI_CONFIG", { enumerable: true, get: function () { return anki_config_interface_1.ANKI_CONFIG; } });
|
|
27
27
|
__exportStar(require("../../types/anki.types"), exports);
|
|
@@ -69,6 +69,12 @@ var get_tags_tool_1 = require("./tools/get-tags.tool");
|
|
|
69
69
|
Object.defineProperty(exports, "GetTagsTool", { enumerable: true, get: function () { return get_tags_tool_1.GetTagsTool; } });
|
|
70
70
|
var tagActions_1 = require("./tools/tagActions");
|
|
71
71
|
Object.defineProperty(exports, "TagActionsTool", { enumerable: true, get: function () { return tagActions_1.TagActionsTool; } });
|
|
72
|
+
var deck_stats_1 = require("./tools/deck-stats");
|
|
73
|
+
Object.defineProperty(exports, "DeckStatsTool", { enumerable: true, get: function () { return deck_stats_1.DeckStatsTool; } });
|
|
74
|
+
var collection_stats_1 = require("./tools/collection-stats");
|
|
75
|
+
Object.defineProperty(exports, "CollectionStatsTool", { enumerable: true, get: function () { return collection_stats_1.CollectionStatsTool; } });
|
|
76
|
+
var review_stats_1 = require("./tools/review-stats");
|
|
77
|
+
Object.defineProperty(exports, "ReviewStatsTool", { enumerable: true, get: function () { return review_stats_1.ReviewStatsTool; } });
|
|
72
78
|
var review_session_prompt_1 = require("./prompts/review-session.prompt");
|
|
73
79
|
Object.defineProperty(exports, "ReviewSessionPrompt", { enumerable: true, get: function () { return review_session_prompt_1.ReviewSessionPrompt; } });
|
|
74
80
|
var twenty_rules_prompt_1 = require("./prompts/twenty-rules.prompt");
|
|
@@ -97,6 +103,9 @@ const delete_notes_tool_2 = require("./tools/delete-notes.tool");
|
|
|
97
103
|
const mediaActions_2 = require("./tools/mediaActions");
|
|
98
104
|
const get_tags_tool_2 = require("./tools/get-tags.tool");
|
|
99
105
|
const tagActions_2 = require("./tools/tagActions");
|
|
106
|
+
const deck_stats_2 = require("./tools/deck-stats");
|
|
107
|
+
const collection_stats_2 = require("./tools/collection-stats");
|
|
108
|
+
const review_stats_2 = require("./tools/review-stats");
|
|
100
109
|
const review_session_prompt_2 = require("./prompts/review-session.prompt");
|
|
101
110
|
const twenty_rules_prompt_2 = require("./prompts/twenty-rules.prompt");
|
|
102
111
|
const system_info_resource_2 = require("./resources/system-info.resource");
|
|
@@ -121,6 +130,9 @@ exports.ESSENTIAL_MCP_TOOLS = [
|
|
|
121
130
|
mediaActions_2.MediaActionsTool,
|
|
122
131
|
get_tags_tool_2.GetTagsTool,
|
|
123
132
|
tagActions_2.TagActionsTool,
|
|
133
|
+
deck_stats_2.DeckStatsTool,
|
|
134
|
+
collection_stats_2.CollectionStatsTool,
|
|
135
|
+
review_stats_2.ReviewStatsTool,
|
|
124
136
|
review_session_prompt_2.ReviewSessionPrompt,
|
|
125
137
|
twenty_rules_prompt_2.TwentyRulesPrompt,
|
|
126
138
|
system_info_resource_2.SystemInfoResource,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/primitives/essential/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AACA,4EAAiE;AAAxD,oHAAA,WAAW,OAAA;AAIpB,yDAAuC;AAGvC,yDAAuC;AAGvC,yEAG2C;AAFzC,wHAAA,iBAAiB,OAAA;AACjB,uHAAA,gBAAgB,OAAA;AAIlB,+CAA6C;AAApC,qGAAA,QAAQ,OAAA;AACjB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,6DAA0D;AAAjD,kHAAA,cAAc,OAAA;AACvB,iEAA6D;AAApD,qHAAA,eAAe,OAAA;AACxB,yDAAsD;AAA7C,8GAAA,YAAY,OAAA;AACrB,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,yDAAsD;AAA7C,8GAAA,YAAY,OAAA;AACrB,6DAA0D;AAAjD,kHAAA,cAAc,OAAA;AACvB,yEAAqE;AAA5D,6HAAA,mBAAmB,OAAA;AAC5B,iEAA8D;AAArD,sHAAA,gBAAgB,OAAA;AACzB,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,+EAA2E;AAAlE,mIAAA,sBAAsB,OAAA;AAC/B,uDAAoD;AAA3C,4GAAA,WAAW,OAAA;AACpB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,2EAAuE;AAA9D,+HAAA,oBAAoB,OAAA;AAC7B,+DAA4D;AAAnD,oHAAA,eAAe,OAAA;AACxB,qDAAwD;AAA/C,gHAAA,gBAAgB,OAAA;AACzB,uDAAoD;AAA3C,4GAAA,WAAW,OAAA;AACpB,iDAAoD;AAA3C,4GAAA,cAAc,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp/primitives/essential/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { Context } from "@rekog/mcp-nest";
|
|
2
|
+
import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
|
|
3
|
+
import type { CollectionStatsParams } from "./collection-stats.types";
|
|
4
|
+
export declare class CollectionStatsTool {
|
|
5
|
+
private readonly ankiClient;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
constructor(ankiClient: AnkiConnectClient);
|
|
8
|
+
execute(params: CollectionStatsParams, context: Context): Promise<{
|
|
9
|
+
[x: string]: unknown;
|
|
10
|
+
content: ({
|
|
11
|
+
type: "text";
|
|
12
|
+
text: string;
|
|
13
|
+
annotations?: {
|
|
14
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
15
|
+
priority?: number | undefined;
|
|
16
|
+
lastModified?: string | undefined;
|
|
17
|
+
} | undefined;
|
|
18
|
+
_meta?: {
|
|
19
|
+
[x: string]: unknown;
|
|
20
|
+
} | undefined;
|
|
21
|
+
} | {
|
|
22
|
+
type: "image";
|
|
23
|
+
data: string;
|
|
24
|
+
mimeType: string;
|
|
25
|
+
annotations?: {
|
|
26
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
27
|
+
priority?: number | undefined;
|
|
28
|
+
lastModified?: string | undefined;
|
|
29
|
+
} | undefined;
|
|
30
|
+
_meta?: {
|
|
31
|
+
[x: string]: unknown;
|
|
32
|
+
} | undefined;
|
|
33
|
+
} | {
|
|
34
|
+
type: "audio";
|
|
35
|
+
data: string;
|
|
36
|
+
mimeType: string;
|
|
37
|
+
annotations?: {
|
|
38
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
39
|
+
priority?: number | undefined;
|
|
40
|
+
lastModified?: string | undefined;
|
|
41
|
+
} | undefined;
|
|
42
|
+
_meta?: {
|
|
43
|
+
[x: string]: unknown;
|
|
44
|
+
} | undefined;
|
|
45
|
+
} | {
|
|
46
|
+
uri: string;
|
|
47
|
+
name: string;
|
|
48
|
+
type: "resource_link";
|
|
49
|
+
description?: string | undefined;
|
|
50
|
+
mimeType?: string | undefined;
|
|
51
|
+
annotations?: {
|
|
52
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
53
|
+
priority?: number | undefined;
|
|
54
|
+
lastModified?: string | undefined;
|
|
55
|
+
} | undefined;
|
|
56
|
+
_meta?: {
|
|
57
|
+
[x: string]: unknown;
|
|
58
|
+
} | undefined;
|
|
59
|
+
icons?: {
|
|
60
|
+
src: string;
|
|
61
|
+
mimeType?: string | undefined;
|
|
62
|
+
sizes?: string[] | undefined;
|
|
63
|
+
theme?: "light" | "dark" | undefined;
|
|
64
|
+
}[] | undefined;
|
|
65
|
+
title?: string | undefined;
|
|
66
|
+
} | {
|
|
67
|
+
type: "resource";
|
|
68
|
+
resource: {
|
|
69
|
+
uri: string;
|
|
70
|
+
text: string;
|
|
71
|
+
mimeType?: string | undefined;
|
|
72
|
+
_meta?: {
|
|
73
|
+
[x: string]: unknown;
|
|
74
|
+
} | undefined;
|
|
75
|
+
} | {
|
|
76
|
+
uri: string;
|
|
77
|
+
blob: string;
|
|
78
|
+
mimeType?: string | undefined;
|
|
79
|
+
_meta?: {
|
|
80
|
+
[x: string]: unknown;
|
|
81
|
+
} | undefined;
|
|
82
|
+
};
|
|
83
|
+
annotations?: {
|
|
84
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
85
|
+
priority?: number | undefined;
|
|
86
|
+
lastModified?: string | undefined;
|
|
87
|
+
} | undefined;
|
|
88
|
+
_meta?: {
|
|
89
|
+
[x: string]: unknown;
|
|
90
|
+
} | undefined;
|
|
91
|
+
})[];
|
|
92
|
+
_meta?: {
|
|
93
|
+
[x: string]: unknown;
|
|
94
|
+
progressToken?: string | number | undefined;
|
|
95
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
96
|
+
taskId: string;
|
|
97
|
+
} | undefined;
|
|
98
|
+
} | undefined;
|
|
99
|
+
structuredContent?: {
|
|
100
|
+
[x: string]: unknown;
|
|
101
|
+
} | undefined;
|
|
102
|
+
isError?: boolean | undefined;
|
|
103
|
+
}>;
|
|
104
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
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 CollectionStatsTool_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.CollectionStatsTool = 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
|
+
const stats_utils_1 = require("../../../../utils/stats.utils");
|
|
20
|
+
let CollectionStatsTool = CollectionStatsTool_1 = class CollectionStatsTool {
|
|
21
|
+
ankiClient;
|
|
22
|
+
logger = new common_1.Logger(CollectionStatsTool_1.name);
|
|
23
|
+
constructor(ankiClient) {
|
|
24
|
+
this.ankiClient = ankiClient;
|
|
25
|
+
}
|
|
26
|
+
async execute(params, context) {
|
|
27
|
+
try {
|
|
28
|
+
const { ease_buckets = [2.0, 2.5, 3.0], interval_buckets = [7, 21, 90] } = params;
|
|
29
|
+
this.logger.log("Getting collection-wide statistics");
|
|
30
|
+
await context.reportProgress({ progress: 10, total: 100 });
|
|
31
|
+
this.logger.log("Fetching deck names...");
|
|
32
|
+
const deckNames = await this.ankiClient.invoke("deckNames");
|
|
33
|
+
if (!deckNames || deckNames.length === 0) {
|
|
34
|
+
this.logger.log("No decks found in collection");
|
|
35
|
+
const result = {
|
|
36
|
+
total_decks: 0,
|
|
37
|
+
counts: {
|
|
38
|
+
total: 0,
|
|
39
|
+
new: 0,
|
|
40
|
+
learning: 0,
|
|
41
|
+
review: 0,
|
|
42
|
+
},
|
|
43
|
+
ease: (0, stats_utils_1.computeDistribution)([], { boundaries: ease_buckets }),
|
|
44
|
+
intervals: (0, stats_utils_1.computeDistribution)([], {
|
|
45
|
+
boundaries: interval_buckets,
|
|
46
|
+
unitSuffix: "d",
|
|
47
|
+
}),
|
|
48
|
+
per_deck: [],
|
|
49
|
+
};
|
|
50
|
+
await context.reportProgress({ progress: 100, total: 100 });
|
|
51
|
+
return (0, anki_utils_1.createSuccessResponse)(result);
|
|
52
|
+
}
|
|
53
|
+
this.logger.log(`Found ${deckNames.length} decks in collection`);
|
|
54
|
+
await context.reportProgress({ progress: 20, total: 100 });
|
|
55
|
+
this.logger.log("Fetching statistics for all decks...");
|
|
56
|
+
const deckStatsResponse = await this.ankiClient.invoke("getDeckStats", {
|
|
57
|
+
decks: deckNames,
|
|
58
|
+
});
|
|
59
|
+
if (!deckStatsResponse || typeof deckStatsResponse !== "object") {
|
|
60
|
+
throw new Error("Invalid getDeckStats response");
|
|
61
|
+
}
|
|
62
|
+
const per_deck = [];
|
|
63
|
+
const counts = {
|
|
64
|
+
total: 0,
|
|
65
|
+
new: 0,
|
|
66
|
+
learning: 0,
|
|
67
|
+
review: 0,
|
|
68
|
+
};
|
|
69
|
+
for (const deckStats of Object.values(deckStatsResponse)) {
|
|
70
|
+
const deckName = deckStats.name;
|
|
71
|
+
const deckCounts = {
|
|
72
|
+
total: deckStats.total_in_deck ?? 0,
|
|
73
|
+
new: deckStats.new_count ?? 0,
|
|
74
|
+
learning: deckStats.learn_count ?? 0,
|
|
75
|
+
review: deckStats.review_count ?? 0,
|
|
76
|
+
};
|
|
77
|
+
per_deck.push({
|
|
78
|
+
deck: deckName,
|
|
79
|
+
...deckCounts,
|
|
80
|
+
});
|
|
81
|
+
counts.total += deckCounts.total;
|
|
82
|
+
counts.new += deckCounts.new;
|
|
83
|
+
counts.learning += deckCounts.learning;
|
|
84
|
+
counts.review += deckCounts.review;
|
|
85
|
+
}
|
|
86
|
+
this.logger.log(`Aggregated counts: ${counts.total} total cards across ${deckNames.length} decks`);
|
|
87
|
+
await context.reportProgress({ progress: 40, total: 100 });
|
|
88
|
+
if (counts.total === 0) {
|
|
89
|
+
this.logger.log("Collection is empty (no cards)");
|
|
90
|
+
const result = {
|
|
91
|
+
total_decks: deckNames.length,
|
|
92
|
+
counts,
|
|
93
|
+
ease: (0, stats_utils_1.computeDistribution)([], { boundaries: ease_buckets }),
|
|
94
|
+
intervals: (0, stats_utils_1.computeDistribution)([], {
|
|
95
|
+
boundaries: interval_buckets,
|
|
96
|
+
unitSuffix: "d",
|
|
97
|
+
}),
|
|
98
|
+
per_deck,
|
|
99
|
+
};
|
|
100
|
+
await context.reportProgress({ progress: 100, total: 100 });
|
|
101
|
+
return (0, anki_utils_1.createSuccessResponse)(result);
|
|
102
|
+
}
|
|
103
|
+
this.logger.log("Finding all cards in collection...");
|
|
104
|
+
const cardIds = await this.ankiClient.invoke("findCards", {
|
|
105
|
+
query: "deck:*",
|
|
106
|
+
});
|
|
107
|
+
if (!cardIds || cardIds.length === 0) {
|
|
108
|
+
this.logger.warn("No cards found via findCards, using counts from getDeckStats");
|
|
109
|
+
const result = {
|
|
110
|
+
total_decks: deckNames.length,
|
|
111
|
+
counts,
|
|
112
|
+
ease: (0, stats_utils_1.computeDistribution)([], { boundaries: ease_buckets }),
|
|
113
|
+
intervals: (0, stats_utils_1.computeDistribution)([], {
|
|
114
|
+
boundaries: interval_buckets,
|
|
115
|
+
unitSuffix: "d",
|
|
116
|
+
}),
|
|
117
|
+
per_deck,
|
|
118
|
+
};
|
|
119
|
+
await context.reportProgress({ progress: 100, total: 100 });
|
|
120
|
+
return (0, anki_utils_1.createSuccessResponse)(result);
|
|
121
|
+
}
|
|
122
|
+
this.logger.log(`Found ${cardIds.length} cards in collection`);
|
|
123
|
+
await context.reportProgress({ progress: 50, total: 100 });
|
|
124
|
+
this.logger.log(`Fetching ease factors for ${cardIds.length} cards...`);
|
|
125
|
+
const easeFactorsRaw = await this.ankiClient.invoke("getEaseFactors", {
|
|
126
|
+
cards: cardIds,
|
|
127
|
+
});
|
|
128
|
+
if (!Array.isArray(easeFactorsRaw)) {
|
|
129
|
+
throw new Error("Invalid getEaseFactors response: expected array");
|
|
130
|
+
}
|
|
131
|
+
const easeValues = easeFactorsRaw
|
|
132
|
+
.map((e) => e / 1000)
|
|
133
|
+
.filter((e) => e > 0);
|
|
134
|
+
this.logger.log(`Processed ${easeValues.length} ease values`);
|
|
135
|
+
await context.reportProgress({ progress: 70, total: 100 });
|
|
136
|
+
this.logger.log(`Fetching intervals for ${cardIds.length} cards...`);
|
|
137
|
+
const intervalsRaw = await this.ankiClient.invoke("getIntervals", {
|
|
138
|
+
cards: cardIds,
|
|
139
|
+
});
|
|
140
|
+
if (!Array.isArray(intervalsRaw)) {
|
|
141
|
+
throw new Error("Invalid getIntervals response: expected array");
|
|
142
|
+
}
|
|
143
|
+
const intervalValues = intervalsRaw.filter((i) => i > 0);
|
|
144
|
+
this.logger.log(`Processed ${intervalValues.length} interval values`);
|
|
145
|
+
await context.reportProgress({ progress: 90, total: 100 });
|
|
146
|
+
this.logger.log("Computing distributions...");
|
|
147
|
+
const ease = (0, stats_utils_1.computeDistribution)(easeValues, {
|
|
148
|
+
boundaries: ease_buckets,
|
|
149
|
+
});
|
|
150
|
+
const intervals = (0, stats_utils_1.computeDistribution)(intervalValues, {
|
|
151
|
+
boundaries: interval_buckets,
|
|
152
|
+
unitSuffix: "d",
|
|
153
|
+
});
|
|
154
|
+
const result = {
|
|
155
|
+
total_decks: deckNames.length,
|
|
156
|
+
counts,
|
|
157
|
+
ease,
|
|
158
|
+
intervals,
|
|
159
|
+
per_deck,
|
|
160
|
+
};
|
|
161
|
+
await context.reportProgress({ progress: 100, total: 100 });
|
|
162
|
+
this.logger.log(`Successfully retrieved collection statistics: ${deckNames.length} decks, ` +
|
|
163
|
+
`${counts.total} total cards, ${ease.count} cards with ease values, ` +
|
|
164
|
+
`${intervals.count} review cards`);
|
|
165
|
+
return (0, anki_utils_1.createSuccessResponse)(result);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
this.logger.error("Failed to get collection statistics", error);
|
|
169
|
+
return (0, anki_utils_1.createErrorResponse)(error, {
|
|
170
|
+
hint: "Make sure Anki is running and AnkiConnect is accessible.",
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
exports.CollectionStatsTool = CollectionStatsTool;
|
|
176
|
+
__decorate([
|
|
177
|
+
(0, mcp_nest_1.Tool)({
|
|
178
|
+
name: "collection_stats",
|
|
179
|
+
description: "Get aggregated statistics across all decks in the collection including card counts, ease factor distribution, and interval distribution. " +
|
|
180
|
+
"Provides both collection-wide metrics and per-deck breakdown. " +
|
|
181
|
+
"Use this to analyze overall collection health and compare deck statistics. " +
|
|
182
|
+
"Ease buckets and interval buckets can be customized to focus on specific ranges.",
|
|
183
|
+
parameters: zod_1.z.object({
|
|
184
|
+
ease_buckets: zod_1.z
|
|
185
|
+
.array(zod_1.z.number().positive())
|
|
186
|
+
.optional()
|
|
187
|
+
.default([2.0, 2.5, 3.0])
|
|
188
|
+
.refine((arr) => arr.length === 0 || arr.every((v, i, a) => i === 0 || v > a[i - 1]), {
|
|
189
|
+
message: "Bucket boundaries must be in ascending order",
|
|
190
|
+
})
|
|
191
|
+
.describe("Bucket boundaries for ease factor distribution. Default: [2.0, 2.5, 3.0]. " +
|
|
192
|
+
"Example: [2.0, 2.5, 3.0] creates buckets: <2.0, 2.0-2.5, 2.5-3.0, >3.0"),
|
|
193
|
+
interval_buckets: zod_1.z
|
|
194
|
+
.array(zod_1.z.number().positive())
|
|
195
|
+
.optional()
|
|
196
|
+
.default([7, 21, 90])
|
|
197
|
+
.refine((arr) => arr.length === 0 || arr.every((v, i, a) => i === 0 || v > a[i - 1]), {
|
|
198
|
+
message: "Bucket boundaries must be in ascending order",
|
|
199
|
+
})
|
|
200
|
+
.describe("Bucket boundaries for interval distribution in days. Default: [7, 21, 90]. " +
|
|
201
|
+
"Example: [7, 21, 90] creates buckets: <7d, 7-21d, 21-90d, >90d"),
|
|
202
|
+
}),
|
|
203
|
+
}),
|
|
204
|
+
__metadata("design:type", Function),
|
|
205
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
206
|
+
__metadata("design:returntype", Promise)
|
|
207
|
+
], CollectionStatsTool.prototype, "execute", null);
|
|
208
|
+
exports.CollectionStatsTool = CollectionStatsTool = CollectionStatsTool_1 = __decorate([
|
|
209
|
+
(0, common_1.Injectable)(),
|
|
210
|
+
__metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
|
|
211
|
+
], CollectionStatsTool);
|
|
212
|
+
//# sourceMappingURL=collection-stats.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-stats.tool.js","sourceRoot":"","sources":["../../../../../../src/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DistributionMetrics } from "@/mcp/utils/stats.utils";
|
|
2
|
+
export interface CollectionStatsParams {
|
|
3
|
+
ease_buckets?: number[];
|
|
4
|
+
interval_buckets?: number[];
|
|
5
|
+
}
|
|
6
|
+
export interface AnkiDeckStatsResponse {
|
|
7
|
+
deck_id: number;
|
|
8
|
+
name: string;
|
|
9
|
+
new_count: number;
|
|
10
|
+
learn_count: number;
|
|
11
|
+
review_count: number;
|
|
12
|
+
total_in_deck: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PerDeckStats {
|
|
15
|
+
deck: string;
|
|
16
|
+
total: number;
|
|
17
|
+
new: number;
|
|
18
|
+
learning: number;
|
|
19
|
+
review: number;
|
|
20
|
+
}
|
|
21
|
+
export interface CollectionStatsResult {
|
|
22
|
+
total_decks: number;
|
|
23
|
+
counts: {
|
|
24
|
+
total: number;
|
|
25
|
+
new: number;
|
|
26
|
+
learning: number;
|
|
27
|
+
review: number;
|
|
28
|
+
};
|
|
29
|
+
ease: DistributionMetrics;
|
|
30
|
+
intervals: DistributionMetrics;
|
|
31
|
+
per_deck: PerDeckStats[];
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-stats.types.js","sourceRoot":"","sources":["../../../../../../src/mcp/primitives/essential/tools/collection-stats/collection-stats.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CollectionStatsTool = void 0;
|
|
4
|
+
var collection_stats_tool_1 = require("./collection-stats.tool");
|
|
5
|
+
Object.defineProperty(exports, "CollectionStatsTool", { enumerable: true, get: function () { return collection_stats_tool_1.CollectionStatsTool; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/mcp/primitives/essential/tools/collection-stats/index.ts"],"names":[],"mappings":";;;AAAA,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Context } from "@rekog/mcp-nest";
|
|
2
|
+
import { AnkiConnectClient } from "@/mcp/clients/anki-connect.client";
|
|
3
|
+
export declare class DeckStatsTool {
|
|
4
|
+
private readonly ankiClient;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
constructor(ankiClient: AnkiConnectClient);
|
|
7
|
+
execute(params: {
|
|
8
|
+
deck: string;
|
|
9
|
+
ease_buckets?: number[];
|
|
10
|
+
interval_buckets?: number[];
|
|
11
|
+
}, context: Context): Promise<{
|
|
12
|
+
[x: string]: unknown;
|
|
13
|
+
content: ({
|
|
14
|
+
type: "text";
|
|
15
|
+
text: string;
|
|
16
|
+
annotations?: {
|
|
17
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
18
|
+
priority?: number | undefined;
|
|
19
|
+
lastModified?: string | undefined;
|
|
20
|
+
} | undefined;
|
|
21
|
+
_meta?: {
|
|
22
|
+
[x: string]: unknown;
|
|
23
|
+
} | undefined;
|
|
24
|
+
} | {
|
|
25
|
+
type: "image";
|
|
26
|
+
data: string;
|
|
27
|
+
mimeType: string;
|
|
28
|
+
annotations?: {
|
|
29
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
30
|
+
priority?: number | undefined;
|
|
31
|
+
lastModified?: string | undefined;
|
|
32
|
+
} | undefined;
|
|
33
|
+
_meta?: {
|
|
34
|
+
[x: string]: unknown;
|
|
35
|
+
} | undefined;
|
|
36
|
+
} | {
|
|
37
|
+
type: "audio";
|
|
38
|
+
data: string;
|
|
39
|
+
mimeType: string;
|
|
40
|
+
annotations?: {
|
|
41
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
42
|
+
priority?: number | undefined;
|
|
43
|
+
lastModified?: string | undefined;
|
|
44
|
+
} | undefined;
|
|
45
|
+
_meta?: {
|
|
46
|
+
[x: string]: unknown;
|
|
47
|
+
} | undefined;
|
|
48
|
+
} | {
|
|
49
|
+
uri: string;
|
|
50
|
+
name: string;
|
|
51
|
+
type: "resource_link";
|
|
52
|
+
description?: string | undefined;
|
|
53
|
+
mimeType?: string | undefined;
|
|
54
|
+
annotations?: {
|
|
55
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
56
|
+
priority?: number | undefined;
|
|
57
|
+
lastModified?: string | undefined;
|
|
58
|
+
} | undefined;
|
|
59
|
+
_meta?: {
|
|
60
|
+
[x: string]: unknown;
|
|
61
|
+
} | undefined;
|
|
62
|
+
icons?: {
|
|
63
|
+
src: string;
|
|
64
|
+
mimeType?: string | undefined;
|
|
65
|
+
sizes?: string[] | undefined;
|
|
66
|
+
theme?: "light" | "dark" | undefined;
|
|
67
|
+
}[] | undefined;
|
|
68
|
+
title?: string | undefined;
|
|
69
|
+
} | {
|
|
70
|
+
type: "resource";
|
|
71
|
+
resource: {
|
|
72
|
+
uri: string;
|
|
73
|
+
text: string;
|
|
74
|
+
mimeType?: string | undefined;
|
|
75
|
+
_meta?: {
|
|
76
|
+
[x: string]: unknown;
|
|
77
|
+
} | undefined;
|
|
78
|
+
} | {
|
|
79
|
+
uri: string;
|
|
80
|
+
blob: string;
|
|
81
|
+
mimeType?: string | undefined;
|
|
82
|
+
_meta?: {
|
|
83
|
+
[x: string]: unknown;
|
|
84
|
+
} | undefined;
|
|
85
|
+
};
|
|
86
|
+
annotations?: {
|
|
87
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
88
|
+
priority?: number | undefined;
|
|
89
|
+
lastModified?: string | undefined;
|
|
90
|
+
} | undefined;
|
|
91
|
+
_meta?: {
|
|
92
|
+
[x: string]: unknown;
|
|
93
|
+
} | undefined;
|
|
94
|
+
})[];
|
|
95
|
+
_meta?: {
|
|
96
|
+
[x: string]: unknown;
|
|
97
|
+
progressToken?: string | number | undefined;
|
|
98
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
99
|
+
taskId: string;
|
|
100
|
+
} | undefined;
|
|
101
|
+
} | undefined;
|
|
102
|
+
structuredContent?: {
|
|
103
|
+
[x: string]: unknown;
|
|
104
|
+
} | undefined;
|
|
105
|
+
isError?: boolean | undefined;
|
|
106
|
+
}>;
|
|
107
|
+
}
|