@ankimcp/anki-mcp-server 0.18.0 → 0.18.4-tunnel

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 (106) hide show
  1. package/bin/ankimcp.js +10 -1
  2. package/dist/app-config.service.d.ts +22 -0
  3. package/dist/app-config.service.js +79 -0
  4. package/dist/app-config.service.js.map +1 -0
  5. package/dist/app.module.d.ts +4 -2
  6. package/dist/app.module.js +99 -11
  7. package/dist/app.module.js.map +1 -1
  8. package/dist/bootstrap.d.ts +6 -1
  9. package/dist/bootstrap.js +7 -2
  10. package/dist/bootstrap.js.map +1 -1
  11. package/dist/cli/__tests__/cli-output.manual.d.ts +2 -0
  12. package/dist/cli/__tests__/cli-output.manual.js +13 -0
  13. package/dist/cli/__tests__/cli-output.manual.js.map +1 -0
  14. package/dist/cli/cli-output.d.ts +20 -0
  15. package/dist/cli/cli-output.js +69 -0
  16. package/dist/cli/cli-output.js.map +1 -0
  17. package/dist/cli/index.d.ts +1 -0
  18. package/dist/cli/index.js +18 -0
  19. package/dist/cli/index.js.map +1 -0
  20. package/dist/cli.d.ts +4 -0
  21. package/dist/cli.js +20 -6
  22. package/dist/cli.js.map +1 -1
  23. package/dist/config/config.factory.d.ts +13 -0
  24. package/dist/config/config.factory.js +32 -0
  25. package/dist/config/config.factory.js.map +1 -0
  26. package/dist/config/config.schema.d.ts +33 -0
  27. package/dist/config/config.schema.js +58 -0
  28. package/dist/config/config.schema.js.map +1 -0
  29. package/dist/config/index.d.ts +3 -0
  30. package/dist/config/index.js +11 -0
  31. package/dist/config/index.js.map +1 -0
  32. package/dist/http/guards/origin-validation.guard.d.ts +1 -0
  33. package/dist/http/guards/origin-validation.guard.js +5 -3
  34. package/dist/http/guards/origin-validation.guard.js.map +1 -1
  35. package/dist/main-http.js +20 -10
  36. package/dist/main-http.js.map +1 -1
  37. package/dist/main-stdio.js +9 -9
  38. package/dist/main-stdio.js.map +1 -1
  39. package/dist/main-tunnel.d.ts +1 -0
  40. package/dist/main-tunnel.js +26 -0
  41. package/dist/main-tunnel.js.map +1 -0
  42. package/dist/mcp/primitives/essential/index.d.ts +1 -0
  43. package/dist/mcp/primitives/essential/index.js +8 -1
  44. package/dist/mcp/primitives/essential/index.js.map +1 -1
  45. package/dist/mcp/primitives/essential/tools/add-note.tool.d.ts +1 -1
  46. package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.js +66 -36
  47. package/dist/mcp/primitives/essential/tools/collection-stats/collection-stats.tool.js.map +1 -1
  48. package/dist/mcp/primitives/essential/tools/deck-stats.tool.js +25 -8
  49. package/dist/mcp/primitives/essential/tools/deck-stats.tool.js.map +1 -1
  50. package/dist/mcp/primitives/essential/tools/deckActions/actions/deckStats.action.js +14 -7
  51. package/dist/mcp/primitives/essential/tools/deckActions/actions/deckStats.action.js.map +1 -1
  52. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js +1 -1
  53. package/dist/mcp/primitives/essential/tools/model-field-names.tool.js.map +1 -1
  54. package/dist/mcp/primitives/gui/index.d.ts +1 -0
  55. package/dist/mcp/primitives/gui/index.js +8 -1
  56. package/dist/mcp/primitives/gui/index.js.map +1 -1
  57. package/dist/mcp/utils/deck-hierarchy.utils.d.ts +3 -0
  58. package/dist/mcp/utils/deck-hierarchy.utils.js +21 -0
  59. package/dist/mcp/utils/deck-hierarchy.utils.js.map +1 -0
  60. package/dist/services/ngrok.service.d.ts +1 -0
  61. package/dist/services/ngrok.service.js +5 -3
  62. package/dist/services/ngrok.service.js.map +1 -1
  63. package/dist/test-fixtures/mock-data.d.ts +8 -0
  64. package/dist/test-fixtures/mock-data.js +8 -0
  65. package/dist/test-fixtures/mock-data.js.map +1 -1
  66. package/dist/tsconfig.build.tsbuildinfo +1 -1
  67. package/dist/tunnel/commands/index.d.ts +3 -0
  68. package/dist/tunnel/commands/index.js +10 -0
  69. package/dist/tunnel/commands/index.js.map +1 -0
  70. package/dist/tunnel/commands/login.command.d.ts +1 -0
  71. package/dist/tunnel/commands/login.command.js +108 -0
  72. package/dist/tunnel/commands/login.command.js.map +1 -0
  73. package/dist/tunnel/commands/logout.command.d.ts +1 -0
  74. package/dist/tunnel/commands/logout.command.js +26 -0
  75. package/dist/tunnel/commands/logout.command.js.map +1 -0
  76. package/dist/tunnel/commands/tunnel.command.d.ts +1 -0
  77. package/dist/tunnel/commands/tunnel.command.js +185 -0
  78. package/dist/tunnel/commands/tunnel.command.js.map +1 -0
  79. package/dist/tunnel/credentials.service.d.ts +23 -0
  80. package/dist/tunnel/credentials.service.js +152 -0
  81. package/dist/tunnel/credentials.service.js.map +1 -0
  82. package/dist/tunnel/device-flow.service.d.ts +46 -0
  83. package/dist/tunnel/device-flow.service.js +237 -0
  84. package/dist/tunnel/device-flow.service.js.map +1 -0
  85. package/dist/tunnel/in-memory.transport.d.ts +14 -0
  86. package/dist/tunnel/in-memory.transport.js +63 -0
  87. package/dist/tunnel/in-memory.transport.js.map +1 -0
  88. package/dist/tunnel/index.d.ts +6 -0
  89. package/dist/tunnel/index.js +31 -0
  90. package/dist/tunnel/index.js.map +1 -0
  91. package/dist/tunnel/tunnel-mcp.service.d.ts +15 -0
  92. package/dist/tunnel/tunnel-mcp.service.js +100 -0
  93. package/dist/tunnel/tunnel-mcp.service.js.map +1 -0
  94. package/dist/tunnel/tunnel.client.d.ts +60 -0
  95. package/dist/tunnel/tunnel.client.js +386 -0
  96. package/dist/tunnel/tunnel.client.js.map +1 -0
  97. package/dist/tunnel/tunnel.protocol.d.ts +68 -0
  98. package/dist/tunnel/tunnel.protocol.js +26 -0
  99. package/dist/tunnel/tunnel.protocol.js.map +1 -0
  100. package/dist/version.d.ts +2 -0
  101. package/dist/version.js +21 -0
  102. package/dist/version.js.map +1 -0
  103. package/package.json +7 -2
  104. package/dist/anki-config.service.d.ts +0 -11
  105. package/dist/anki-config.service.js +0 -46
  106. package/dist/anki-config.service.js.map +0 -1
@@ -0,0 +1,386 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TunnelClient = exports.TunnelClientError = void 0;
7
+ const events_1 = require("events");
8
+ const ws_1 = __importDefault(require("ws"));
9
+ const common_1 = require("@nestjs/common");
10
+ const ky_1 = require("ky");
11
+ const tunnel_protocol_1 = require("./tunnel.protocol");
12
+ const device_flow_service_1 = require("./device-flow.service");
13
+ class TunnelClientError extends Error {
14
+ code;
15
+ originalError;
16
+ constructor(message, code, originalError) {
17
+ super(message);
18
+ this.code = code;
19
+ this.originalError = originalError;
20
+ this.name = "TunnelClientError";
21
+ }
22
+ }
23
+ exports.TunnelClientError = TunnelClientError;
24
+ class TunnelClient extends events_1.EventEmitter {
25
+ mcpHandler;
26
+ credentialsService;
27
+ deviceFlowService;
28
+ tunnelUrl;
29
+ logger = new common_1.Logger(TunnelClient.name);
30
+ ws = null;
31
+ reconnectAttempts = 0;
32
+ reconnectTimer = null;
33
+ isConnecting = false;
34
+ isManualDisconnect = false;
35
+ currentTunnelUrl = null;
36
+ credentials = null;
37
+ connectionTimeout = null;
38
+ lastServerPingTime = 0;
39
+ healthCheckInterval = null;
40
+ pongTimeout = null;
41
+ constructor(mcpHandler, credentialsService, deviceFlowService, tunnelUrl = tunnel_protocol_1.TUNNEL_DEFAULTS.URL) {
42
+ super();
43
+ this.mcpHandler = mcpHandler;
44
+ this.credentialsService = credentialsService;
45
+ this.deviceFlowService = deviceFlowService;
46
+ this.tunnelUrl = tunnelUrl;
47
+ }
48
+ async connect(providedTunnelUrl) {
49
+ if (this.isConnecting) {
50
+ throw new TunnelClientError("Connection already in progress", "connection_in_progress");
51
+ }
52
+ if (this.ws?.readyState === ws_1.default.OPEN) {
53
+ throw new TunnelClientError("Already connected", "already_connected");
54
+ }
55
+ const url = providedTunnelUrl || this.tunnelUrl;
56
+ this.isManualDisconnect = false;
57
+ this.isConnecting = true;
58
+ try {
59
+ this.credentials = await this.credentialsService.loadCredentials();
60
+ if (!this.credentials) {
61
+ throw new TunnelClientError("No credentials found. Please run login first.", "no_credentials");
62
+ }
63
+ if (this.credentialsService.isTokenExpired(this.credentials)) {
64
+ this.logger.log("Access token expired, refreshing...");
65
+ await this.refreshTokenAndSave();
66
+ }
67
+ const tunnelUrl = await this.establishConnection(url);
68
+ this.reconnectAttempts = 0;
69
+ this.isConnecting = false;
70
+ return tunnelUrl;
71
+ }
72
+ catch (error) {
73
+ this.isConnecting = false;
74
+ throw this.wrapError(error, "connect");
75
+ }
76
+ }
77
+ disconnect() {
78
+ this.logger.log("Disconnecting from tunnel (manual)");
79
+ this.isManualDisconnect = true;
80
+ this.clearReconnectTimer();
81
+ this.clearConnectionTimeout();
82
+ this.stopHealthCheck();
83
+ if (this.ws) {
84
+ this.ws.close(tunnel_protocol_1.TunnelCloseCodes.NORMAL, "Client disconnect");
85
+ this.ws = null;
86
+ }
87
+ this.currentTunnelUrl = null;
88
+ }
89
+ isConnected() {
90
+ return this.ws?.readyState === ws_1.default.OPEN;
91
+ }
92
+ getTunnelUrl() {
93
+ return this.currentTunnelUrl;
94
+ }
95
+ async establishConnection(url) {
96
+ return new Promise((resolve, reject) => {
97
+ if (!this.credentials) {
98
+ return reject(new TunnelClientError("No credentials available", "no_credentials"));
99
+ }
100
+ this.logger.log(`Connecting to tunnel server: ${url}`);
101
+ this.ws = new ws_1.default(url, {
102
+ headers: {
103
+ Authorization: `Bearer ${this.credentials.access_token}`,
104
+ },
105
+ });
106
+ this.connectionTimeout = setTimeout(() => {
107
+ if (this.ws?.readyState !== ws_1.default.OPEN) {
108
+ this.ws?.terminate();
109
+ reject(new TunnelClientError("Connection timeout", "connection_timeout"));
110
+ }
111
+ }, tunnel_protocol_1.TUNNEL_DEFAULTS.CONNECTION_TIMEOUT);
112
+ this.ws.once("open", () => {
113
+ this.clearConnectionTimeout();
114
+ this.logger.log("WebSocket connected, waiting for tunnel_established");
115
+ });
116
+ this.ws.on("pong", () => this.handlePong());
117
+ this.ws.on("message", (data) => {
118
+ try {
119
+ const message = JSON.parse(data.toString());
120
+ if (message.type === "tunnel_established" &&
121
+ this.currentTunnelUrl === null) {
122
+ const establishedMsg = message;
123
+ this.currentTunnelUrl = establishedMsg.url;
124
+ this.logger.log(`Tunnel established: ${establishedMsg.url}`);
125
+ this.startHealthCheck();
126
+ this.emit("connected");
127
+ this.emit("tunnel_url", establishedMsg.url);
128
+ resolve(establishedMsg.url);
129
+ }
130
+ else {
131
+ this.handleMessage(message).catch((error) => {
132
+ this.logger.error("Error handling message:", error);
133
+ this.emit("error", new TunnelClientError("Message handling failed", "message_error", error));
134
+ });
135
+ }
136
+ }
137
+ catch (error) {
138
+ this.logger.error("Failed to parse message:", error);
139
+ this.emit("error", new TunnelClientError("Invalid message format", "parse_error", error));
140
+ }
141
+ });
142
+ this.ws.on("close", (code, reason) => {
143
+ this.clearConnectionTimeout();
144
+ this.stopHealthCheck();
145
+ const reasonStr = reason.toString();
146
+ this.logger.log(`WebSocket closed: ${code} - ${reasonStr}`);
147
+ this.currentTunnelUrl = null;
148
+ this.emit("disconnected", code, reasonStr);
149
+ if (!this.isManualDisconnect) {
150
+ this.handleReconnection(code);
151
+ }
152
+ });
153
+ this.ws.on("error", (error) => {
154
+ this.logger.error("WebSocket error:", error);
155
+ this.emit("error", new TunnelClientError("WebSocket error", "websocket_error", error));
156
+ if (this.currentTunnelUrl === null) {
157
+ reject(new TunnelClientError(`Failed to connect: ${error.message}`, "connection_failed", error));
158
+ }
159
+ });
160
+ });
161
+ }
162
+ async handleMessage(message) {
163
+ switch (message.type) {
164
+ case "request":
165
+ await this.handleRequest(message);
166
+ break;
167
+ case "ping":
168
+ this.handlePing(message);
169
+ break;
170
+ case "error":
171
+ this.handleError(message);
172
+ break;
173
+ case "url_changed":
174
+ this.handleUrlChanged(message);
175
+ break;
176
+ default:
177
+ this.logger.warn(`Unknown message type: ${message.type}`);
178
+ }
179
+ }
180
+ async handleRequest(message) {
181
+ this.logger.debug(`Handling request ${message.requestId}: ${message.method} ${message.path}`);
182
+ this.emit("request", message.requestId, message);
183
+ try {
184
+ const bodyStr = message.body ?? "";
185
+ const response = await this.mcpHandler.handle({
186
+ method: message.method,
187
+ path: message.path,
188
+ headers: message.headers,
189
+ body: bodyStr,
190
+ });
191
+ this.sendResponse({
192
+ type: "response",
193
+ requestId: message.requestId,
194
+ statusCode: response.status,
195
+ headers: response.headers || {},
196
+ body: response.body,
197
+ });
198
+ }
199
+ catch (error) {
200
+ this.logger.error(`Error handling request ${message.requestId}:`, error);
201
+ this.sendResponse({
202
+ type: "response",
203
+ requestId: message.requestId,
204
+ statusCode: 500,
205
+ headers: {},
206
+ body: JSON.stringify({
207
+ error: "Internal server error",
208
+ message: error instanceof Error ? error.message : String(error),
209
+ }),
210
+ });
211
+ }
212
+ }
213
+ handlePing(message) {
214
+ this.lastServerPingTime = Date.now();
215
+ this.logger.debug("Received ping, sending pong");
216
+ this.sendPong({ type: "pong", timestamp: message.timestamp });
217
+ }
218
+ handleError(message) {
219
+ this.logger.warn(`Server error: ${message.code} - ${message.message}`);
220
+ this.emit("error", new TunnelClientError(message.message, message.code));
221
+ }
222
+ handleUrlChanged(message) {
223
+ this.logger.log(`Tunnel URL changed: ${message.oldUrl} → ${message.newUrl}`);
224
+ this.currentTunnelUrl = message.newUrl;
225
+ this.emit("url_changed", message.oldUrl, message.newUrl);
226
+ }
227
+ sendResponse(message) {
228
+ if (this.ws?.readyState === ws_1.default.OPEN) {
229
+ this.ws.send(JSON.stringify(message));
230
+ }
231
+ else {
232
+ this.logger.error("Cannot send response: WebSocket not open");
233
+ }
234
+ }
235
+ sendPong(message) {
236
+ if (this.ws?.readyState === ws_1.default.OPEN) {
237
+ this.ws.send(JSON.stringify(message));
238
+ }
239
+ else {
240
+ this.logger.error("Cannot send pong: WebSocket not open");
241
+ }
242
+ }
243
+ handleReconnection(closeCode) {
244
+ this.clearReconnectTimer();
245
+ if (closeCode === tunnel_protocol_1.TunnelCloseCodes.NORMAL) {
246
+ this.logger.log("Normal closure, not reconnecting");
247
+ return;
248
+ }
249
+ if (closeCode === tunnel_protocol_1.TunnelCloseCodes.ACCOUNT_DELETED) {
250
+ this.logger.warn("Account deleted, not reconnecting");
251
+ return;
252
+ }
253
+ if (closeCode === tunnel_protocol_1.TunnelCloseCodes.SESSION_REPLACED) {
254
+ this.logger.warn("Disconnected: another device connected. Run `ankimcp --tunnel` to reconnect.");
255
+ return;
256
+ }
257
+ if (closeCode === tunnel_protocol_1.TunnelCloseCodes.TOKEN_REVOKED) {
258
+ this.emit("error", new TunnelClientError("Token was revoked. Please run `ankimcp --login` to re-authenticate.", "session_expired"));
259
+ return;
260
+ }
261
+ if (this.reconnectAttempts >= tunnel_protocol_1.TUNNEL_DEFAULTS.RECONNECT_MAX_ATTEMPTS) {
262
+ this.logger.error(`Max reconnection attempts (${tunnel_protocol_1.TUNNEL_DEFAULTS.RECONNECT_MAX_ATTEMPTS}) reached, giving up`);
263
+ this.emit("error", new TunnelClientError("Max reconnection attempts reached", "max_reconnect_attempts"));
264
+ return;
265
+ }
266
+ const baseDelay = tunnel_protocol_1.TUNNEL_DEFAULTS.RECONNECT_INITIAL_DELAY;
267
+ const maxDelay = tunnel_protocol_1.TUNNEL_DEFAULTS.RECONNECT_MAX_DELAY;
268
+ const exponentialDelay = baseDelay * Math.pow(2, this.reconnectAttempts);
269
+ const jitter = Math.random() * 0.3 * exponentialDelay;
270
+ const delay = Math.min(exponentialDelay + jitter, maxDelay);
271
+ this.reconnectAttempts++;
272
+ this.logger.log(`Reconnecting in ${Math.round(delay / 1000)}s (attempt ${this.reconnectAttempts}/${tunnel_protocol_1.TUNNEL_DEFAULTS.RECONNECT_MAX_ATTEMPTS})`);
273
+ const isAuthError = closeCode === tunnel_protocol_1.TunnelCloseCodes.AUTH_FAILED ||
274
+ closeCode === tunnel_protocol_1.TunnelCloseCodes.TUNNEL_AUTH_FAILED;
275
+ this.reconnectTimer = setTimeout(async () => {
276
+ try {
277
+ if (isAuthError) {
278
+ this.logger.log("Auth error detected, refreshing token before reconnect");
279
+ await this.refreshTokenAndSave();
280
+ }
281
+ await this.connect();
282
+ }
283
+ catch (error) {
284
+ this.logger.error("Reconnection failed:", error);
285
+ if (error instanceof TunnelClientError &&
286
+ error.code === "session_expired") {
287
+ this.emit("error", error);
288
+ }
289
+ else {
290
+ this.emit("error", new TunnelClientError("Reconnection failed", "reconnect_failed", error));
291
+ }
292
+ }
293
+ }, delay);
294
+ }
295
+ startHealthCheck() {
296
+ this.stopHealthCheck();
297
+ this.lastServerPingTime = Date.now();
298
+ this.healthCheckInterval = setInterval(() => {
299
+ this.checkConnectionHealth();
300
+ }, tunnel_protocol_1.TUNNEL_DEFAULTS.HEARTBEAT_INTERVAL);
301
+ }
302
+ stopHealthCheck() {
303
+ if (this.healthCheckInterval) {
304
+ clearInterval(this.healthCheckInterval);
305
+ this.healthCheckInterval = null;
306
+ }
307
+ if (this.pongTimeout) {
308
+ clearTimeout(this.pongTimeout);
309
+ this.pongTimeout = null;
310
+ }
311
+ }
312
+ checkConnectionHealth() {
313
+ if (this.ws?.readyState !== ws_1.default.OPEN) {
314
+ return;
315
+ }
316
+ const timeSinceServerPing = Date.now() - this.lastServerPingTime;
317
+ const maxSilence = tunnel_protocol_1.TUNNEL_DEFAULTS.HEARTBEAT_INTERVAL * 2;
318
+ if (timeSinceServerPing > maxSilence) {
319
+ this.logger.error(`Connection appears dead: no server ping in ${Math.round(timeSinceServerPing / 1000)}s`);
320
+ this.ws.terminate();
321
+ return;
322
+ }
323
+ this.logger.debug("Sending health check ping");
324
+ this.ws.ping();
325
+ if (this.pongTimeout) {
326
+ clearTimeout(this.pongTimeout);
327
+ }
328
+ this.pongTimeout = setTimeout(() => {
329
+ this.logger.error(`Connection dead: no pong received in ${tunnel_protocol_1.TUNNEL_DEFAULTS.HEARTBEAT_TIMEOUT}ms`);
330
+ this.ws?.terminate();
331
+ }, tunnel_protocol_1.TUNNEL_DEFAULTS.HEARTBEAT_TIMEOUT);
332
+ }
333
+ handlePong() {
334
+ this.logger.debug("Received pong (health check)");
335
+ if (this.pongTimeout) {
336
+ clearTimeout(this.pongTimeout);
337
+ this.pongTimeout = null;
338
+ }
339
+ }
340
+ async refreshTokenAndSave() {
341
+ if (!this.credentials) {
342
+ throw new TunnelClientError("No credentials to refresh", "no_credentials");
343
+ }
344
+ try {
345
+ const tokenResponse = await this.deviceFlowService.refreshToken(this.credentials.refresh_token);
346
+ const expiresAt = new Date(Date.now() + tokenResponse.expires_in * 1000).toISOString();
347
+ this.credentials = {
348
+ ...this.credentials,
349
+ access_token: tokenResponse.access_token,
350
+ refresh_token: tokenResponse.refresh_token,
351
+ expires_at: expiresAt,
352
+ };
353
+ await this.credentialsService.saveCredentials(this.credentials);
354
+ this.logger.log("Access token refreshed and saved");
355
+ }
356
+ catch (error) {
357
+ if (error instanceof device_flow_service_1.DeviceFlowError || error instanceof ky_1.HTTPError) {
358
+ throw new TunnelClientError("Session expired. Please run `ankimcp --login` to re-authenticate.", "session_expired", error);
359
+ }
360
+ throw error;
361
+ }
362
+ }
363
+ clearReconnectTimer() {
364
+ if (this.reconnectTimer) {
365
+ clearTimeout(this.reconnectTimer);
366
+ this.reconnectTimer = null;
367
+ }
368
+ }
369
+ clearConnectionTimeout() {
370
+ if (this.connectionTimeout) {
371
+ clearTimeout(this.connectionTimeout);
372
+ this.connectionTimeout = null;
373
+ }
374
+ }
375
+ wrapError(error, operation) {
376
+ if (error instanceof TunnelClientError) {
377
+ return error;
378
+ }
379
+ if (error instanceof device_flow_service_1.DeviceFlowError) {
380
+ return new TunnelClientError(`${operation} failed: ${error.message}`, error.code, error);
381
+ }
382
+ return new TunnelClientError(`${operation} failed: ${error instanceof Error ? error.message : String(error)}`, "unknown_error", error);
383
+ }
384
+ }
385
+ exports.TunnelClient = TunnelClient;
386
+ //# sourceMappingURL=tunnel.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.client.js","sourceRoot":"","sources":["../../src/tunnel/tunnel.client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ export interface TunnelMessage {
2
+ type: string;
3
+ [key: string]: unknown;
4
+ }
5
+ export interface TunnelEstablishedMessage extends TunnelMessage {
6
+ type: "tunnel_established";
7
+ url: string;
8
+ expiresAt: string | null;
9
+ }
10
+ export interface TunnelRequestMessage extends TunnelMessage {
11
+ type: "request";
12
+ requestId: string;
13
+ method: string;
14
+ path: string;
15
+ headers: Record<string, string>;
16
+ body?: string;
17
+ }
18
+ export interface TunnelPingMessage extends TunnelMessage {
19
+ type: "ping";
20
+ timestamp: number;
21
+ }
22
+ export interface TunnelErrorMessage extends TunnelMessage {
23
+ type: "error";
24
+ code: string;
25
+ message: string;
26
+ details?: unknown;
27
+ }
28
+ export interface TunnelUrlChangedMessage extends TunnelMessage {
29
+ type: "url_changed";
30
+ oldUrl: string;
31
+ newUrl: string;
32
+ }
33
+ export type ServerMessage = TunnelEstablishedMessage | TunnelRequestMessage | TunnelPingMessage | TunnelErrorMessage | TunnelUrlChangedMessage;
34
+ export interface TunnelResponseMessage extends TunnelMessage {
35
+ type: "response";
36
+ requestId: string;
37
+ statusCode: number;
38
+ headers: Record<string, string>;
39
+ body?: string;
40
+ }
41
+ export interface TunnelPongMessage extends TunnelMessage {
42
+ type: "pong";
43
+ timestamp: number;
44
+ }
45
+ export type ClientMessage = TunnelResponseMessage | TunnelPongMessage;
46
+ export declare const TunnelCloseCodes: {
47
+ readonly NORMAL: 1000;
48
+ readonly GOING_AWAY: 1001;
49
+ readonly AUTH_FAILED: 4001;
50
+ readonly TOKEN_REVOKED: 4002;
51
+ readonly TUNNEL_AUTH_FAILED: 4003;
52
+ readonly ACCOUNT_DELETED: 4004;
53
+ readonly SESSION_REPLACED: 4005;
54
+ readonly URL_REGENERATED: 4006;
55
+ readonly SERVICE_UNAVAILABLE: 4008;
56
+ readonly SHUTDOWN: 4009;
57
+ };
58
+ export type TunnelCloseCode = (typeof TunnelCloseCodes)[keyof typeof TunnelCloseCodes];
59
+ export declare const TUNNEL_DEFAULTS: {
60
+ readonly URL: "ws://localhost:3004/tunnel";
61
+ readonly CONNECTION_TIMEOUT: 10000;
62
+ readonly REQUEST_TIMEOUT: 30000;
63
+ readonly HEARTBEAT_INTERVAL: 30000;
64
+ readonly HEARTBEAT_TIMEOUT: 10000;
65
+ readonly RECONNECT_INITIAL_DELAY: 1000;
66
+ readonly RECONNECT_MAX_DELAY: 30000;
67
+ readonly RECONNECT_MAX_ATTEMPTS: 10;
68
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TUNNEL_DEFAULTS = exports.TunnelCloseCodes = void 0;
4
+ exports.TunnelCloseCodes = {
5
+ NORMAL: 1000,
6
+ GOING_AWAY: 1001,
7
+ AUTH_FAILED: 4001,
8
+ TOKEN_REVOKED: 4002,
9
+ TUNNEL_AUTH_FAILED: 4003,
10
+ ACCOUNT_DELETED: 4004,
11
+ SESSION_REPLACED: 4005,
12
+ URL_REGENERATED: 4006,
13
+ SERVICE_UNAVAILABLE: 4008,
14
+ SHUTDOWN: 4009,
15
+ };
16
+ exports.TUNNEL_DEFAULTS = {
17
+ URL: "ws://localhost:3004/tunnel",
18
+ CONNECTION_TIMEOUT: 10000,
19
+ REQUEST_TIMEOUT: 30000,
20
+ HEARTBEAT_INTERVAL: 30000,
21
+ HEARTBEAT_TIMEOUT: 10000,
22
+ RECONNECT_INITIAL_DELAY: 1000,
23
+ RECONNECT_MAX_DELAY: 30000,
24
+ RECONNECT_MAX_ATTEMPTS: 10,
25
+ };
26
+ //# sourceMappingURL=tunnel.protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.protocol.js","sourceRoot":"","sources":["../../src/tunnel/tunnel.protocol.ts"],"names":[],"mappings":";;;AA2Fa,QAAA,gBAAgB,GAAG;IAE9B,MAAM,EAAE,IAAI;IAEZ,UAAU,EAAE,IAAI;IAEhB,WAAW,EAAE,IAAI;IAEjB,aAAa,EAAE,IAAI;IAEnB,kBAAkB,EAAE,IAAI;IAExB,eAAe,EAAE,IAAI;IAErB,gBAAgB,EAAE,IAAI;IAEtB,eAAe,EAAE,IAAI;IAErB,mBAAmB,EAAE,IAAI;IAEzB,QAAQ,EAAE,IAAI;CACN,CAAC;AASE,QAAA,eAAe,GAAG;IAC7B,GAAG,EAAE,4BAA4B;IACjC,kBAAkB,EAAE,KAAK;IACzB,eAAe,EAAE,KAAK;IACtB,kBAAkB,EAAE,KAAK;IACzB,iBAAiB,EAAE,KAAK;IACxB,uBAAuB,EAAE,IAAI;IAC7B,mBAAmB,EAAE,KAAK;IAC1B,sBAAsB,EAAE,EAAE;CAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function getVersion(): string;
2
+ export declare function getPackageName(): string;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getVersion = getVersion;
4
+ exports.getPackageName = getPackageName;
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ function getPackageJson() {
8
+ try {
9
+ return JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, "../package.json"), "utf-8"));
10
+ }
11
+ catch {
12
+ return { version: "0.0.0", name: "ankimcp" };
13
+ }
14
+ }
15
+ function getVersion() {
16
+ return getPackageJson().version;
17
+ }
18
+ function getPackageName() {
19
+ return getPackageJson().name;
20
+ }
21
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;AAaA,gCAEC;AAED,wCAEC;AAnBD,2BAAkC;AAClC,+BAA4B;AAE5B,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CACf,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO,cAAc,EAAE,CAAC,OAAO,CAAC;AAClC,CAAC;AAED,SAAgB,cAAc;IAC5B,OAAO,cAAc,EAAE,CAAC,IAAI,CAAC;AAC/B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@ankimcp/anki-mcp-server",
3
- "version": "0.18.0",
3
+ "mcpName": "ai.ankimcp/anki-mcp-server",
4
+ "version": "0.18.4-tunnel",
4
5
  "description": "Model Context Protocol server for Anki - enables AI assistants to interact with your Anki flashcards",
5
6
  "author": "Anatoly Tarnavsky",
6
7
  "private": false,
@@ -17,6 +18,7 @@
17
18
  "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
18
19
  "start:dev:stdio": "nest start --watch --entryFile main-stdio",
19
20
  "start:dev:http": "nest start --watch --entryFile main-http",
21
+ "start:dev:tunnel": "nest start --watch --entryFile main-tunnel -- --tunnel --debug",
20
22
  "start:debug:stdio": "nest start --debug --watch --entryFile main-stdio",
21
23
  "start:debug:http": "nest start --debug --watch --entryFile main-http",
22
24
  "start:prod:stdio": "node dist/main-stdio",
@@ -48,6 +50,7 @@
48
50
  "mcpb:bundle": "npm run sync-version && npm run mcpb:clean && npm run build && mcpb pack . \"anki-mcp-server-$npm_package_version.mcpb\" && mcpb clean \"anki-mcp-server-$npm_package_version.mcpb\"",
49
51
  "pack:local": "rm -f *.tgz && npm run build && npm pack",
50
52
  "install:local": "npm install -g ./ankimcp-anki-mcp-server-*.tgz",
53
+ "install:npm": "npm install -g @ankimcp/anki-mcp-server@tunnel",
51
54
  "uninstall:local": "npm uninstall -g @ankimcp/anki-mcp-server",
52
55
  "upgrade:interactive": "npx npm-check-updates -i",
53
56
  "prepare": "husky"
@@ -76,6 +79,7 @@
76
79
  "unified": "^11.0.5",
77
80
  "unist-util-visit": "^5.1.0",
78
81
  "update-notifier": "^7.3.1",
82
+ "ws": "^8.20.0",
79
83
  "zod": "^4.3.6",
80
84
  "zod-to-json-schema": "^3.25.2"
81
85
  },
@@ -94,6 +98,7 @@
94
98
  "@types/node": "^25.6.0",
95
99
  "@types/supertest": "^7.2.0",
96
100
  "@types/update-notifier": "^6.0.8",
101
+ "@types/ws": "^8.18.1",
97
102
  "eslint": "^10.2.1",
98
103
  "eslint-config-prettier": "^10.1.8",
99
104
  "eslint-plugin-prettier": "^5.5.5",
@@ -157,7 +162,7 @@
157
162
  ],
158
163
  "forceExit": true
159
164
  },
160
- "packageManager": "npm@11.12.1",
165
+ "packageManager": "npm@11.13.0",
161
166
  "engines": {
162
167
  "node": ">=20.19.0 <21.0.0 || >=22.12.0"
163
168
  },
@@ -1,11 +0,0 @@
1
- import { ConfigService } from "@nestjs/config";
2
- import { IAnkiConfig } from "./mcp/config/anki-config.interface";
3
- export declare class AnkiConfigService implements IAnkiConfig {
4
- private configService;
5
- constructor(configService: ConfigService);
6
- get ankiConnectUrl(): string;
7
- get ankiConnectApiVersion(): number;
8
- get ankiConnectApiKey(): string | undefined;
9
- get ankiConnectTimeout(): number;
10
- get readOnly(): boolean;
11
- }
@@ -1,46 +0,0 @@
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.AnkiConfigService = void 0;
13
- const common_1 = require("@nestjs/common");
14
- const config_1 = require("@nestjs/config");
15
- const mcpb_workarounds_1 = require("./mcp/utils/mcpb-workarounds");
16
- let AnkiConfigService = class AnkiConfigService {
17
- configService;
18
- constructor(configService) {
19
- this.configService = configService;
20
- }
21
- get ankiConnectUrl() {
22
- return this.configService.get("ANKI_CONNECT_URL", "http://localhost:8765");
23
- }
24
- get ankiConnectApiVersion() {
25
- const version = this.configService.get("ANKI_CONNECT_API_VERSION", "6");
26
- return parseInt(version, 10);
27
- }
28
- get ankiConnectApiKey() {
29
- const apiKey = this.configService.get("ANKI_CONNECT_API_KEY");
30
- return (0, mcpb_workarounds_1.sanitizeMcpbConfigValue)(apiKey);
31
- }
32
- get ankiConnectTimeout() {
33
- const timeout = this.configService.get("ANKI_CONNECT_TIMEOUT", "5000");
34
- return parseInt(timeout, 10);
35
- }
36
- get readOnly() {
37
- const readOnly = this.configService.get("READ_ONLY", "false");
38
- return readOnly === "true" || readOnly === "1";
39
- }
40
- };
41
- exports.AnkiConfigService = AnkiConfigService;
42
- exports.AnkiConfigService = AnkiConfigService = __decorate([
43
- (0, common_1.Injectable)(),
44
- __metadata("design:paramtypes", [config_1.ConfigService])
45
- ], AnkiConfigService);
46
- //# sourceMappingURL=anki-config.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"anki-config.service.js","sourceRoot":"","sources":["../src/anki-config.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAA+C;AAE/C,mEAAuE;AAMhE,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IACR;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAC3B,kBAAkB,EAClB,uBAAuB,CACxB,CAAC;IACJ,CAAC;IAED,IAAI,qBAAqB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CACpC,0BAA0B,EAC1B,GAAG,CACJ,CAAC;QACF,OAAO,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,iBAAiB;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,sBAAsB,CAAC,CAAC;QACtE,OAAO,IAAA,0CAAuB,EAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,kBAAkB;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CACpC,sBAAsB,EACtB,MAAM,CACP,CAAC;QACF,OAAO,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,QAAQ;QACV,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,WAAW,EAAE,OAAO,CAAC,CAAC;QACtE,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,GAAG,CAAC;IACjD,CAAC;CACF,CAAA;AAnCY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;qCAEwB,sBAAa;GADrC,iBAAiB,CAmC7B"}