anki-mcp-http 0.19.2 → 0.20.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/README.md +7 -1
- package/dist/mcp/clients/anki-connect.client.js +5 -0
- package/dist/mcp/clients/anki-connect.client.js.map +1 -1
- package/dist/mcp/primitives/essential/index.d.ts +13 -1
- package/dist/mcp/primitives/essential/index.js +25 -1
- package/dist/mcp/primitives/essential/index.js.map +1 -1
- package/dist/mcp/primitives/essential/tools/add-model-field.tool.d.ts +113 -0
- package/dist/mcp/primitives/essential/tools/add-model-field.tool.js +150 -0
- package/dist/mcp/primitives/essential/tools/add-model-field.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/model-templates.tool.d.ts +116 -0
- package/dist/mcp/primitives/essential/tools/model-templates.tool.js +95 -0
- package/dist/mcp/primitives/essential/tools/model-templates.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/remove-model-field.tool.d.ts +112 -0
- package/dist/mcp/primitives/essential/tools/remove-model-field.tool.js +107 -0
- package/dist/mcp/primitives/essential/tools/remove-model-field.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/rename-model-field.tool.d.ts +114 -0
- package/dist/mcp/primitives/essential/tools/rename-model-field.tool.js +156 -0
- package/dist/mcp/primitives/essential/tools/rename-model-field.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/reposition-model-field.tool.d.ts +113 -0
- package/dist/mcp/primitives/essential/tools/reposition-model-field.tool.js +137 -0
- package/dist/mcp/primitives/essential/tools/reposition-model-field.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/update-model-templates.tool.d.ts +115 -0
- package/dist/mcp/primitives/essential/tools/update-model-templates.tool.js +140 -0
- package/dist/mcp/primitives/essential/tools/update-model-templates.tool.js.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { AnkiConnectClient } from "../../../clients/anki-connect.client";
|
|
2
|
+
export declare class RepositionModelFieldTool {
|
|
3
|
+
private readonly ankiClient;
|
|
4
|
+
private readonly logger;
|
|
5
|
+
constructor(ankiClient: AnkiConnectClient);
|
|
6
|
+
repositionModelField({ modelName, fieldName, index, }: {
|
|
7
|
+
modelName: string;
|
|
8
|
+
fieldName: string;
|
|
9
|
+
index: number;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
[x: string]: unknown;
|
|
12
|
+
content: ({
|
|
13
|
+
type: "text";
|
|
14
|
+
text: string;
|
|
15
|
+
annotations?: {
|
|
16
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
17
|
+
priority?: number | undefined;
|
|
18
|
+
lastModified?: string | undefined;
|
|
19
|
+
} | undefined;
|
|
20
|
+
_meta?: {
|
|
21
|
+
[x: string]: unknown;
|
|
22
|
+
} | undefined;
|
|
23
|
+
} | {
|
|
24
|
+
type: "image";
|
|
25
|
+
data: string;
|
|
26
|
+
mimeType: string;
|
|
27
|
+
annotations?: {
|
|
28
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
29
|
+
priority?: number | undefined;
|
|
30
|
+
lastModified?: string | undefined;
|
|
31
|
+
} | undefined;
|
|
32
|
+
_meta?: {
|
|
33
|
+
[x: string]: unknown;
|
|
34
|
+
} | undefined;
|
|
35
|
+
} | {
|
|
36
|
+
type: "audio";
|
|
37
|
+
data: string;
|
|
38
|
+
mimeType: string;
|
|
39
|
+
annotations?: {
|
|
40
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
41
|
+
priority?: number | undefined;
|
|
42
|
+
lastModified?: string | undefined;
|
|
43
|
+
} | undefined;
|
|
44
|
+
_meta?: {
|
|
45
|
+
[x: string]: unknown;
|
|
46
|
+
} | undefined;
|
|
47
|
+
} | {
|
|
48
|
+
uri: string;
|
|
49
|
+
name: string;
|
|
50
|
+
type: "resource_link";
|
|
51
|
+
description?: string | undefined;
|
|
52
|
+
mimeType?: string | undefined;
|
|
53
|
+
size?: number | 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
|
+
success: boolean;
|
|
108
|
+
modelName: string;
|
|
109
|
+
fieldName: string;
|
|
110
|
+
newIndex: number;
|
|
111
|
+
message: string;
|
|
112
|
+
}>;
|
|
113
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
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 RepositionModelFieldTool_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.RepositionModelFieldTool = 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 RepositionModelFieldTool = RepositionModelFieldTool_1 = class RepositionModelFieldTool {
|
|
20
|
+
ankiClient;
|
|
21
|
+
logger = new common_1.Logger(RepositionModelFieldTool_1.name);
|
|
22
|
+
constructor(ankiClient) {
|
|
23
|
+
this.ankiClient = ankiClient;
|
|
24
|
+
}
|
|
25
|
+
async repositionModelField({ modelName, fieldName, index, }) {
|
|
26
|
+
try {
|
|
27
|
+
this.logger.log(`Repositioning field "${fieldName}" to index ${index} in model "${modelName}"`);
|
|
28
|
+
const fields = await this.ankiClient.invoke("modelFieldNames", {
|
|
29
|
+
modelName,
|
|
30
|
+
});
|
|
31
|
+
if (!fields || fields.length === 0) {
|
|
32
|
+
return (0, anki_utils_1.createErrorResponse)(new Error(`Model "${modelName}" has no fields or does not exist`), {
|
|
33
|
+
modelName,
|
|
34
|
+
fieldName,
|
|
35
|
+
index,
|
|
36
|
+
hint: "Model not found. Use modelNames tool to see available models.",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (!fields.includes(fieldName)) {
|
|
40
|
+
return (0, anki_utils_1.createErrorResponse)(new Error(`Field "${fieldName}" does not exist in model "${modelName}"`), {
|
|
41
|
+
modelName,
|
|
42
|
+
fieldName,
|
|
43
|
+
index,
|
|
44
|
+
hint: "Field names are case-sensitive. Use modelFieldNames to see the current field names.",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (index < 0 || index > fields.length - 1) {
|
|
48
|
+
return (0, anki_utils_1.createErrorResponse)(new Error(`Index ${index} is out of range for model "${modelName}". ` +
|
|
49
|
+
`Valid range is 0-${fields.length - 1} (the model has ${fields.length} fields). ` +
|
|
50
|
+
"AnkiConnect would silently clamp the index instead of erroring."), {
|
|
51
|
+
modelName,
|
|
52
|
+
fieldName,
|
|
53
|
+
index,
|
|
54
|
+
hint: "Index out of range. Use modelFieldNames to see how many fields exist.",
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
await this.ankiClient.invoke("modelFieldReposition", {
|
|
58
|
+
modelName,
|
|
59
|
+
fieldName,
|
|
60
|
+
index,
|
|
61
|
+
});
|
|
62
|
+
this.logger.log(`Successfully repositioned field "${fieldName}" to index ${index} in model "${modelName}"`);
|
|
63
|
+
return {
|
|
64
|
+
success: true,
|
|
65
|
+
modelName,
|
|
66
|
+
fieldName,
|
|
67
|
+
newIndex: index,
|
|
68
|
+
message: `Successfully moved field "${fieldName}" to position ${index} in model "${modelName}"`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
this.logger.error(`Failed to reposition field "${fieldName}" in model "${modelName}"`, error);
|
|
73
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
74
|
+
if (errorMessage.includes("not found") ||
|
|
75
|
+
errorMessage.includes("does not exist")) {
|
|
76
|
+
return (0, anki_utils_1.createErrorResponse)(error, {
|
|
77
|
+
modelName,
|
|
78
|
+
fieldName,
|
|
79
|
+
index,
|
|
80
|
+
hint: "Model or field not found. Use modelNames and modelFieldNames tools to verify names.",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return (0, anki_utils_1.createErrorResponse)(error, {
|
|
84
|
+
modelName,
|
|
85
|
+
fieldName,
|
|
86
|
+
index,
|
|
87
|
+
hint: "Make sure Anki is running and the model and field names are correct.",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.RepositionModelFieldTool = RepositionModelFieldTool;
|
|
93
|
+
__decorate([
|
|
94
|
+
(0, mcp_nest_1.Tool)({
|
|
95
|
+
name: "repositionModelField",
|
|
96
|
+
description: "Change the position of a field within an Anki note type (model). " +
|
|
97
|
+
"Fields are ordered 0-based: index 0 is the first field. " +
|
|
98
|
+
"(Which field is the sort field is a separate model setting and is not changed by repositioning.) " +
|
|
99
|
+
"Use modelFieldNames to see the current field order before repositioning.",
|
|
100
|
+
parameters: zod_1.z.object({
|
|
101
|
+
modelName: zod_1.z
|
|
102
|
+
.string()
|
|
103
|
+
.min(1)
|
|
104
|
+
.describe('Name of the note type to modify (e.g., "Basic", "Latin Vocabulary")'),
|
|
105
|
+
fieldName: zod_1.z
|
|
106
|
+
.string()
|
|
107
|
+
.min(1)
|
|
108
|
+
.describe('Name of the field to reposition (e.g., "Grammar")'),
|
|
109
|
+
index: zod_1.z
|
|
110
|
+
.number()
|
|
111
|
+
.int()
|
|
112
|
+
.min(0)
|
|
113
|
+
.describe("New 0-based position for the field (0 = first field)."),
|
|
114
|
+
}),
|
|
115
|
+
outputSchema: zod_1.z.object({
|
|
116
|
+
success: zod_1.z.boolean(),
|
|
117
|
+
modelName: zod_1.z.string(),
|
|
118
|
+
fieldName: zod_1.z.string(),
|
|
119
|
+
newIndex: zod_1.z.number(),
|
|
120
|
+
message: zod_1.z.string(),
|
|
121
|
+
}),
|
|
122
|
+
annotations: {
|
|
123
|
+
title: "Reposition Field in Note Type",
|
|
124
|
+
readOnlyHint: false,
|
|
125
|
+
destructiveHint: false,
|
|
126
|
+
idempotentHint: true,
|
|
127
|
+
},
|
|
128
|
+
}),
|
|
129
|
+
__metadata("design:type", Function),
|
|
130
|
+
__metadata("design:paramtypes", [Object]),
|
|
131
|
+
__metadata("design:returntype", Promise)
|
|
132
|
+
], RepositionModelFieldTool.prototype, "repositionModelField", null);
|
|
133
|
+
exports.RepositionModelFieldTool = RepositionModelFieldTool = RepositionModelFieldTool_1 = __decorate([
|
|
134
|
+
(0, common_1.Injectable)(),
|
|
135
|
+
__metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
|
|
136
|
+
], RepositionModelFieldTool);
|
|
137
|
+
//# sourceMappingURL=reposition-model-field.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reposition-model-field.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/essential/tools/reposition-model-field.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { AnkiConnectClient } from "../../../clients/anki-connect.client";
|
|
2
|
+
export declare class UpdateModelTemplatesTool {
|
|
3
|
+
private readonly ankiClient;
|
|
4
|
+
private readonly logger;
|
|
5
|
+
constructor(ankiClient: AnkiConnectClient);
|
|
6
|
+
updateModelTemplates({ modelName, templates, }: {
|
|
7
|
+
modelName: string;
|
|
8
|
+
templates: Record<string, {
|
|
9
|
+
Front: string;
|
|
10
|
+
Back: string;
|
|
11
|
+
}>;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
[x: string]: unknown;
|
|
14
|
+
content: ({
|
|
15
|
+
type: "text";
|
|
16
|
+
text: string;
|
|
17
|
+
annotations?: {
|
|
18
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
19
|
+
priority?: number | undefined;
|
|
20
|
+
lastModified?: string | undefined;
|
|
21
|
+
} | undefined;
|
|
22
|
+
_meta?: {
|
|
23
|
+
[x: string]: unknown;
|
|
24
|
+
} | undefined;
|
|
25
|
+
} | {
|
|
26
|
+
type: "image";
|
|
27
|
+
data: string;
|
|
28
|
+
mimeType: string;
|
|
29
|
+
annotations?: {
|
|
30
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
31
|
+
priority?: number | undefined;
|
|
32
|
+
lastModified?: string | undefined;
|
|
33
|
+
} | undefined;
|
|
34
|
+
_meta?: {
|
|
35
|
+
[x: string]: unknown;
|
|
36
|
+
} | undefined;
|
|
37
|
+
} | {
|
|
38
|
+
type: "audio";
|
|
39
|
+
data: string;
|
|
40
|
+
mimeType: string;
|
|
41
|
+
annotations?: {
|
|
42
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
43
|
+
priority?: number | undefined;
|
|
44
|
+
lastModified?: string | undefined;
|
|
45
|
+
} | undefined;
|
|
46
|
+
_meta?: {
|
|
47
|
+
[x: string]: unknown;
|
|
48
|
+
} | undefined;
|
|
49
|
+
} | {
|
|
50
|
+
uri: string;
|
|
51
|
+
name: string;
|
|
52
|
+
type: "resource_link";
|
|
53
|
+
description?: string | undefined;
|
|
54
|
+
mimeType?: string | undefined;
|
|
55
|
+
size?: number | undefined;
|
|
56
|
+
annotations?: {
|
|
57
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
58
|
+
priority?: number | undefined;
|
|
59
|
+
lastModified?: string | undefined;
|
|
60
|
+
} | undefined;
|
|
61
|
+
_meta?: {
|
|
62
|
+
[x: string]: unknown;
|
|
63
|
+
} | undefined;
|
|
64
|
+
icons?: {
|
|
65
|
+
src: string;
|
|
66
|
+
mimeType?: string | undefined;
|
|
67
|
+
sizes?: string[] | undefined;
|
|
68
|
+
theme?: "light" | "dark" | undefined;
|
|
69
|
+
}[] | undefined;
|
|
70
|
+
title?: string | undefined;
|
|
71
|
+
} | {
|
|
72
|
+
type: "resource";
|
|
73
|
+
resource: {
|
|
74
|
+
uri: string;
|
|
75
|
+
text: string;
|
|
76
|
+
mimeType?: string | undefined;
|
|
77
|
+
_meta?: {
|
|
78
|
+
[x: string]: unknown;
|
|
79
|
+
} | undefined;
|
|
80
|
+
} | {
|
|
81
|
+
uri: string;
|
|
82
|
+
blob: string;
|
|
83
|
+
mimeType?: string | undefined;
|
|
84
|
+
_meta?: {
|
|
85
|
+
[x: string]: unknown;
|
|
86
|
+
} | undefined;
|
|
87
|
+
};
|
|
88
|
+
annotations?: {
|
|
89
|
+
audience?: ("user" | "assistant")[] | undefined;
|
|
90
|
+
priority?: number | undefined;
|
|
91
|
+
lastModified?: string | undefined;
|
|
92
|
+
} | undefined;
|
|
93
|
+
_meta?: {
|
|
94
|
+
[x: string]: unknown;
|
|
95
|
+
} | undefined;
|
|
96
|
+
})[];
|
|
97
|
+
_meta?: {
|
|
98
|
+
[x: string]: unknown;
|
|
99
|
+
progressToken?: string | number | undefined;
|
|
100
|
+
"io.modelcontextprotocol/related-task"?: {
|
|
101
|
+
taskId: string;
|
|
102
|
+
} | undefined;
|
|
103
|
+
} | undefined;
|
|
104
|
+
structuredContent?: {
|
|
105
|
+
[x: string]: unknown;
|
|
106
|
+
} | undefined;
|
|
107
|
+
isError?: boolean | undefined;
|
|
108
|
+
} | {
|
|
109
|
+
success: boolean;
|
|
110
|
+
modelName: string;
|
|
111
|
+
templateCount: number;
|
|
112
|
+
message: string;
|
|
113
|
+
hint: string;
|
|
114
|
+
}>;
|
|
115
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
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 UpdateModelTemplatesTool_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.UpdateModelTemplatesTool = 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 UpdateModelTemplatesTool = UpdateModelTemplatesTool_1 = class UpdateModelTemplatesTool {
|
|
20
|
+
ankiClient;
|
|
21
|
+
logger = new common_1.Logger(UpdateModelTemplatesTool_1.name);
|
|
22
|
+
constructor(ankiClient) {
|
|
23
|
+
this.ankiClient = ankiClient;
|
|
24
|
+
}
|
|
25
|
+
async updateModelTemplates({ modelName, templates, }) {
|
|
26
|
+
try {
|
|
27
|
+
this.logger.log(`Updating templates for model: ${modelName}`);
|
|
28
|
+
const existingTemplates = await this.ankiClient.invoke("modelTemplates", {
|
|
29
|
+
modelName,
|
|
30
|
+
});
|
|
31
|
+
if (!existingTemplates || Object.keys(existingTemplates).length === 0) {
|
|
32
|
+
return (0, anki_utils_1.createErrorResponse)(new Error(`Model "${modelName}" has no templates or does not exist`), {
|
|
33
|
+
modelName,
|
|
34
|
+
hint: "Model not found. Use modelNames tool to see available models.",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
const existingNames = new Set(Object.keys(existingTemplates));
|
|
38
|
+
const unknownNames = Object.keys(templates).filter((name) => !existingNames.has(name));
|
|
39
|
+
if (unknownNames.length > 0) {
|
|
40
|
+
const offending = unknownNames.map((name) => `"${name}"`).join(", ");
|
|
41
|
+
const validNames = Object.keys(existingTemplates)
|
|
42
|
+
.map((name) => `"${name}"`)
|
|
43
|
+
.join(", ");
|
|
44
|
+
return (0, anki_utils_1.createErrorResponse)(new Error(`Card template(s) not found in model "${modelName}": ${offending}. ` +
|
|
45
|
+
`Valid templates: ${validNames}. ` +
|
|
46
|
+
"Use modelTemplates to see current names."), {
|
|
47
|
+
modelName,
|
|
48
|
+
hint: `Card template names are case-sensitive and must match exactly. Valid templates: ${validNames}.`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const templateCount = Object.keys(templates).length;
|
|
52
|
+
await this.ankiClient.invoke("updateModelTemplates", {
|
|
53
|
+
model: {
|
|
54
|
+
name: modelName,
|
|
55
|
+
templates,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
this.logger.log(`Successfully updated ${templateCount} templates for model: ${modelName}`);
|
|
59
|
+
return {
|
|
60
|
+
success: true,
|
|
61
|
+
modelName,
|
|
62
|
+
templateCount,
|
|
63
|
+
message: `Successfully updated ${templateCount} card template(s) for model "${modelName}"`,
|
|
64
|
+
hint: "Template changes apply to all cards using this model. Use guiBrowse to preview changes.",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.logger.error(`Failed to update templates for model ${modelName}`, error);
|
|
69
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
70
|
+
if (errorMessage.includes("not found") ||
|
|
71
|
+
errorMessage.includes("does not exist") ||
|
|
72
|
+
errorMessage.includes("model not found")) {
|
|
73
|
+
return (0, anki_utils_1.createErrorResponse)(error, {
|
|
74
|
+
modelName,
|
|
75
|
+
hint: "Model not found. Use modelNames tool to see available models.",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return (0, anki_utils_1.createErrorResponse)(error, {
|
|
79
|
+
modelName,
|
|
80
|
+
hint: "Make sure Anki is running and the model name is correct.",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
exports.UpdateModelTemplatesTool = UpdateModelTemplatesTool;
|
|
86
|
+
__decorate([
|
|
87
|
+
(0, mcp_nest_1.Tool)({
|
|
88
|
+
name: "updateModelTemplates",
|
|
89
|
+
description: "Update the card templates (Front and Back HTML) for an existing note type (model). " +
|
|
90
|
+
"Each card template defines how the card's front and back sides are rendered. " +
|
|
91
|
+
"Use modelTemplates first to see current templates, then modify and pass back the templates object. " +
|
|
92
|
+
"Changes apply to all cards using this model. " +
|
|
93
|
+
"WARNING: Invalid HTML or missing required fields may break card rendering. " +
|
|
94
|
+
"Card template names are validated against the model's existing templates (case-sensitive) — unknown or mis-cased names are rejected before any update. " +
|
|
95
|
+
"An empty string cannot be used to blank a side.",
|
|
96
|
+
parameters: zod_1.z.object({
|
|
97
|
+
modelName: zod_1.z
|
|
98
|
+
.string()
|
|
99
|
+
.min(1)
|
|
100
|
+
.describe('Name of the model to update (e.g., "Basic", "Cloze")'),
|
|
101
|
+
templates: zod_1.z
|
|
102
|
+
.record(zod_1.z.string(), zod_1.z.object({
|
|
103
|
+
Front: zod_1.z
|
|
104
|
+
.string()
|
|
105
|
+
.min(1)
|
|
106
|
+
.describe("HTML template for the front/question side"),
|
|
107
|
+
Back: zod_1.z
|
|
108
|
+
.string()
|
|
109
|
+
.min(1)
|
|
110
|
+
.describe("HTML template for the back/answer side"),
|
|
111
|
+
}))
|
|
112
|
+
.refine((t) => Object.keys(t).length > 0, {
|
|
113
|
+
message: "At least one card template is required",
|
|
114
|
+
})
|
|
115
|
+
.describe('Card templates keyed by card name (e.g., { "Card 1": { Front: "...", Back: "..." } }). ' +
|
|
116
|
+
"Use modelTemplates first to get the current structure, then modify the Front/Back HTML as needed."),
|
|
117
|
+
}),
|
|
118
|
+
outputSchema: zod_1.z.object({
|
|
119
|
+
success: zod_1.z.boolean(),
|
|
120
|
+
modelName: zod_1.z.string(),
|
|
121
|
+
templateCount: zod_1.z.number(),
|
|
122
|
+
message: zod_1.z.string(),
|
|
123
|
+
hint: zod_1.z.string(),
|
|
124
|
+
}),
|
|
125
|
+
annotations: {
|
|
126
|
+
title: "Update Note Type Templates",
|
|
127
|
+
readOnlyHint: false,
|
|
128
|
+
destructiveHint: false,
|
|
129
|
+
idempotentHint: true,
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
__metadata("design:type", Function),
|
|
133
|
+
__metadata("design:paramtypes", [Object]),
|
|
134
|
+
__metadata("design:returntype", Promise)
|
|
135
|
+
], UpdateModelTemplatesTool.prototype, "updateModelTemplates", null);
|
|
136
|
+
exports.UpdateModelTemplatesTool = UpdateModelTemplatesTool = UpdateModelTemplatesTool_1 = __decorate([
|
|
137
|
+
(0, common_1.Injectable)(),
|
|
138
|
+
__metadata("design:paramtypes", [anki_connect_client_1.AnkiConnectClient])
|
|
139
|
+
], UpdateModelTemplatesTool);
|
|
140
|
+
//# sourceMappingURL=update-model-templates.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-model-templates.tool.js","sourceRoot":"","sources":["../../../../../src/mcp/primitives/essential/tools/update-model-templates.tool.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anki-mcp-http",
|
|
3
3
|
"mcpName": "ai.ankimcp/anki-mcp-server",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.20.0",
|
|
5
5
|
"description": "Model Context Protocol server for Anki - enables AI assistants to interact with your Anki flashcards",
|
|
6
6
|
"author": "Anatoly Tarnavsky",
|
|
7
7
|
"private": false,
|
|
@@ -57,12 +57,12 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
60
|
-
"@nestjs/common": "^11.1.
|
|
60
|
+
"@nestjs/common": "^11.1.26",
|
|
61
61
|
"@nestjs/config": "^4.0.4",
|
|
62
|
-
"@nestjs/core": "11.1.
|
|
62
|
+
"@nestjs/core": "11.1.26",
|
|
63
63
|
"@nestjs/jwt": "^11.0.2",
|
|
64
64
|
"@nestjs/passport": "^11.0.5",
|
|
65
|
-
"@nestjs/platform-express": "^11.1.
|
|
65
|
+
"@nestjs/platform-express": "^11.1.26",
|
|
66
66
|
"@rekog/mcp-nest": "^1.9.10",
|
|
67
67
|
"commander": "^15.0.0",
|
|
68
68
|
"ipaddr.js": "^2.4.0",
|
|
@@ -87,15 +87,15 @@
|
|
|
87
87
|
"@anthropic-ai/mcpb": "^2.1.2",
|
|
88
88
|
"@eslint/eslintrc": "^3.3.5",
|
|
89
89
|
"@eslint/js": "^10.0.1",
|
|
90
|
-
"@modelcontextprotocol/inspector": "^0.
|
|
91
|
-
"@nestjs/cli": "^11.0.
|
|
90
|
+
"@modelcontextprotocol/inspector": "^0.22.0",
|
|
91
|
+
"@nestjs/cli": "^11.0.23",
|
|
92
92
|
"@nestjs/schematics": "^11.1.0",
|
|
93
|
-
"@nestjs/testing": "^11.1.
|
|
93
|
+
"@nestjs/testing": "^11.1.26",
|
|
94
94
|
"@types/express": "^5.0.6",
|
|
95
95
|
"@types/jest": "^30.0.0",
|
|
96
96
|
"@types/jsonwebtoken": "^9.0.10",
|
|
97
97
|
"@types/mdast": "^4.0.4",
|
|
98
|
-
"@types/node": "^25.9.
|
|
98
|
+
"@types/node": "^25.9.3",
|
|
99
99
|
"@types/supertest": "^7.2.0",
|
|
100
100
|
"@types/update-notifier": "^6.0.8",
|
|
101
101
|
"@types/ws": "^8.18.1",
|
|
@@ -105,8 +105,8 @@
|
|
|
105
105
|
"globals": "^17.6.0",
|
|
106
106
|
"husky": "^9.1.7",
|
|
107
107
|
"jest": "^30.4.2",
|
|
108
|
-
"prettier": "^3.8.
|
|
109
|
-
"sharp": "^0.
|
|
108
|
+
"prettier": "^3.8.4",
|
|
109
|
+
"sharp": "^0.35.0",
|
|
110
110
|
"source-map-support": "^0.5.21",
|
|
111
111
|
"supertest": "^7.2.2",
|
|
112
112
|
"ts-jest": "^29.4.11",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"ts-node": "^10.9.2",
|
|
115
115
|
"tsconfig-paths": "^4.2.0",
|
|
116
116
|
"typescript": "^6.0.3",
|
|
117
|
-
"typescript-eslint": "^8.
|
|
117
|
+
"typescript-eslint": "^8.61.0"
|
|
118
118
|
},
|
|
119
119
|
"jest": {
|
|
120
120
|
"moduleFileExtensions": [
|