anki-mcp-http 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +591 -0
  3. package/bin/ankimcp.js +2 -0
  4. package/dist/anki-config.service.d.ts +10 -0
  5. package/dist/anki-config.service.js +42 -0
  6. package/dist/anki-config.service.js.map +1 -0
  7. package/dist/app.module.d.ts +5 -0
  8. package/dist/app.module.js +74 -0
  9. package/dist/app.module.js.map +1 -0
  10. package/dist/bootstrap.d.ts +3 -0
  11. package/dist/bootstrap.js +39 -0
  12. package/dist/bootstrap.js.map +1 -0
  13. package/dist/cli.d.ts +7 -0
  14. package/dist/cli.js +68 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/http/guards/origin-validation.guard.d.ts +7 -0
  17. package/dist/http/guards/origin-validation.guard.js +52 -0
  18. package/dist/http/guards/origin-validation.guard.js.map +1 -0
  19. package/dist/main-http.d.ts +1 -0
  20. package/dist/main-http.js +27 -0
  21. package/dist/main-http.js.map +1 -0
  22. package/dist/main-stdio.d.ts +1 -0
  23. package/dist/main-stdio.js +20 -0
  24. package/dist/main-stdio.js.map +1 -0
  25. package/dist/mcp/clients/__mocks__/anki-connect.client.d.ts +6 -0
  26. package/dist/mcp/clients/__mocks__/anki-connect.client.js +18 -0
  27. package/dist/mcp/clients/__mocks__/anki-connect.client.js.map +1 -0
  28. package/dist/mcp/clients/anki-connect.client.d.ts +15 -0
  29. package/dist/mcp/clients/anki-connect.client.js +145 -0
  30. package/dist/mcp/clients/anki-connect.client.js.map +1 -0
  31. package/dist/mcp/config/anki-config.interface.d.ts +7 -0
  32. package/dist/mcp/config/anki-config.interface.js +5 -0
  33. package/dist/mcp/config/anki-config.interface.js.map +1 -0
  34. package/dist/mcp/primitives/essential/index.d.ts +30 -0
  35. package/dist/mcp/primitives/essential/index.js +125 -0
  36. package/dist/mcp/primitives/essential/index.js.map +1 -0
  37. package/dist/mcp/primitives/essential/prompts/review-session.prompt.d.ts +12 -0
  38. package/dist/mcp/primitives/essential/prompts/review-session.prompt.js +113 -0
  39. package/dist/mcp/primitives/essential/prompts/review-session.prompt.js.map +1 -0
  40. package/dist/mcp/primitives/essential/resources/system-info.resource.d.ts +21 -0
  41. package/dist/mcp/primitives/essential/resources/system-info.resource.js +115 -0
  42. package/dist/mcp/primitives/essential/resources/system-info.resource.js.map +1 -0
  43. package/dist/mcp/primitives/essential/tools/add-note.tool.d.ts +93 -0
  44. package/dist/mcp/primitives/essential/tools/add-note.tool.js +188 -0
  45. package/dist/mcp/primitives/essential/tools/add-note.tool.js.map +1 -0
  46. package/dist/mcp/primitives/essential/tools/create-deck.tool.d.ts +83 -0
  47. package/dist/mcp/primitives/essential/tools/create-deck.tool.js +120 -0
  48. package/dist/mcp/primitives/essential/tools/create-deck.tool.js.map +1 -0
  49. package/dist/mcp/primitives/essential/tools/create-model.tool.d.ts +88 -0
  50. package/dist/mcp/primitives/essential/tools/create-model.tool.js +142 -0
  51. package/dist/mcp/primitives/essential/tools/create-model.tool.js.map +1 -0
  52. package/dist/mcp/primitives/essential/tools/delete-notes.tool.d.ts +84 -0
  53. package/dist/mcp/primitives/essential/tools/delete-notes.tool.js +120 -0
  54. package/dist/mcp/primitives/essential/tools/delete-notes.tool.js.map +1 -0
  55. package/dist/mcp/primitives/essential/tools/find-notes.tool.d.ts +83 -0
  56. package/dist/mcp/primitives/essential/tools/find-notes.tool.js +106 -0
  57. package/dist/mcp/primitives/essential/tools/find-notes.tool.js.map +1 -0
  58. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.d.ts +84 -0
  59. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js +106 -0
  60. package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js.map +1 -0
  61. package/dist/mcp/primitives/essential/tools/list-decks.tool.d.ts +83 -0
  62. package/dist/mcp/primitives/essential/tools/list-decks.tool.js +117 -0
  63. package/dist/mcp/primitives/essential/tools/list-decks.tool.js.map +1 -0
  64. package/dist/mcp/primitives/essential/tools/model-field-names.tool.d.ts +83 -0
  65. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js +116 -0
  66. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js.map +1 -0
  67. package/dist/mcp/primitives/essential/tools/model-names.tool.d.ts +81 -0
  68. package/dist/mcp/primitives/essential/tools/model-names.tool.js +78 -0
  69. package/dist/mcp/primitives/essential/tools/model-names.tool.js.map +1 -0
  70. package/dist/mcp/primitives/essential/tools/model-styling.tool.d.ts +83 -0
  71. package/dist/mcp/primitives/essential/tools/model-styling.tool.js +93 -0
  72. package/dist/mcp/primitives/essential/tools/model-styling.tool.js.map +1 -0
  73. package/dist/mcp/primitives/essential/tools/notes-info.tool.d.ts +83 -0
  74. package/dist/mcp/primitives/essential/tools/notes-info.tool.js +111 -0
  75. package/dist/mcp/primitives/essential/tools/notes-info.tool.js.map +1 -0
  76. package/dist/mcp/primitives/essential/tools/present-card.tool.d.ts +84 -0
  77. package/dist/mcp/primitives/essential/tools/present-card.tool.js +100 -0
  78. package/dist/mcp/primitives/essential/tools/present-card.tool.js.map +1 -0
  79. package/dist/mcp/primitives/essential/tools/rate-card.tool.d.ts +84 -0
  80. package/dist/mcp/primitives/essential/tools/rate-card.tool.js +96 -0
  81. package/dist/mcp/primitives/essential/tools/rate-card.tool.js.map +1 -0
  82. package/dist/mcp/primitives/essential/tools/sync.tool.d.ts +81 -0
  83. package/dist/mcp/primitives/essential/tools/sync.tool.js +61 -0
  84. package/dist/mcp/primitives/essential/tools/sync.tool.js.map +1 -0
  85. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.d.ts +84 -0
  86. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js +119 -0
  87. package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js.map +1 -0
  88. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.d.ts +96 -0
  89. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js +154 -0
  90. package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js.map +1 -0
  91. package/dist/mcp/primitives/gui/index.d.ts +4 -0
  92. package/dist/mcp/primitives/gui/index.js +26 -0
  93. package/dist/mcp/primitives/gui/index.js.map +1 -0
  94. package/dist/mcp/types/anki.types.d.ts +152 -0
  95. package/dist/mcp/types/anki.types.js +18 -0
  96. package/dist/mcp/types/anki.types.js.map +1 -0
  97. package/dist/mcp/utils/anki.utils.d.ts +19 -0
  98. package/dist/mcp/utils/anki.utils.js +153 -0
  99. package/dist/mcp/utils/anki.utils.js.map +1 -0
  100. package/dist/mcp/utils/mcpb-workarounds.d.ts +1 -0
  101. package/dist/mcp/utils/mcpb-workarounds.js +13 -0
  102. package/dist/mcp/utils/mcpb-workarounds.js.map +1 -0
  103. package/dist/test-fixtures/mock-data.d.ts +126 -0
  104. package/dist/test-fixtures/mock-data.js +112 -0
  105. package/dist/test-fixtures/mock-data.js.map +1 -0
  106. package/dist/test-fixtures/test-helpers.d.ts +12 -0
  107. package/dist/test-fixtures/test-helpers.js +24 -0
  108. package/dist/test-fixtures/test-helpers.js.map +1 -0
  109. package/dist/tsconfig.build.tsbuildinfo +1 -0
  110. package/package.json +153 -0
@@ -0,0 +1,74 @@
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 AppModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.AppModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const config_1 = require("@nestjs/config");
13
+ const mcp_nest_1 = require("@rekog/mcp-nest");
14
+ const essential_1 = require("./mcp/primitives/essential");
15
+ const gui_1 = require("./mcp/primitives/gui");
16
+ const anki_config_service_1 = require("./anki-config.service");
17
+ let AppModule = AppModule_1 = class AppModule {
18
+ static forStdio() {
19
+ return {
20
+ module: AppModule_1,
21
+ imports: [
22
+ config_1.ConfigModule.forRoot({
23
+ isGlobal: true,
24
+ cache: true,
25
+ envFilePath: ['.env.local', '.env'],
26
+ }),
27
+ mcp_nest_1.McpModule.forRoot({
28
+ name: process.env.MCP_SERVER_NAME || 'anki-mcp-desktop',
29
+ version: process.env.MCP_SERVER_VERSION || '1.0.0',
30
+ transport: mcp_nest_1.McpTransportType.STDIO,
31
+ }),
32
+ essential_1.McpPrimitivesAnkiEssentialModule.forRoot({
33
+ ankiConfigProvider: {
34
+ provide: essential_1.ANKI_CONFIG,
35
+ useClass: anki_config_service_1.AnkiConfigService,
36
+ },
37
+ }),
38
+ gui_1.McpPrimitivesAnkiGuiModule.forRoot(),
39
+ ],
40
+ providers: [anki_config_service_1.AnkiConfigService],
41
+ };
42
+ }
43
+ static forHttp() {
44
+ return {
45
+ module: AppModule_1,
46
+ imports: [
47
+ config_1.ConfigModule.forRoot({
48
+ isGlobal: true,
49
+ cache: true,
50
+ envFilePath: ['.env.local', '.env'],
51
+ }),
52
+ mcp_nest_1.McpModule.forRoot({
53
+ name: process.env.MCP_SERVER_NAME || 'anki-mcp-desktop',
54
+ version: process.env.MCP_SERVER_VERSION || '1.0.0',
55
+ transport: mcp_nest_1.McpTransportType.STREAMABLE_HTTP,
56
+ mcpEndpoint: '/',
57
+ }),
58
+ essential_1.McpPrimitivesAnkiEssentialModule.forRoot({
59
+ ankiConfigProvider: {
60
+ provide: essential_1.ANKI_CONFIG,
61
+ useClass: anki_config_service_1.AnkiConfigService,
62
+ },
63
+ }),
64
+ gui_1.McpPrimitivesAnkiGuiModule.forRoot(),
65
+ ],
66
+ providers: [anki_config_service_1.AnkiConfigService],
67
+ };
68
+ }
69
+ };
70
+ exports.AppModule = AppModule;
71
+ exports.AppModule = AppModule = AppModule_1 = __decorate([
72
+ (0, common_1.Module)({})
73
+ ], AppModule);
74
+ //# sourceMappingURL=app.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AACvD,2CAA8C;AAC9C,8CAA8D;AAC9D,0DAGoC;AACpC,8CAAkE;AAClE,+DAA0D;AAGnD,IAAM,SAAS,iBAAf,MAAM,SAAS;IAIpB,MAAM,CAAC,QAAQ;QACb,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,OAAO,EAAE;gBAEP,qBAAY,CAAC,OAAO,CAAC;oBACnB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,IAAI;oBACX,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;iBACpC,CAAC;gBAGF,oBAAS,CAAC,OAAO,CAAC;oBAChB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,kBAAkB;oBACvD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO;oBAClD,SAAS,EAAE,2BAAgB,CAAC,KAAK;iBAClC,CAAC;gBAGF,4CAAgC,CAAC,OAAO,CAAC;oBACvC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;gBAGF,gCAA0B,CAAC,OAAO,EAAE;aACrC;YACD,SAAS,EAAE,CAAC,uCAAiB,CAAC;SAC/B,CAAC;IACJ,CAAC;IAKD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,OAAO,EAAE;gBAEP,qBAAY,CAAC,OAAO,CAAC;oBACnB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,IAAI;oBACX,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;iBACpC,CAAC;gBAGF,oBAAS,CAAC,OAAO,CAAC;oBAChB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,kBAAkB;oBACvD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO;oBAClD,SAAS,EAAE,2BAAgB,CAAC,eAAe;oBAC3C,WAAW,EAAE,GAAG;iBACjB,CAAC;gBAGF,4CAAgC,CAAC,OAAO,CAAC;oBACvC,kBAAkB,EAAE;wBAClB,OAAO,EAAE,uBAAW;wBACpB,QAAQ,EAAE,uCAAiB;qBAC5B;iBACF,CAAC;gBAGF,gCAA0B,CAAC,OAAO,EAAE;aACrC;YACD,SAAS,EAAE,CAAC,uCAAiB,CAAC;SAC/B,CAAC;IACJ,CAAC;CACF,CAAA;AAzEY,8BAAS;oBAAT,SAAS;IADrB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,SAAS,CAyErB"}
@@ -0,0 +1,3 @@
1
+ import { LoggerService } from '@nestjs/common';
2
+ export declare function createPinoLogger(destination: 1 | 2): import("pino").Logger<never, boolean>;
3
+ export declare function createLoggerService(pinoLogger: any): LoggerService;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPinoLogger = createPinoLogger;
4
+ exports.createLoggerService = createLoggerService;
5
+ const pino_1 = require("pino");
6
+ function createPinoLogger(destination) {
7
+ return (0, pino_1.pino)({
8
+ level: process.env.LOG_LEVEL || 'info',
9
+ transport: {
10
+ target: 'pino-pretty',
11
+ options: {
12
+ destination,
13
+ colorize: true,
14
+ translateTime: 'HH:MM:ss Z',
15
+ ignore: 'pid,hostname',
16
+ },
17
+ },
18
+ });
19
+ }
20
+ function createLoggerService(pinoLogger) {
21
+ return {
22
+ log: (message, context) => {
23
+ pinoLogger.info({ context }, message);
24
+ },
25
+ error: (message, trace, context) => {
26
+ pinoLogger.error({ context, trace }, message);
27
+ },
28
+ warn: (message, context) => {
29
+ pinoLogger.warn({ context }, message);
30
+ },
31
+ debug: (message, context) => {
32
+ pinoLogger.debug({ context }, message);
33
+ },
34
+ verbose: (message, context) => {
35
+ pinoLogger.trace({ context }, message);
36
+ },
37
+ };
38
+ }
39
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":";;AASA,4CAaC;AAQD,kDAkBC;AA/CD,+BAA4B;AAQ5B,SAAgB,gBAAgB,CAAC,WAAkB;IACjD,OAAO,IAAA,WAAI,EAAC;QACV,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;QACtC,SAAS,EAAE;YACT,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE;gBACP,WAAW;gBACX,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,YAAY;gBAC3B,MAAM,EAAE,cAAc;aACvB;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAQD,SAAgB,mBAAmB,CAAC,UAAe;IACjD,OAAO;QACL,GAAG,EAAE,CAAC,OAAY,EAAE,OAAgB,EAAE,EAAE;YACtC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,KAAK,EAAE,CAAC,OAAY,EAAE,KAAc,EAAE,OAAgB,EAAE,EAAE;YACxD,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,EAAE,CAAC,OAAY,EAAE,OAAgB,EAAE,EAAE;YACvC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,KAAK,EAAE,CAAC,OAAY,EAAE,OAAgB,EAAE,EAAE;YACxC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,EAAE,CAAC,OAAY,EAAE,OAAgB,EAAE,EAAE;YAC1C,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export interface CliOptions {
2
+ port: number;
3
+ host: string;
4
+ ankiConnect: string;
5
+ }
6
+ export declare function parseCliArgs(): CliOptions;
7
+ export declare function displayStartupBanner(options: CliOptions): void;
package/dist/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseCliArgs = parseCliArgs;
4
+ exports.displayStartupBanner = displayStartupBanner;
5
+ const commander_1 = require("commander");
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ function getVersion() {
9
+ try {
10
+ const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '../package.json'), 'utf-8'));
11
+ return packageJson.version;
12
+ }
13
+ catch {
14
+ return '0.0.0';
15
+ }
16
+ }
17
+ function parseCliArgs() {
18
+ const program = new commander_1.Command();
19
+ program
20
+ .name('ankimcp')
21
+ .description('AnkiMCP HTTP Server - Model Context Protocol server for Anki')
22
+ .version(getVersion())
23
+ .option('-p, --port <number>', 'Port to listen on', '3000')
24
+ .option('-h, --host <address>', 'Host to bind to', '127.0.0.1')
25
+ .option('-a, --anki-connect <url>', 'AnkiConnect URL', 'http://localhost:8765')
26
+ .addHelpText('after', `
27
+ Examples:
28
+ $ ankimcp # Use defaults
29
+ $ ankimcp --port 8080 # Custom port
30
+ $ ankimcp --host 0.0.0.0 --port 3000 # Listen on all interfaces
31
+ $ ankimcp --anki-connect http://localhost:8765
32
+
33
+ Usage with ngrok:
34
+ 1. Start ankimcp in one terminal
35
+ 2. In another terminal: ngrok http 3000
36
+ 3. Share the ngrok URL with your AI assistant
37
+ `);
38
+ program.parse();
39
+ const options = program.opts();
40
+ return {
41
+ port: parseInt(options.port.toString(), 10),
42
+ host: options.host,
43
+ ankiConnect: options.ankiConnect,
44
+ };
45
+ }
46
+ function displayStartupBanner(options) {
47
+ console.log(`
48
+ ╔════════════════════════════════════════════════════════════════╗
49
+ ║ AnkiMCP HTTP Server ║
50
+ ╚════════════════════════════════════════════════════════════════╝
51
+
52
+ 🚀 Server running on: http://${options.host}:${options.port}
53
+ 🔌 AnkiConnect URL: ${options.ankiConnect}
54
+
55
+ Configuration:
56
+ • Port: ${options.port} (override: --port 8080)
57
+ • Host: ${options.host} (override: --host 0.0.0.0)
58
+ • AnkiConnect: ${options.ankiConnect}
59
+ (override: --anki-connect http://localhost:8765)
60
+
61
+ Usage with ngrok:
62
+ 1. In another terminal: ngrok http ${options.port}
63
+ 2. Share the ngrok URL with your AI assistant
64
+
65
+ Run 'ankimcp --help' for more options.
66
+ `);
67
+ }
68
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AAqBA,oCAuCC;AAED,oDAqBC;AAnFD,yCAAoC;AACpC,2BAAkC;AAClC,+BAA4B;AAQ5B,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;QACF,OAAO,WAAW,CAAC,OAAO,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAgB,YAAY;IAC1B,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,8DAA8D,CAAC;SAC3E,OAAO,CAAC,UAAU,EAAE,CAAC;SACrB,MAAM,CAAC,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,CAAC;SAC1D,MAAM,CAAC,sBAAsB,EAAE,iBAAiB,EAAE,WAAW,CAAC;SAC9D,MAAM,CACL,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,CACxB;SACA,WAAW,CACV,OAAO,EACP;;;;;;;;;;;CAWL,CACI,CAAC;IAEJ,OAAO,CAAC,KAAK,EAAE,CAAC;IAEhB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAc,CAAC;IAE3C,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC3C,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAAC,OAAmB;IACtD,OAAO,CAAC,GAAG,CAAC;;;;;+BAKiB,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;wBACnC,OAAO,CAAC,WAAW;;;0BAGjB,OAAO,CAAC,IAAI;0BACZ,OAAO,CAAC,IAAI;0BACZ,OAAO,CAAC,WAAW;;;;uCAIN,OAAO,CAAC,IAAI;;;;CAIlD,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ export declare class OriginValidationGuard implements CanActivate {
3
+ private readonly allowedOrigins;
4
+ constructor();
5
+ canActivate(context: ExecutionContext): boolean;
6
+ private matchesPattern;
7
+ }
@@ -0,0 +1,52 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.OriginValidationGuard = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ let OriginValidationGuard = class OriginValidationGuard {
15
+ allowedOrigins;
16
+ constructor() {
17
+ const defaultOrigins = 'http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:*';
18
+ const originsEnv = process.env.ALLOWED_ORIGINS || defaultOrigins;
19
+ this.allowedOrigins = originsEnv.split(',').map((o) => o.trim());
20
+ }
21
+ canActivate(context) {
22
+ const request = context.switchToHttp().getRequest();
23
+ const origin = request.headers.origin || request.headers.referer;
24
+ if (!origin) {
25
+ return true;
26
+ }
27
+ const isAllowed = this.allowedOrigins.some((allowedOrigin) => this.matchesPattern(origin, allowedOrigin));
28
+ if (!isAllowed) {
29
+ console.warn(`[OriginValidationGuard] Rejected request from unauthorized origin: ${origin}`);
30
+ }
31
+ return isAllowed;
32
+ }
33
+ matchesPattern(origin, pattern) {
34
+ if (origin === pattern) {
35
+ return true;
36
+ }
37
+ if (pattern.includes('*')) {
38
+ const regexPattern = pattern
39
+ .replace(/\./g, '\\.')
40
+ .replace(/\*/g, '.*');
41
+ const regex = new RegExp(`^${regexPattern}$`);
42
+ return regex.test(origin);
43
+ }
44
+ return false;
45
+ }
46
+ };
47
+ exports.OriginValidationGuard = OriginValidationGuard;
48
+ exports.OriginValidationGuard = OriginValidationGuard = __decorate([
49
+ (0, common_1.Injectable)(),
50
+ __metadata("design:paramtypes", [])
51
+ ], OriginValidationGuard);
52
+ //# sourceMappingURL=origin-validation.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin-validation.guard.js","sourceRoot":"","sources":["../../../src/http/guards/origin-validation.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA2E;AAiBpE,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IACf,cAAc,CAAW;IAE1C;QACE,MAAM,cAAc,GAClB,+EAA+E,CAAC;QAClF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,cAAc,CAAC;QACjE,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,WAAW,CAAC,OAAyB;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;QAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAGjE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE,CAC3D,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,CAC3C,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACV,sEAAsE,MAAM,EAAE,CAC/E,CAAC;QACJ,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IASO,cAAc,CAAC,MAAc,EAAE,OAAe;QAEpD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,YAAY,GAAG,OAAO;iBACzB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;iBACrB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAA;AAzDY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;;GACA,qBAAqB,CAyDjC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@nestjs/core");
4
+ const app_module_1 = require("./app.module");
5
+ const bootstrap_1 = require("./bootstrap");
6
+ const origin_validation_guard_1 = require("./http/guards/origin-validation.guard");
7
+ const cli_1 = require("./cli");
8
+ async function bootstrap() {
9
+ const options = (0, cli_1.parseCliArgs)();
10
+ process.env.PORT = options.port.toString();
11
+ process.env.HOST = options.host;
12
+ process.env.ANKI_CONNECT_URL = options.ankiConnect;
13
+ const pinoLogger = (0, bootstrap_1.createPinoLogger)(1);
14
+ const loggerService = (0, bootstrap_1.createLoggerService)(pinoLogger);
15
+ const app = await core_1.NestFactory.create(app_module_1.AppModule.forHttp(), {
16
+ logger: loggerService,
17
+ bufferLogs: true,
18
+ });
19
+ app.useGlobalGuards(new origin_validation_guard_1.OriginValidationGuard());
20
+ await app.listen(options.port, options.host);
21
+ (0, cli_1.displayStartupBanner)(options);
22
+ }
23
+ bootstrap().catch((err) => {
24
+ console.error('Failed to start MCP HTTP server:', err);
25
+ process.exit(1);
26
+ });
27
+ //# sourceMappingURL=main-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-http.js","sourceRoot":"","sources":["../src/main-http.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AACzC,2CAAoE;AACpE,mFAA8E;AAC9E,+BAA2D;AAE3D,KAAK,UAAU,SAAS;IACtB,MAAM,OAAO,GAAG,IAAA,kBAAY,GAAE,CAAC;IAG/B,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;IAGnD,MAAM,UAAU,GAAG,IAAA,4BAAgB,EAAC,CAAC,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,IAAA,+BAAmB,EAAC,UAAU,CAAC,CAAC;IAGtD,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,OAAO,EAAE,EAAE;QACxD,MAAM,EAAE,aAAa;QACrB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IAGH,GAAG,CAAC,eAAe,CAAC,IAAI,+CAAqB,EAAE,CAAC,CAAC;IAEjD,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAG7C,IAAA,0BAAoB,EAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACxB,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@nestjs/core");
4
+ const app_module_1 = require("./app.module");
5
+ const bootstrap_1 = require("./bootstrap");
6
+ async function bootstrap() {
7
+ const pinoLogger = (0, bootstrap_1.createPinoLogger)(2);
8
+ const loggerService = (0, bootstrap_1.createLoggerService)(pinoLogger);
9
+ await core_1.NestFactory.createApplicationContext(app_module_1.AppModule.forStdio(), {
10
+ logger: loggerService,
11
+ bufferLogs: true,
12
+ });
13
+ pinoLogger.info('MCP STDIO server started successfully');
14
+ await new Promise(() => { });
15
+ }
16
+ bootstrap().catch((err) => {
17
+ console.error('Failed to start MCP STDIO server:', err);
18
+ process.exit(1);
19
+ });
20
+ //# sourceMappingURL=main-stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-stdio.js","sourceRoot":"","sources":["../src/main-stdio.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AACzC,2CAAoE;AAEpE,KAAK,UAAU,SAAS;IAEtB,MAAM,UAAU,GAAG,IAAA,4BAAgB,EAAC,CAAC,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,IAAA,+BAAmB,EAAC,UAAU,CAAC,CAAC;IAGtD,MAAM,kBAAW,CAAC,wBAAwB,CAAC,sBAAS,CAAC,QAAQ,EAAE,EAAE;QAC/D,MAAM,EAAE,aAAa;QACrB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IAEH,UAAU,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IAGzD,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACxB,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const AnkiConnectClient: jest.Mock<any, any, any>;
2
+ export declare class AnkiConnectError extends Error {
3
+ readonly action?: string | undefined;
4
+ readonly originalError?: string | undefined;
5
+ constructor(message: string, action?: string | undefined, originalError?: string | undefined);
6
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnkiConnectError = exports.AnkiConnectClient = void 0;
4
+ exports.AnkiConnectClient = jest.fn().mockImplementation(() => ({
5
+ invoke: jest.fn(),
6
+ }));
7
+ class AnkiConnectError extends Error {
8
+ action;
9
+ originalError;
10
+ constructor(message, action, originalError) {
11
+ super(message);
12
+ this.action = action;
13
+ this.originalError = originalError;
14
+ this.name = 'AnkiConnectError';
15
+ }
16
+ }
17
+ exports.AnkiConnectError = AnkiConnectError;
18
+ //# sourceMappingURL=anki-connect.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anki-connect.client.js","sourceRoot":"","sources":["../../../../src/mcp/clients/__mocks__/anki-connect.client.ts"],"names":[],"mappings":";;;AACa,QAAA,iBAAiB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC,CAAC;IACnE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE;CAClB,CAAC,CAAC,CAAC;AAEJ,MAAa,gBAAiB,SAAQ,KAAK;IAGvB;IACA;IAHlB,YACE,OAAe,EACC,MAAe,EACf,aAAsB;QAEtC,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,WAAM,GAAN,MAAM,CAAS;QACf,kBAAa,GAAb,aAAa,CAAS;QAGtC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AATD,4CASC"}
@@ -0,0 +1,15 @@
1
+ import type { IAnkiConfig } from '../config/anki-config.interface';
2
+ export declare class AnkiConnectError extends Error {
3
+ readonly action?: string | undefined;
4
+ readonly originalError?: string | undefined;
5
+ constructor(message: string, action?: string | undefined, originalError?: string | undefined);
6
+ }
7
+ export declare class AnkiConnectClient {
8
+ private readonly config;
9
+ private readonly client;
10
+ private readonly apiVersion;
11
+ private readonly apiKey?;
12
+ private readonly logger;
13
+ constructor(config: IAnkiConfig);
14
+ invoke<T = any>(action: string, params?: Record<string, any>): Promise<T>;
15
+ }
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ 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;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
45
+ return function (target, key) { decorator(target, key, paramIndex); }
46
+ };
47
+ var AnkiConnectClient_1;
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.AnkiConnectClient = exports.AnkiConnectError = void 0;
50
+ const common_1 = require("@nestjs/common");
51
+ const ky_1 = __importStar(require("ky"));
52
+ const anki_config_interface_1 = require("../config/anki-config.interface");
53
+ class AnkiConnectError extends Error {
54
+ action;
55
+ originalError;
56
+ constructor(message, action, originalError) {
57
+ super(message);
58
+ this.action = action;
59
+ this.originalError = originalError;
60
+ this.name = 'AnkiConnectError';
61
+ }
62
+ }
63
+ exports.AnkiConnectError = AnkiConnectError;
64
+ let AnkiConnectClient = AnkiConnectClient_1 = class AnkiConnectClient {
65
+ config;
66
+ client;
67
+ apiVersion;
68
+ apiKey;
69
+ logger = new common_1.Logger(AnkiConnectClient_1.name);
70
+ constructor(config) {
71
+ this.config = config;
72
+ this.apiVersion = config.ankiConnectApiVersion;
73
+ this.apiKey = config.ankiConnectApiKey;
74
+ this.client = ky_1.default.create({
75
+ prefixUrl: config.ankiConnectUrl,
76
+ timeout: config.ankiConnectTimeout,
77
+ headers: {
78
+ 'Content-Type': 'application/json',
79
+ },
80
+ retry: {
81
+ limit: 2,
82
+ methods: ['POST'],
83
+ statusCodes: [408, 413, 429, 500, 502, 503, 504],
84
+ backoffLimit: 3000,
85
+ },
86
+ hooks: {
87
+ beforeRequest: [
88
+ (request) => {
89
+ this.logger.debug(`AnkiConnect request: ${request.method} ${request.url}`);
90
+ },
91
+ ],
92
+ afterResponse: [
93
+ (_request, _options, response) => {
94
+ this.logger.debug(`AnkiConnect response: ${response.status} ${response.statusText}`);
95
+ },
96
+ ],
97
+ },
98
+ });
99
+ }
100
+ async invoke(action, params) {
101
+ const request = {
102
+ action,
103
+ version: this.apiVersion,
104
+ params,
105
+ };
106
+ if (this.apiKey) {
107
+ request.key = this.apiKey;
108
+ }
109
+ try {
110
+ this.logger.log(`Invoking AnkiConnect action: ${action}`);
111
+ const response = await this.client
112
+ .post('', {
113
+ json: request,
114
+ })
115
+ .json();
116
+ if (response.error) {
117
+ throw new AnkiConnectError(`AnkiConnect error: ${response.error}`, action, response.error);
118
+ }
119
+ this.logger.log(`AnkiConnect action successful: ${action}`);
120
+ return response.result;
121
+ }
122
+ catch (error) {
123
+ if (error instanceof ky_1.HTTPError) {
124
+ if (error.response.status === 403) {
125
+ throw new AnkiConnectError('Permission denied. Please check AnkiConnect configuration and API key.', action);
126
+ }
127
+ throw new AnkiConnectError(`HTTP error ${error.response.status}: ${error.message}`, action);
128
+ }
129
+ if (error instanceof Error && error.message.includes('fetch')) {
130
+ throw new AnkiConnectError('Cannot connect to Anki. Please ensure Anki is running and AnkiConnect plugin is installed.', action);
131
+ }
132
+ if (error instanceof AnkiConnectError) {
133
+ throw error;
134
+ }
135
+ throw new AnkiConnectError(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`, action);
136
+ }
137
+ }
138
+ };
139
+ exports.AnkiConnectClient = AnkiConnectClient;
140
+ exports.AnkiConnectClient = AnkiConnectClient = AnkiConnectClient_1 = __decorate([
141
+ (0, common_1.Injectable)(),
142
+ __param(0, (0, common_1.Inject)(anki_config_interface_1.ANKI_CONFIG)),
143
+ __metadata("design:paramtypes", [Object])
144
+ ], AnkiConnectClient);
145
+ //# sourceMappingURL=anki-connect.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anki-connect.client.js","sourceRoot":"","sources":["../../../src/mcp/clients/anki-connect.client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface IAnkiConfig {
2
+ ankiConnectUrl: string;
3
+ ankiConnectApiVersion: number;
4
+ ankiConnectApiKey?: string;
5
+ ankiConnectTimeout: number;
6
+ }
7
+ export declare const ANKI_CONFIG: unique symbol;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ANKI_CONFIG = void 0;
4
+ exports.ANKI_CONFIG = Symbol('ANKI_CONFIG');
5
+ //# sourceMappingURL=anki-config.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anki-config.interface.js","sourceRoot":"","sources":["../../../src/mcp/config/anki-config.interface.ts"],"names":[],"mappings":";;;AAgCa,QAAA,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ export { ANKI_CONFIG } from '../../config/anki-config.interface';
2
+ export type { IAnkiConfig } from '../../config/anki-config.interface';
3
+ export * from '../../types/anki.types';
4
+ export * from '../../utils/anki.utils';
5
+ export { AnkiConnectClient, AnkiConnectError } from '../../clients/anki-connect.client';
6
+ export { SyncTool } from './tools/sync.tool';
7
+ export { ListDecksTool } from './tools/list-decks.tool';
8
+ export { CreateDeckTool } from './tools/create-deck.tool';
9
+ export { GetDueCardsTool } from './tools/get-due-cards.tool';
10
+ export { PresentCardTool } from './tools/present-card.tool';
11
+ export { RateCardTool } from './tools/rate-card.tool';
12
+ export { ModelNamesTool } from './tools/model-names.tool';
13
+ export { ModelFieldNamesTool } from './tools/model-field-names.tool';
14
+ export { ModelStylingTool } from './tools/model-styling.tool';
15
+ export { CreateModelTool } from './tools/create-model.tool';
16
+ export { UpdateModelStylingTool } from './tools/update-model-styling.tool';
17
+ export { AddNoteTool } from './tools/add-note.tool';
18
+ export { FindNotesTool } from './tools/find-notes.tool';
19
+ export { NotesInfoTool } from './tools/notes-info.tool';
20
+ export { UpdateNoteFieldsTool } from './tools/update-note-fields.tool';
21
+ export { DeleteNotesTool } from './tools/delete-notes.tool';
22
+ export { ReviewSessionPrompt } from './prompts/review-session.prompt';
23
+ export { SystemInfoResource } from './resources/system-info.resource';
24
+ import { DynamicModule, Provider } from '@nestjs/common';
25
+ export interface McpPrimitivesAnkiEssentialModuleOptions {
26
+ ankiConfigProvider: Provider;
27
+ }
28
+ export declare class McpPrimitivesAnkiEssentialModule {
29
+ static forRoot(options: McpPrimitivesAnkiEssentialModuleOptions): DynamicModule;
30
+ }